import from github

This commit is contained in:
2022-05-19 17:14:13 +00:00
parent 5247c34f50
commit ab32b30591
12612 changed files with 1905035 additions and 83 deletions

7
agbcc/libc/.gitattributes vendored Normal file
View File

@ -0,0 +1,7 @@
* text eol=lf
*.s text
*.S text
*.txt text
Makefile text
*.c text
*.h text

5
agbcc/libc/.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
tools/
libc.a
*.o
*.i
*.s

130
agbcc/libc/COPYING.NEWLIB Normal file
View File

@ -0,0 +1,130 @@
The newlib subdirectory is a collection of software from several sources.
Each have their own copyrights embedded in each file that they concern.
(1) University of California, Berkeley
Copyright (c) 1990 The Regents of the University of California.
All rights reserved.
Redistribution and use in source and binary forms are permitted
provided that the above copyright notice and this paragraph are
duplicated in all such forms and that any documentation,
advertising materials, and other materials related to such
distribution and use acknowledge that the software was developed
by the University of California, Berkeley. The name of the
University may not 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.
(2) DJ Delorie
Copyright (C) 1991 DJ Delorie, 24 Kirsten Ave, Rochester NH 03867-2954
This file is distributed under the terms listed in the document
"copying.dj", available from DJ Delorie at the address above.
A copy of "copying.dj" should accompany this file; if not, a copy
should be available from where this file was obtained. This file
may not be distributed without a verbatim copy of "copying.dj".
This file is distributed WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
(3) David M. Gay at AT&T
The author of this software is David M. Gay.
Copyright (c) 1991 by AT&T.
Permission to use, copy, modify, and distribute this software for any
purpose without fee is hereby granted, provided that this entire notice
is included in all copies of any software which is or includes a copy
or modification of this software and in all copies of the supporting
documentation for such software.
THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY
REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
(4) Advanced Micro Devices
Copyright 1989, 1990 Advanced Micro Devices, Inc.
This software is the property of Advanced Micro Devices, Inc (AMD) which
specifically grants the user the right to modify, use and distribute this
software provided this notice is not removed or altered. All other rights
are reserved by AMD.
AMD MAKES NO WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, WITH REGARD TO THIS
SOFTWARE. IN NO EVENT SHALL AMD BE LIABLE FOR INCIDENTAL OR CONSEQUENTIAL
DAMAGES IN CONNECTION WITH OR ARISING FROM THE FURNISHING, PERFORMANCE, OR
USE OF THIS SOFTWARE.
So that all may benefit from your experience, please report any problems
or suggestions about this software to the 29K Technical Support Center at
800-29-29-AMD (800-292-9263) in the USA, or 0800-89-1131 in the UK, or
0031-11-1129 in Japan, toll free. The direct dial number is 512-462-4118.
Advanced Micro Devices, Inc.
29K Support Products
Mail Stop 573
5900 E. Ben White Blvd.
Austin, TX 78741
800-292-9263
(5) C.W. Sandmann
Copyright (C) 1993 C.W. Sandmann
This file may be freely distributed as long as the author's name remains.
(6) Eric Backus
(C) Copyright 1992 Eric Backus
This software may be used freely so long as this copyright notice is
left intact. There is no warrantee on this software.
(7) Sun Microsystems
Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
Developed at SunPro, a Sun Microsystems, Inc. business.
Permission to use, copy, modify, and distribute this
software is freely granted, provided that this notice
is preserved.
(8) Hewlett Packard
(c) Copyright 1986 HEWLETT-PACKARD COMPANY
To anyone who acknowledges that this file is provided "AS IS"
without any express or implied warranty:
permission to use, copy, modify, and distribute this file
for any purpose is hereby granted without fee, provided that
the above copyright notice and this notice appears in all
copies, and that the name of Hewlett-Packard Company not be
used in advertising or publicity pertaining to distribution
of the software without specific, written prior permission.
Hewlett-Packard Company makes no representations about the
suitability of this software for any purpose.
(9) Unless otherwise stated in each remaining newlib file, the remaining
files in the newlib subdirectory are governed by the following copyright.
Copyright (c) 1994, 1997 Cygnus Solutions.
All rights reserved.
Redistribution and use in source and binary forms are permitted
provided that the above copyright notice and this paragraph are
duplicated in all such forms and that any documentation,
advertising materials, and other materials related to such
distribution and use acknowledge that the software was developed
at Cygnus Solutions. Cygnus Solutions may not 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.

118
agbcc/libc/Makefile Normal file
View File

@ -0,0 +1,118 @@
ifneq (,$(DEVKITARM))
ifneq (,$(wildcard $(DEVKITARM)/bin))
include $(DEVKITARM)/base_tools
DKA_EXISTS=1
else
DKA_EXISTS=0
endif
else
DKA_EXISTS=0
endif
ifneq ($(DKA_EXISTS),1)
PREFIX := arm-none-eabi-
export AR := $(PREFIX)ar
export AS := $(PREFIX)as
endif
SHELL := /bin/bash -o pipefail
ASFLAGS := -mcpu=arm7tdmi
CC1 := ../old_agbcc
CFLAGS := -O2 -fno-builtin
CPPFLAGS := -I ../ginclude -I include -nostdinc -undef \
-DABORT_PROVIDED -DHAVE_GETTIMEOFDAY -D__thumb__ -DARM_RDI_MONITOR \
-D__GNUC__ -DINTERNAL_NEWLIB -D__USER_LABEL_PREFIX__=
# Clear the default suffixes.
.SUFFIXES:
# Secondary expansion is required for dependency variables in object rules.
.SECONDEXPANSION:
.PHONY: all clean
C_SRCS := $(shell find . -iname "*.c" -a ! -iname "mallocr.c")
C_INTRS := $(C_SRCS:%.c=%.i)
C_OBJS := $(C_SRCS:%.c=%.o) \
stdlib/mallocr.o stdlib/freer.o stdlib/reallocr.o stdlib/callocr.o \
stdlib/cfreer.o stdlib/malignr.o stdlib/vallocr.o stdlib/pvallocr.o \
stdlib/mallinfor.o stdlib/mallstatsr.o stdlib/msizer.o stdlib/malloptr.o \
stdio/vfiprintf.o
S_SRCS := arm/setjmp.s arm/trap.s
S_OBJS := $(S_SRCS:%.s=%.o)
OBJS := $(C_OBJS) $(S_OBJS)
all: libc.a
@:
clean:
rm -f $(OBJS)
rm -f $(C_OBJS:%.o=%.i)
rm -f $(C_OBJS:%.o=%.s)
rm -f $(S_OBJS:%.o=%.i)
rm -f libc.a
PREPROCESS := $(CPP) $(CPPFLAGS)
stdlib/mallocr.i: stdlib/mallocr.c
$(PREPROCESS) -DDEFINE_MALLOC $< -o $@
stdlib/freer.i: stdlib/mallocr.c
$(PREPROCESS) -DDEFINE_FREE $< -o $@
stdlib/reallocr.i: stdlib/mallocr.c
$(PREPROCESS) -DDEFINE_REALLOC $< -o $@
stdlib/callocr.i: stdlib/mallocr.c
$(PREPROCESS) -DDEFINE_CALLOC $< -o $@
stdlib/cfreer.i: stdlib/mallocr.c
$(PREPROCESS) -DDEFINE_CFREE $< -o $@
stdlib/malignr.i: stdlib/mallocr.c
$(PREPROCESS) -DDEFINE_MEMALIGN $< -o $@
stdlib/vallocr.i: stdlib/mallocr.c
$(PREPROCESS) -DDEFINE_VALLOC $< -o $@
stdlib/pvallocr.i: stdlib/mallocr.c
$(PREPROCESS) -DDEFINE_PVALLOC $< -o $@
stdlib/mallinfor.i: stdlib/mallocr.c
$(PREPROCESS) -DDEFINE_MALLINFO $< -o $@
stdlib/mallstatsr.i: stdlib/mallocr.c
$(PREPROCESS) -DDEFINE_MALLOC_STATS $< -o $@
stdlib/msizer.i: stdlib/mallocr.c
$(PREPROCESS) -DDEFINE_MALLOC_USABLE_SIZE $< -o $@
stdlib/malloptr.i: stdlib/mallocr.c
$(PREPROCESS) -DDEFINE_MALLOPT $< -o $@
stdio/vfiprintf.i: stdio/vfprintf.c
$(PREPROCESS) -DINTEGER_ONLY $< -o $@
$(C_INTRS): %.i : %.c
$(PREPROCESS) $< -o $@
stdlib/mbtowc_r.o: CFLAGS := $(CFLAGS) -fshort-enums
$(C_OBJS): %.o : %.i
@$(CC1) $(CFLAGS) $< -o $*.s
@printf ".text\n\t.align\t2, 0\n" >> $*.s
$(AS) $(ASFLAGS) -o $@ $*.s
$(S_OBJS): %.o: %.s
@$(CPP) $(CPPFLAGS) $< -o $*.i
@printf ".text\n\t.align\t2, 0\n" >> $*.i
$(AS) $(ASFLAGS) -o $@ $*.i
libc.a: $(OBJS)
$(AR) -rc libc.a $(OBJS)

45
agbcc/libc/arm/libcfunc.c Normal file
View File

@ -0,0 +1,45 @@
/* Support files for GNU libc. Files in the C namespace go here.
Files in the system namespace (ie those that start with an underscore)
go in syscalls.c.
Note: These functions are in a seperate file so that OS providers can
overrride the system call stubs (defined in syscalls.c) without having
to provide libc funcitons as well. */
#include "swi.h"
#ifdef ARM_RDI_MONITOR
static inline int
do_AngelSWI (int reason, void * arg)
{
int value;
asm volatile ("mov r0, %1; mov r1, %2; swi %a3; mov %0, r0"
: "=r" (value) /* Outputs */
: "r" (reason), "r" (arg), "i" (AngelSWI) /* Inputs */
: "r0", "r1", "lr"
/* Clobbers r0 and r1, and lr if in supervisor mode */);
return value;
}
#endif /* ARM_RDI_MONITOR */
void
abort (void)
{
#ifdef ARM_RDI_MONITOR
do_AngelSWI (AngelSWI_Reason_ReportException,
(void *) ADP_Stopped_RunTimeError);
#else
asm ("mov r0,#17\nswi %a0" :: "i" (SWI_Exit));
#endif
}
isatty (int fd)
{
return 1;
}
void
alarm (void)
{
}

65
agbcc/libc/arm/swi.h Normal file
View File

@ -0,0 +1,65 @@
/***************************************************************************\
* SWI numbers *
\***************************************************************************/
/* SWI numbers for RDP (Demon) monitor */
#define SWI_WriteC 0x0
#define SWI_Write0 0x2
#define SWI_ReadC 0x4
#define SWI_CLI 0x5
#define SWI_GetEnv 0x10
#define SWI_Exit 0x11
#define SWI_EnterOS 0x16
#define SWI_GetErrno 0x60
#define SWI_Clock 0x61
#define SWI_Time 0x63
#define SWI_Remove 0x64
#define SWI_Rename 0x65
#define SWI_Open 0x66
#define SWI_Close 0x68
#define SWI_Write 0x69
#define SWI_Read 0x6a
#define SWI_Seek 0x6b
#define SWI_Flen 0x6c
#define SWI_IsTTY 0x6e
#define SWI_TmpNam 0x6f
#define SWI_InstallHandler 0x70
#define SWI_GenerateError 0x71
/* Now the SWI numbers and reason codes for RDI (Angel) monitors */
#define AngelSWI_ARM (0x123456)
#ifdef __thumb__
#define AngelSWI (0xAB)
#else
#define AngelSWI AngelSWI_ARM
#endif
/* The reason codes: */
#define AngelSWI_Reason_Open (0x01)
#define AngelSWI_Reason_Close (0x02)
#define AngelSWI_Reason_WriteC (0x03)
#define AngelSWI_Reason_Write0 (0x04)
#define AngelSWI_Reason_Write (0x05)
#define AngelSWI_Reason_Read (0x06)
#define AngelSWI_Reason_ReadC (0x07)
#define AngelSWI_Reason_IsTTY (0x09)
#define AngelSWI_Reason_Seek (0x0A)
#define AngelSWI_Reason_FLen (0x0C)
#define AngelSWI_Reason_TmpNam (0x0D)
#define AngelSWI_Reason_Remove (0x0E)
#define AngelSWI_Reason_Rename (0x0F)
#define AngelSWI_Reason_Clock (0x10)
#define AngelSWI_Reason_Time (0x11)
#define AngelSWI_Reason_System (0x12)
#define AngelSWI_Reason_Errno (0x13)
#define AngelSWI_Reason_GetCmdLine (0x15)
#define AngelSWI_Reason_HeapInfo (0x16)
#define AngelSWI_Reason_EnterSVC (0x17)
#define AngelSWI_Reason_ReportException (0x18)
#define ADP_Stopped_ApplicationExit ((2 << 16) + 38)
#define ADP_Stopped_RunTimeError ((2 << 16) + 34)

View File

@ -0,0 +1,10 @@
/* ARM configuration file; HZ is 100 rather than the default 60 */
#ifndef _SYS_PARAM_H
# define _SYS_PARAM_H
# define HZ (100)
# define NOFILE (60)
# define PATHSIZE (1024)
#endif

504
agbcc/libc/arm/syscalls.c Normal file
View File

@ -0,0 +1,504 @@
/* Support files for GNU libc. Files in the system namespace go here.
Files in the C namespace (ie those that do not start with an
underscore) go in .c. */
#include <_ansi.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/fcntl.h>
#include <stdio.h>
#include <time.h>
#include <sys/time.h>
#include <sys/times.h>
#include <errno.h>
#include "swi.h"
/* Adjust our internal handles to stay away from std* handles */
#define FILE_HANDLE_OFFSET (0x20)
static int monitor_stdin;
static int monitor_stdout;
static int monitor_stderr;
/* Struct used to keep track of the file position, just so we
can implement fseek(fh,x,SEEK_CUR). */
typedef struct
{
int handle;
int pos;
}
poslog;
#define MAX_OPEN_FILES 20
static poslog openfiles [MAX_OPEN_FILES];
static int
findslot (int fh)
{
int i;
for (i = 0; i < MAX_OPEN_FILES; i ++)
if (openfiles[i].handle == fh)
break;
return i;
}
#ifdef ARM_RDI_MONITOR
static inline int
do_AngelSWI (int reason, void * arg)
{
int value;
asm volatile ("mov r0, %1; mov r1, %2; swi %a3; mov %0, r0"
: "=r" (value) /* Outputs */
: "r" (reason), "r" (arg), "i" (AngelSWI) /* Inputs */
: "r0", "r1", "lr"
/* Clobbers r0 and r1, and lr if in supervisor mode */);
return value;
}
#endif /* ARM_RDI_MONITOR */
/* Function to convert std(in|out|err) handles to internal versions */
static int
remap_handle (int fh)
{
if (fh == __sfileno (stdin))
return monitor_stdin;
if (fh == __sfileno (stdout))
return monitor_stdout;
if (fh == __sfileno (stderr))
return monitor_stderr;
return fh - FILE_HANDLE_OFFSET;
}
void
initialise_monitor_handles (void)
{
int i;
#ifdef ARM_RDI_MONITOR
int block[3];
block[0] = (int) ":tt";
block[2] = 3; /* length of filename */
block[1] = 0; /* mode "r" */
monitor_stdin = do_AngelSWI (AngelSWI_Reason_Open, block);
block[0] = (int) ":tt";
block[2] = 3; /* length of filename */
block[1] = 4; /* mode "w" */
monitor_stdout = monitor_stderr = do_AngelSWI (AngelSWI_Reason_Open, block);
#else
int fh;
const char * name;
name = ":tt";
asm ("mov r0,%2; mov r1, #0; swi %a1; mov %0, r0"
: "=r"(fh)
: "i" (SWI_Open),"r"(name)
: "r0","r1");
monitor_stdin = fh;
name = ":tt";
asm ("mov r0,%2; mov r1, #4; swi %a1; mov %0, r0"
: "=r"(fh)
: "i" (SWI_Open),"r"(name)
: "r0","r1");
monitor_stdout = monitor_stderr = fh;
#endif
for (i = 0; i < MAX_OPEN_FILES; i ++)
openfiles[i].handle = -1;
openfiles[0].handle = monitor_stdin;
openfiles[0].pos = 0;
openfiles[1].handle = monitor_stdout;
openfiles[1].pos = 0;
}
static int
get_errno ()
{
#ifdef ARM_RDI_MONITOR
return do_AngelSWI (AngelSWI_Reason_Errno, NULL);
#else
asm ("swi %a0" :: "i" (SWI_GetErrno));
#endif
}
static int
error (int result)
{
errno = get_errno ();
return result;
}
static int
wrap (int result)
{
if (result == -1)
return error (-1);
return result;
}
/* Returns # chars not! written */
int
_swiread (int file,
char * ptr,
int len)
{
int fh = remap_handle (file);
#ifdef ARM_RDI_MONITOR
int block[3];
block[0] = fh;
block[1] = (int) ptr;
block[2] = len;
return do_AngelSWI (AngelSWI_Reason_Read, block);
#else
asm ("mov r0, %1; mov r1, %2;mov r2, %3; swi %a0"
: /* No outputs */
: "i"(SWI_Read), "r"(fh), "r"(ptr), "r"(len)
: "r0","r1","r2");
#endif
}
int
_read (int file,
char * ptr,
int len)
{
int slot = findslot (remap_handle (file));
int x = _swiread (file, ptr, len);
if (x < 0)
return error (-1);
if (slot != MAX_OPEN_FILES)
openfiles [slot].pos += len - x;
/* x == len is not an error, at least if we want feof() to work */
return len - x;
}
int
_swilseek (int file,
int ptr,
int dir)
{
int res;
int fh = remap_handle (file);
int slot = findslot (fh);
#ifdef ARM_RDI_MONITOR
int block[2];
#endif
if (dir == SEEK_CUR)
{
if (slot == MAX_OPEN_FILES)
return -1;
ptr = openfiles[slot].pos + ptr;
dir = SEEK_SET;
}
#ifdef ARM_RDI_MONITOR
if (dir == SEEK_END)
{
block[0] = fh;
ptr += do_AngelSWI (AngelSWI_Reason_FLen, block);
}
/* This code only does absolute seeks */
block[0] = remap_handle (file);
block[1] = ptr;
res = do_AngelSWI (AngelSWI_Reason_Seek, block);
#else
if (dir == SEEK_END)
{
asm ("mov r0, %2; swi %a1; mov %0, r0"
: "=r" (res)
: "i" (SWI_Flen), "r" (fh)
: "r0");
ptr += res;
}
/* This code only does absolute seeks */
asm ("mov r0, %2; mov r1, %3; swi %a1; mov %0, r0"
: "=r" (res)
: "i" (SWI_Seek), "r" (fh), "r" (ptr)
: "r0", "r1");
#endif
if (slot != MAX_OPEN_FILES && res == 0)
openfiles[slot].pos = ptr;
/* This is expected to return the position in the file */
return res == 0 ? ptr : -1;
}
int
_lseek (int file,
int ptr,
int dir)
{
return wrap (_swilseek (file, ptr, dir));
}
/* Returns #chars not! written */
int
_swiwrite (
int file,
char * ptr,
int len)
{
int fh = remap_handle (file);
#ifdef ARM_RDI_MONITOR
int block[3];
block[0] = fh;
block[1] = (int) ptr;
block[2] = len;
return do_AngelSWI (AngelSWI_Reason_Write, block);
#else
asm ("mov r0, %1; mov r1, %2;mov r2, %3; swi %a0"
: /* No outputs */
: "i"(SWI_Write), "r"(fh), "r"(ptr), "r"(len)
: "r0","r1","r2");
#endif
}
int
_write (int file,
char * ptr,
int len)
{
int slot = findslot (remap_handle (file));
int x = _swiwrite (file, ptr,len);
if (x == -1 || x == len)
return error (-1);
if (slot != MAX_OPEN_FILES)
openfiles[slot].pos += len - x;
return len - x;
}
int
_swiopen (const char * path,
int flags)
{
int aflags = 0, fh;
#ifdef ARM_RDI_MONITOR
int block[3];
#endif
int i = findslot (-1);
if (i == MAX_OPEN_FILES)
return -1;
/* The flags are Unix-style, so we need to convert them */
#ifdef O_BINARY
if (flags & O_BINARY)
aflags |= 1;
#endif
if (flags & O_RDWR)
aflags |= 2;
if (flags & O_CREAT)
aflags |= 4;
if (flags & O_TRUNC)
aflags |= 4;
if (flags & O_APPEND)
{
aflags &= ~4; /* Can't ask for w AND a; means just 'a' */
aflags |= 8;
}
#ifdef ARM_RDI_MONITOR
block[0] = (int) path;
block[2] = strlen (path);
block[1] = aflags;
fh = do_AngelSWI (AngelSWI_Reason_Open, block);
#else
asm ("mov r0,%2; mov r1, %3; swi %a1; mov %0, r0"
: "=r"(fh)
: "i" (SWI_Open),"r"(path),"r"(aflags)
: "r0","r1");
#endif
if (fh >= 0)
{
openfiles[i].handle = fh;
openfiles[i].pos = 0;
}
return fh >= 0 ? fh + FILE_HANDLE_OFFSET : error (fh);
}
int
_open (const char * path,
int flags,
...)
{
return wrap (_swiopen (path, flags));
}
int
_swiclose (int file)
{
int myhan = remap_handle (file);
int slot = findslot (myhan);
if (slot != MAX_OPEN_FILES)
openfiles[slot].handle = -1;
#ifdef ARM_RDI_MONITOR
return do_AngelSWI (AngelSWI_Reason_Close, & myhan);
#else
asm ("mov r0, %1; swi %a0" :: "i" (SWI_Close),"r"(myhan):"r0");
#endif
}
int
_close (int file)
{
return wrap (_swiclose (file));
}
void
_exit (int n)
{
/* FIXME: return code is thrown away */
#ifdef ARM_RDI_MONITOR
do_AngelSWI (AngelSWI_Reason_ReportException,
(void *) ADP_Stopped_ApplicationExit);
#else
asm ("swi %a0" :: "i" (SWI_Exit));
#endif
}
int
_kill (int n, int m)
{
#ifdef ARM_RDI_MONITOR
do_AngelSWI (AngelSWI_Reason_ReportException,
(void *) ADP_Stopped_ApplicationExit);
#else
asm ("swi %a0" :: "i" (SWI_Exit));
#endif
}
int
_getpid (int n)
{
return 1;
}
register char * stack_ptr asm ("sp");
caddr_t
_sbrk (int incr)
{
extern char end asm ("end"); /* Defined by the linker */
static char * heap_end;
char * prev_heap_end;
if (heap_end == NULL)
heap_end = & end;
prev_heap_end = heap_end;
if (heap_end + incr > stack_ptr)
{
_write (1, "_sbrk: Heap and stack collision\n", 32);
abort ();
}
heap_end += incr;
return (caddr_t) prev_heap_end;
}
int
_fstat (int file,
struct stat * st)
{
st->st_mode = S_IFCHR;
return 0;
}
int
_unlink (void)
{
return -1;
}
void
_raise (void)
{
}
int
_gettimeofday (struct timeval * tp, struct timezone * tzp)
{
if (tp)
{
/* Ask the host for the seconds since the Unix epoch */
#ifdef ARM_RDI_MONITOR
tp->tv_sec = do_AngelSWI (AngelSWI_Reason_Time,NULL);
#else
{
int value;
asm ("swi %a1; mov %0, r0" : "=r" (value): "i" (SWI_Time) : "r0");
tp->tv_sec = value;
}
#endif
tp->tv_usec = 0;
}
/* Return fixed data for the timezone */
if (tzp)
{
tzp->tz_minuteswest = 0;
tzp->tz_dsttime = 0;
}
return 0;
}
/* Return a clock that ticks at 100Hz. */
clock_t
_times(struct tms * tp)
{
clock_t timeval;
#ifdef ARM_RDI_MONITOR
timeval = do_AngelSWI (AngelSWI_Reason_Clock,NULL);
#else
asm ("swi %a1; mov %0, r0" : "=r" (timeval): "i" (SWI_Clock) : "r0");
#endif
if (tp)
{
tp->tms_utime = timeval; /* user time */
tp->tms_stime = 0; /* system time */
tp->tms_cutime = 0; /* user time, children */
tp->tms_cstime = 0; /* system time, children */
}
return timeval;
};

View File

@ -0,0 +1,9 @@
#include <_ansi.h>
#include <ctype.h>
#undef _tolower
int
_DEFUN(_tolower,(c),int c)
{
return isupper(c) ? (c) - 'A' + 'a' : c;
}

View File

@ -0,0 +1,9 @@
#include <_ansi.h>
#include <ctype.h>
#undef _toupper
int
_DEFUN(_toupper,(c),int c)
{
return islower(c) ? c - 'a' + 'A' : c;
}

62
agbcc/libc/ctype/ctype_.c Normal file
View File

@ -0,0 +1,62 @@
/*
* Copyright (c) 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.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)ctype_.c 5.6 (Berkeley) 6/1/90";
#endif /* LIBC_SCCS and not lint */
#include <ctype.h>
#if defined(__CYGWIN__) || defined(__CYGWIN32__)
_CONST char __declspec(dllexport) _ctype_[1 + 256] = {
#else
_CONST char _ctype_[1 + 256] = {
#endif
0,
_C, _C, _C, _C, _C, _C, _C, _C,
_C, _C|_S, _C|_S, _C|_S, _C|_S, _C|_S, _C, _C,
_C, _C, _C, _C, _C, _C, _C, _C,
_C, _C, _C, _C, _C, _C, _C, _C,
_S|_B, _P, _P, _P, _P, _P, _P, _P,
_P, _P, _P, _P, _P, _P, _P, _P,
_N, _N, _N, _N, _N, _N, _N, _N,
_N, _N, _P, _P, _P, _P, _P, _P,
_P, _U|_X, _U|_X, _U|_X, _U|_X, _U|_X, _U|_X, _U,
_U, _U, _U, _U, _U, _U, _U, _U,
_U, _U, _U, _U, _U, _U, _U, _U,
_U, _U, _U, _P, _P, _P, _P, _P,
_P, _L|_X, _L|_X, _L|_X, _L|_X, _L|_X, _L|_X, _L,
_L, _L, _L, _L, _L, _L, _L, _L,
_L, _L, _L, _L, _L, _L, _L, _L,
_L, _L, _L, _P, _P, _P, _P, _C
};

View File

@ -0,0 +1,46 @@
/*
FUNCTION
<<isalnum>>---alphanumeric character predicate
INDEX
isalnum
ANSI_SYNOPSIS
#include <ctype.h>
int isalnum(int <[c]>);
TRAD_SYNOPSIS
#include <ctype.h>
int isalnum(<[c]>);
DESCRIPTION
<<isalnum>> is a macro which classifies ASCII integer values by table
lookup. It is a predicate returning non-zero for alphabetic or
numeric ASCII characters, and <<0>> for other arguments. It is defined
for all integer values.
You can use a compiled subroutine instead of the macro definition by
undefining the macro using `<<#undef isalnum>>'.
RETURNS
<<isalnum>> returns non-zero if <[c]> is a letter (<<a>>--<<z>> or
<<A>>--<<Z>>) or a digit (<<0>>--<<9>>).
PORTABILITY
<<isalnum>> is ANSI C.
No OS subroutines are required.
*/
#include <_ansi.h>
#include <ctype.h>
#undef isalnum
int
_DEFUN(isalnum,(c),int c)
{
return((_ctype_ + 1)[c] & (_U|_L|_N));
}

View File

@ -0,0 +1,44 @@
/*
FUNCTION
<<isalpha>>---alphabetic character predicate
INDEX
isalpha
ANSI_SYNOPSIS
#include <ctype.h>
int isalpha(int <[c]>);
TRAD_SYNOPSIS
#include <ctype.h>
int isalpha(<[c]>);
DESCRIPTION
<<isalpha>> is a macro which classifies ASCII integer values by table
lookup. It is a predicate returning non-zero when <[c]> represents an
alphabetic ASCII character, and 0 otherwise. It is defined only when
<<isascii>>(<[c]>) is true or <[c]> is EOF.
You can use a compiled subroutine instead of the macro definition by
undefining the macro using `<<#undef isalpha>>'.
RETURNS
<<isalpha>> returns non-zero if <[c]> is a letter (<<A>>--<<Z>> or
<<a>>--<<z>>).
PORTABILITY
<<isalpha>> is ANSI C.
No supporting OS subroutines are required.
*/
#include <_ansi.h>
#include <ctype.h>
#undef isalpha
int
_DEFUN(isalpha,(c),int c)
{
return((_ctype_ + 1)[c] & (_U|_L));
}

View File

@ -0,0 +1,43 @@
/*
FUNCTION
<<isascii>>---ASCII character predicate
INDEX
isascii
ANSI_SYNOPSIS
#include <ctype.h>
int isascii(int <[c]>);
TRAD_SYNOPSIS
#include <ctype.h>
int isascii(<[c]>);
DESCRIPTION
<<isascii>> is a macro which returns non-zero when <[c]> is an ASCII
character, and 0 otherwise. It is defined for all integer values.
You can use a compiled subroutine instead of the macro definition by
undefining the macro using `<<#undef isascii>>'.
RETURNS
<<isascii>> returns non-zero if the low order byte of <[c]> is in the range
0 to 127 (<<0x00>>--<<0x7F>>).
PORTABILITY
<<isascii>> is ANSI C.
No supporting OS subroutines are required.
*/
#include <_ansi.h>
#include <ctype.h>
#undef isascii
int
_DEFUN(isascii,(c),int c)
{
return c >= 0 && c< 128;
}

View File

@ -0,0 +1,48 @@
/*
FUNCTION
<<iscntrl>>---control character predicate
INDEX
iscntrl
ANSI_SYNOPSIS
#include <ctype.h>
int iscntrl(int <[c]>);
TRAD_SYNOPSIS
#include <ctype.h>
int iscntrl(<[c]>);
DESCRIPTION
<<iscntrl>> is a macro which classifies ASCII integer values by table
lookup. It is a predicate returning non-zero for control characters, and 0
for other characters. It is defined only when <<isascii>>(<[c]>) is
true or <[c]> is EOF.
You can use a compiled subroutine instead of the macro definition by
undefining the macro using `<<#undef iscntrl>>'.
RETURNS
<<iscntrl>> returns non-zero if <[c]> is a delete character or ordinary
control character (<<0x7F>> or <<0x00>>--<<0x1F>>).
PORTABILITY
<<iscntrl>> is ANSI C.
No supporting OS subroutines are required.
*/
#include <_ansi.h>
#include <ctype.h>
#undef iscntrl
int
_DEFUN(iscntrl,(c),int c)
{
return((_ctype_ + 1)[c] & _C);
}

View File

@ -0,0 +1,43 @@
/*
FUNCTION
<<isdigit>>---decimal digit predicate
INDEX
isdigit
ANSI_SYNOPSIS
#include <ctype.h>
int isdigit(int <[c]>);
TRAD_SYNOPSIS
#include <ctype.h>
int isdigit(<[c]>);
DESCRIPTION
<<isdigit>> is a macro which classifies ASCII integer values by table
lookup. It is a predicate returning non-zero for decimal digits, and 0 for
other characters. It is defined only when <<isascii>>(<[c]>) is true
or <[c]> is EOF.
You can use a compiled subroutine instead of the macro definition by
undefining the macro using `<<#undef isdigit>>'.
RETURNS
<<isdigit>> returns non-zero if <[c]> is a decimal digit (<<0>>--<<9>>).
PORTABILITY
<<isdigit>> is ANSI C.
No supporting OS subroutines are required.
*/
#include <_ansi.h>
#include <ctype.h>
#undef isdigit
int
_DEFUN(isdigit,(c),int c)
{
return((_ctype_ + 1)[c] & _N);
}

View File

@ -0,0 +1,43 @@
/*
FUNCTION
<<islower>>---lower-case character predicate
INDEX
islower
ANSI_SYNOPSIS
#include <ctype.h>
int islower(int <[c]>);
TRAD_SYNOPSIS
#include <ctype.h>
int islower(<[c]>);
DESCRIPTION
<<islower>> is a macro which classifies ASCII integer values by table
lookup. It is a predicate returning non-zero for minuscules
(lower-case alphabetic characters), and 0 for other characters.
It is defined only when <<isascii>>(<[c]>) is true or <[c]> is EOF.
You can use a compiled subroutine instead of the macro definition by
undefining the macro using `<<#undef islower>>'.
RETURNS
<<islower>> returns non-zero if <[c]> is a lower case letter (<<a>>--<<z>>).
PORTABILITY
<<islower>> is ANSI C.
No supporting OS subroutines are required.
*/
#include <_ansi.h>
#include <ctype.h>
#undef islower
int
_DEFUN(islower,(c),int c)
{
return((_ctype_ + 1)[c] & _L);
}

View File

@ -0,0 +1,60 @@
/*
FUNCTION
<<isprint>>, <<isgraph>>---printable character predicates
INDEX
isprint
INDEX
isgraph
ANSI_SYNOPSIS
#include <ctype.h>
int isprint(int <[c]>);
int isgraph(int <[c]>);
TRAD_SYNOPSIS
#include <ctype.h>
int isprint(<[c]>);
int isgraph(<[c]>);
DESCRIPTION
<<isprint>> is a macro which classifies ASCII integer values by table
lookup. It is a predicate returning non-zero for printable
characters, and 0 for other character arguments.
It is defined only when <<isascii>>(<[c]>) is true or <[c]> is EOF.
You can use a compiled subroutine instead of the macro definition by
undefining either macro using `<<#undef isprint>>' or `<<#undef isgraph>>'.
RETURNS
<<isprint>> returns non-zero if <[c]> is a printing character,
(<<0x20>>--<<0x7E>>).
<<isgraph>> behaves identically to <<isprint>>, except that the space
character (<<0x20>>) is excluded.
PORTABILITY
<<isprint>> and <<isgraph>> are ANSI C.
No supporting OS subroutines are required.
*/
#include <_ansi.h>
#include <ctype.h>
#undef isgraph
int
_DEFUN(isgraph,(c),int c)
{
return((_ctype_ + 1)[c] & (_P|_U|_L|_N));
}
#undef isprint
int
_DEFUN(isprint,(c),int c)
{
return((_ctype_ + 1)[c] & (_P|_U|_L|_N|_B));
}

View File

@ -0,0 +1,46 @@
/*
FUNCTION
<<ispunct>>---punctuation character predicate
INDEX
ispunct
ANSI_SYNOPSIS
#include <ctype.h>
int ispunct(int <[c]>);
TRAD_SYNOPSIS
#include <ctype.h>
int ispunct(<[c]>);
DESCRIPTION
<<ispunct>> is a macro which classifies ASCII integer values by table
lookup. It is a predicate returning non-zero for printable
punctuation characters, and 0 for other characters. It is defined
only when <<isascii>>(<[c]>) is true or <[c]> is EOF.
You can use a compiled subroutine instead of the macro definition by
undefining the macro using `<<#undef ispunct>>'.
RETURNS
<<ispunct>> returns non-zero if <[c]> is a printable punctuation character
(<<isgraph(<[c]>) && !isalnum(<[c]>)>>).
PORTABILITY
<<ispunct>> is ANSI C.
No supporting OS subroutines are required.
*/
#include <_ansi.h>
#include <ctype.h>
#undef ispunct
int
_DEFUN(ispunct,(c),int c)
{
return((_ctype_ + 1)[c] & _P);
}

View File

@ -0,0 +1,44 @@
/*
FUNCTION
<<isspace>>---whitespace character predicate
INDEX
isspace
ANSI_SYNOPSIS
#include <ctype.h>
int isspace(int <[c]>);
TRAD_SYNOPSIS
#include <ctype.h>
int isspace(<[c]>);
DESCRIPTION
<<isspace>> is a macro which classifies ASCII integer values by table
lookup. It is a predicate returning non-zero for whitespace
characters, and 0 for other characters. It is defined only when <<isascii>>(<[c]>) is true or <[c]> is EOF.
You can use a compiled subroutine instead of the macro definition by
undefining the macro using `<<#undef isspace>>'.
RETURNS
<<isspace>> returns non-zero if <[c]> is a space, tab, carriage return, new
line, vertical tab, or formfeed (<<0x09>>--<<0x0D>>, <<0x20>>).
PORTABILITY
<<isspace>> is ANSI C.
No supporting OS subroutines are required.
*/
#include <_ansi.h>
#include <ctype.h>
#undef isspace
int
_DEFUN(isspace,(c),int c)
{
return((_ctype_ + 1)[c] & _S);
}

View File

@ -0,0 +1,43 @@
/*
FUNCTION
<<isupper>>---uppercase character predicate
INDEX
isupper
ANSI_SYNOPSIS
#include <ctype.h>
int isupper(int <[c]>);
TRAD_SYNOPSIS
#include <ctype.h>
int isupper(<[c]>);
DESCRIPTION
<<isupper>> is a macro which classifies ASCII integer values by table
lookup. It is a predicate returning non-zero for upper-case letters
(<<A>>--<<Z>>), and 0 for other characters. It is defined only when
<<isascii>>(<[c]>) is true or <[c]> is EOF.
You can use a compiled subroutine instead of the macro definition by
undefining the macro using `<<#undef isupper>>'.
RETURNS
<<isupper>> returns non-zero if <[c]> is a upper case letter (A-Z).
PORTABILITY
<<isupper>> is ANSI C.
No supporting OS subroutines are required.
*/
#include <_ansi.h>
#include <ctype.h>
#undef isupper
int
_DEFUN(isupper,(c),int c)
{
return((_ctype_ + 1)[c] & _U);
}

View File

@ -0,0 +1,45 @@
/*
FUNCTION
<<isxdigit>>---hexadecimal digit predicate
INDEX
isxdigit
ANSI_SYNOPSIS
#include <ctype.h>
int isxdigit(int <[c]>);
TRAD_SYNOPSIS
#include <ctype.h>
int isxdigit(int <[c]>);
DESCRIPTION
<<isxdigit>> is a macro which classifies ASCII integer values by table
lookup. It is a predicate returning non-zero for hexadecimal digits,
and <<0>> for other characters. It is defined only when
<<isascii>>(<[c]>) is true or <[c]> is EOF.
You can use a compiled subroutine instead of the macro definition by
undefining the macro using `<<#undef isxdigit>>'.
RETURNS
<<isxdigit>> returns non-zero if <[c]> is a hexadecimal digit
(<<0>>--<<9>>, <<a>>--<<f>>, or <<A>>--<<F>>).
PORTABILITY
<<isxdigit>> is ANSI C.
No supporting OS subroutines are required.
*/
#include <_ansi.h>
#include <ctype.h>
#undef isxdigit
int
_DEFUN(isxdigit,(c),int c)
{
return((_ctype_ + 1)[c] & ((_X)|(_N)));
}

View File

@ -0,0 +1,41 @@
/*
FUNCTION
<<toascii>>---force integers to ASCII range
INDEX
toascii
ANSI_SYNOPSIS
#include <ctype.h>
int toascii(int <[c]>);
TRAD_SYNOPSIS
#include <ctype.h>
int toascii(<[c]>);
int (<[c]>);
DESCRIPTION
<<toascii>> is a macro which coerces integers to the ASCII range (0--127) by zeroing any higher-order bits.
You can use a compiled subroutine instead of the macro definition by
undefining this macro using `<<#undef toascii>>'.
RETURNS
<<toascii>> returns integers between 0 and 127.
PORTABILITY
<<toascii>> is not ANSI C.
No supporting OS subroutines are required.
*/
#include <_ansi.h>
#include <ctype.h>
#undef toascii
int
_DEFUN(toascii,(c),int c)
{
return (c)&0177;
}

View File

@ -0,0 +1,55 @@
/*
FUNCTION
<<tolower>>---translate characters to lower case
INDEX
tolower
INDEX
_tolower
ANSI_SYNOPSIS
#include <ctype.h>
int tolower(int <[c]>);
int _tolower(int <[c]>);
TRAD_SYNOPSIS
#include <ctype.h>
int tolower(<[c]>);
int _tolower(<[c]>);
DESCRIPTION
<<tolower>> is a macro which converts upper-case characters to lower
case, leaving all other characters unchanged. It is only defined when
<[c]> is an integer in the range <<EOF>> to <<255>>.
You can use a compiled subroutine instead of the macro definition by
undefining this macro using `<<#undef tolower>>'.
<<_tolower>> performs the same conversion as <<tolower>>, but should
only be used when <[c]> is known to be an uppercase character (<<A>>--<<Z>>).
RETURNS
<<tolower>> returns the lower-case equivalent of <[c]> when it is a
character between <<A>> and <<Z>>, and <[c]> otherwise.
<<_tolower>> returns the lower-case equivalent of <[c]> when it is a
character between <<A>> and <<Z>>. If <[c]> is not one of these
characters, the behaviour of <<_tolower>> is undefined.
PORTABILITY
<<tolower>> is ANSI C. <<_tolower>> is not recommended for portable
programs.
No supporting OS subroutines are required.
*/
#include <_ansi.h>
#include <ctype.h>
#undef tolower
int
_DEFUN(tolower,(c),int c)
{
return isupper(c) ? (c) - 'A' + 'a' : c;
}

View File

@ -0,0 +1,54 @@
/*
FUNCTION
<<toupper>>---translate characters to upper case
INDEX
toupper
INDEX
_toupper
ANSI_SYNOPSIS
#include <ctype.h>
int toupper(int <[c]>);
int _toupper(int <[c]>);
TRAD_SYNOPSIS
#include <ctype.h>
int toupper(<[c]>);
int _toupper(<[c]>);
DESCRIPTION
<<toupper>> is a macro which converts lower-case characters to upper
case, leaving all other characters unchanged. It is only defined when
<[c]> is an integer in the range <<EOF>> to <<255>>.
You can use a compiled subroutine instead of the macro definition by
undefining this macro using `<<#undef toupper>>'.
<<_toupper>> performs the same conversion as <<toupper>>, but should
only be used when <[c]> is known to be a lowercase character (<<a>>--<<z>>).
RETURNS
<<toupper>> returns the upper-case equivalent of <[c]> when it is a
character between <<a>> and <<z>>, and <[c]> otherwise.
<<_toupper>> returns the upper-case equivalent of <[c]> when it is a
character between <<a>> and <<z>>. If <[c]> is not one of these
characters, the behaviour of <<_toupper>> is undefined.
PORTABILITY
<<toupper>> is ANSI C. <<_toupper>> is not recommended for portable programs.
No supporting OS subroutines are required.
*/
#include <_ansi.h>
#include <ctype.h>
#undef toupper
int
_DEFUN(toupper,(c),int c)
{
return islower(c) ? c - 'a' + 'A' : c;
}

16
agbcc/libc/errno/errno.c Normal file
View File

@ -0,0 +1,16 @@
/* The errno variable is stored in the reentrancy structure. This
function returns its address for use by the macro errno defined in
errno.h. */
#include <errno.h>
#include <reent.h>
#ifndef _REENT_ONLY
int *
__errno ()
{
return &_REENT->_errno;
}
#endif

View File

@ -0,0 +1,71 @@
/* Provide support for both ANSI and non-ANSI environments. */
/* Some ANSI environments are "broken" in the sense that __STDC__ cannot be
relied upon to have it's intended meaning. Therefore we must use our own
concoction: _HAVE_STDC. Always use _HAVE_STDC instead of __STDC__ in newlib
sources!
To get a strict ANSI C environment, define macro __STRICT_ANSI__. This will
"comment out" the non-ANSI parts of the ANSI header files (non-ANSI header
files aren't affected). */
#ifndef _ANSIDECL_H_
#define _ANSIDECL_H_
#include <sys/config.h>
/* First try to figure out whether we really are in an ANSI C environment. */
/* FIXME: This probably needs some work. Perhaps sys/config.h can be
prevailed upon to give us a clue. */
#ifdef __STDC__
#define _HAVE_STDC
#endif
#ifdef _HAVE_STDC
#define _PTR void *
#define _AND ,
#define _NOARGS void
#define _CONST const
#define _VOLATILE volatile
#define _SIGNED signed
#define _DOTS , ...
#define _VOID void
#define _EXFUN(name, proto) name proto
#define _DEFUN(name, arglist, args) name(args)
#define _DEFUN_VOID(name) name(_NOARGS)
#define _CAST_VOID (void)
#ifndef _LONG_DOUBLE
#define _LONG_DOUBLE long double
#endif
#ifndef _PARAMS
#define _PARAMS(paramlist) paramlist
#endif
#else
#define _PTR char *
#define _AND ;
#define _NOARGS
#define _CONST
#define _VOLATILE
#define _SIGNED
#define _DOTS
#define _VOID void
#define _EXFUN(name, proto) name()
#define _DEFUN(name, arglist, args) name arglist args;
#define _DEFUN_VOID(name) name()
#define _CAST_VOID
#define _LONG_DOUBLE double
#ifndef _PARAMS
#define _PARAMS(paramlist) ()
#endif
#endif
/* Support gcc's __attribute__ facility. */
#ifdef __GNUC__
#define _ATTRIBUTE(attrs) __attribute__ (attrs)
#else
#define _ATTRIBUTE(attrs)
#endif
#endif /* _ANSIDECL_H_ */

View File

@ -0,0 +1,29 @@
/* internal use only -- mapping of "system calls" for libraries that lose
and only provide C names, so that we end up in violation of ANSI */
#ifndef __SYSLIST_H
#define __SYSLIST_H
#ifdef MISSING_SYSCALL_NAMES
#define _close close
#define _execve execve
#define _fcntl fcntl
#define _fork fork
#define _fstat fstat
#define _getpid getpid
#define _gettimeofday gettimeofday
#define _kill kill
#define _link link
#define _lseek lseek
#define _open open
#define _read read
#define _sbrk sbrk
#define _stat stat
#define _times times
#define _unlink unlink
#define _wait wait
#define _write write
/* functions not yet sysfaked */
#define _opendir opendir
#define _readdir readdir
#define _closedir closedir
#endif
#endif

69
agbcc/libc/include/ar.h Normal file
View File

@ -0,0 +1,69 @@
/* $NetBSD: ar.h,v 1.4 1994/10/26 00:55:43 cgd Exp $ */
/*-
* 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 "!<arch>\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_ */

View File

@ -0,0 +1,29 @@
/*
assert.h
*/
#ifdef __cplusplus
extern "C" {
#endif
#include "_ansi.h"
#undef assert
#ifdef NDEBUG /* required by ANSI standard */
#define assert(p) ((void)0)
#else
#ifdef __STDC__
#define assert(e) ((e) ? (void)0 : __assert(__FILE__, __LINE__, #e))
#else /* PCC */
#define assert(e) ((e) ? (void)0 : __assert(__FILE__, __LINE__, "e"))
#endif
#endif /* NDEBUG */
void _EXFUN(__assert,(const char *, int, const char *));
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,73 @@
#ifndef _CTYPE_H_
#ifdef __cplusplus
extern "C" {
#endif
#define _CTYPE_H_
#include "_ansi.h"
int _EXFUN(isalnum, (int __c));
int _EXFUN(isalpha, (int __c));
int _EXFUN(iscntrl, (int __c));
int _EXFUN(isdigit, (int __c));
int _EXFUN(isgraph, (int __c));
int _EXFUN(islower, (int __c));
int _EXFUN(isprint, (int __c));
int _EXFUN(ispunct, (int __c));
int _EXFUN(isspace, (int __c));
int _EXFUN(isupper, (int __c));
int _EXFUN(isxdigit,(int __c));
int _EXFUN(tolower, (int __c));
int _EXFUN(toupper, (int __c));
#ifndef __STRICT_ANSI__
int _EXFUN(isascii, (int __c));
int _EXFUN(toascii, (int __c));
int _EXFUN(_tolower, (int __c));
int _EXFUN(_toupper, (int __c));
#endif
#define _U 01
#define _L 02
#define _N 04
#define _S 010
#define _P 020
#define _C 040
#define _X 0100
#define _B 0200
#if !defined(__CYGWIN32__) || defined(__INSIDE_CYGWIN__) || defined(_COMPILING_NEWLIB)
extern _CONST char _ctype_[];
#else
extern _CONST char _ctype_[] __declspec(dllimport);
#endif
#define isalpha(c) ((_ctype_+1)[(unsigned)(c)]&(_U|_L))
#define isupper(c) ((_ctype_+1)[(unsigned)(c)]&_U)
#define islower(c) ((_ctype_+1)[(unsigned)(c)]&_L)
#define isdigit(c) ((_ctype_+1)[(unsigned)(c)]&_N)
#define isxdigit(c) ((_ctype_+1)[(unsigned)(c)]&(_X|_N))
#define isspace(c) ((_ctype_+1)[(unsigned)(c)]&_S)
#define ispunct(c) ((_ctype_+1)[(unsigned)(c)]&_P)
#define isalnum(c) ((_ctype_+1)[(unsigned)(c)]&(_U|_L|_N))
#define isprint(c) ((_ctype_+1)[(unsigned)(c)]&(_P|_U|_L|_N|_B))
#define isgraph(c) ((_ctype_+1)[(unsigned)(c)]&(_P|_U|_L|_N))
#define iscntrl(c) ((_ctype_+1)[(unsigned)(c)]&_C)
/* Non-gcc versions will get the library versions, and will be
slightly slower */
#ifdef __GNUC__
# define toupper(c) \
({ int __x = (c); islower(__x) ? (__x - 'a' + 'A') : __x;})
# define tolower(c) \
({ int __x = (c); isupper(__x) ? (__x - 'A' + 'a') : __x;})
#endif
#ifndef __STRICT_ANSI__
#define isascii(c) ((unsigned)(c)<=0177)
#define toascii(c) ((c)&0177)
#endif
#ifdef __cplusplus
}
#endif
#endif /* _CTYPE_H_ */

View File

@ -0,0 +1,7 @@
#ifdef __cplusplus
extern "C" {
#endif
#include <sys/dirent.h>
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1 @@
#include <sys/errno.h>

View File

@ -0,0 +1,13 @@
#ifndef _FASTMATH_H_
#ifdef __cplusplus
extern "C" {
#endif
#define _FASTMATH_H_
#include <math.h>
#include <machine/fastmath.h>
#ifdef __cplusplus
}
#endif
#endif /* _FASTMATH_H_ */

View File

@ -0,0 +1 @@
#include <sys/fcntl.h>

81
agbcc/libc/include/grp.h Normal file
View File

@ -0,0 +1,81 @@
/* $NetBSD: grp.h,v 1.7 1995/04/29 05:30:40 cgd Exp $ */
/*-
* 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.
*
* 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.
*
* @(#)grp.h 8.2 (Berkeley) 1/21/94
*/
#ifndef _GRP_H_
#define _GRP_H_
#include <sys/types.h>
#if !defined(_POSIX_SOURCE) && !defined(_XOPEN_SOURCE)
#define _PATH_GROUP "/etc/group"
#endif
struct group {
char *gr_name; /* group name */
char *gr_passwd; /* group password */
int gr_gid; /* group id */
char **gr_mem; /* group members */
};
#ifdef __cplusplus
extern "C" {
#endif
struct group *getgrgid (gid_t);
struct group *getgrnam (const char *);
#ifndef _POSIX_SOURCE
struct group *getgrent (void);
void setgrent (void);
void endgrent (void);
void setgrfile (const char *);
#ifndef _XOPEN_SOURCE
char *group_from_gid (gid_t, int);
int setgroupent (int);
#endif /* !_XOPEN_SOURCE */
#endif /* !_POSIX_SOURCE */
#ifdef __cplusplus
}
#endif
#endif /* !_GRP_H_ */

241
agbcc/libc/include/ieeefp.h Normal file
View File

@ -0,0 +1,241 @@
#ifndef _IEEE_FP_H_
#define _IEEE_FP_H_
#include "_ansi.h"
#include <machine/ieeefp.h>
/* FIXME FIXME FIXME:
Neither of __ieee_{float,double}_shape_tape seem to be used anywhere
except in libm/test. If that is the case, please delete these from here.
If that is not the case, please insert documentation here describing why
they're needed. */
#ifdef __IEEE_BIG_ENDIAN
typedef union
{
double value;
struct
{
unsigned int sign : 1;
unsigned int exponent: 11;
unsigned int fraction0:4;
unsigned int fraction1:16;
unsigned int fraction2:16;
unsigned int fraction3:16;
} number;
struct
{
unsigned int sign : 1;
unsigned int exponent: 11;
unsigned int quiet:1;
unsigned int function0:3;
unsigned int function1:16;
unsigned int function2:16;
unsigned int function3:16;
} nan;
struct
{
unsigned long msw;
unsigned long lsw;
} parts;
long aslong[2];
} __ieee_double_shape_type;
#endif
#ifdef __IEEE_LITTLE_ENDIAN
typedef union
{
double value;
struct
{
#ifdef __SMALL_BITFIELDS
unsigned int fraction3:16;
unsigned int fraction2:16;
unsigned int fraction1:16;
unsigned int fraction0: 4;
#else
unsigned int fraction1:32;
unsigned int fraction0:20;
#endif
unsigned int exponent :11;
unsigned int sign : 1;
} number;
struct
{
#ifdef __SMALL_BITFIELDS
unsigned int function3:16;
unsigned int function2:16;
unsigned int function1:16;
unsigned int function0:3;
#else
unsigned int function1:32;
unsigned int function0:19;
#endif
unsigned int quiet:1;
unsigned int exponent: 11;
unsigned int sign : 1;
} nan;
struct
{
unsigned long lsw;
unsigned long msw;
} parts;
long aslong[2];
} __ieee_double_shape_type;
#endif
#ifdef __IEEE_BIG_ENDIAN
typedef union
{
float value;
struct
{
unsigned int sign : 1;
unsigned int exponent: 8;
unsigned int fraction0: 7;
unsigned int fraction1: 16;
} number;
struct
{
unsigned int sign:1;
unsigned int exponent:8;
unsigned int quiet:1;
unsigned int function0:6;
unsigned int function1:16;
} nan;
long p1;
} __ieee_float_shape_type;
#endif
#ifdef __IEEE_LITTLE_ENDIAN
typedef union
{
float value;
struct
{
unsigned int fraction0: 7;
unsigned int fraction1: 16;
unsigned int exponent: 8;
unsigned int sign : 1;
} number;
struct
{
unsigned int function1:16;
unsigned int function0:6;
unsigned int quiet:1;
unsigned int exponent:8;
unsigned int sign:1;
} nan;
long p1;
} __ieee_float_shape_type;
#endif
/* FLOATING ROUNDING */
typedef int fp_rnd;
#define FP_RN 0 /* Round to nearest */
#define FP_RM 1 /* Round down */
#define FP_RP 2 /* Round up */
#define FP_RZ 3 /* Round to zero (trunate) */
fp_rnd _EXFUN(fpgetround,(void));
fp_rnd _EXFUN(fpsetround, (fp_rnd));
/* EXCEPTIONS */
typedef int fp_except;
#define FP_X_INV 0x10 /* Invalid operation */
#define FP_X_DX 0x80 /* Divide by zero */
#define FP_X_OFL 0x04 /* Overflow exception */
#define FP_X_UFL 0x02 /* Underflow exception */
#define FP_X_IMP 0x01 /* imprecise exception */
fp_except _EXFUN(fpgetmask,(void));
fp_except _EXFUN(fpsetmask,(fp_except));
fp_except _EXFUN(fpgetsticky,(void));
fp_except _EXFUN(fpsetsticky, (fp_except));
/* INTEGER ROUNDING */
typedef int fp_rdi;
#define FP_RDI_TOZ 0 /* Round to Zero */
#define FP_RDI_RD 1 /* Follow float mode */
fp_rdi _EXFUN(fpgetroundtoi,(void));
fp_rdi _EXFUN(fpsetroundtoi,(fp_rdi));
int _EXFUN(isnan, (double));
int _EXFUN(isinf, (double));
int _EXFUN(finite, (double));
int _EXFUN(isnanf, (float));
int _EXFUN(isinff, (float));
int _EXFUN(finitef, (float));
#define __IEEE_DBL_EXPBIAS 1023
#define __IEEE_FLT_EXPBIAS 127
#define __IEEE_DBL_EXPLEN 11
#define __IEEE_FLT_EXPLEN 8
#define __IEEE_DBL_FRACLEN (64 - (__IEEE_DBL_EXPLEN + 1))
#define __IEEE_FLT_FRACLEN (32 - (__IEEE_FLT_EXPLEN + 1))
#define __IEEE_DBL_MAXPOWTWO ((double)(1L << 32 - 2) * (1L << (32-11) - 32 + 1))
#define __IEEE_FLT_MAXPOWTWO ((float)(1L << (32-8) - 1))
#define __IEEE_DBL_NAN_EXP 0x7ff
#define __IEEE_FLT_NAN_EXP 0xff
#define isnanf(x) (((*(long *)&(x) & 0x7f800000L)==0x7f800000L) && \
((*(long *)&(x) & 0x007fffffL)!=0000000000L))
#define isinff(x) (((*(long *)&(x) & 0x7f800000L)==0x7f800000L) && \
((*(long *)&(x) & 0x007fffffL)==0000000000L))
#define finitef(x) (((*(long *)&(x) & 0x7f800000L)!=0x7f800000L))
#ifdef _DOUBLE_IS_32BITS
#undef __IEEE_DBL_EXPBIAS
#define __IEEE_DBL_EXPBIAS __IEEE_FLT_EXPBIAS
#undef __IEEE_DBL_EXPLEN
#define __IEEE_DBL_EXPLEN __IEEE_FLT_EXPLEN
#undef __IEEE_DBL_FRACLEN
#define __IEEE_DBL_FRACLEN __IEEE_FLT_FRACLEN
#undef __IEEE_DBL_MAXPOWTWO
#define __IEEE_DBL_MAXPOWTWO __IEEE_FLT_MAXPOWTWO
#undef __IEEE_DBL_NAN_EXP
#define __IEEE_DBL_NAN_EXP __IEEE_FLT_NAN_EXP
#undef __ieee_double_shape_type
#define __ieee_double_shape_type __ieee_float_shape_type
#endif /* _DOUBLE_IS_32BITS */
#endif /* _IEEE_FP_H_ */

View File

@ -0,0 +1,60 @@
/*
locale.h
Values appropriate for the formatting of monetary and other
numberic quantities.
*/
#ifndef _LOCALE_H_
#ifdef __cplusplus
extern "C" {
#endif
#define _LOCALE_H_
#include "_ansi.h"
#ifndef NULL
#define NULL 0L
#endif
#define LC_ALL 0
#define LC_COLLATE 1
#define LC_CTYPE 2
#define LC_MONETARY 3
#define LC_NUMERIC 4
#define LC_TIME 5
struct lconv
{
char *decimal_point;
char *thousands_sep;
char *grouping;
char *int_curr_symbol;
char *currency_symbol;
char *mon_decimal_point;
char *mon_thousands_sep;
char *mon_grouping;
char *positive_sign;
char *negative_sign;
char int_frac_digits;
char frac_digits;
char p_cs_precedes;
char p_sep_by_space;
char n_cs_precedes;
char n_sep_by_space;
char p_sign_posn;
char n_sign_posn;
};
#ifndef _REENT_ONLY
char *_EXFUN(setlocale,(int category, const char *locale));
struct lconv *_EXFUN(localeconv,(void));
#endif
struct _reent;
char *_EXFUN(_setlocale_r,(struct _reent *, int category, const char *locale));
struct lconv *_EXFUN(_localeconv_r,(struct _reent *));
#ifdef __cplusplus
}
#endif
#endif /* _LOCALE_H_ */

View File

@ -0,0 +1,101 @@
#ifdef __sysvnecv70_target
double EXFUN(fast_sin,(double));
double EXFUN(fast_cos,(double));
double EXFUN(fast_tan,(double));
double EXFUN(fast_asin,(double));
double EXFUN(fast_acos,(double));
double EXFUN(fast_atan,(double));
double EXFUN(fast_sinh,(double));
double EXFUN(fast_cosh,(double));
double EXFUN(fast_tanh,(double));
double EXFUN(fast_asinh,(double));
double EXFUN(fast_acosh,(double));
double EXFUN(fast_atanh,(double));
double EXFUN(fast_abs,(double));
double EXFUN(fast_sqrt,(double));
double EXFUN(fast_exp2,(double));
double EXFUN(fast_exp10,(double));
double EXFUN(fast_expe,(double));
double EXFUN(fast_log10,(double));
double EXFUN(fast_log2,(double));
double EXFUN(fast_loge,(double));
#define sin(x) fast_sin(x)
#define cos(x) fast_cos(x)
#define tan(x) fast_tan(x)
#define asin(x) fast_asin(x)
#define acos(x) fast_acos(x)
#define atan(x) fast_atan(x)
#define sinh(x) fast_sinh(x)
#define cosh(x) fast_cosh(x)
#define tanh(x) fast_tanh(x)
#define asinh(x) fast_asinh(x)
#define acosh(x) fast_acosh(x)
#define atanh(x) fast_atanh(x)
#define abs(x) fast_abs(x)
#define sqrt(x) fast_sqrt(x)
#define exp2(x) fast_exp2(x)
#define exp10(x) fast_exp10(x)
#define expe(x) fast_expe(x)
#define log10(x) fast_log10(x)
#define log2(x) fast_log2(x)
#define loge(x) fast_loge(x)
#ifdef _HAVE_STDC
/* These functions are in assembler, they really do take floats. This
can only be used with a real ANSI compiler */
float EXFUN(fast_sinf,(float));
float EXFUN(fast_cosf,(float));
float EXFUN(fast_tanf,(float));
float EXFUN(fast_asinf,(float));
float EXFUN(fast_acosf,(float));
float EXFUN(fast_atanf,(float));
float EXFUN(fast_sinhf,(float));
float EXFUN(fast_coshf,(float));
float EXFUN(fast_tanhf,(float));
float EXFUN(fast_asinhf,(float));
float EXFUN(fast_acoshf,(float));
float EXFUN(fast_atanhf,(float));
float EXFUN(fast_absf,(float));
float EXFUN(fast_sqrtf,(float));
float EXFUN(fast_exp2f,(float));
float EXFUN(fast_exp10f,(float));
float EXFUN(fast_expef,(float));
float EXFUN(fast_log10f,(float));
float EXFUN(fast_log2f,(float));
float EXFUN(fast_logef,(float));
#define sinf(x) fast_sinf(x)
#define cosf(x) fast_cosf(x)
#define tanf(x) fast_tanf(x)
#define asinf(x) fast_asinf(x)
#define acosf(x) fast_acosf(x)
#define atanf(x) fast_atanf(x)
#define sinhf(x) fast_sinhf(x)
#define coshf(x) fast_coshf(x)
#define tanhf(x) fast_tanhf(x)
#define asinhf(x) fast_asinhf(x)
#define acoshf(x) fast_acoshf(x)
#define atanhf(x) fast_atanhf(x)
#define absf(x) fast_absf(x)
#define sqrtf(x) fast_sqrtf(x)
#define exp2f(x) fast_exp2f(x)
#define exp10f(x) fast_exp10f(x)
#define expef(x) fast_expef(x)
#define log10f(x) fast_log10f(x)
#define log2f(x) fast_log2f(x)
#define logef(x) fast_logef(x)
#endif
/* Override the functions defined in math.h */
#endif /* __sysvnecv70_target */

View File

@ -0,0 +1,144 @@
#ifndef __IEEE_BIG_ENDIAN
#ifndef __IEEE_LITTLE_ENDIAN
#if defined(__arm__) || defined(__thumb__)
/* ARM always has big-endian words. Within those words the byte ordering
appears to be big or little endian. Newlib doesn't seem to care about
the byte ordering within words. */
#define __IEEE_BIG_ENDIAN
#endif
#ifdef __hppa__
#define __IEEE_BIG_ENDIAN
#endif
#ifdef __sparc__
#ifdef __LITTLE_ENDIAN_DATA__
#define __IEEE_LITTLE_ENDIAN
#else
#define __IEEE_BIG_ENDIAN
#endif
#endif
#if defined(__m68k__) || defined(__mc68000__)
#define __IEEE_BIG_ENDIAN
#endif
#if defined (__H8300__) || defined (__H8300H__) || defined (__H8300S__)
#define __IEEE_BIG_ENDIAN
#define __SMALL_BITFIELDS
#define _DOUBLE_IS_32BITS
#endif
#ifdef __H8500__
#define __IEEE_BIG_ENDIAN
#define __SMALL_BITFIELDS
#define _DOUBLE_IS_32BITS
#endif
#ifdef __sh__
#ifdef __LITTLE_ENDIAN__
#define __IEEE_LITTLE_ENDIAN
#else
#define __IEEE_BIG_ENDIAN
#endif
#if defined(__SH3E__) || defined(__SH4_SINGLE_ONLY__)
#define _DOUBLE_IS_32BITS
#endif
#endif
#ifdef _AM29K
#define __IEEE_BIG_ENDIAN
#endif
#ifdef __i386__
#define __IEEE_LITTLE_ENDIAN
#endif
#ifdef __i960__
#define __IEEE_LITTLE_ENDIAN
#endif
#ifdef __M32R__
#define __IEEE_BIG_ENDIAN
#endif
#ifdef __MIPSEL__
#define __IEEE_LITTLE_ENDIAN
#endif
#ifdef __MIPSEB__
#define __IEEE_BIG_ENDIAN
#endif
/* necv70 was __IEEE_LITTLE_ENDIAN. */
#ifdef __W65__
#define __IEEE_LITTLE_ENDIAN
#define __SMALL_BITFIELDS
#define _DOUBLE_IS_32BITS
#endif
#if defined(__Z8001__) || defined(__Z8002__)
#define __IEEE_BIG_ENDIAN
#endif
#ifdef __m88k__
#define __IEEE_BIG_ENDIAN
#endif
#ifdef __mn10300__
#define __IEEE_LITTLE_ENDIAN
#endif
#ifdef __mn10200__
#define __IEEE_LITTLE_ENDIAN
#define __SMALL_BITFIELDS
#define _DOUBLE_IS_32BITS
#endif
#ifdef __v800
#define __IEEE_LITTLE_ENDIAN
#endif
#ifdef __v850
#define __IEEE_LITTLE_ENDIAN
#endif
#ifdef __D10V__
#define __IEEE_BIG_ENDIAN
#define _DOUBLE_IS_32BITS
#define __SMALL_BITFIELDS
#endif
#ifdef __PPC__
#if (defined(_BIG_ENDIAN) && _BIG_ENDIAN) || (defined(_AIX) && _AIX)
#define __IEEE_BIG_ENDIAN
#else
#if (defined(_LITTLE_ENDIAN) && _LITTLE_ENDIAN) || (defined(__sun__) && __sun__) || (defined(_WIN32) && _WIN32)
#define __IEEE_LITTLE_ENDIAN
#endif
#endif
#endif
#ifdef __arc__
#ifdef __big_endian__
#define __IEEE_BIG_ENDIAN
#else
#define __IEEE_LITTLE_ENDIAN
#endif
#endif
#ifdef __fr30__
#define __IEEE_BIG_ENDIAN
#endif
#ifndef __IEEE_BIG_ENDIAN
#ifndef __IEEE_LITTLE_ENDIAN
#error Endianess not declared!!
#endif /* not __IEEE_LITTLE_ENDIAN */
#endif /* not __IEEE_BIG_ENDIAN */
#endif /* not __IEEE_LITTLE_ENDIAN */
#endif /* not __IEEE_BIG_ENDIAN */

View File

@ -0,0 +1,44 @@
/*
** Copyright (C) 1991 DJ Delorie, 24 Kirsten Ave, Rochester NH 03867-2954
**
** This file is distributed under the terms listed in the document
** "copying.dj", available from DJ Delorie at the address above.
** A copy of "copying.dj" should accompany this file; if not, a copy
** should be available from where this file was obtained. This file
** may not be distributed without a verbatim copy of "copying.dj".
**
** This file is distributed WITHOUT ANY WARRANTY; without even the implied
** warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
/* Modified to use SETJMP_DJ_H rather than SETJMP_H to avoid
conflicting with setjmp.h. Ian Taylor, Cygnus support, April,
1993. */
#ifndef _SETJMP_DJ_H_
#define _SETJMP_DJ_H_
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
unsigned long eax;
unsigned long ebx;
unsigned long ecx;
unsigned long edx;
unsigned long esi;
unsigned long edi;
unsigned long ebp;
unsigned long esp;
unsigned long eip;
} jmp_buf[1];
extern int setjmp(jmp_buf);
extern void longjmp(jmp_buf, int);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,160 @@
#if defined(__arm__) || defined(__thumb__)
/*
* All callee preserved registers:
* v1 - v7, fp, ip, sp, lr, f4, f5, f6, f7
*/
#define _JBLEN 23
#endif
#ifdef __sparc__
/*
* onsstack,sigmask,sp,pc,npc,psr,g1,o0,wbcnt (sigcontext).
* All else recovered by under/over(flow) handling.
*/
#define _JBLEN 13
#endif
/* necv70 was 9 as well. */
#ifdef __mc68000__
/*
* onsstack,sigmask,sp,pc,psl,d2-d7,a2-a6,
* fp2-fp7 for 68881.
* All else recovered by under/over(flow) handling.
*/
#define _JBLEN 34
#endif
#if defined(__Z8001__) || defined(__Z8002__)
/* 16 regs + pc */
#define _JBLEN 20
#endif
#ifdef _AM29K
/*
* onsstack,sigmask,sp,pc,npc,psr,g1,o0,wbcnt (sigcontext).
* All else recovered by under/over(flow) handling.
*/
#define _JBLEN 9
#endif
#ifdef __i386__
#ifdef __unix__
# define _JBLEN 36
#elif defined(_WIN32)
#define _JBLEN (13 * 4)
#else
#include "setjmp-dj.h"
#endif
#endif
#ifdef __i960__
#define _JBLEN 35
#endif
#ifdef __M32R__
/* Only 8 words are currently needed. 10 gives us some slop if we need
to expand. */
#define _JBLEN 10
#endif
#ifdef __mips__
#define _JBLEN 11
#endif
#ifdef __m88000__
#define _JBLEN 21
#endif
#ifdef __H8300__
#define _JBLEN 5
typedef int jmp_buf[_JBLEN];
#endif
#ifdef __H8300H__
/* same as H8/300 but registers are twice as big */
#define _JBLEN 5
#define _JBTYPE long
#endif
#ifdef __H8300S__
/* same as H8/300 but registers are twice as big */
#define _JBLEN 5
#define _JBTYPE long
#endif
#ifdef __H8500__
#define _JBLEN 4
#endif
#ifdef __sh__
#define _JBLEN 20
#endif
#ifdef __v800
#define _JBLEN 28
#endif
#ifdef __PPC__
#define _JBLEN 32
#define _JBTYPE double
#endif
#ifdef __hppa__
/* %r30, %r2-%r18, %r27, pad, %fr12-%fr15.
Note space exists for the FP registers, but they are not
saved. */
#define _JBLEN 28
#endif
#if defined(__mn10300__) || defined(__mn10200__)
/* A guess */
#define _JBLEN 10
#endif
#ifdef __v850
/* I think our setjmp is saving 15 regs at the moment. Gives us one word
slop if we need to expand. */
#define _JBLEN 16
#endif
#ifdef __D10V__
#define _JBLEN 8
#endif
#ifdef __D30V__
#define _JBLEN ((64 /* GPR */ + (2*2) /* ACs */ + 18 /* CRs */) / 2)
#define _JBTYPE double
#endif
#ifdef __fr30__
#define _JBLEN 10
#endif
#ifdef _JBLEN
#ifdef _JBTYPE
typedef _JBTYPE jmp_buf[_JBLEN];
#else
typedef int jmp_buf[_JBLEN];
#endif
#ifdef __CYGWIN32__
#include <signal.h>
/* POSIX sigsetjmp/siglongjmp macros */
typedef int sigjmp_buf[_JBLEN+2];
#define _SAVEMASK _JBLEN
#define _SIGMASK (_JBLEN+1)
#define sigsetjmp(env, savemask) (env[_SAVEMASK] = savemask,\
sigprocmask (SIG_SETMASK, 0, (sigset_t *) &env[_SIGMASK]),\
setjmp (env))
#define siglongjmp(env, val) (((env[_SAVEMASK])?\
sigprocmask (SIG_SETMASK, (sigset_t *) &env[_SIGMASK], 0):0),\
longjmp (env, val))
#endif /* __CYGWIN32__*/
#endif

View File

@ -0,0 +1,10 @@
#ifndef _MACHTIME_H_
#define _MACHTIME_H_
#if defined(__arm__) || defined(__thumb__)
#define _CLOCKS_PER_SEC_ 100
#endif
#endif /* _MACHTIME_H_ */

View File

@ -0,0 +1,9 @@
#ifndef _MACHTYPES_H_
#define _MACHTYPES_H_
#define _CLOCK_T_ unsigned long /* clock() */
#define _TIME_T_ long /* time() */
#endif /* _MACHTYPES_H_ */

View File

@ -0,0 +1,97 @@
/* malloc.h -- header file for memory routines. */
#ifndef _INCLUDE_MALLOC_H_
#define _INCLUDE_MALLOC_H_
#include <_ansi.h>
#include <sys/reent.h>
#define __need_size_t
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
/* This version of struct mallinfo must match the one in
libc/stdlib/mallocr.c. */
struct mallinfo {
int arena; /* total space allocated from system */
int ordblks; /* number of non-inuse chunks */
int smblks; /* unused -- always zero */
int hblks; /* number of mmapped regions */
int hblkhd; /* total space in mmapped regions */
int usmblks; /* unused -- always zero */
int fsmblks; /* unused -- always zero */
int uordblks; /* total allocated space */
int fordblks; /* total non-inuse space */
int keepcost; /* top-most, releasable (via malloc_trim) space */
};
/* The routines. */
extern _PTR malloc _PARAMS ((size_t));
extern _PTR _malloc_r _PARAMS ((struct _reent *, size_t));
extern _VOID free _PARAMS ((_PTR));
extern _VOID _free_r _PARAMS ((struct _reent *, _PTR));
extern _PTR realloc _PARAMS ((_PTR, size_t));
extern _PTR _realloc_r _PARAMS ((struct _reent *, _PTR, size_t));
extern _PTR calloc _PARAMS ((size_t, size_t));
extern _PTR _calloc_r _PARAMS ((struct _reent *, size_t, size_t));
extern _PTR memalign _PARAMS ((size_t, size_t));
extern _PTR _memalign_r _PARAMS ((struct _reent *, size_t, size_t));
extern struct mallinfo mallinfo _PARAMS ((void));
extern struct mallinfo _mallinfo_r _PARAMS ((struct _reent *));
extern void malloc_stats _PARAMS ((void));
extern void _malloc_stats_r _PARAMS ((struct _reent *));
extern int mallopt _PARAMS ((int, int));
extern int _mallopt_r _PARAMS ((struct _reent *, int, int));
extern size_t malloc_usable_size _PARAMS ((_PTR));
extern size_t _malloc_usable_size_r _PARAMS ((struct _reent *, _PTR));
/* These aren't too useful on an embedded system, but we define them
anyhow. */
extern _PTR valloc _PARAMS ((size_t));
extern _PTR _valloc_r _PARAMS ((struct _reent *, size_t));
extern _PTR pvalloc _PARAMS ((size_t));
extern _PTR _pvalloc_r _PARAMS ((struct _reent *, size_t));
extern int malloc_trim _PARAMS ((size_t));
extern int _malloc_trim_r _PARAMS ((struct _reent *, size_t));
/* Some systems provide this, so do too for compatibility. */
extern void cfree _PARAMS ((_PTR));
/* A compatibility routine for an earlier version of the allocator. */
extern _VOID mstats _PARAMS ((char *));
extern _VOID _mstats_r _PARAMS ((struct _reent *, char *));
#ifdef __CYGWIN32__
/* Cygwin32 needs to be able to copy all the malloc information from
the parent to the child. However, cygwin32 does not normally copy
any data in the DLL data section. This routine handles copying
that information. */
extern int __malloc_copy _PARAMS ((int (*) (void *, void *, void *, int),
void *, int));
#endif /* __CYGWIN32 */
#ifdef __cplusplus
}
#endif
#endif /* _INCLUDE_MALLOC_H_ */

269
agbcc/libc/include/math.h Normal file
View File

@ -0,0 +1,269 @@
/* math.h -- Definitions for the math floating point package. */
#ifndef _MATH_H_
#ifdef __cplusplus
extern "C" {
#endif
#define _MATH_H_
#include <sys/reent.h>
#include <machine/ieeefp.h>
#include "_ansi.h"
#ifndef HUGE_VAL
/* Define HUGE_VAL as infinity, unless HUGE_VAL is already defined
(which might have been done by something like math-68881.h). */
union __dmath
{
__uint32_t i[2];
double d;
};
extern const union __dmath __infinity;
#define HUGE_VAL (__infinity.d)
#endif /* ! defined (HUGE_VAL) */
/* Reentrant ANSI C functions. */
#ifndef __math_68881
extern double atan _PARAMS((double));
extern double cos _PARAMS((double));
extern double sin _PARAMS((double));
extern double tan _PARAMS((double));
extern double tanh _PARAMS((double));
extern double frexp _PARAMS((double, int *));
extern double modf _PARAMS((double, double *));
extern double ceil _PARAMS((double));
extern double fabs _PARAMS((double));
extern double floor _PARAMS((double));
#endif /* ! defined (__math_68881) */
/* Non reentrant ANSI C functions. */
#ifndef _REENT_ONLY
#ifndef __math_6881
extern double acos _PARAMS((double));
extern double asin _PARAMS((double));
extern double atan2 _PARAMS((double, double));
extern double cosh _PARAMS((double));
extern double sinh _PARAMS((double));
extern double exp _PARAMS((double));
extern double ldexp _PARAMS((double, int));
extern double log _PARAMS((double));
extern double log10 _PARAMS((double));
extern double pow _PARAMS((double, double));
extern double sqrt _PARAMS((double));
extern double fmod _PARAMS((double, double));
#endif /* ! defined (__math_68881) */
#endif /* ! defined (_REENT_ONLY) */
#ifndef __STRICT_ANSI__
/* Non ANSI double precision functions. */
extern double infinity _PARAMS((void));
extern double nan _PARAMS((void));
extern int isnan _PARAMS((double));
extern int isinf _PARAMS((double));
extern int finite _PARAMS((double));
extern double copysign _PARAMS((double, double));
extern int ilogb _PARAMS((double));
extern double asinh _PARAMS((double));
extern double cbrt _PARAMS((double));
extern double nextafter _PARAMS((double, double));
extern double rint _PARAMS((double));
extern double scalbn _PARAMS((double, int));
#ifndef __math_68881
extern double log1p _PARAMS((double));
extern double expm1 _PARAMS((double));
#endif /* ! defined (__math_68881) */
#ifndef _REENT_ONLY
extern double acosh _PARAMS((double));
extern double atanh _PARAMS((double));
extern double remainder _PARAMS((double, double));
extern double gamma _PARAMS((double));
extern double gamma_r _PARAMS((double, int *));
extern double lgamma _PARAMS((double));
extern double lgamma_r _PARAMS((double, int *));
extern double erf _PARAMS((double));
extern double erfc _PARAMS((double));
extern double y0 _PARAMS((double));
extern double y1 _PARAMS((double));
extern double yn _PARAMS((int, double));
extern double j0 _PARAMS((double));
extern double j1 _PARAMS((double));
extern double jn _PARAMS((int, double));
#define log2(x) (log (x) / M_LOG2_E)
#ifndef __math_68881
extern double hypot _PARAMS((double, double));
#endif
extern double cabs();
extern double drem _PARAMS((double, double));
#endif /* ! defined (_REENT_ONLY) */
/* Single precision versions of ANSI functions. */
extern float atanf _PARAMS((float));
extern float cosf _PARAMS((float));
extern float sinf _PARAMS((float));
extern float tanf _PARAMS((float));
extern float tanhf _PARAMS((float));
extern float frexpf _PARAMS((float, int *));
extern float modff _PARAMS((float, float *));
extern float ceilf _PARAMS((float));
extern float fabsf _PARAMS((float));
extern float floorf _PARAMS((float));
#ifndef _REENT_ONLY
extern float acosf _PARAMS((float));
extern float asinf _PARAMS((float));
extern float atan2f _PARAMS((float, float));
extern float coshf _PARAMS((float));
extern float sinhf _PARAMS((float));
extern float expf _PARAMS((float));
extern float ldexpf _PARAMS((float, int));
extern float logf _PARAMS((float));
extern float log10f _PARAMS((float));
extern float powf _PARAMS((float, float));
extern float sqrtf _PARAMS((float));
extern float fmodf _PARAMS((float, float));
#endif /* ! defined (_REENT_ONLY) */
/* Other single precision functions. */
extern float infinityf _PARAMS((void));
extern float nanf _PARAMS((void));
extern int isnanf _PARAMS((float));
extern int isinff _PARAMS((float));
extern int finitef _PARAMS((float));
extern float copysignf _PARAMS((float, float));
extern int ilogbf _PARAMS((float));
extern float asinhf _PARAMS((float));
extern float cbrtf _PARAMS((float));
extern float nextafterf _PARAMS((float, float));
extern float rintf _PARAMS((float));
extern float scalbnf _PARAMS((float, int));
extern float log1pf _PARAMS((float));
extern float expm1f _PARAMS((float));
#ifndef _REENT_ONLY
extern float acoshf _PARAMS((float));
extern float atanhf _PARAMS((float));
extern float remainderf _PARAMS((float, float));
extern float gammaf _PARAMS((float));
extern float gammaf_r _PARAMS((float, int *));
extern float lgammaf _PARAMS((float));
extern float lgammaf_r _PARAMS((float, int *));
extern float erff _PARAMS((float));
extern float erfcf _PARAMS((float));
extern float y0f _PARAMS((float));
extern float y1f _PARAMS((float));
extern float ynf _PARAMS((int, float));
extern float j0f _PARAMS((float));
extern float j1f _PARAMS((float));
extern float jnf _PARAMS((int, float));
#define log2f(x) (logf (x) / (float) M_LOG2_E)
extern float hypotf _PARAMS((float, float));
extern float cabsf();
extern float dremf _PARAMS((float, float));
#endif /* ! defined (_REENT_ONLY) */
/* The gamma functions use a global variable, signgam. */
extern int signgam;
/* The exception structure passed to the matherr routine. */
#ifdef __cplusplus
struct __exception
#else
struct exception
#endif
{
int type;
char *name;
double arg1;
double arg2;
double retval;
int err;
};
#ifdef __cplusplus
extern int matherr _PARAMS((struct __exception *e));
#else
extern int matherr _PARAMS((struct exception *e));
#endif
/* Values for the type field of struct exception. */
#define DOMAIN 1
#define SING 2
#define OVERFLOW 3
#define UNDERFLOW 4
#define TLOSS 5
#define PLOSS 6
/* Useful constants. */
#define M_E 2.7182818284590452354
#define M_LOG2E 1.4426950408889634074
#define M_LOG10E 0.43429448190325182765
#define M_LN2 0.69314718055994530942
#define M_LN10 2.30258509299404568402
#define M_PI 3.14159265358979323846
#define M_TWOPI (M_PI * 2.0)
#define M_PI_2 1.57079632679489661923
#define M_PI_4 0.78539816339744830962
#define M_3PI_4 2.3561944901923448370E0
#define M_SQRTPI 1.77245385090551602792981
#define M_1_PI 0.31830988618379067154
#define M_2_PI 0.63661977236758134308
#define M_2_SQRTPI 1.12837916709551257390
#define M_SQRT2 1.41421356237309504880
#define M_SQRT1_2 0.70710678118654752440
#define M_LN2LO 1.9082149292705877000E-10
#define M_LN2HI 6.9314718036912381649E-1
#define M_SQRT3 1.73205080756887719000
#define M_IVLN10 0.43429448190325182765 /* 1 / log(10) */
#define M_LOG2_E 0.693147180559945309417
#define M_INVLN2 1.4426950408889633870E0 /* 1 / log(2) */
/* Global control over fdlibm error handling. */
enum __fdlibm_version
{
__fdlibm_ieee = -1,
__fdlibm_svid,
__fdlibm_xopen,
__fdlibm_posix
};
#define _LIB_VERSION_TYPE enum __fdlibm_version
#define _LIB_VERSION __fdlib_version
extern _CONST _LIB_VERSION_TYPE _LIB_VERSION;
#define _IEEE_ __fdlibm_ieee
#define _SVID_ __fdlibm_svid
#define _XOPEN_ __fdlibm_xopen
#define _POSIX_ __fdlibm_posix
#endif /* ! defined (__STRICT_ANSI__) */
#ifdef __cplusplus
}
#endif
#endif /* _MATH_H_ */

View File

@ -0,0 +1,7 @@
#ifndef _PATHS_H_
#define _PATHS_H_
#define _PATH_DEV "/dev/"
#define _PATH_BSHELL "/bin/sh"
#endif /* _PATHS_H_ */

View File

@ -0,0 +1,60 @@
/* process.h. This file comes with MSDOS and WIN32 systems. */
#ifndef __PROCESS_H_
#define __PROCESS_H_
#ifdef __cplusplus
extern "C" {
#endif
int execl(const char *path, const char *argv0, ...);
int execle(const char *path, const char *argv0, ... /*, char * const *envp */);
int execlp(const char *path, const char *argv0, ...);
int execlpe(const char *path, const char *argv0, ... /*, char * const *envp */);
int execv(const char *path, char * const *argv);
int execve(const char *path, char * const *argv, char * const *envp);
int execvp(const char *path, char * const *argv);
int execvpe(const char *path, char * const *argv, char * const *envp);
int spawnl(int mode, const char *path, const char *argv0, ...);
int spawnle(int mode, const char *path, const char *argv0, ... /*, char * const *envp */);
int spawnlp(int mode, const char *path, const char *argv0, ...);
int spawnlpe(int mode, const char *path, const char *argv0, ... /*, char * const *envp */);
int spawnv(int mode, const char *path, const char * const *argv);
int spawnve(int mode, const char *path, char * const *argv, const char * const *envp);
int spawnvp(int mode, const char *path, const char * const *argv);
int spawnvpe(int mode, const char *path, const char * const *argv, const char * const *envp);
#ifdef __CYGWIN32__
/* Secure exec() functions family */
/* The first arg should really be a HANDLE which is a void *. But we
can't include windows.h here so... */
#include <sys/types.h>
pid_t sexecl(void *, const char *path, const char *argv0, ...);
pid_t sexecle(void *, const char *path, const char *argv0, ... /*, char * const *envp */);
pid_t sexeclp(void *, const char *path, const char *argv0, ...);
pid_t sexeclpe(void *, const char *path, const char *argv0, ... /*, char * const *envp */);
pid_t sexecv(void *, const char *path, const char * const *argv);
pid_t sexecve(void *, const char *path, const char * const *argv, const char * const *envp);
pid_t sexecvp(void *, const char *path, const char * const *argv);
pid_t sexecvpe(void *, const char *path, const char * const *argv, const char * const *envp);
#endif
int cwait(int *, int, int);
#define _P_WAIT 1
#define _P_NOWAIT 2 /* always generates error */
#define _P_OVERLAY 3
#define _P_NOWAITO 4
#define _P_DETACH 5
#define WAIT_CHILD 1
#ifdef __cplusplus
}
#endif
#endif

72
agbcc/libc/include/pwd.h Normal file
View File

@ -0,0 +1,72 @@
/*-
* Copyright (c) 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.
*
* @(#)pwd.h 5.13 (Berkeley) 5/28/91
*/
#ifndef _PWD_H_
#ifdef __cplusplus
extern "C" {
#endif
#define _PWD_H_
#include <sys/types.h>
#ifndef _POSIX_SOURCE
#define _PATH_PASSWD "/etc/passwd"
#define _PASSWORD_LEN 128 /* max length, not counting NULL */
#endif
struct passwd {
char *pw_name; /* user name */
char *pw_passwd; /* encrypted password */
int pw_uid; /* user uid */
int pw_gid; /* user gid */
char *pw_comment; /* comment */
char *pw_gecos; /* Honeywell login info */
char *pw_dir; /* home directory */
char *pw_shell; /* default shell */
};
struct passwd *getpwuid (uid_t);
struct passwd *getpwnam (const char *);
#ifndef _POSIX_SOURCE
struct passwd *getpwent (void);
void setpwent (void);
void endpwent (void);
#endif
#ifdef __cplusplus
}
#endif
#endif /* _PWD_H_ */

View File

@ -0,0 +1,87 @@
/* This header file provides the reentrancy. */
/* The reentrant system calls here serve two purposes:
1) Provide reentrant versions of the system calls the ANSI C library
requires.
2) Provide these system calls in a namespace clean way.
It is intended that *all* system calls that the ANSI C library needs
be declared here. It documents them all in one place. All library access
to the system is via some form of these functions.
There are three ways a target may provide the needed syscalls.
1) Define the reentrant versions of the syscalls directly.
(eg: _open_r, _close_r, etc.). Please keep the namespace clean.
When you do this, set "syscall_dir" to "syscalls" in configure.in,
and add -DREENTRANT_SYSCALLS_PROVIDED to target_cflags in configure.in.
2) Define namespace clean versions of the system calls by prefixing
them with '_' (eg: _open, _close, etc.). Technically, there won't be
true reentrancy at the syscall level, but the library will be namespace
clean.
When you do this, set "syscall_dir" to "syscalls" in configure.in.
3) Define or otherwise provide the regular versions of the syscalls
(eg: open, close, etc.). The library won't be reentrant nor namespace
clean, but at least it will work.
When you do this, add -DMISSING_SYSCALL_NAMES to target_cflags in
configure.in.
Stubs of the reentrant versions of the syscalls exist in the libc/reent
source directory and are used if REENTRANT_SYSCALLS_PROVIDED isn't defined.
They use the native system calls: _open, _close, etc. if they're available
(MISSING_SYSCALL_NAMES is *not* defined), otherwise open, close, etc.
(MISSING_SYSCALL_NAMES *is* defined). */
/* WARNING: All identifiers here must begin with an underscore. This file is
included by stdio.h and others and we therefore must only use identifiers
in the namespace allotted to us. */
#ifndef _REENT_H_
#ifdef __cplusplus
extern "C" {
#endif
#define _REENT_H_
#include <sys/reent.h>
#include <sys/_types.h>
#include <machine/types.h>
#define __need_size_t
#include <stddef.h>
/* FIXME: not namespace clean */
struct stat;
struct tms;
struct timeval;
struct timezone;
/* Reentrant versions of system calls. */
extern int _close_r _PARAMS ((struct _reent *, int));
extern int _execve_r _PARAMS ((struct _reent *, char *, char **, char **));
extern int _fcntl_r _PARAMS ((struct _reent *, int, int, int));
extern int _fork_r _PARAMS ((struct _reent *));
extern int _fstat_r _PARAMS ((struct _reent *, int, struct stat *));
extern int _getpid_r _PARAMS ((struct _reent *));
extern int _kill_r _PARAMS ((struct _reent *, int, int));
extern int _link_r _PARAMS ((struct _reent *, const char *, const char *));
extern _off_t _lseek_r _PARAMS ((struct _reent *, int, _off_t, int));
extern int _open_r _PARAMS ((struct _reent *, const char *, int, int));
extern _ssize_t _read_r _PARAMS ((struct _reent *, int, void *, size_t));
extern void *_sbrk_r _PARAMS ((struct _reent *, size_t));
extern int _stat_r _PARAMS ((struct _reent *, const char *, struct stat *));
extern _CLOCK_T_ _times_r _PARAMS ((struct _reent *, struct tms *));
extern int _unlink_r _PARAMS ((struct _reent *, const char *));
extern int _wait_r _PARAMS ((struct _reent *, int *));
extern _ssize_t _write_r _PARAMS ((struct _reent *, int, const void *, size_t));
/* This one is not guaranteed to be available on all targets. */
extern int _gettimeofday_r _PARAMS ((struct _reent *, struct timeval *tp, struct timezone *tzp));
#ifdef __cplusplus
}
#endif
#endif /* _REENT_H_ */

View File

@ -0,0 +1,7 @@
/* regdef.h -- define register names. */
/* This is a standard include file for MIPS targets. Other target
probably don't define it, and attempts to include this file will
fail. */
#include <machine/regdef.h>

View File

@ -0,0 +1,22 @@
/*
setjmp.h
stubs for future use.
*/
#ifndef _SETJMP_H_
#ifdef __cplusplus
extern "C" {
#endif
#define _SETJMP_H_
#include "_ansi.h"
#include <machine/setjmp.h>
void _EXFUN(longjmp,(jmp_buf __jmpb, int __retval));
int _EXFUN(setjmp,(jmp_buf __jmpb));
#ifdef __cplusplus
}
#endif
#endif /* _SETJMP_H_ */

View File

@ -0,0 +1,31 @@
#ifndef _SIGNAL_H_
#ifdef __cplusplus
extern "C" {
#endif
#define _SIGNAL_H_
#include "_ansi.h"
#include <sys/signal.h>
typedef int sig_atomic_t; /* Atomic entity type (ANSI) */
#define SIG_DFL ((void (*)(int))0) /* Default action */
#define SIG_IGN ((void (*)(int))1) /* Ignore action */
#define SIG_ERR ((void (*)(int))-1) /* Error return */
typedef void (*_sig_func_ptr) (int);
struct _reent;
_sig_func_ptr _EXFUN(_signal_r, (struct _reent *, int, _sig_func_ptr));
int _EXFUN(_raise_r, (struct _reent *, int));
#ifndef _REENT_ONLY
_sig_func_ptr _EXFUN(signal, (int, _sig_func_ptr));
int _EXFUN(raise, (int));
#endif
#ifdef __cplusplus
}
#endif
#endif /* _SIGNAL_H_ */

309
agbcc/libc/include/stdio.h Normal file
View File

@ -0,0 +1,309 @@
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not 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.
*
* @(#)stdio.h 5.3 (Berkeley) 3/15/86
*/
/*
* NB: to fit things in six character monocase externals, the
* stdio code uses the prefix `__s' for stdio objects, typically
* followed by a three-character attempt at a mnemonic.
*/
#ifndef _STDIO_H_
#ifdef __cplusplus
extern "C" {
#endif
#define _STDIO_H_
#include "_ansi.h"
#define _FSTDIO /* ``function stdio'' */
#define __need_size_t
#include <stddef.h>
#define __need___va_list
#include <stdarg.h>
/*
* <sys/reent.h> defines __sFILE, _fpos_t.
* They must be defined there because struct _reent needs them (and we don't
* want reent.h to include this file.
*/
#include <sys/reent.h>
typedef _fpos_t fpos_t;
typedef struct __sFILE FILE;
#define __SLBF 0x0001 /* line buffered */
#define __SNBF 0x0002 /* unbuffered */
#define __SRD 0x0004 /* OK to read */
#define __SWR 0x0008 /* OK to write */
/* RD and WR are never simultaneously asserted */
#define __SRW 0x0010 /* open for reading & writing */
#define __SEOF 0x0020 /* found EOF */
#define __SERR 0x0040 /* found error */
#define __SMBF 0x0080 /* _buf is from malloc */
#define __SAPP 0x0100 /* fdopen()ed in append mode - so must write to end */
#define __SSTR 0x0200 /* this is an sprintf/snprintf string */
#define __SOPT 0x0400 /* do fseek() optimisation */
#define __SNPT 0x0800 /* do not do fseek() optimisation */
#define __SOFF 0x1000 /* set iff _offset is in fact correct */
#define __SMOD 0x2000 /* true => fgetline modified _p text */
/*
* The following three definitions are for ANSI C, which took them
* from System V, which stupidly took internal interface macros and
* made them official arguments to setvbuf(), without renaming them.
* Hence, these ugly _IOxxx names are *supposed* to appear in user code.
*
* Although these happen to match their counterparts above, the
* implementation does not rely on that (so these could be renumbered).
*/
#define _IOFBF 0 /* setvbuf should set fully buffered */
#define _IOLBF 1 /* setvbuf should set line buffered */
#define _IONBF 2 /* setvbuf should set unbuffered */
#ifndef NULL
#define NULL 0L
#endif
#define BUFSIZ 1024
#define EOF (-1)
#define FOPEN_MAX 20 /* must be <= OPEN_MAX <sys/syslimits.h> */
#define FILENAME_MAX 1024 /* must be <= PATH_MAX <sys/syslimits.h> */
#define L_tmpnam 1024 /* XXX must be == PATH_MAX */
#ifndef __STRICT_ANSI__
#define P_tmpdir "/tmp"
#endif
#ifndef SEEK_SET
#define SEEK_SET 0 /* set file offset to offset */
#endif
#ifndef SEEK_CUR
#define SEEK_CUR 1 /* set file offset to current plus offset */
#endif
#ifndef SEEK_END
#define SEEK_END 2 /* set file offset to EOF plus offset */
#endif
#define TMP_MAX 26
#define stdin (_impure_ptr->_stdin)
#define stdout (_impure_ptr->_stdout)
#define stderr (_impure_ptr->_stderr)
#define _stdin_r(x) ((x)->_stdin)
#define _stdout_r(x) ((x)->_stdout)
#define _stderr_r(x) ((x)->_stderr)
/*
* Functions defined in ANSI C standard.
*/
#ifdef __GNUC__
#define __VALIST __gnuc_va_list
#else
#define __VALIST char*
#endif
#ifndef _REENT_ONLY
int _EXFUN(remove, (const char *));
int _EXFUN(rename, (const char *, const char *));
#endif
char * _EXFUN(tempnam, (const char *, const char *));
FILE * _EXFUN(tmpfile, (void));
char * _EXFUN(tmpnam, (char *));
int _EXFUN(fclose, (FILE *));
int _EXFUN(fflush, (FILE *));
FILE * _EXFUN(freopen, (const char *, const char *, FILE *));
void _EXFUN(setbuf, (FILE *, char *));
int _EXFUN(setvbuf, (FILE *, char *, int, size_t));
int _EXFUN(fprintf, (FILE *, const char *, ...));
int _EXFUN(fscanf, (FILE *, const char *, ...));
int _EXFUN(printf, (const char *, ...));
int _EXFUN(scanf, (const char *, ...));
int _EXFUN(sscanf, (const char *, const char *, ...));
int _EXFUN(vfprintf, (FILE *, const char *, __VALIST));
int _EXFUN(vprintf, (const char *, __VALIST));
int _EXFUN(vsprintf, (char *, const char *, __VALIST));
int _EXFUN(fgetc, (FILE *));
char * _EXFUN(fgets, (char *, int, FILE *));
int _EXFUN(fputc, (int, FILE *));
int _EXFUN(fputs, (const char *, FILE *));
int _EXFUN(getc, (FILE *));
int _EXFUN(getchar, (void));
char * _EXFUN(gets, (char *));
int _EXFUN(putc, (int, FILE *));
int _EXFUN(putchar, (int));
int _EXFUN(puts, (const char *));
int _EXFUN(ungetc, (int, FILE *));
size_t _EXFUN(fread, (_PTR, size_t _size, size_t _n, FILE *));
size_t _EXFUN(fwrite, (const _PTR , size_t _size, size_t _n, FILE *));
int _EXFUN(fgetpos, (FILE *, fpos_t *));
int _EXFUN(fseek, (FILE *, long, int));
int _EXFUN(fsetpos, (FILE *, const fpos_t *));
long _EXFUN(ftell, ( FILE *));
void _EXFUN(rewind, (FILE *));
void _EXFUN(clearerr, (FILE *));
int _EXFUN(feof, (FILE *));
int _EXFUN(ferror, (FILE *));
void _EXFUN(perror, (const char *));
#ifndef _REENT_ONLY
FILE * _EXFUN(fopen, (const char *_name, const char *_type));
int _EXFUN(sprintf, (char *, const char *, ...));
#endif
#ifndef __STRICT_ANSI__
int _EXFUN(vfiprintf, (FILE *, const char *, __VALIST));
int _EXFUN(iprintf, (const char *, ...));
int _EXFUN(fiprintf, (FILE *, const char *, ...));
int _EXFUN(siprintf, (char *, const char *, ...));
#endif
/*
* Routines in POSIX 1003.1.
*/
#ifndef __STRICT_ANSI__
#ifndef _REENT_ONLY
FILE * _EXFUN(fdopen, (int, const char *));
#endif
int _EXFUN(fileno, (FILE *));
int _EXFUN(getw, (FILE *));
int _EXFUN(pclose, (FILE *));
FILE * _EXFUN(popen, (const char *, const char *));
int _EXFUN(putw, (int, FILE *));
void _EXFUN(setbuffer, (FILE *, char *, int));
int _EXFUN(setlinebuf, (FILE *));
#endif
/*
* Recursive versions of the above.
*/
FILE * _EXFUN(_fdopen_r, (struct _reent *, int, const char *));
FILE * _EXFUN(_fopen_r, (struct _reent *, const char *, const char *));
int _EXFUN(_getchar_r, (struct _reent *));
char * _EXFUN(_gets_r, (struct _reent *, char *));
int _EXFUN(_iprintf_r, (struct _reent *, const char *, ...));
int _EXFUN(_mkstemp_r, (struct _reent *, char *));
char * _EXFUN(_mktemp_r, (struct _reent *, char *));
void _EXFUN(_perror_r, (struct _reent *, const char *));
int _EXFUN(_printf_r, (struct _reent *, const char *, ...));
int _EXFUN(_putchar_r, (struct _reent *, int));
int _EXFUN(_puts_r, (struct _reent *, const char *));
int _EXFUN(_remove_r, (struct _reent *, const char *));
int _EXFUN(_rename_r, (struct _reent *,
const char *_old, const char *_new));
int _EXFUN(_scanf_r, (struct _reent *, const char *, ...));
int _EXFUN(_sprintf_r, (struct _reent *, char *, const char *, ...));
char * _EXFUN(_tempnam_r, (struct _reent *, const char *, const char *));
FILE * _EXFUN(_tmpfile_r, (struct _reent *));
char * _EXFUN(_tmpnam_r, (struct _reent *, char *));
int _EXFUN(_vfprintf_r, (struct _reent *, FILE *, const char *, __VALIST));
int _EXFUN(_vprintf_r, (struct _reent *, const char *, __VALIST));
int _EXFUN(_vsprintf_r, (struct _reent *, char *, const char *, __VALIST));
/*
* Routines internal to the implementation.
*/
int _EXFUN(__srget, (FILE *));
int _EXFUN(__swbuf, (int, FILE *));
/*
* Stdio function-access interface.
*/
#ifndef __STRICT_ANSI__
FILE *_EXFUN(funopen,(const _PTR _cookie,
int (*readfn)(_PTR _cookie, char *_buf, int _n),
int (*writefn)(_PTR _cookie, const char *_buf, int _n),
fpos_t (*seekfn)(_PTR _cookie, fpos_t _off, int _whence),
int (*closefn)(_PTR _cookie)));
#define fropen(cookie, fn) funopen(cookie, fn, (int (*)())0, (fpos_t (*)())0, (int (*)())0)
#define fwopen(cookie, fn) funopen(cookie, (int (*)())0, fn, (fpos_t (*)())0, (int (*)())0)
#endif
/*
* The __sfoo macros are here so that we can
* define function versions in the C library.
*/
#define __sgetc(p) (--(p)->_r < 0 ? __srget(p) : (int)(*(p)->_p++))
#ifdef _never /* __GNUC__ */
/* If this inline is actually used, then systems using coff debugging
info get hopelessly confused. 21sept93 rich@cygnus.com. */
static __inline int __sputc(int _c, FILE *_p) {
if (--_p->_w >= 0 || (_p->_w >= _p->_lbfsize && (char)_c != '\n'))
return (*_p->_p++ = _c);
else
return (__swbuf(_c, _p));
}
#else
/*
* This has been tuned to generate reasonable code on the vax using pcc
*/
#define __sputc(c, p) \
(--(p)->_w < 0 ? \
(p)->_w >= (p)->_lbfsize ? \
(*(p)->_p = (c)), *(p)->_p != '\n' ? \
(int)*(p)->_p++ : \
__swbuf('\n', p) : \
__swbuf((int)(c), p) : \
(*(p)->_p = (c), (int)*(p)->_p++))
#endif
#define __sfeof(p) (((p)->_flags & __SEOF) != 0)
#define __sferror(p) (((p)->_flags & __SERR) != 0)
#define __sclearerr(p) ((void)((p)->_flags &= ~(__SERR|__SEOF)))
#define __sfileno(p) ((p)->_file)
#define feof(p) __sfeof(p)
#define ferror(p) __sferror(p)
#define clearerr(p) __sclearerr(p)
#if 0 /*ndef __STRICT_ANSI__ - FIXME: must initialize stdio first, use fn */
#define fileno(p) __sfileno(p)
#endif
#ifndef lint
#define getc(fp) __sgetc(fp)
#define putc(x, fp) __sputc(x, fp)
#endif /* lint */
#define getchar() getc(stdin)
#define putchar(x) putc(x, stdout)
#ifndef __STRICT_ANSI__
/* fast always-buffered version, true iff error */
#define fast_putc(x,p) (--(p)->_w < 0 ? \
__swbuf((int)(x), p) == EOF : (*(p)->_p = (x), (p)->_p++, 0))
#define L_cuserid 9 /* posix says it goes in stdio.h :( */
#ifdef __CYGWIN32__
#define L_ctermid 16
#endif
#endif
#ifdef __cplusplus
}
#endif
#endif /* _STDIO_H_ */

132
agbcc/libc/include/stdlib.h Normal file
View File

@ -0,0 +1,132 @@
/*
* stdlib.h
*
* Definitions for common types, variables, and functions.
*/
#ifndef _STDLIB_H_
#ifdef __cplusplus
extern "C" {
#endif
#define _STDLIB_H_
#include "_ansi.h"
#define __need_size_t
#define __need_wchar_t
#include <stddef.h>
#include <sys/reent.h>
typedef struct
{
int quot; /* quotient */
int rem; /* remainder */
} div_t;
typedef struct
{
long quot; /* quotient */
long rem; /* remainder */
} ldiv_t;
#ifndef NULL
#define NULL 0L
#endif
#define EXIT_FAILURE 1
#define EXIT_SUCCESS 0
#define RAND_MAX 0x7fffffff
#if (defined(__CYGWIN__) || defined(__CYGWIN32__)) && ! defined(_COMPILING_NEWLIB)
extern __declspec(dllimport) int __mb_cur_max;
#else
extern int __mb_cur_max;
#endif
#define MB_CUR_MAX __mb_cur_max
_VOID _EXFUN(abort,(_VOID) _ATTRIBUTE ((noreturn)));
int _EXFUN(abs,(int));
int _EXFUN(atexit,(_VOID (*__func)(_VOID)));
double _EXFUN(atof,(const char *__nptr));
#ifndef __STRICT_ANSI__
float _EXFUN(atoff,(const char *__nptr));
#endif
int _EXFUN(atoi,(const char *__nptr));
long _EXFUN(atol,(const char *__nptr));
_PTR _EXFUN(bsearch,(const _PTR __key,
const _PTR __base,
size_t __nmemb,
size_t __size,
int _EXFUN((*_compar),(const _PTR, const _PTR))));
_PTR _EXFUN(calloc,(size_t __nmemb, size_t __size));
div_t _EXFUN(div,(int __numer, int __denom));
_VOID _EXFUN(exit,(int __status) _ATTRIBUTE ((noreturn)));
_VOID _EXFUN(free,(_PTR));
char * _EXFUN(getenv,(const char *__string));
long _EXFUN(labs,(long));
ldiv_t _EXFUN(ldiv,(long __numer, long __denom));
_PTR _EXFUN(malloc,(size_t __size));
int _EXFUN(mblen,(const char *, size_t));
int _EXFUN(mbtowc,(wchar_t *, const char *, size_t));
int _EXFUN(_mbtowc_r,(struct _reent *, wchar_t *, const char *, size_t, int *));
int _EXFUN(wctomb,(char *, wchar_t));
int _EXFUN(_wctomb_r,(struct _reent *, char *, wchar_t, int *));
size_t _EXFUN(mbstowcs,(wchar_t *, const char *, size_t));
size_t _EXFUN(_mbstowcs_r,(struct _reent *, wchar_t *, const char *, size_t, int *));
size_t _EXFUN(wcstombs,(char *, const wchar_t *, size_t));
size_t _EXFUN(_wcstombs_r,(struct _reent *, char *, const wchar_t *, size_t, int *));
_VOID _EXFUN(qsort,(_PTR __base, size_t __nmemb, size_t __size, int(*_compar)(const _PTR, const _PTR)));
int _EXFUN(rand,(_VOID));
_PTR _EXFUN(realloc,(_PTR __r, size_t __size));
_VOID _EXFUN(srand,(unsigned __seed));
double _EXFUN(strtod,(const char *__n, char **_end_PTR));
#ifndef __STRICT_ANSI__
float _EXFUN(strtodf,(const char *__n, char **_end_PTR));
#endif
long _EXFUN(strtol,(const char *__n, char **_end_PTR, int __base));
unsigned long _EXFUN(strtoul,(const char *_n_PTR, char **_end_PTR, int __base));
unsigned long _EXFUN(_strtoul_r,(struct _reent *,const char *_n_PTR, char **_end_PTR, int __base));
int _EXFUN(system,(const char *__string));
#ifndef __STRICT_ANSI__
_VOID _EXFUN(cfree,(_PTR));
int _EXFUN(putenv,(const char *__string));
int _EXFUN(setenv,(const char *__string, const char *__value, int __overwrite));
char * _EXFUN(gcvt,(double,int,char *));
char * _EXFUN(gcvtf,(float,int,char *));
char * _EXFUN(fcvt,(double,int,int *,int *));
char * _EXFUN(fcvtf,(float,int,int *,int *));
char * _EXFUN(ecvt,(double,int,int *,int *));
char * _EXFUN(ecvtbuf,(double, int, int*, int*, char *));
char * _EXFUN(fcvtbuf,(double, int, int*, int*, char *));
char * _EXFUN(ecvtf,(float,int,int *,int *));
char * _EXFUN(dtoa,(double, int, int, int *, int*, char**));
int _EXFUN(rand_r,(unsigned *__seed));
#ifdef __CYGWIN32__
char * _EXFUN(realpath,(const char *, char *));
void _EXFUN(unsetenv,(const char *__string));
int _EXFUN(random,(_VOID));
long _EXFUN(srandom,(unsigned __seed));
#endif
#endif /* ! __STRICT_ANSI__ */
char * _EXFUN(_dtoa_r,(struct _reent *, double, int, int, int *, int*, char**));
_PTR _EXFUN(_malloc_r,(struct _reent *, size_t));
_PTR _EXFUN(_calloc_r,(struct _reent *, size_t, size_t));
_VOID _EXFUN(_free_r,(struct _reent *, _PTR));
_PTR _EXFUN(_realloc_r,(struct _reent *, _PTR, size_t));
_VOID _EXFUN(_mstats_r,(struct _reent *, char *));
int _EXFUN(_system_r,(struct _reent *, const char *));
_VOID _EXFUN(__eprintf,(const char *, const char *, unsigned int, const char *));
#ifdef __cplusplus
}
#endif
#endif /* _STDLIB_H_ */

View File

@ -0,0 +1,90 @@
/*
* string.h
*
* Definitions for memory and string functions.
*/
#ifndef _STRING_H_
#define _STRING_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "_ansi.h"
#define __need_size_t
#include <stddef.h>
#ifndef NULL
#define NULL 0L
#endif
_PTR _EXFUN(memchr,(const _PTR, int, size_t));
int _EXFUN(memcmp,(const _PTR, const _PTR, size_t));
_PTR _EXFUN(memcpy,(_PTR, const _PTR, size_t));
_PTR _EXFUN(memmove,(_PTR, const _PTR, size_t));
_PTR _EXFUN(memset,(_PTR, int, size_t));
char *_EXFUN(strcat,(char *, const char *));
char *_EXFUN(strchr,(const char *, int));
int _EXFUN(strcmp,(const char *, const char *));
int _EXFUN(strcoll,(const char *, const char *));
char *_EXFUN(strcpy,(char *, const char *));
size_t _EXFUN(strcspn,(const char *, const char *));
char *_EXFUN(strerror,(int));
size_t _EXFUN(strlen,(const char *));
char *_EXFUN(strncat,(char *, const char *, size_t));
int _EXFUN(strncmp,(const char *, const char *, size_t));
char *_EXFUN(strncpy,(char *, const char *, size_t));
char *_EXFUN(strpbrk,(const char *, const char *));
char *_EXFUN(strrchr,(const char *, int));
size_t _EXFUN(strspn,(const char *, const char *));
char *_EXFUN(strstr,(const char *, const char *));
#ifndef _REENT_ONLY
char *_EXFUN(strtok,(char *, const char *));
#endif
size_t _EXFUN(strxfrm,(char *, const char *, size_t));
#ifndef __STRICT_ANSI__
char *_EXFUN(strtok_r,(char *, const char *, char **));
int _EXFUN(bcmp,(const char *, const char *, size_t));
void _EXFUN(bcopy,(const char *, char *, size_t));
void _EXFUN(bzero,(char *, size_t));
int _EXFUN(ffs,(int));
char *_EXFUN(index,(const char *, int));
_PTR _EXFUN(memccpy,(_PTR, const _PTR, int, size_t));
char *_EXFUN(rindex,(const char *, int));
int _EXFUN(strcasecmp,(const char *, const char *));
char *_EXFUN(strdup,(const char *));
int _EXFUN(strncasecmp,(const char *, const char *, size_t));
char *_EXFUN(strsep,(char **, const char *));
char *_EXFUN(strlwr,(char *));
char *_EXFUN(strupr,(char *));
#ifdef __CYGWIN32__
char *_EXFUN(strsignal, (int __signo));
int _EXFUN(strtosigno, (const char *__name));
#endif
/* These function names are used on Windows and perhaps other systems. */
#ifndef strcmpi
#define strcmpi strcasecmp
#endif
#ifndef stricmp
#define stricmp strcasecmp
#endif
#ifndef strncmpi
#define strncmpi strncasecmp
#endif
#ifndef strnicmp
#define strnicmp strncasecmp
#endif
#endif /* ! __STRICT_ANSI__ */
#ifdef __cplusplus
}
#endif
#endif /* _STRING_H_ */

View File

@ -0,0 +1,15 @@
/* ANSI C namespace clean utility typedefs */
/* This file defines various typedefs needed by the system calls that support
the C library. Basically, they're just the POSIX versions with an '_'
prepended. This file lives in the `sys' directory so targets can provide
their own if desired (or they can put target dependant conditionals here).
*/
#ifndef _SYS__TYPES_H
#define _SYS__TYPES_H
typedef long _off_t;
typedef long _ssize_t;
#endif /* _SYS__TYPES_H */

View File

@ -0,0 +1,111 @@
#ifndef __SYS_CONFIG_H__
#define __SYS_CONFIG_H__
/* exceptions first */
/* ??? Why is much of this stuff duplicated with machine/ieeefp.h? */
#if defined(__H8300__) || defined(__H8500__) || defined (__H8300H__) || defined(__W65__) || defined (__H8300S__)
#define _FLOAT_ARG float
#define __SMALL_BITFIELDS
#define _DOUBLE_IS_32BITS
#define __IEEE_BIG_ENDIAN
/* ??? This conditional is true for the h8500 and the w65, defining H8300
in those cases probably isn't the right thing to do. */
#define H8300 1
#endif
#ifdef __W65__
#define _DOUBLE_IS_32BITS
#define __SMALL_BITFIELDS
#define __IEEE_BIG_ENDIAN
#undef INT_MAX
#undef UINT_MAX
#define INT_MAX 32767
#define UINT_MAX 65535
#endif
/* 16 bit integer machines */
#if defined(__Z8001__) || defined(__Z8002__) || defined(__H8300__) || defined(__H8500__) || defined(__W65__) || defined (__H8300H__) || defined (__H8300S__) || defined (__mn10200__)
#undef INT_MAX
#undef UINT_MAX
#define INT_MAX 32767
#define UINT_MAX 65535
#endif
#if defined(__D10V__)
#undef INT_MAX
#undef UINT_MAX
#define INT_MAX __INT_MAX__
#define UINT_MAX (__INT_MAX__ * 2U + 1)
#define _DOUBLE_IS_32BITS
#define _POINTER_INT short
#define __IEEE_BIG_ENDIAN
#endif
#ifdef ___AM29K__
#define _FLOAT_RET double
#endif
#ifdef __i386__
#ifndef __unix__
/* in other words, go32 */
#define _FLOAT_RET double
#endif
#endif
#ifdef __M32R__
#define __IEEE_BIG_ENDIAN
#endif
#ifdef __m68k__
/* This is defined in machine/ieeefp.h; need to check is it redundant here? */
#define __IEEE_BIG_ENDIAN
#endif
#ifdef __mn10300__
#define __IEEE_LITTLE_ENDIAN
#endif
#ifdef __mn10200__
#define _DOUBLE_IS_32BITS
#define __SMALL_BITFIELDS
#define __IEEE_LITTLE_ENDIAN
#endif
#ifdef __v850
#define __IEEE_LITTLE_ENDIAN
#define __ATTRIBUTE_IMPURE_PTR__ __attribute__((__sda__))
#endif
#ifdef __D30V__
#define __IEEE_BIG_ENDIAN
#endif
/* For the PowerPC eabi, force the _impure_ptr to be in .sdata */
#if defined(__PPC__) && defined(_CALL_SYSV)
#define __ATTRIBUTE_IMPURE_PTR__ __attribute__((__section__(".sdata")))
#endif
#ifdef __sparc__
#ifdef __LITTLE_ENDIAN_DATA__
#define __IEEE_LITTLE_ENDIAN
#else
#define __IEEE_BIG_ENDIAN
#endif
#endif
#if INT_MAX == 32767
typedef long int __int32_t;
typedef unsigned long int __uint32_t;
#else
typedef int __int32_t;
typedef unsigned int __uint32_t;
#endif
#ifndef _POINTER_INT
#define _POINTER_INT long
#endif
#endif /* __SYS_CONFIG_H__ */

View File

@ -0,0 +1,15 @@
/* <dirent.h> includes <sys/dirent.h>, which is this file. On a
system which supports <dirent.h>, this file is overridden by
dirent.h in the libc/sys/.../sys directory. On a system which does
not support <dirent.h>, we will get this file which tries to find
any other <dirent.h> which may be lurking around. If there isn't
one, the user will get an error indicating that there is no
<dirent.h>. */
#ifdef __cplusplus
extern "C" {
#endif
#include_next <dirent.h>
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,154 @@
/* errno is not a global variable, because that would make using it
non-reentrant. Instead, its address is returned by the function
__errno. */
#ifndef _SYS_ERRNO_H_
#ifdef __cplusplus
extern "C" {
#endif
#define _SYS_ERRNO_H_
#include <sys/reent.h>
#ifndef _REENT_ONLY
#define errno (*__errno())
extern int *__errno _PARAMS ((void));
#endif
#if !defined(__CYGWIN32__) || defined(__INSIDE_CYGWIN__)
extern _CONST char * _CONST _sys_errlist[];
extern int _sys_nerr;
#else
extern _CONST char * _CONST _sys_errlist[] __declspec(dllimport);
extern int _sys_nerr __declspec(dllimport);
#endif
#define __errno_r(ptr) ((ptr)->_errno)
#define EPERM 1 /* Not super-user */
#define ENOENT 2 /* No such file or directory */
#define ESRCH 3 /* No such process */
#define EINTR 4 /* Interrupted system call */
#define EIO 5 /* I/O error */
#define ENXIO 6 /* No such device or address */
#define E2BIG 7 /* Arg list too long */
#define ENOEXEC 8 /* Exec format error */
#define EBADF 9 /* Bad file number */
#define ECHILD 10 /* No children */
#define EAGAIN 11 /* No more processes */
#define ENOMEM 12 /* Not enough core */
#define EACCES 13 /* Permission denied */
#define EFAULT 14 /* Bad address */
#define ENOTBLK 15 /* Block device required */
#define EBUSY 16 /* Mount device busy */
#define EEXIST 17 /* File exists */
#define EXDEV 18 /* Cross-device link */
#define ENODEV 19 /* No such device */
#define ENOTDIR 20 /* Not a directory */
#define EISDIR 21 /* Is a directory */
#define EINVAL 22 /* Invalid argument */
#define ENFILE 23 /* Too many open files in system */
#define EMFILE 24 /* Too many open files */
#define ENOTTY 25 /* Not a typewriter */
#define ETXTBSY 26 /* Text file busy */
#define EFBIG 27 /* File too large */
#define ENOSPC 28 /* No space left on device */
#define ESPIPE 29 /* Illegal seek */
#define EROFS 30 /* Read only file system */
#define EMLINK 31 /* Too many links */
#define EPIPE 32 /* Broken pipe */
#define EDOM 33 /* Math arg out of domain of func */
#define ERANGE 34 /* Math result not representable */
#define ENOMSG 35 /* No message of desired type */
#define EIDRM 36 /* Identifier removed */
#define ECHRNG 37 /* Channel number out of range */
#define EL2NSYNC 38 /* Level 2 not synchronized */
#define EL3HLT 39 /* Level 3 halted */
#define EL3RST 40 /* Level 3 reset */
#define ELNRNG 41 /* Link number out of range */
#define EUNATCH 42 /* Protocol driver not attached */
#define ENOCSI 43 /* No CSI structure available */
#define EL2HLT 44 /* Level 2 halted */
#define EDEADLK 45 /* Deadlock condition */
#define ENOLCK 46 /* No record locks available */
#define EBADE 50 /* Invalid exchange */
#define EBADR 51 /* Invalid request descriptor */
#define EXFULL 52 /* Exchange full */
#define ENOANO 53 /* No anode */
#define EBADRQC 54 /* Invalid request code */
#define EBADSLT 55 /* Invalid slot */
#define EDEADLOCK 56 /* File locking deadlock error */
#define EBFONT 57 /* Bad font file fmt */
#define ENOSTR 60 /* Device not a stream */
#define ENODATA 61 /* No data (for no delay io) */
#define ETIME 62 /* Timer expired */
#define ENOSR 63 /* Out of streams resources */
#define ENONET 64 /* Machine is not on the network */
#define ENOPKG 65 /* Package not installed */
#define EREMOTE 66 /* The object is remote */
#define ENOLINK 67 /* The link has been severed */
#define EADV 68 /* Advertise error */
#define ESRMNT 69 /* Srmount error */
#define ECOMM 70 /* Communication error on send */
#define EPROTO 71 /* Protocol error */
#define EMULTIHOP 74 /* Multihop attempted */
#define ELBIN 75 /* Inode is remote (not really error) */
#define EDOTDOT 76 /* Cross mount point (not really error) */
#define EBADMSG 77 /* Trying to read unreadable message */
#define ENOTUNIQ 80 /* Given log. name not unique */
#define EBADFD 81 /* f.d. invalid for this operation */
#define EREMCHG 82 /* Remote address changed */
#define ELIBACC 83 /* Can't access a needed shared lib */
#define ELIBBAD 84 /* Accessing a corrupted shared lib */
#define ELIBSCN 85 /* .lib section in a.out corrupted */
#define ELIBMAX 86 /* Attempting to link in too many libs */
#define ELIBEXEC 87 /* Attempting to exec a shared library */
#define ENOSYS 88 /* Function not implemented */
#define ENMFILE 89 /* No more files */
#define ENOTEMPTY 90 /* Directory not empty */
#define ENAMETOOLONG 91 /* File or path name too long */
#define ELOOP 92 /* Too many symbolic links */
#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
#define EPFNOSUPPORT 96 /* Protocol family not supported */
#define ECONNRESET 104 /* Connection reset by peer */
#define ENOBUFS 105 /* No buffer space available */
#define EAFNOSUPPORT 106
#define EPROTOTYPE 107
#define ENOTSOCK 108
#define ENOPROTOOPT 109
#define ESHUTDOWN 110
#define ECONNREFUSED 111 /* Connection refused */
#define EADDRINUSE 112 /* Address already in use */
#define ECONNABORTED 113 /* Connection aborted */
#define ENETUNREACH 114
#define ENETDOWN 115
#define ETIMEDOUT 116
#define EHOSTDOWN 117
#define EHOSTUNREACH 118
#define EINPROGRESS 119
#define EALREADY 120
#define EDESTADDRREQ 121
#define EMSGSIZE 122
#define EPROTONOSUPPORT 123
#define ESOCKTNOSUPPORT 124
#define EADDRNOTAVAIL 125
#define ENETRESET 126
#define EISCONN 127
#define ENOTCONN 128
#define ETOOMANYREFS 129
#define EPROCLIM 130
#define EUSERS 131
#define EDQUOT 132
#define ESTALE 133
#define ENOTSUP 134
#define ENOMEDIUM 135
/* From cygwin32. */
#define EWOULDBLOCK EAGAIN /* Operation would block */
#define __ELASTERROR 2000 /* Users can add values starting here */
#ifdef __cplusplus
}
#endif
#endif /* _SYS_ERRNO_H */

View File

@ -0,0 +1,178 @@
#ifndef _FCNTL_
#ifdef __cplusplus
extern "C" {
#endif
#define _FCNTL_
#include <_ansi.h>
#define _FOPEN (-1) /* from sys/file.h, kernel use only */
#define _FREAD 0x0001 /* read enabled */
#define _FWRITE 0x0002 /* write enabled */
#define _FNDELAY 0x0004 /* non blocking I/O (4.2 style) */
#define _FAPPEND 0x0008 /* append (writes guaranteed at the end) */
#define _FMARK 0x0010 /* internal; mark during gc() */
#define _FDEFER 0x0020 /* internal; defer for next gc pass */
#define _FASYNC 0x0040 /* signal pgrp when data ready */
#define _FSHLOCK 0x0080 /* BSD flock() shared lock present */
#define _FEXLOCK 0x0100 /* BSD flock() exclusive lock present */
#define _FCREAT 0x0200 /* open with file create */
#define _FTRUNC 0x0400 /* open with truncation */
#define _FEXCL 0x0800 /* error on open if file exists */
#define _FNBIO 0x1000 /* non blocking I/O (sys5 style) */
#define _FSYNC 0x2000 /* do all writes synchronously */
#define _FNONBLOCK 0x4000 /* non blocking I/O (POSIX style) */
#define _FNOCTTY 0x8000 /* don't assign a ctty on this open */
#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)
/*
* Flag values for open(2) and fcntl(2)
* The kernel adds 1 to the open modes to turn it into some
* combination of FREAD and FWRITE.
*/
#define O_RDONLY 0 /* +1 == FREAD */
#define O_WRONLY 1 /* +1 == FWRITE */
#define O_RDWR 2 /* +1 == FREAD|FWRITE */
#define O_APPEND _FAPPEND
#define O_CREAT _FCREAT
#define O_TRUNC _FTRUNC
#define O_EXCL _FEXCL
/* O_SYNC _FSYNC not posix, defined below */
/* O_NDELAY _FNDELAY set in include/fcntl.h */
/* O_NDELAY _FNBIO set in 5include/fcntl.h */
#define O_NONBLOCK _FNONBLOCK
#define O_NOCTTY _FNOCTTY
/* For machines which care - */
#ifdef _WIN32
#define _FBINARY 0x10000
#define _FTEXT 0x20000
#define _FNOINHERIT 0x40000
#define O_BINARY _FBINARY
#define O_TEXT _FTEXT
#define O_NOINHERIT _FNOINHERIT
/* The windows header files define versions with a leading underscore. */
#define _O_RDONLY O_RDONLY
#define _O_WRONLY O_WRONLY
#define _O_RDWR O_RDWR
#define _O_APPEND O_APPEND
#define _O_CREATE O_CREAT
#define _O_TRUNC O_TRUNC
#define _O_EXCL O_EXCL
#define _O_TEXT O_TEXT
#define _O_BINARY O_BINARY
#define _O_RAW O_BINARY
#define _O_NOINHERIT O_NOINHERIT
#endif
#ifndef _POSIX_SOURCE
#define O_SYNC _FSYNC
/*
* Flags that work for fcntl(fd, F_SETFL, FXXXX)
*/
#define FAPPEND _FAPPEND
#define FSYNC _FSYNC
#define FASYNC _FASYNC
#define FNBIO _FNBIO
#define FNONBIO _FNONBLOCK /* XXX fix to be NONBLOCK everywhere */
#define FNDELAY _FNDELAY
/*
* Flags that are disallowed for fcntl's (FCNTLCANT);
* used for opens, internal state, or locking.
*/
#define FREAD _FREAD
#define FWRITE _FWRITE
#define FMARK _FMARK
#define FDEFER _FDEFER
#define FSHLOCK _FSHLOCK
#define FEXLOCK _FEXLOCK
/*
* The rest of the flags, used only for opens
*/
#define FOPEN _FOPEN
#define FCREAT _FCREAT
#define FTRUNC _FTRUNC
#define FEXCL _FEXCL
#define FNOCTTY _FNOCTTY
#endif /* !_POSIX_SOURCE */
/* XXX close on exec request; must match UF_EXCLOSE in user.h */
#define FD_CLOEXEC 1 /* posix */
/* fcntl(2) requests */
#define F_DUPFD 0 /* Duplicate fildes */
#define F_GETFD 1 /* Get fildes flags (close on exec) */
#define F_SETFD 2 /* Set fildes flags (close on exec) */
#define F_GETFL 3 /* Get file flags */
#define F_SETFL 4 /* Set file flags */
#ifndef _POSIX_SOURCE
#define F_GETOWN 5 /* Get owner - for ASYNC */
#define F_SETOWN 6 /* Set owner - for ASYNC */
#endif /* !_POSIX_SOURCE */
#define F_GETLK 7 /* Get record-locking information */
#define F_SETLK 8 /* Set or Clear a record-lock (Non-Blocking) */
#define F_SETLKW 9 /* Set or Clear a record-lock (Blocking) */
#ifndef _POSIX_SOURCE
#define F_RGETLK 10 /* Test a remote lock to see if it is blocked */
#define F_RSETLK 11 /* Set or unlock a remote lock */
#define F_CNVT 12 /* Convert a fhandle to an open fd */
#define F_RSETLKW 13 /* Set or Clear remote record-lock(Blocking) */
#endif /* !_POSIX_SOURCE */
/* fcntl(2) flags (l_type field of flock structure) */
#define F_RDLCK 1 /* read lock */
#define F_WRLCK 2 /* write lock */
#define F_UNLCK 3 /* remove lock(s) */
#ifndef _POSIX_SOURCE
#define F_UNLKSYS 4 /* remove remote locks for a given system */
#endif /* !_POSIX_SOURCE */
/*#include <sys/stdtypes.h>*/
/* file segment locking set data type - information passed to system by user */
struct flock {
short l_type; /* F_RDLCK, F_WRLCK, or F_UNLCK */
short l_whence; /* flag to choose starting offset */
long l_start; /* relative offset, in bytes */
long l_len; /* length, in bytes; 0 means lock to EOF */
short l_pid; /* returned with F_GETLK */
short l_xxx; /* reserved for future use */
};
#ifndef _POSIX_SOURCE
/* extended file segment locking set data type */
struct eflock {
short l_type; /* F_RDLCK, F_WRLCK, or F_UNLCK */
short l_whence; /* flag to choose starting offset */
long l_start; /* relative offset, in bytes */
long l_len; /* length, in bytes; 0 means lock to EOF */
short l_pid; /* returned with F_GETLK */
short l_xxx; /* reserved for future use */
long l_rpid; /* Remote process id wanting this lock */
long l_rsys; /* Remote system id wanting this lock */
};
#endif /* !_POSIX_SOURCE */
#include <sys/types.h>
#include <sys/stat.h> /* sigh. for the mode bits for open/creat */
extern int open _PARAMS ((const char *, int, ...));
extern int creat _PARAMS ((const char *, mode_t));
extern int fcntl _PARAMS ((int, int, ...));
/* Provide _<systemcall> prototypes for functions provided by some versions
of newlib. */
extern int _open _PARAMS ((const char *, int, ...));
extern int _fcntl _PARAMS ((int, int, ...));
#ifdef __cplusplus
}
#endif
#endif /* !_FCNTL_ */

View File

@ -0,0 +1,2 @@
#include <sys/fcntl.h>

View File

@ -0,0 +1,18 @@
/* This is a dummy <sys/param.h> file, not customized for any
particular system. If there is a param.h in libc/sys/SYSDIR/sys,
it will override this one. */
#ifndef _SYS_PARAM_H
# define _SYS_PARAM_H
# define HZ (60)
# define NOFILE (60)
# define PATHSIZE (1024)
#ifdef __i386__
#define BIG_ENDIAN 4321
#define LITTLE_ENDIAN 1234
#define BYTE_ORDER LITTLE_ENDIAN
#endif
#endif

View File

@ -0,0 +1,238 @@
/* This header file provides the reentrancy. */
/* WARNING: All identifiers here must begin with an underscore. This file is
included by stdio.h and others and we therefore must only use identifiers
in the namespace allotted to us. */
#ifndef _SYS_REENT_H_
#ifdef __cplusplus
extern "C" {
#endif
#define _SYS_REENT_H_
#include <_ansi.h>
#include <time.h>
#ifndef Long
#if __LONG_MAX__ == 2147483647L
#define Long long
typedef unsigned Long ULong;
#elif __INT_MAX__ == 2147483647
#define Long int
typedef unsigned Long ULong;
#endif
#endif
#ifndef Long
#define Long __int32_t
typedef __uint32_t ULong;
#endif
struct _glue
{
struct _glue *_next;
int _niobs;
struct __sFILE *_iobs;
};
struct _Bigint
{
struct _Bigint *_next;
int _k, _maxwds, _sign, _wds;
ULong _x[1];
};
/*
* atexit() support
*/
#define _ATEXIT_SIZE 32 /* must be at least 32 to guarantee ANSI conformance */
struct _atexit {
struct _atexit *_next; /* next in list */
int _ind; /* next index in this table */
void (*_fns[_ATEXIT_SIZE])(void); /* the table itself */
};
/*
* Stdio buffers.
*
* This and __sFILE are defined here because we need them for struct _reent,
* but we don't want stdio.h included when stdlib.h is.
*/
struct __sbuf {
unsigned char *_base;
int _size;
};
/*
* We need fpos_t for the following, but it doesn't have a leading "_",
* so we use _fpos_t instead.
*/
typedef long _fpos_t; /* XXX must match off_t in <sys/types.h> */
/* (and must be `long' for now) */
/*
* Stdio state variables.
*
* The following always hold:
*
* if (_flags&(__SLBF|__SWR)) == (__SLBF|__SWR),
* _lbfsize is -_bf._size, else _lbfsize is 0
* if _flags&__SRD, _w is 0
* if _flags&__SWR, _r is 0
*
* This ensures that the getc and putc macros (or inline functions) never
* try to write or read from a file that is in `read' or `write' mode.
* (Moreover, they can, and do, automatically switch from read mode to
* write mode, and back, on "r+" and "w+" files.)
*
* _lbfsize is used only to make the inline line-buffered output stream
* code as compact as possible.
*
* _ub, _up, and _ur are used when ungetc() pushes back more characters
* than fit in the current _bf, or when ungetc() pushes back a character
* that does not match the previous one in _bf. When this happens,
* _ub._base becomes non-nil (i.e., a stream has ungetc() data iff
* _ub._base!=NULL) and _up and _ur save the current values of _p and _r.
*/
struct __sFILE {
unsigned char *_p; /* current position in (some) buffer */
int _r; /* read space left for getc() */
int _w; /* write space left for putc() */
short _flags; /* flags, below; this FILE is free if 0 */
short _file; /* fileno, if Unix descriptor, else -1 */
struct __sbuf _bf; /* the buffer (at least 1 byte, if !NULL) */
int _lbfsize; /* 0 or -_bf._size, for inline putc */
/* operations */
_PTR _cookie; /* cookie passed to io functions */
int _EXFUN((*_read),(_PTR _cookie, char *_buf, int _n));
int _EXFUN((*_write),(_PTR _cookie, const char *_buf, int _n));
_fpos_t _EXFUN((*_seek),(_PTR _cookie, _fpos_t _offset, int _whence));
int _EXFUN((*_close),(_PTR _cookie));
/* separate buffer for long sequences of ungetc() */
struct __sbuf _ub; /* ungetc buffer */
unsigned char *_up; /* saved _p when _p is doing ungetc data */
int _ur; /* saved _r when _r is counting ungetc data */
/* tricks to meet minimum requirements even when malloc() fails */
unsigned char _ubuf[3]; /* guarantee an ungetc() buffer */
unsigned char _nbuf[1]; /* guarantee a getc() buffer */
/* separate buffer for fgetline() when line crosses buffer boundary */
struct __sbuf _lb; /* buffer for fgetline() */
/* Unix stdio files get aligned to block boundaries on fseek() */
int _blksize; /* stat.st_blksize (may be != _bf._size) */
int _offset; /* current lseek offset */
struct _reent *_data;
};
/*
* struct _reent
*
* This structure contains *all* globals needed by the library.
* It's raison d'etre is to facilitate threads by making all library routines
* reentrant. IE: All state information is contained here.
*/
struct _reent
{
/* local copy of errno */
int _errno;
/* FILE is a big struct and may change over time. To try to achieve binary
compatibility with future versions, put stdin,stdout,stderr here.
These are pointers into member __sf defined below. */
struct __sFILE *_stdin, *_stdout, *_stderr;
int _inc; /* used by tmpnam */
char _emergency[25];
int _current_category; /* used by setlocale */
_CONST char *_current_locale;
int __sdidinit; /* 1 means stdio has been init'd */
void _EXFUN((*__cleanup),(struct _reent *));
/* used by mprec routines */
struct _Bigint *_result;
int _result_k;
struct _Bigint *_p5s;
struct _Bigint **_freelist;
/* used by some fp conversion routines */
int _cvtlen; /* should be size_t */
char *_cvtbuf;
union
{
struct
{
unsigned int _rand_next;
char * _strtok_last;
char _asctime_buf[26];
struct tm _localtime_buf;
int _gamma_signgam;
} _reent;
/* Two next two fields were once used by malloc. They are no longer
used. They are used to preserve the space used before so as to
allow addition of new reent fields and keep binary compatibility. */
struct
{
#define _N_LISTS 30
unsigned char * _nextf[_N_LISTS];
unsigned int _nmalloc[_N_LISTS];
} _unused;
} _new;
/* atexit stuff */
struct _atexit *_atexit; /* points to head of LIFO stack */
struct _atexit _atexit0; /* one guaranteed table, required by ANSI */
/* signal info */
void (**(_sig_func))(int);
/* These are here last so that __sFILE can grow without changing the offsets
of the above members (on the off chance that future binary compatibility
would be broken otherwise). */
struct _glue __sglue; /* root of glue chain */
struct __sFILE __sf[3]; /* first three file descriptors */
};
#define _REENT_INIT(var) \
{ 0, &var.__sf[0], &var.__sf[1], &var.__sf[2], 0, "", 0, "C", \
0, NULL, NULL, 0, NULL, NULL, 0, NULL, { {1, NULL, "", \
{ 0,0,0,0,0,0,0,0}, 0 } } }
/*
* All references to struct _reent are via this pointer.
* Internally, newlib routines that need to reference it should use _REENT.
*/
#ifndef __ATTRIBUTE_IMPURE_PTR__
#define __ATTRIBUTE_IMPURE_PTR__
#endif
extern struct _reent *_impure_ptr __ATTRIBUTE_IMPURE_PTR__;
void _reclaim_reent _PARAMS ((struct _reent *));
/* #define _REENT_ONLY define this to get only reentrant routines */
#ifndef _REENT_ONLY
#define _REENT _impure_ptr
#endif
#ifdef __cplusplus
}
#endif
#endif /* _SYS_REENT_H_ */

View File

@ -0,0 +1,15 @@
#ifndef _SYS_RESOURCE_H_
#define _SYS_RESOURCE_H_
#include <sys/time.h>
#define RUSAGE_SELF 0 /* calling process */
#define RUSAGE_CHILDREN -1 /* terminated child processes */
struct rusage {
struct timeval ru_utime; /* user time used */
struct timeval ru_stime; /* system time used */
};
#endif

View File

@ -0,0 +1,182 @@
/* sys/signal.h */
#ifndef _SYS_SIGNAL_H
#define _SYS_SIGNAL_H
#ifdef __cplusplus
extern "C" {
#endif
#include "_ansi.h"
#ifndef __STRICT_ANSI__
typedef unsigned long sigset_t;
struct sigaction
{
void (*sa_handler)(int);
sigset_t sa_mask;
int sa_flags;
};
#define SA_NOCLDSTOP 1 /* only value supported now for sa_flags */
#define SIG_SETMASK 0 /* set mask with sigprocmask() */
#define SIG_BLOCK 1 /* set of signals to block */
#define SIG_UNBLOCK 2 /* set of signals to, well, unblock */
/* These depend upon the type of sigset_t, which right now
is always a long.. They're in the POSIX namespace, but
are not ANSI. */
#define sigaddset(what,sig) (*(what) |= (1<<(sig)))
#define sigemptyset(what) (*(what) = 0)
int sigprocmask (int __how, const sigset_t *__a, sigset_t *__b);
/* protos for functions found in winsup sources */
#if defined(__CYGWIN32__)
#undef sigaddset
#undef sigemptyset
/* The first argument to kill should be pid_t. Right now
<sys/types.h> always defines pid_t to be int. If that ever
changes, then we will need to do something else, perhaps along the
lines of <machine/types.h>. */
int _EXFUN(kill, (int, int));
int _EXFUN(sigaction, (int, const struct sigaction *, struct sigaction *));
int _EXFUN(sigaddset, (sigset_t *, const int));
int _EXFUN(sigdelset, (sigset_t *, const int));
int _EXFUN(sigismember, (const sigset_t *, int));
int _EXFUN(sigfillset, (sigset_t *));
int _EXFUN(sigemptyset, (sigset_t *));
int _EXFUN(sigpending, (sigset_t *));
int _EXFUN(sigsuspend, (const sigset_t *));
int _EXFUN(sigpause, (int));
#endif
#endif /* __STRICT_ANSI__ */
#if defined(___AM29K__)
/* These all need to be defined for ANSI C, but I don't think they are
meaningful. */
#define SIGABRT 1
#define SIGFPE 1
#define SIGILL 1
#define SIGINT 1
#define SIGSEGV 1
#define SIGTERM 1
/* These need to be defined for POSIX, and some others do too. */
#define SIGHUP 1
#define SIGQUIT 1
#define NSIG 2
#elif defined(__GO32__)
#define SIGINT 1
#define SIGKILL 2
#define SIGPIPE 3
#define SIGFPE 4
#define SIGHUP 5
#define SIGTERM 6
#define SIGSEGV 7
#define SIGTSTP 8
#define SIGQUIT 9
#define SIGTRAP 10
#define SIGILL 11
#define SIGEMT 12
#define SIGALRM 13
#define SIGBUS 14
#define SIGLOST 15
#define SIGSTOP 16
#define SIGABRT 17
#define SIGUSR1 18
#define SIGUSR2 19
#define NSIG 20
#elif defined(__CYGWIN32__) /* BSD signals symantics */
#define SIGHUP 1 /* hangup */
#define SIGINT 2 /* interrupt */
#define SIGQUIT 3 /* quit */
#define SIGILL 4 /* illegal instruction (not reset when caught) */
#define SIGTRAP 5 /* trace trap (not reset when caught) */
#define SIGABRT 6 /* used by abort */
#define SIGEMT 7 /* EMT instruction */
#define SIGFPE 8 /* floating point exception */
#define SIGKILL 9 /* kill (cannot be caught or ignored) */
#define SIGBUS 10 /* bus error */
#define SIGSEGV 11 /* segmentation violation */
#define SIGSYS 12 /* bad argument to system call */
#define SIGPIPE 13 /* write on a pipe with no one to read it */
#define SIGALRM 14 /* alarm clock */
#define SIGTERM 15 /* software termination signal from kill */
#define SIGURG 16 /* urgent condition on IO channel */
#define SIGSTOP 17 /* sendable stop signal not from tty */
#define SIGTSTP 18 /* stop signal from tty */
#define SIGCONT 19 /* continue a stopped process */
#define SIGCHLD 20 /* to parent on child stop or exit */
#define SIGCLD 20 /* System V name for SIGCHLD */
#define SIGTTIN 21 /* to readers pgrp upon background tty read */
#define SIGTTOU 22 /* like TTIN for output if (tp->t_local&LTOSTOP) */
#define SIGIO 23 /* input/output possible signal */
#define SIGPOLL SIGIO /* System V name for SIGIO */
#define SIGXCPU 24 /* exceeded CPU time limit */
#define SIGXFSZ 25 /* exceeded file size limit */
#define SIGVTALRM 26 /* virtual time alarm */
#define SIGPROF 27 /* profiling time alarm */
#define SIGWINCH 28 /* window changed */
#define SIGLOST 29 /* resource lost (eg, record-lock lost) */
#define SIGUSR1 30 /* user defined signal 1 */
#define SIGUSR2 31 /* user defined signal 2 */
#define NSIG 32 /* signal 0 implied */
#else
#define SIGHUP 1 /* hangup */
#define SIGINT 2 /* interrupt */
#define SIGQUIT 3 /* quit */
#define SIGILL 4 /* illegal instruction (not reset when caught) */
#define SIGTRAP 5 /* trace trap (not reset when caught) */
#define SIGIOT 6 /* IOT instruction */
#define SIGABRT 6 /* used by abort, replace SIGIOT in the future */
#define SIGEMT 7 /* EMT instruction */
#define SIGFPE 8 /* floating point exception */
#define SIGKILL 9 /* kill (cannot be caught or ignored) */
#define SIGBUS 10 /* bus error */
#define SIGSEGV 11 /* segmentation violation */
#define SIGSYS 12 /* bad argument to system call */
#define SIGPIPE 13 /* write on a pipe with no one to read it */
#define SIGALRM 14 /* alarm clock */
#define SIGTERM 15 /* software termination signal from kill */
#if defined(__svr4__)
/* svr4 specifics. different signals above 15, and sigaction. */
#define SIGUSR1 16
#define SIGUSR2 17
#define SIGCLD 18
#define SIGPWR 19
#define SIGWINCH 20
#define SIGPOLL 22 /* 20 for x.out binaries!!!! */
#define SIGSTOP 23 /* sendable stop signal not from tty */
#define SIGTSTP 24 /* stop signal from tty */
#define SIGCONT 25 /* continue a stopped process */
#define SIGTTIN 26 /* to readers pgrp upon background tty read */
#define SIGTTOU 27 /* like TTIN for output if (tp->t_local&LTOSTOP) */
#define NSIG 28
#else
#define SIGURG 16 /* urgent condition on IO channel */
#define SIGSTOP 17 /* sendable stop signal not from tty */
#define SIGTSTP 18 /* stop signal from tty */
#define SIGCONT 19 /* continue a stopped process */
#define SIGCHLD 20 /* to parent on child stop or exit */
#define SIGCLD 20 /* System V name for SIGCHLD */
#define SIGTTIN 21 /* to readers pgrp upon background tty read */
#define SIGTTOU 22 /* like TTIN for output if (tp->t_local&LTOSTOP) */
#define SIGIO 23 /* input/output possible signal */
#define SIGPOLL SIGIO /* System V name for SIGIO */
#define SIGXCPU 24 /* exceeded CPU time limit */
#define SIGXFSZ 25 /* exceeded file size limit */
#define SIGVTALRM 26 /* virtual time alarm */
#define SIGPROF 27 /* profiling time alarm */
#define SIGWINCH 28 /* window changed */
#define SIGLOST 29 /* resource lost (eg, record-lock lost) */
#define SIGUSR1 30 /* user defined signal 1 */
#define SIGUSR2 31 /* user defined signal 2 */
#define NSIG 32 /* signal 0 implied */
#endif
#endif
#ifdef __cplusplus
}
#endif
#endif /* _SYS_SIGNAL_H */

View File

@ -0,0 +1,59 @@
/* This is file STAT.H */
/*
** Copyright (C) 1991 DJ Delorie, 24 Kirsten Ave, Rochester NH 03867-2954
**
** This file is distributed under the terms listed in the document
** "copying.dj", available from DJ Delorie at the address above.
** A copy of "copying.dj" should accompany this file; if not, a copy
** should be available from where this file was obtained. This file
** may not be distributed without a verbatim copy of "copying.dj".
**
** This file is distributed WITHOUT ANY WARRANTY; without even the implied
** warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef _STAT_H_
#define _STAT_H_
struct stat {
short st_dev;
short st_ino;
unsigned short st_mode;
short st_nlink;
short st_uid;
short st_gid;
short st_rdev;
short st_align_for_word32;
long st_size;
long st_atime;
long st_mtime;
long st_ctime;
long st_blksize;
};
#define S_IFMT 0xF000 /* file type mask */
#define S_IFDIR 0x4000 /* directory */
#define S_IFIFO 0x1000 /* FIFO special */
#define S_IFCHR 0x2000 /* character special */
#define S_IFBLK 0x3000 /* block special */
#define S_IFREG 0x8000 /* or just 0x0000, regular */
#define S_IREAD 0x0100 /* owner may read */
#define S_IWRITE 0x0080 /* owner may write */
#define S_IEXEC 0x0040 /* owner may execute <directory search> */
#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
#ifdef __cplusplus
extern "C" {
#endif
int stat(const char *, struct stat *);
int fstat(int, struct stat *);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,140 @@
#ifndef _SYS_STAT_H
#define _SYS_STAT_H
#ifdef __cplusplus
extern "C" {
#endif
#include <_ansi.h>
#include <time.h>
#include <sys/types.h>
#ifdef __i386__
#ifdef __MSDOS__
#include "stat-dj.h"
#endif
#endif
/* dj's stat defines _STAT_H_ */
#ifndef _STAT_H_
/* It is intended that the layout of this structure not change when the
sizes of any of the basic types change (short, int, long) [via a compile
time option]. */
struct stat
{
dev_t st_dev;
ino_t st_ino;
mode_t st_mode;
nlink_t st_nlink;
uid_t st_uid;
gid_t st_gid;
dev_t st_rdev;
off_t st_size;
/* SysV/sco doesn't have the rest... But Solaris, eabi does. */
#if defined(__svr4__) && !defined(__PPC__) && !defined(__sun__)
time_t st_atime;
time_t st_mtime;
time_t st_ctime;
#else
time_t st_atime;
long st_spare1;
time_t st_mtime;
long st_spare2;
time_t st_ctime;
long st_spare3;
long st_blksize;
long st_blocks;
long st_spare4[2];
#endif
};
#define _IFMT 0170000 /* type of file */
#define _IFDIR 0040000 /* directory */
#define _IFCHR 0020000 /* character special */
#define _IFBLK 0060000 /* block special */
#define _IFREG 0100000 /* regular */
#define _IFLNK 0120000 /* symbolic link */
#define _IFSOCK 0140000 /* socket */
#define _IFIFO 0010000 /* fifo */
#define S_BLKSIZE 1024 /* size of a block */
#define S_ISUID 0004000 /* set user id on execution */
#define S_ISGID 0002000 /* set group id on execution */
#ifndef _POSIX_SOURCE
#define S_ISVTX 0001000 /* save swapped text even after use */
#define S_IREAD 0000400 /* read permission, owner */
#define S_IWRITE 0000200 /* write permission, owner */
#define S_IEXEC 0000100 /* execute/search permission, owner */
#define S_ENFMT 0002000 /* enforcement-mode locking */
#define S_IFMT _IFMT
#define S_IFDIR _IFDIR
#define S_IFCHR _IFCHR
#define S_IFBLK _IFBLK
#define S_IFREG _IFREG
#define S_IFLNK _IFLNK
#define S_IFSOCK _IFSOCK
#define S_IFIFO _IFIFO
#endif /* !_POSIX_SOURCE */
#ifdef _WIN32
/* The Windows header files define _S_ forms of these, so we do too
for easier portability. */
#define _S_IFMT _IFMT
#define _S_IFDIR _IFDIR
#define _S_IFCHR _IFCHR
#define _S_IFIFO _IFIFO
#define _S_IFREG _IFREG
#define _S_IREAD 0000400
#define _S_IWRITE 0000200
#define _S_IEXEC 0000100
#endif
#define S_IRWXU 0000700 /* rwx, owner */
#define S_IRUSR 0000400 /* read permission, owner */
#define S_IWUSR 0000200 /* write permission, owner */
#define S_IXUSR 0000100 /* execute/search permission, owner */
#define S_IRWXG 0000070 /* rwx, group */
#define S_IRGRP 0000040 /* read permission, group */
#define S_IWGRP 0000020 /* write permission, grougroup */
#define S_IXGRP 0000010 /* execute/search permission, group */
#define S_IRWXO 0000007 /* rwx, other */
#define S_IROTH 0000004 /* read permission, other */
#define S_IWOTH 0000002 /* write permission, other */
#define S_IXOTH 0000001 /* execute/search permission, other */
#define S_ISBLK(m) (((m)&_IFMT) == _IFBLK)
#define S_ISCHR(m) (((m)&_IFMT) == _IFCHR)
#define S_ISDIR(m) (((m)&_IFMT) == _IFDIR)
#define S_ISFIFO(m) (((m)&_IFMT) == _IFIFO)
#define S_ISREG(m) (((m)&_IFMT) == _IFREG)
#define S_ISLNK(m) (((m)&_IFMT) == _IFLNK)
#define S_ISSOCK(m) (((m)&_IFMT) == _IFSOCK)
int _EXFUN(chmod,( const char *__path, mode_t __mode ));
int _EXFUN(fchmod,(int __fd, mode_t __mode));
int _EXFUN(fstat,( int __fd, struct stat *__sbuf ));
int _EXFUN(mkdir,( const char *_path, mode_t __mode ));
int _EXFUN(mkfifo,( char *__path, mode_t __mode ));
int _EXFUN(stat,( const char *__path, struct stat *__sbuf ));
mode_t _EXFUN(umask,( mode_t __mask ));
/* Provide prototypes for most of the _<systemcall> names that are
provided in newlib for some compilers. */
int _EXFUN(_fstat,( int __fd, struct stat *__sbuf ));
int _EXFUN(_stat,( const char *__path, struct stat *__sbuf ));
#ifdef __CYGWIN32__
int _EXFUN(lstat,( const char *__path, struct stat *__buf ));
#endif
#endif /* !_STAT_H_ */
#ifdef __cplusplus
}
#endif
#endif /* _SYS_STAT_H */

View File

@ -0,0 +1,51 @@
/* time.h -- An implementation of the standard Unix <sys/time.h> file.
Written by Geoffrey Noer <noer@cygnus.com>
Public domain; no rights reserved. */
#ifndef _SYS_TIME_H_
#define _SYS_TIME_H_
#include <_ansi.h>
#include <sys/types.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifndef _GNU_H_WINDOWS32_SOCKETS
struct timeval {
long tv_sec;
long tv_usec;
};
struct timezone {
int tz_minuteswest;
int tz_dsttime;
};
#ifdef __CYGWIN32__
#include <sys/select.h>
#endif /* __CYGWIN32__ */
#endif /* _GNU_H_WINDOWS32_SOCKETS */
#define ITIMER_REAL 0
#define ITIMER_VIRTUAL 1
#define ITIMER_PROF 2
struct itimerval {
struct timeval it_interval;
struct timeval it_value;
};
int _EXFUN(gettimeofday, (struct timeval *__p, struct timezone *__z));
int _EXFUN(settimeofday, (const struct timeval *, const struct timezone *));
int _EXFUN(utimes, (const char *__path, struct timeval *__tvp));
int _EXFUN(getitimer, (int __which, struct itimerval *__value));
int _EXFUN(setitimer, (int __which, const struct itimerval *__value,
struct itimerval *__ovalue));
#ifdef __cplusplus
}
#endif
#endif /* _SYS_TIME_H_ */

View File

@ -0,0 +1,39 @@
/* timeb.h -- An implementation of the standard Unix <sys/timeb.h> file.
Written by Ian Lance Taylor <ian@cygnus.com>
Public domain; no rights reserved.
<sys/timeb.h> declares the structure used by the ftime function, as
well as the ftime function itself. Newlib does not provide an
implementation of ftime. */
#ifndef _SYS_TIMEB_H
#ifdef __cplusplus
extern "C" {
#endif
#define _SYS_TIMEB_H
#include <_ansi.h>
#include <machine/types.h>
#ifndef __time_t_defined
typedef _TIME_T_ time_t;
#define __time_t_defined
#endif
struct timeb
{
time_t time;
unsigned short millitm;
short timezone;
short dstflag;
};
extern int ftime _PARAMS ((struct timeb *));
#ifdef __cplusplus
}
#endif
#endif /* ! defined (_SYS_TIMEB_H) */

View File

@ -0,0 +1,27 @@
#ifndef _SYS_TIMES_H
#ifdef __cplusplus
extern "C" {
#endif
#define _SYS_TIMES_H
#include <_ansi.h>
#include <machine/types.h>
#ifndef __clock_t_defined
typedef _CLOCK_T_ clock_t;
#define __clock_t_defined
#endif
struct tms {
clock_t tms_utime; /* user time */
clock_t tms_stime; /* system time */
clock_t tms_cutime; /* user time, children */
clock_t tms_cstime; /* system time, children */
};
clock_t _EXFUN(times,(struct tms *));
#ifdef __cplusplus
}
#endif
#endif /* !_SYS_TIMES_H */

View File

@ -0,0 +1,170 @@
/* unified sys/types.h:
start with sef's sysvi386 version.
merge go32 version -- a few ifdefs.
h8300hms, h8300xray, and sysvnecv70 disagree on the following types:
typedef int gid_t;
typedef int uid_t;
typedef int dev_t;
typedef int ino_t;
typedef int mode_t;
typedef int caddr_t;
however, these aren't "reasonable" values, the sysvi386 ones make far
more sense, and should work sufficiently well (in particular, h8300
doesn't have a stat, and the necv70 doesn't matter.) -- eichin
*/
#ifndef _SYS_TYPES_H
#define _SYS_TYPES_H
#ifdef __i386__
#if defined (GO32) || defined (__MSDOS__) || defined (_WIN32)
#define __MS_types__
#endif
#endif
# include <stddef.h>
# include <machine/types.h>
/* To ensure the stat struct's layout doesn't change when sizeof(int), etc.
changes, we assume sizeof short and long never change and have all types
used to define struct stat use them and not int where possible.
Where not possible, _ST_INTxx are used. It would be preferable to not have
such assumptions, but until the extra fluff is necessary, it's avoided.
No 64 bit targets use stat yet. What to do about them is postponed
until necessary. */
#ifdef __GNUC__
#define _ST_INT32 __attribute__ ((__mode__ (__SI__)))
#else
#define _ST_INT32
#endif
# ifndef _POSIX_SOURCE
# define physadr physadr_t
# define quad quad_t
#ifndef _GNU_H_WINDOWS32_SOCKETS
typedef unsigned char u_char;
typedef unsigned short u_short;
typedef unsigned int u_int;
typedef unsigned long u_long;
#endif
typedef unsigned short ushort; /* System V compatibility */
typedef unsigned int uint; /* System V compatibility */
# endif /*!_POSIX_SOURCE */
#ifndef __time_t_defined
typedef _TIME_T_ time_t;
#define __time_t_defined
#endif
typedef long daddr_t;
typedef char * caddr_t;
#ifdef __MS_types__
typedef unsigned long ino_t;
#else
#ifdef __sparc__
typedef unsigned long ino_t;
#else
typedef unsigned short ino_t;
#endif
#endif
#ifdef __MS_types__
typedef unsigned long vm_offset_t;
typedef unsigned long vm_size_t;
#define __BIT_TYPES_DEFINED__
typedef char int8_t;
typedef unsigned char u_int8_t;
typedef short int16_t;
typedef unsigned short u_int16_t;
typedef int int32_t;
typedef unsigned int u_int32_t;
typedef long long int64_t;
typedef unsigned long long u_int64_t;
typedef int32_t register_t;
#endif /* __MS_types__ */
/*
* All these should be machine specific - right now they are all broken.
* However, for all of Cygnus' embedded targets, we want them to all be
* the same. Otherwise things like sizeof (struct stat) might depend on
* how the file was compiled (e.g. -mint16 vs -mint32, etc.).
*/
typedef short dev_t;
typedef long off_t;
typedef unsigned short uid_t;
typedef unsigned short gid_t;
typedef int pid_t;
typedef long key_t;
typedef long ssize_t;
#ifdef __MS_types__
typedef char * addr_t;
typedef int mode_t;
#else
#if defined (__sparc__) && !defined (__sparc_v9__)
#ifdef __svr4__
typedef unsigned long mode_t;
#else
typedef unsigned short mode_t;
#endif
#else
typedef unsigned int mode_t _ST_INT32;
#endif
#endif /* ! __MS_types__ */
typedef unsigned short nlink_t;
/* We don't define fd_set and friends if we are compiling POSIX
source, or if we have included the Windows Sockets.h header (which
defines Windows versions of them). Note that a program which
includes the Windows sockets.h header must know what it is doing;
it must not call the cygwin select function. */
# if ! defined (_POSIX_SOURCE) && ! defined (_GNU_H_WINDOWS32_SOCKETS)
# define NBBY 8 /* number of bits in a byte */
/*
* Select uses bit masks of file descriptors in longs.
* These macros manipulate such bit fields (the filesystem macros use chars).
* FD_SETSIZE may be defined by the user, but the default here
* should be >= NOFILE (param.h).
*/
# ifndef FD_SETSIZE
# define FD_SETSIZE 64
# endif
typedef long fd_mask;
# define NFDBITS (sizeof (fd_mask) * NBBY) /* bits per mask */
# ifndef howmany
# define howmany(x,y) (((x)+((y)-1))/(y))
# endif
/* We use a macro for fd_set so that including Sockets.h afterwards
can work. */
typedef struct _types_fd_set {
fd_mask fds_bits[howmany(FD_SETSIZE, NFDBITS)];
} _types_fd_set;
#define fd_set _types_fd_set
# define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1L << ((n) % NFDBITS)))
# define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1L << ((n) % NFDBITS)))
# define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1L << ((n) % NFDBITS)))
# define FD_ZERO(p) bzero((caddr_t)(p), sizeof (*(p)))
# endif /* ! defined (_POSIX_SOURCE) && ! defined (GNU_H_WINDOWS32_SOCKETS) */
#undef __MS_types__
#undef _ST_INT32
#endif /* _SYS_TYPES_H */

View File

@ -0,0 +1,155 @@
#ifndef _SYS_UNISTD_H
#define _SYS_UNISTD_H
#ifdef __cplusplus
extern "C" {
#endif
#include <_ansi.h>
#include <sys/types.h>
#define __need_size_t
#include <stddef.h>
extern char **environ;
void _EXFUN(_exit, (int __status ) _ATTRIBUTE ((noreturn)));
int _EXFUN(access,(const char *__path, int __amode ));
unsigned _EXFUN(alarm, (unsigned __secs ));
int _EXFUN(chdir, (const char *__path ));
int _EXFUN(chmod, (const char *__path, mode_t __mode ));
int _EXFUN(chown, (const char *__path, uid_t __owner, gid_t __group ));
int _EXFUN(close, (int __fildes ));
char _EXFUN(*ctermid, (char *__s ));
char _EXFUN(*cuserid, (char *__s ));
int _EXFUN(dup, (int __fildes ));
int _EXFUN(dup2, (int __fildes, int __fildes2 ));
int _EXFUN(execl, (const char *__path, const char *, ... ));
int _EXFUN(execle, (const char *__path, const char *, ... ));
int _EXFUN(execlp, (const char *__file, const char *, ... ));
int _EXFUN(execv, (const char *__path, char * const __argv[] ));
int _EXFUN(execve, (const char *__path, char * const __argv[], char * const __envp[] ));
int _EXFUN(execvp, (const char *__file, char * const __argv[] ));
pid_t _EXFUN(fork, (void ));
long _EXFUN(fpathconf, (int __fd, int __name ));
int _EXFUN(fsync, (int __fd));
char _EXFUN(*getcwd, (char *__buf, size_t __size ));
gid_t _EXFUN(getegid, (void ));
uid_t _EXFUN(geteuid, (void ));
gid_t _EXFUN(getgid, (void ));
int _EXFUN(getgroups, (int __gidsetsize, gid_t __grouplist[] ));
char _EXFUN(*getlogin, (void ));
char _EXFUN(*getpass, (__const char *__prompt));
size_t _EXFUN(getpagesize, (void));
pid_t _EXFUN(getpgrp, (void ));
pid_t _EXFUN(getpid, (void ));
pid_t _EXFUN(getppid, (void ));
uid_t _EXFUN(getuid, (void ));
int _EXFUN(isatty, (int __fildes ));
int _EXFUN(link, (const char *__path1, const char *__path2 ));
off_t _EXFUN(lseek, (int __fildes, off_t __offset, int __whence ));
long _EXFUN(pathconf, (char *__path, int __name ));
int _EXFUN(pause, (void ));
int _EXFUN(pipe, (int __fildes[2] ));
int _EXFUN(read, (int __fildes, void *__buf, size_t __nbyte ));
int _EXFUN(rmdir, (const char *__path ));
void * _EXFUN(sbrk, (size_t __incr));
int _EXFUN(setgid, (gid_t __gid ));
int _EXFUN(setpgid, (pid_t __pid, pid_t __pgid ));
pid_t _EXFUN(setsid, (void ));
int _EXFUN(setuid, (uid_t __uid ));
unsigned _EXFUN(sleep, (unsigned int __seconds ));
void _EXFUN(swab, (const void *, void *, ssize_t));
long _EXFUN(sysconf, (int __name ));
pid_t _EXFUN(tcgetpgrp, (int __fildes ));
int _EXFUN(tcsetpgrp, (int __fildes, pid_t __pgrp_id ));
char _EXFUN(*ttyname, (int __fildes ));
int _EXFUN(unlink, (const char *__path ));
int _EXFUN(write, (int __fildes, const void *__buf, size_t __nbyte ));
/* Provide prototypes for most of the _<systemcall> names that are
provided in newlib for some compilers. */
int _EXFUN(_close, (int __fildes ));
pid_t _EXFUN(_fork, (void ));
pid_t _EXFUN(_getpid, (void ));
int _EXFUN(_link, (const char *__path1, const char *__path2 ));
off_t _EXFUN(_lseek, (int __fildes, off_t __offset, int __whence ));
int _EXFUN(_read, (int __fildes, void *__buf, size_t __nbyte ));
void * _EXFUN(_sbrk, (size_t __incr));
int _EXFUN(_unlink, (const char *__path ));
int _EXFUN(_write, (int __fildes, const void *__buf, size_t __nbyte ));
#ifdef __CYGWIN32__
unsigned _EXFUN(usleep, (unsigned int __useconds));
int _EXFUN(ftruncate, (int __fd, off_t __length));
int _EXFUN(truncate, (const char *, off_t __length));
int _EXFUN(gethostname, (char *__name, size_t __len));
char * _EXFUN(mktemp, (char *));
int _EXFUN(sync, (void));
int _EXFUN(readlink, (const char *__path, char *__buf, int __buflen));
int _EXFUN(symlink, (const char *__name1, const char *__name2));
#endif
# define F_OK 0
# define R_OK 4
# define W_OK 2
# define X_OK 1
# define SEEK_SET 0
# define SEEK_CUR 1
# define SEEK_END 2
#ifdef __svr4__
# define _POSIX_JOB_CONTROL 1
# define _POSIX_SAVED_IDS 1
# define _POSIX_VERSION 199009L
#endif
#ifdef __CYGWIN32__
# define _POSIX_JOB_CONTROL 1
# define _POSIX_SAVED_IDS 0
# define _POSIX_VERSION 199009L
#endif
#define STDIN_FILENO 0 /* standard input file descriptor */
#define STDOUT_FILENO 1 /* standard output file descriptor */
#define STDERR_FILENO 2 /* standard error file descriptor */
long _EXFUN(sysconf, (int __name));
# define _SC_ARG_MAX 0
# define _SC_CHILD_MAX 1
# define _SC_CLK_TCK 2
# define _SC_NGROUPS_MAX 3
# define _SC_OPEN_MAX 4
/* no _SC_STREAM_MAX */
# define _SC_JOB_CONTROL 5
# define _SC_SAVED_IDS 6
# define _SC_VERSION 7
# define _SC_PAGESIZE 8
# define _PC_LINK_MAX 0
# define _PC_MAX_CANON 1
# define _PC_MAX_INPUT 2
# define _PC_NAME_MAX 3
# define _PC_PATH_MAX 4
# define _PC_PIPE_BUF 5
# define _PC_CHOWN_RESTRICTED 6
# define _PC_NO_TRUNC 7
# define _PC_VDISABLE 8
# ifndef _POSIX_SOURCE
# define MAXNAMLEN 1024
# endif /* _POSIX_SOURCE */
/* FIXME: This is temporary until winsup gets sorted out. */
#ifdef __CYGWIN32__
#define MAXPATHLEN (260 - 1 /* NUL */)
#else
# define MAXPATHLEN 1024
#endif
#ifdef __cplusplus
}
#endif
#endif /* _SYS_UNISTD_H */

View File

@ -0,0 +1,22 @@
#ifndef _SYS_UTIME_H
#define _SYS_UTIME_H
/* This is a dummy <sys/utime.h> file, not customized for any
particular system. If there is a utime.h in libc/sys/SYSDIR/sys,
it will override this one. */
#ifdef __cplusplus
extern "C" {
#endif
struct utimbuf
{
time_t actime;
time_t modtime;
};
#ifdef __cplusplus
};
#endif
#endif /* _SYS_UTIME_H */

View File

@ -0,0 +1,40 @@
#ifndef _SYS_WAIT_H
#define _SYS_WAIT_H
#ifdef __cplusplus
extern "C" {
#endif
#include <sys/types.h>
#define WNOHANG 1
#define WUNTRACED 2
/* A status looks like:
<2 bytes info> <2 bytes code>
<code> == 0, child has exited, info is the exit value
<code> == 1..7e, child has exited, info is the signal number.
<code> == 7f, child has stopped, info was the signal number.
<code> == 80, there was a core dump.
*/
#define WIFEXITED(w) (((w) & 0xff) == 0)
#define WIFSIGNALED(w) (((w) & 0x7f) > 0 && (((w) & 0x7f) < 0x7f))
#define WIFSTOPPED(w) (((w) & 0xff) == 0x7f)
#define WEXITSTATUS(w) (((w) >> 8) & 0xff)
#define WTERMSIG(w) ((w) & 0x7f)
#define WSTOPSIG WEXITSTATUS
pid_t wait (int *);
pid_t waitpid (pid_t, int *, int);
/* Provide prototypes for most of the _<systemcall> names that are
provided in newlib for some compilers. */
pid_t _wait (int *);
#ifdef __cplusplus
};
#endif
#endif

View File

@ -0,0 +1,7 @@
#ifdef __cplusplus
extern "C" {
#endif
#include <sys/termios.h>
#ifdef __cplusplus
}
#endif

90
agbcc/libc/include/time.h Normal file
View File

@ -0,0 +1,90 @@
/*
* time.h
*
* Struct and function declarations for dealing with time.
*/
#ifndef _TIME_H_
#define _TIME_H_
#include "_ansi.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifndef NULL
#define NULL 0L
#endif
/* Get _CLOCKS_PER_SEC_ */
#include <machine/time.h>
#ifndef _CLOCKS_PER_SEC_
#define _CLOCKS_PER_SEC_ 1000
#endif
#define CLOCKS_PER_SEC _CLOCKS_PER_SEC_
#define CLK_TCK CLOCKS_PER_SEC
#define __need_size_t
#include <stddef.h>
/* Get _CLOCK_T_ and _TIME_T_. */
#include <machine/types.h>
#ifndef __clock_t_defined
typedef _CLOCK_T_ clock_t;
#define __clock_t_defined
#endif
#ifndef __time_t_defined
typedef _TIME_T_ time_t;
#define __time_t_defined
#endif
struct tm
{
int tm_sec;
int tm_min;
int tm_hour;
int tm_mday;
int tm_mon;
int tm_year;
int tm_wday;
int tm_yday;
int tm_isdst;
};
clock_t _EXFUN(clock, (void));
double _EXFUN(difftime, (time_t _time2, time_t _time1));
time_t _EXFUN(mktime, (struct tm *_timeptr));
time_t _EXFUN(time, (time_t *_timer));
#ifndef _REENT_ONLY
char *_EXFUN(asctime, (const struct tm *_tblock));
char *_EXFUN(ctime, (const time_t *_time));
struct tm *_EXFUN(gmtime, (const time_t *_timer));
struct tm *_EXFUN(localtime,(const time_t *_timer));
#endif
size_t _EXFUN(strftime, (char *_s, size_t _maxsize, const char *_fmt, const struct tm *_t));
char *_EXFUN(asctime_r, (const struct tm *, char *));
char *_EXFUN(ctime_r, (const time_t *, char *));
struct tm *_EXFUN(gmtime_r, (const time_t *, struct tm *));
struct tm *_EXFUN(localtime_r, (const time_t *, struct tm *));
#ifdef __CYGWIN32__
#ifndef __STRICT_ANSI__
extern time_t _timezone __declspec(dllimport);
extern int _daylight __declspec(dllimport);
extern char *_tzname[2] __declspec(dllimport);
char *_EXFUN(timezone, (void));
void _EXFUN(tzset, (void));
#endif
#endif /* __CYGWIN32__ */
#ifdef __cplusplus
}
#endif
#endif /* _TIME_H_ */

View File

@ -0,0 +1,46 @@
/* From curses.h. */
/*
* Copyright (c) 1981, 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.
*/
#ifndef _UNCTRL_H_
#define _UNCTRL_H_
#include <_ansi.h>
#define unctrl(c) __unctrl[(c) & 0xff]
#define unctrllen(ch) __unctrllen[(ch) & 0xff]
extern _CONST char * _CONST __unctrl[256]; /* Control strings. */
extern _CONST char __unctrllen[256]; /* Control strings length. */
#endif /* _UNCTRL_H_ */

View File

@ -0,0 +1,6 @@
#ifndef _UNISTD_H_
#define _UNISTD_H_
# include <sys/unistd.h>
#endif /* _UNISTD_H_ */

View File

@ -0,0 +1,10 @@
#ifdef __cplusplus
extern "C" {
#endif
/* The utime function is defined in libc/sys/<arch>/sys if it exists. */
#include <sys/utime.h>
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,8 @@
#ifdef __cplusplus
extern "C" {
#endif
#include <sys/utmp.h>
#ifdef __cplusplus
}
#endif

198
agbcc/libc/locale/locale.c Normal file
View File

@ -0,0 +1,198 @@
/*
FUNCTION
<<setlocale>>, <<localeconv>>---select or query locale
INDEX
setlocale
INDEX
localeconv
INDEX
_setlocale_r
INDEX
_localeconv_r
ANSI_SYNOPSIS
#include <locale.h>
char *setlocale(int <[category]>, const char *<[locale]>);
lconv *localeconv(void);
char *_setlocale_r(void *<[reent]>,
int <[category]>, const char *<[locale]>);
lconv *_localeconv_r(void *<[reent]>);
TRAD_SYNOPSIS
#include <locale.h>
char *setlocale(<[category]>, <[locale]>)
int <[category]>;
char *<[locale]>;
lconv *localeconv();
char *_setlocale_r(<[reent]>, <[category]>, <[locale]>)
char *<[reent]>;
int <[category]>;
char *<[locale]>;
lconv *_localeconv_r(<[reent]>);
char *<[reent]>;
DESCRIPTION
<<setlocale>> is the facility defined by ANSI C to condition the
execution environment for international collating and formatting
information; <<localeconv>> reports on the settings of the current
locale.
This is a minimal implementation, supporting only the required <<``C''>>
value for <[locale]>; strings representing other locales are not
honored unless MB_CAPABLE is defined in which case three new
extensions are allowed for LC_CTYPE only: <<''C-JIS''>>, <<''C-EUCJP''>>,
and <<''C-SJIS''>>. (<<``''>> is also accepted; it represents the default locale
for an implementation, here equivalent to <<``C''>>.)
If you use <<NULL>> as the <[locale]> argument, <<setlocale>> returns
a pointer to the string representing the current locale (always
<<``C''>> in this implementation). The acceptable values for
<[category]> are defined in `<<locale.h>>' as macros beginning with
<<"LC_">>, but this implementation does not check the values you pass
in the <[category]> argument.
<<localeconv>> returns a pointer to a structure (also defined in
`<<locale.h>>') describing the locale-specific conventions currently
in effect.
<<_localeconv_r>> and <<_setlocale_r>> are reentrant versions of
<<localeconv>> and <<setlocale>> respectively. The extra argument
<[reent]> is a pointer to a reentrancy structure.
RETURNS
<<setlocale>> returns either a pointer to a string naming the locale
currently in effect (always <<``C''>> for this implementation, or, if
the locale request cannot be honored, <<NULL>>.
<<localeconv>> returns a pointer to a structure of type <<lconv>>,
which describes the formatting and collating conventions in effect (in
this implementation, always those of the C locale).
PORTABILITY
ANSI C requires <<setlocale>>, but the only locale required across all
implementations is the C locale.
No supporting OS subroutines are required.
*/
/*
* setlocale, localeconv : internationalize your locale.
* (Only "C" or null supported).
*/
#include <locale.h>
#include <string.h>
#include <limits.h>
#include <reent.h>
#ifdef __CYGWIN__
int __declspec(dllexport) __mb_cur_max = 1;
#else
int __mb_cur_max = 1;
#endif
static _CONST struct lconv lconv =
{
".", "", "", "", "", "", "", "", "", "",
CHAR_MAX, CHAR_MAX, CHAR_MAX, CHAR_MAX,
CHAR_MAX, CHAR_MAX, CHAR_MAX, CHAR_MAX,
};
char *
_DEFUN(_setlocale_r, (p, category, locale),
struct _reent *p _AND
int category _AND
_CONST char *locale)
{
static char lc_ctype[8] = "C";
static char last_lc_ctype[8] = "C";
#ifndef MB_CAPABLE
if (locale)
{
if (strcmp (locale, "C") && strcmp (locale, ""))
return 0;
p->_current_category = category;
p->_current_locale = locale;
}
return "C";
#else
if (locale)
{
if (category != LC_CTYPE)
{
if (strcmp (locale, "C") && strcmp (locale, ""))
return 0;
if (category == LC_ALL)
{
strcpy (last_lc_ctype, lc_ctype);
strcpy (lc_ctype, locale);
__mb_cur_max = 1;
}
}
else
{
if (strcmp (locale, "C") && strcmp (locale, "") &&
strcmp (locale, "C") && strcmp (locale, "C-JIS") &&
strcmp (locale, "C-EUCJP") && strcmp (locale, "C-SJIS"))
return 0;
strcpy (last_lc_ctype, lc_ctype);
strcpy (lc_ctype, locale);
if (!strcmp (locale, "C-JIS"))
__mb_cur_max = 8;
else if (strlen (locale) > 1)
__mb_cur_max = 2;
else
__mb_cur_max = 1;
}
p->_current_category = category;
p->_current_locale = locale;
if (category == LC_CTYPE)
return last_lc_ctype;
}
else
{
if (category == LC_CTYPE)
return lc_ctype;
}
return "C";
#endif
}
struct lconv *
_DEFUN(_localeconv_r, (data),
struct _reent *data)
{
return (struct lconv *) &lconv;
}
#ifndef _REENT_ONLY
char *
_DEFUN(setlocale, (category, locale),
int category _AND
_CONST char *locale)
{
return _setlocale_r (_REENT, category, locale);
}
struct lconv *
_DEFUN_VOID(localeconv)
{
return _localeconv_r (_REENT);
}
#endif

261
agbcc/libc/math/fdlibm.h Normal file
View File

@ -0,0 +1,261 @@
/* @(#)fdlibm.h 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/* CYGNUS LOCAL: Include files. */
#include <math.h>
#include <machine/ieeefp.h>
/* CYGNUS LOCAL: Default to XOPEN_MODE. */
#define _XOPEN_MODE
#ifdef __STDC__
#define __P(p) p
#else
#define __P(p) ()
#endif
#define HUGE ((float)3.40282346638528860e+38)
/*
* set X_TLOSS = pi*2**52, which is possibly defined in <values.h>
* (one may replace the following line by "#include <values.h>")
*/
#define X_TLOSS 1.41484755040568800000e+16
/* Functions that are not documented, and are not in <math.h>. */
extern double logb __P((double));
#ifdef _SCALB_INT
extern double scalb __P((double, int));
#else
extern double scalb __P((double, double));
#endif
extern double significand __P((double));
/* ieee style elementary functions */
extern double __ieee754_sqrt __P((double));
extern double __ieee754_acos __P((double));
extern double __ieee754_acosh __P((double));
extern double __ieee754_log __P((double));
extern double __ieee754_atanh __P((double));
extern double __ieee754_asin __P((double));
extern double __ieee754_atan2 __P((double,double));
extern double __ieee754_exp __P((double));
extern double __ieee754_cosh __P((double));
extern double __ieee754_fmod __P((double,double));
extern double __ieee754_pow __P((double,double));
extern double __ieee754_lgamma_r __P((double,int *));
extern double __ieee754_gamma_r __P((double,int *));
extern double __ieee754_log10 __P((double));
extern double __ieee754_sinh __P((double));
extern double __ieee754_hypot __P((double,double));
extern double __ieee754_j0 __P((double));
extern double __ieee754_j1 __P((double));
extern double __ieee754_y0 __P((double));
extern double __ieee754_y1 __P((double));
extern double __ieee754_jn __P((int,double));
extern double __ieee754_yn __P((int,double));
extern double __ieee754_remainder __P((double,double));
extern __int32_t __ieee754_rem_pio2 __P((double,double*));
#ifdef _SCALB_INT
extern double __ieee754_scalb __P((double,int));
#else
extern double __ieee754_scalb __P((double,double));
#endif
/* fdlibm kernel function */
extern double __kernel_standard __P((double,double,int));
extern double __kernel_sin __P((double,double,int));
extern double __kernel_cos __P((double,double));
extern double __kernel_tan __P((double,double,int));
extern int __kernel_rem_pio2 __P((double*,double*,int,int,int,const __int32_t*));
/* Undocumented float functions. */
extern float logbf __P((float));
#ifdef _SCALB_INT
extern float scalbf __P((float, int));
#else
extern float scalbf __P((float, float));
#endif
extern float significandf __P((float));
/* ieee style elementary float functions */
extern float __ieee754_sqrtf __P((float));
extern float __ieee754_acosf __P((float));
extern float __ieee754_acoshf __P((float));
extern float __ieee754_logf __P((float));
extern float __ieee754_atanhf __P((float));
extern float __ieee754_asinf __P((float));
extern float __ieee754_atan2f __P((float,float));
extern float __ieee754_expf __P((float));
extern float __ieee754_coshf __P((float));
extern float __ieee754_fmodf __P((float,float));
extern float __ieee754_powf __P((float,float));
extern float __ieee754_lgammaf_r __P((float,int *));
extern float __ieee754_gammaf_r __P((float,int *));
extern float __ieee754_log10f __P((float));
extern float __ieee754_sinhf __P((float));
extern float __ieee754_hypotf __P((float,float));
extern float __ieee754_j0f __P((float));
extern float __ieee754_j1f __P((float));
extern float __ieee754_y0f __P((float));
extern float __ieee754_y1f __P((float));
extern float __ieee754_jnf __P((int,float));
extern float __ieee754_ynf __P((int,float));
extern float __ieee754_remainderf __P((float,float));
extern __int32_t __ieee754_rem_pio2f __P((float,float*));
#ifdef _SCALB_INT
extern float __ieee754_scalbf __P((float,int));
#else
extern float __ieee754_scalbf __P((float,float));
#endif
/* float versions of fdlibm kernel functions */
extern float __kernel_sinf __P((float,float,int));
extern float __kernel_cosf __P((float,float));
extern float __kernel_tanf __P((float,float,int));
extern int __kernel_rem_pio2f __P((float*,float*,int,int,int,const __int32_t*));
/* The original code used statements like
n0 = ((*(int*)&one)>>29)^1; * index of high word *
ix0 = *(n0+(int*)&x); * high word of x *
ix1 = *((1-n0)+(int*)&x); * low word of x *
to dig two 32 bit words out of the 64 bit IEEE floating point
value. That is non-ANSI, and, moreover, the gcc instruction
scheduler gets it wrong. We instead use the following macros.
Unlike the original code, we determine the endianness at compile
time, not at run time; I don't see much benefit to selecting
endianness at run time. */
#ifndef __IEEE_BIG_ENDIAN
#ifndef __IEEE_LITTLE_ENDIAN
#error Must define endianness
#endif
#endif
/* A union which permits us to convert between a double and two 32 bit
ints. */
#ifdef __IEEE_BIG_ENDIAN
typedef union
{
double value;
struct
{
__uint32_t msw;
__uint32_t lsw;
} parts;
} ieee_double_shape_type;
#endif
#ifdef __IEEE_LITTLE_ENDIAN
typedef union
{
double value;
struct
{
__uint32_t lsw;
__uint32_t msw;
} parts;
} ieee_double_shape_type;
#endif
/* Get two 32 bit ints from a double. */
#define EXTRACT_WORDS(ix0,ix1,d) \
do { \
ieee_double_shape_type ew_u; \
ew_u.value = (d); \
(ix0) = ew_u.parts.msw; \
(ix1) = ew_u.parts.lsw; \
} while (0)
/* Get the more significant 32 bit int from a double. */
#define GET_HIGH_WORD(i,d) \
do { \
ieee_double_shape_type gh_u; \
gh_u.value = (d); \
(i) = gh_u.parts.msw; \
} while (0)
/* Get the less significant 32 bit int from a double. */
#define GET_LOW_WORD(i,d) \
do { \
ieee_double_shape_type gl_u; \
gl_u.value = (d); \
(i) = gl_u.parts.lsw; \
} while (0)
/* Set a double from two 32 bit ints. */
#define INSERT_WORDS(d,ix0,ix1) \
do { \
ieee_double_shape_type iw_u; \
iw_u.parts.msw = (ix0); \
iw_u.parts.lsw = (ix1); \
(d) = iw_u.value; \
} while (0)
/* Set the more significant 32 bits of a double from an int. */
#define SET_HIGH_WORD(d,v) \
do { \
ieee_double_shape_type sh_u; \
sh_u.value = (d); \
sh_u.parts.msw = (v); \
(d) = sh_u.value; \
} while (0)
/* Set the less significant 32 bits of a double from an int. */
#define SET_LOW_WORD(d,v) \
do { \
ieee_double_shape_type sl_u; \
sl_u.value = (d); \
sl_u.parts.lsw = (v); \
(d) = sl_u.value; \
} while (0)
/* A union which permits us to convert between a float and a 32 bit
int. */
typedef union
{
float value;
__uint32_t word;
} ieee_float_shape_type;
/* Get a 32 bit int from a float. */
#define GET_FLOAT_WORD(i,d) \
do { \
ieee_float_shape_type gf_u; \
gf_u.value = (d); \
(i) = gf_u.word; \
} while (0)
/* Set a float from a 32 bit int. */
#define SET_FLOAT_WORD(d,i) \
do { \
ieee_float_shape_type sf_u; \
sf_u.word = (i); \
(d) = sf_u.value; \
} while (0)

View File

@ -0,0 +1,82 @@
/* @(#)s_copysign.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/*
FUNCTION
<<copysign>>, <<copysignf>>---sign of <[y]>, magnitude of <[x]>
INDEX
copysign
INDEX
copysignf
ANSI_SYNOPSIS
#include <math.h>
double copysign (double <[x]>, double <[y]>);
float copysignf (float <[x]>, float <[y]>);
TRAD_SYNOPSIS
#include <math.h>
double copysign (<[x]>, <[y]>)
double <[x]>;
double <[y]>;
float copysignf (<[x]>, <[y]>)
float <[x]>;
float <[y]>;
DESCRIPTION
<<copysign>> constructs a number with the magnitude (absolute value)
of its first argument, <[x]>, and the sign of its second argument,
<[y]>.
<<copysignf>> does the same thing; the two functions differ only in
the type of their arguments and result.
RETURNS
<<copysign>> returns a <<double>> with the magnitude of
<[x]> and the sign of <[y]>.
<<copysignf>> returns a <<float>> with the magnitude of
<[x]> and the sign of <[y]>.
PORTABILITY
<<copysign>> is not required by either ANSI C or the System V Interface
Definition (Issue 2).
*/
/*
* copysign(double x, double y)
* copysign(x,y) returns a value with the magnitude of x and
* with the sign bit of y.
*/
#include "fdlibm.h"
#ifndef _DOUBLE_IS_32BITS
#ifdef __STDC__
double copysign(double x, double y)
#else
double copysign(x,y)
double x,y;
#endif
{
__uint32_t hx,hy;
GET_HIGH_WORD(hx,x);
GET_HIGH_WORD(hy,y);
SET_HIGH_WORD(x,(hx&0x7fffffff)|(hy&0x80000000));
return x;
}
#endif /* _DOUBLE_IS_32BITS */

View File

@ -0,0 +1,35 @@
/* @(#)s_finite.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/*
* finite(x) returns 1 is x is finite, else 0;
* no branching!
*/
#include "fdlibm.h"
#ifndef _DOUBLE_IS_32BITS
#ifdef __STDC__
int finite(double x)
#else
int finite(x)
double x;
#endif
{
__int32_t hx;
GET_HIGH_WORD(hx,x);
return (int)((__uint32_t)((hx&0x7fffffff)-0x7ff00000)>>31);
}
#endif /* _DOUBLE_IS_32BITS */

114
agbcc/libc/math/s_frexp.c Normal file
View File

@ -0,0 +1,114 @@
/* @(#)s_frexp.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/*
FUNCTION
<<frexp>>, <<frexpf>>---split floating-point number
INDEX
frexp
INDEX
frexpf
ANSI_SYNOPSIS
#include <math.h>
double frexp(double <[val]>, int *<[exp]>);
float frexpf(float <[val]>, int *<[exp]>);
TRAD_SYNOPSIS
#include <math.h>
double frexp(<[val]>, <[exp]>)
double <[val]>;
int *<[exp]>;
float frexpf(<[val]>, <[exp]>)
float <[val]>;
int *<[exp]>;
DESCRIPTION
All non zero, normal numbers can be described as <[m]> * 2**<[p]>.
<<frexp>> represents the double <[val]> as a mantissa <[m]>
and a power of two <[p]>. The resulting mantissa will always
be greater than or equal to <<0.5>>, and less than <<1.0>> (as
long as <[val]> is nonzero). The power of two will be stored
in <<*>><[exp]>.
@ifinfo
<[m]> and <[p]> are calculated so that
<[val]> is <[m]> times <<2>> to the power <[p]>.
@end ifinfo
@tex
<[m]> and <[p]> are calculated so that
$ val = m \times 2^p $.
@end tex
<<frexpf>> is identical, other than taking and returning
floats rather than doubles.
RETURNS
<<frexp>> returns the mantissa <[m]>. If <[val]> is <<0>>, infinity,
or Nan, <<frexp>> will set <<*>><[exp]> to <<0>> and return <[val]>.
PORTABILITY
<<frexp>> is ANSI.
<<frexpf>> is an extension.
*/
/*
* for non-zero x
* x = frexp(arg,&exp);
* return a double fp quantity x such that 0.5 <= |x| <1.0
* and the corresponding binary exponent "exp". That is
* arg = x*2^exp.
* If arg is inf, 0.0, or NaN, then frexp(arg,&exp) returns arg
* with *exp=0.
*/
#include "fdlibm.h"
#ifndef _DOUBLE_IS_32BITS
#ifdef __STDC__
static const double
#else
static double
#endif
two54 = 1.80143985094819840000e+16; /* 0x43500000, 0x00000000 */
#ifdef __STDC__
double frexp(double x, int *eptr)
#else
double frexp(x, eptr)
double x; int *eptr;
#endif
{
__int32_t hx, ix, lx;
EXTRACT_WORDS(hx,lx,x);
ix = 0x7fffffff&hx;
*eptr = 0;
if(ix>=0x7ff00000||((ix|lx)==0)) return x; /* 0,inf,nan */
if (ix<0x00100000) { /* subnormal */
x *= two54;
GET_HIGH_WORD(hx,x);
ix = hx&0x7fffffff;
*eptr = -54;
}
*eptr += (ix>>20)-1022;
hx = (hx&0x800fffff)|0x3fe00000;
SET_HIGH_WORD(x,hx);
return x;
}
#endif /* _DOUBLE_IS_32BITS */

View File

@ -0,0 +1,15 @@
/* Infinity as a constant value. This is used for HUGE_VAL.
* Added by Cygnus Support.
*/
#include "fdlibm.h"
#ifndef _DOUBLE_IS_32BITS
#ifdef __IEEE_BIG_ENDIAN
const union __dmath __infinity = { 0x7ff00000, 0 };
#else
const union __dmath __infinity = { 0, 0x7ff00000 };
#endif
#else /* defined (_DOUBLE_IS_32BITS) */
const union __dmath __infinity = { 0x7f800000, 0 };
#endif /* defined (_DOUBLE_IS_32BITS) */

26
agbcc/libc/math/s_isinf.c Normal file
View File

@ -0,0 +1,26 @@
/*
* isinf(x) returns 1 if x is infinity, else 0;
* no branching!
* Added by Cygnus Support.
*/
#include "fdlibm.h"
#ifndef _DOUBLE_IS_32BITS
#ifdef __STDC__
int isinf(double x)
#else
int isinf(x)
double x;
#endif
{
__int32_t hx,lx;
EXTRACT_WORDS(hx,lx,x);
hx &= 0x7fffffff;
hx |= (__uint32_t)(lx|(-lx))>>31;
hx = 0x7ff00000 - hx;
return 1 - (int)((__uint32_t)(hx|(-hx))>>31);
}
#endif /* _DOUBLE_IS_32BITS */

122
agbcc/libc/math/s_isnan.c Normal file
View File

@ -0,0 +1,122 @@
/* @(#)s_isnan.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/*
FUNCTION
<<isnan>>,<<isnanf>>,<<isinf>>,<<isinff>>,<<finite>>,<<finitef>>---test for exceptional numbers
INDEX
isnan
INDEX
isinf
INDEX
finite
INDEX
isnanf
INDEX
isinff
INDEX
finitef
ANSI_SYNOPSIS
#include <ieeefp.h>
int isnan(double <[arg]>);
int isinf(double <[arg]>);
int finite(double <[arg]>);
int isnanf(float <[arg]>);
int isinff(float <[arg]>);
int finitef(float <[arg]>);
TRAD_SYNOPSIS
#include <ieeefp.h>
int isnan(<[arg]>)
double <[arg]>;
int isinf(<[arg]>)
double <[arg]>;
int finite(<[arg]>);
double <[arg]>;
int isnanf(<[arg]>);
float <[arg]>;
int isinff(<[arg]>);
float <[arg]>;
int finitef(<[arg]>);
float <[arg]>;
DESCRIPTION
These functions provide information on the floating point
argument supplied.
There are five major number formats -
o+
o zero
a number which contains all zero bits.
o subnormal
Is used to represent number with a zero exponent, but a non zero fraction.
o normal
A number with an exponent, and a fraction
o infinity
A number with an all 1's exponent and a zero fraction.
o NAN
A number with an all 1's exponent and a non zero fraction.
o-
<<isnan>> returns 1 if the argument is a nan. <<isinf>>
returns 1 if the argument is infinity. <<finite>> returns 1 if the
argument is zero, subnormal or normal.
The <<isnanf>>, <<isinff>> and <<finitef>> perform the same
operations as their <<isnan>>, <<isinf>> and <<finite>>
counterparts, but on single precision floating point numbers.
QUICKREF
isnan - pure
QUICKREF
isinf - pure
QUICKREF
finite - pure
QUICKREF
isnan - pure
QUICKREF
isinf - pure
QUICKREF
finite - pure
*/
/*
* isnan(x) returns 1 is x is nan, else 0;
* no branching!
*/
#include "fdlibm.h"
#ifndef _DOUBLE_IS_32BITS
#ifdef __STDC__
int isnan(double x)
#else
int isnan(x)
double x;
#endif
{
__int32_t hx,lx;
EXTRACT_WORDS(hx,lx,x);
hx &= 0x7fffffff;
hx |= (__uint32_t)(lx|(-lx))>>31;
hx = 0x7ff00000 - hx;
return (int)(((__uint32_t)(hx))>>31);
}
#endif /* _DOUBLE_IS_32BITS */

81
agbcc/libc/math/s_ldexp.c Normal file
View File

@ -0,0 +1,81 @@
/* @(#)s_ldexp.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/*
FUNCTION
<<ldexp>>, <<ldexpf>>---load exponent
INDEX
ldexp
INDEX
ldexpf
ANSI_SYNOPSIS
#include <math.h>
double ldexp(double <[val]>, int <[exp]>);
float ldexpf(float <[val]>, int <[exp]>);
TRAD_SYNOPSIS
#include <math.h>
double ldexp(<[val]>, <[exp]>)
double <[val]>;
int <[exp]>;
float ldexpf(<[val]>, <[exp]>)
float <[val]>;
int <[exp]>;
DESCRIPTION
<<ldexp>> calculates the value
@ifinfo
<[val]> times 2 to the power <[exp]>.
@end ifinfo
@tex
$val\times 2^{exp}$.
@end tex
<<ldexpf>> is identical, save that it takes and returns <<float>>
rather than <<double>> values.
RETURNS
<<ldexp>> returns the calculated value.
Underflow and overflow both set <<errno>> to <<ERANGE>>.
On underflow, <<ldexp>> and <<ldexpf>> return 0.0.
On overflow, <<ldexp>> returns plus or minus <<HUGE_VAL>>.
PORTABILITY
<<ldexp>> is ANSI, <<ldexpf>> is an extension.
*/
#include "fdlibm.h"
#include <errno.h>
#ifndef _DOUBLE_IS_32BITS
#ifdef __STDC__
double ldexp(double value, int exp)
#else
double ldexp(value, exp)
double value; int exp;
#endif
{
if(!finite(value)||value==0.0) return value;
value = scalbn(value,exp);
if(!finite(value)||value==0.0) errno = ERANGE;
return value;
}
#endif /* _DOUBLE_IS_32BITS */

131
agbcc/libc/math/s_modf.c Normal file
View File

@ -0,0 +1,131 @@
/* @(#)s_modf.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/*
FUNCTION
<<modf>>, <<modff>>---split fractional and integer parts
INDEX
modf
INDEX
modff
ANSI_SYNOPSIS
#include <math.h>
double modf(double <[val]>, double *<[ipart]>);
float modff(float <[val]>, float *<[ipart]>);
TRAD_SYNOPSIS
#include <math.h>
double modf(<[val]>, <[ipart]>)
double <[val]>;
double *<[ipart]>;
float modff(<[val]>, <[ipart]>)
float <[val]>;
float *<[ipart]>;
DESCRIPTION
<<modf>> splits the double <[val]> apart into an integer part
and a fractional part, returning the fractional part and
storing the integer part in <<*<[ipart]>>>. No rounding
whatsoever is done; the sum of the integer and fractional
parts is guaranteed to be exactly equal to <[val]>. That
is, if . <[realpart]> = modf(<[val]>, &<[intpart]>); then
`<<<[realpart]>+<[intpart]>>>' is the same as <[val]>.
<<modff>> is identical, save that it takes and returns
<<float>> rather than <<double>> values.
RETURNS
The fractional part is returned. Each result has the same
sign as the supplied argument <[val]>.
PORTABILITY
<<modf>> is ANSI C. <<modff>> is an extension.
QUICKREF
modf ansi pure
modff - pure
*/
/*
* modf(double x, double *iptr)
* return fraction part of x, and return x's integral part in *iptr.
* Method:
* Bit twiddling.
*
* Exception:
* No exception.
*/
#include "fdlibm.h"
#ifndef _DOUBLE_IS_32BITS
#ifdef __STDC__
static const double one = 1.0;
#else
static double one = 1.0;
#endif
#ifdef __STDC__
double modf(double x, double *iptr)
#else
double modf(x, iptr)
double x,*iptr;
#endif
{
__int32_t i0,i1,j0;
__uint32_t i;
EXTRACT_WORDS(i0,i1,x);
j0 = ((i0>>20)&0x7ff)-0x3ff; /* exponent of x */
if(j0<20) { /* integer part in high x */
if(j0<0) { /* |x|<1 */
INSERT_WORDS(*iptr,i0&0x80000000,0); /* *iptr = +-0 */
return x;
} else {
i = (0x000fffff)>>j0;
if(((i0&i)|i1)==0) { /* x is integral */
__uint32_t high;
*iptr = x;
GET_HIGH_WORD(high,x);
INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */
return x;
} else {
INSERT_WORDS(*iptr,i0&(~i),0);
return x - *iptr;
}
}
} else if (j0>51) { /* no fraction part */
__uint32_t high;
*iptr = x*one;
GET_HIGH_WORD(high,x);
INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */
return x;
} else { /* fraction part in low x */
i = ((__uint32_t)(0xffffffff))>>(j0-20);
if((i1&i)==0) { /* x is integral */
__uint32_t high;
*iptr = x;
GET_HIGH_WORD(high,x);
INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */
return x;
} else {
INSERT_WORDS(*iptr,i0,i1&(~i));
return x - *iptr;
}
}
}
#endif /* _DOUBLE_IS_32BITS */

103
agbcc/libc/math/s_scalbn.c Normal file
View File

@ -0,0 +1,103 @@
/* @(#)s_scalbn.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/*
FUNCTION
<<scalbn>>, <<scalbnf>>---scale by integer
INDEX
scalbn
INDEX
scalbnf
ANSI_SYNOPSIS
#include <math.h>
double scalbn(double <[x]>, int <[y]>);
float scalbnf(float <[x]>, int <[y]>);
TRAD_SYNOPSIS
#include <math.h>
double scalbn(<[x]>,<[y]>)
double <[x]>;
int <[y]>;
float scalbnf(<[x]>,<[y]>)
float <[x]>;
int <[y]>;
DESCRIPTION
<<scalbn>> and <<scalbnf>> scale <[x]> by <[n]>, returning <[x]> times
2 to the power <[n]>. The result is computed by manipulating the
exponent, rather than by actually performing an exponentiation or
multiplication.
RETURNS
<[x]> times 2 to the power <[n]>.
PORTABILITY
Neither <<scalbn>> nor <<scalbnf>> is required by ANSI C or by the System V
Interface Definition (Issue 2).
*/
/*
* scalbn (double x, int n)
* scalbn(x,n) returns x* 2**n computed by exponent
* manipulation rather than by actually performing an
* exponentiation or a multiplication.
*/
#include "fdlibm.h"
#ifndef _DOUBLE_IS_32BITS
#ifdef __STDC__
static const double
#else
static double
#endif
two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */
twom54 = 5.55111512312578270212e-17, /* 0x3C900000, 0x00000000 */
huge = 1.0e+300,
tiny = 1.0e-300;
#ifdef __STDC__
double scalbn (double x, int n)
#else
double scalbn (x,n)
double x; int n;
#endif
{
__int32_t k,hx,lx;
EXTRACT_WORDS(hx,lx,x);
k = (hx&0x7ff00000)>>20; /* extract exponent */
if (k==0) { /* 0 or subnormal x */
if ((lx|(hx&0x7fffffff))==0) return x; /* +-0 */
x *= two54;
GET_HIGH_WORD(hx,x);
k = ((hx&0x7ff00000)>>20) - 54;
if (n< -50000) return tiny*x; /*underflow*/
}
if (k==0x7ff) return x+x; /* NaN or Inf */
k = k+n;
if (k > 0x7fe) return huge*copysign(huge,x); /* overflow */
if (k > 0) /* normal result */
{SET_HIGH_WORD(x,(hx&0x800fffff)|(k<<20)); return x;}
if (k <= -54)
if (n > 50000) /* in case integer overflow in n+k */
return huge*copysign(huge,x); /*overflow*/
else return tiny*copysign(tiny,x); /*underflow*/
k += 54; /* subnormal result */
SET_HIGH_WORD(x,(hx&0x800fffff)|(k<<20));
return x*twom54;
}
#endif /* _DOUBLE_IS_32BITS */

View File

@ -0,0 +1,50 @@
/* sf_copysign.c -- float version of s_copysign.c.
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/*
* copysignf(float x, float y)
* copysignf(x,y) returns a value with the magnitude of x and
* with the sign bit of y.
*/
#include "fdlibm.h"
#ifdef __STDC__
float copysignf(float x, float y)
#else
float copysignf(x,y)
float x,y;
#endif
{
__uint32_t ix,iy;
GET_FLOAT_WORD(ix,x);
GET_FLOAT_WORD(iy,y);
SET_FLOAT_WORD(x,(ix&0x7fffffff)|(iy&0x80000000));
return x;
}
#ifdef _DOUBLE_IS_32BITS
#ifdef __STDC__
double copysign(double x, double y)
#else
double copysign(x,y)
double x,y;
#endif
{
return (double) copysignf((float) x, (float) y);
}
#endif /* defined(_DOUBLE_IS_32BITS) */

View File

@ -0,0 +1,47 @@
/* sf_finite.c -- float version of s_finite.c.
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/*
* finitef(x) returns 1 is x is finite, else 0;
* no branching!
*/
#include "fdlibm.h"
#ifdef __STDC__
int finitef(float x)
#else
int finitef(x)
float x;
#endif
{
__int32_t ix;
GET_FLOAT_WORD(ix,x);
return (int)((__uint32_t)((ix&0x7fffffff)-0x7f800000)>>31);
}
#ifdef _DOUBLE_IS_32BITS
#ifdef __STDC__
int finite(double x)
#else
int finite(x)
double x;
#endif
{
return finitef((float) x);
}
#endif /* defined(_DOUBLE_IS_32BITS) */

View File

@ -0,0 +1,61 @@
/* sf_frexp.c -- float version of s_frexp.c.
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
#include "fdlibm.h"
#ifdef __STDC__
static const float
#else
static float
#endif
two25 = 3.3554432000e+07; /* 0x4c000000 */
#ifdef __STDC__
float frexpf(float x, int *eptr)
#else
float frexpf(x, eptr)
float x; int *eptr;
#endif
{
__int32_t hx, ix;
GET_FLOAT_WORD(hx,x);
ix = 0x7fffffff&hx;
*eptr = 0;
if(ix>=0x7f800000||(ix==0)) return x; /* 0,inf,nan */
if (ix<0x00800000) { /* subnormal */
x *= two25;
GET_FLOAT_WORD(hx,x);
ix = hx&0x7fffffff;
*eptr = -25;
}
*eptr += (ix>>23)-126;
hx = (hx&0x807fffff)|0x3f000000;
SET_FLOAT_WORD(x,hx);
return x;
}
#ifdef _DOUBLE_IS_32BITS
#ifdef __STDC__
double frexp(double x, int *eptr)
#else
double frexp(x, eptr)
double x; int *eptr;
#endif
{
return (double) frexpf((float) x, eptr);
}
#endif /* defined(_DOUBLE_IS_32BITS) */

View File

@ -0,0 +1,35 @@
/*
* isinff(x) returns 1 if x is infinity, else 0;
* no branching!
* Added by Cygnus Support.
*/
#include "fdlibm.h"
#ifdef __STDC__
int isinff(float x)
#else
int isinff(x)
float x;
#endif
{
__int32_t ix;
GET_FLOAT_WORD(ix,x);
ix &= 0x7fffffff;
ix = 0x7f800000 - ix;
return 1 - (int)((__uint32_t)(ix|(-ix))>>31);
}
#ifdef _DOUBLE_IS_32BITS
#ifdef __STDC__
int isinf(double x)
#else
int isinf(x)
double x;
#endif
{
return isinff((float) x);
}
#endif /* defined(_DOUBLE_IS_32BITS) */

View File

@ -0,0 +1,49 @@
/* sf_isnan.c -- float version of s_isnan.c.
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/*
* isnanf(x) returns 1 is x is nan, else 0;
* no branching!
*/
#include "fdlibm.h"
#ifdef __STDC__
int isnanf(float x)
#else
int isnanf(x)
float x;
#endif
{
__int32_t ix;
GET_FLOAT_WORD(ix,x);
ix &= 0x7fffffff;
ix = 0x7f800000 - ix;
return (int)(((__uint32_t)(ix))>>31);
}
#ifdef _DOUBLE_IS_32BITS
#ifdef __STDC__
int isnan(double x)
#else
int isnan(x)
double x;
#endif
{
return isnanf((float) x);
}
#endif /* defined(_DOUBLE_IS_32BITS) */

View File

@ -0,0 +1,44 @@
/* sf_ldexp.c -- float version of s_ldexp.c.
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
#include "fdlibm.h"
#include <errno.h>
#ifdef __STDC__
float ldexpf(float value, int exp)
#else
float ldexpf(value, exp)
float value; int exp;
#endif
{
if(!finitef(value)||value==(float)0.0) return value;
value = scalbnf(value,exp);
if(!finitef(value)||value==(float)0.0) errno = ERANGE;
return value;
}
#ifdef _DOUBLE_IS_32BITS
#ifdef __STDC__
double ldexp(double value, int exp)
#else
double ldexp(value, exp)
double value; int exp;
#endif
{
return (double) ldexpf((float) value, exp);
}
#endif /* defined(_DOUBLE_IS_32BITS) */

73
agbcc/libc/math/sf_modf.c Normal file
View File

@ -0,0 +1,73 @@
/* sf_modf.c -- float version of s_modf.c.
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
#include "fdlibm.h"
#ifdef __STDC__
static const float one = 1.0;
#else
static float one = 1.0;
#endif
#ifdef __STDC__
float modff(float x, float *iptr)
#else
float modff(x, iptr)
float x,*iptr;
#endif
{
__int32_t i0,j0;
__uint32_t i;
GET_FLOAT_WORD(i0,x);
j0 = ((i0>>23)&0xff)-0x7f; /* exponent of x */
if(j0<23) { /* integer part in x */
if(j0<0) { /* |x|<1 */
SET_FLOAT_WORD(*iptr,i0&0x80000000); /* *iptr = +-0 */
return x;
} else {
i = (0x007fffff)>>j0;
if((i0&i)==0) { /* x is integral */
__uint32_t ix;
*iptr = x;
GET_FLOAT_WORD(ix,x);
SET_FLOAT_WORD(x,ix&0x80000000); /* return +-0 */
return x;
} else {
SET_FLOAT_WORD(*iptr,i0&(~i));
return x - *iptr;
}
}
} else { /* no fraction part */
__uint32_t ix;
*iptr = x*one;
GET_FLOAT_WORD(ix,x);
SET_FLOAT_WORD(x,ix&0x80000000); /* return +-0 */
return x;
}
}
#ifdef _DOUBLE_IS_32BITS
#ifdef __STDC__
double modf(double x, double *iptr)
#else
double modf(x, iptr)
double x,*iptr;
#endif
{
return (double) modff((float) x, (float *) iptr);
}
#endif /* defined(_DOUBLE_IS_32BITS) */

View File

@ -0,0 +1,79 @@
/* sf_scalbn.c -- float version of s_scalbn.c.
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
#include "fdlibm.h"
#include <limits.h>
#if INT_MAX > 50000
#define OVERFLOW_INT 50000
#else
#define OVERFLOW_INT 30000
#endif
#ifdef __STDC__
static const float
#else
static float
#endif
two25 = 3.355443200e+07, /* 0x4c000000 */
twom25 = 2.9802322388e-08, /* 0x33000000 */
huge = 1.0e+30,
tiny = 1.0e-30;
#ifdef __STDC__
float scalbnf (float x, int n)
#else
float scalbnf (x,n)
float x; int n;
#endif
{
__int32_t k,ix;
GET_FLOAT_WORD(ix,x);
k = (ix&0x7f800000)>>23; /* extract exponent */
if (k==0) { /* 0 or subnormal x */
if ((ix&0x7fffffff)==0) return x; /* +-0 */
x *= two25;
GET_FLOAT_WORD(ix,x);
k = ((ix&0x7f800000)>>23) - 25;
if (n< -50000) return tiny*x; /*underflow*/
}
if (k==0xff) return x+x; /* NaN or Inf */
k = k+n;
if (k > 0xfe) return huge*copysignf(huge,x); /* overflow */
if (k > 0) /* normal result */
{SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23)); return x;}
if (k <= -25)
if (n > OVERFLOW_INT) /* in case integer overflow in n+k */
return huge*copysignf(huge,x); /*overflow*/
else return tiny*copysignf(tiny,x); /*underflow*/
k += 25; /* subnormal result */
SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23));
return x*twom25;
}
#ifdef _DOUBLE_IS_32BITS
#ifdef __STDC__
double scalbn(double x, int n)
#else
double scalbn(x,n)
double x;
int n;
#endif
{
return (double) scalbnf((float) x, n);
}
#endif /* defined(_DOUBLE_IS_32BITS) */

266
agbcc/libc/misc/dprintf.c Normal file
View File

@ -0,0 +1,266 @@
/* Debugging printf, for debugging the library itself.
We don't assume stdio is working.
We do assume _write_r is working.
*/
#include "ctype.h"
#include "reent.h"
#include "string.h"
#include "unctrl.h"
#ifdef __STDC__
#include "stdarg.h"
#else
#include "varargs.h"
#endif
static char *parse_number ();
static long get_number ();
static void print_number ();
static void write_char ();
static void write_string ();
/* Non-zero for big-endian systems. */
static int big_endian_p;
/* For now hardcode 2 (stderr) as the console file descriptor.
May wish to let the caller pass in a file descriptor or some such but
this is only for debugging purposes anyway. */
#define CONSOLE_FD 2
/* Standalone printf routine.
The format string has been enhanced so that multiple values can be dumped
without having to have a %-field for each one (say if you want to dump
20 words at a certain address). A modifier of `N' says the next argument
is a count, and the one after that is a pointer.
Example: __dprintf (stderr, "%Nx\n", 20, p); /-* print 20 ints at `p' *-/
Supported formats are: c d u x s p.
All ints are retrieved a byte at a time so alignment issues are not
a problem.
This routine is used in situations where the only debugging capability
is console output and was written to aid debugging newlib itself. We don't
use printf ourselves as we may be debugging it. We do assume _write_r is
working.
*/
void
#ifdef __STDC__
__dprintf (char *fmt, ...)
#else
__dprintf (fmt, va_alist)
char *fmt;
va_dcl
#endif
{
va_list args;
/* Which endian are we? */
{
short tmp = 1;
big_endian_p = *(char *) &tmp == 0;
}
#ifdef __STDC__
va_start (args, fmt);
#else
va_start (args);
#endif
while (*fmt)
{
char c, *p;
int count;
long l;
if (*fmt != '%' || *++fmt == '%')
{
write_char (*fmt++);
continue;
}
if (*fmt == 'N')
{
count = va_arg (args, int);
p = va_arg (args, char *);
++fmt;
c = *fmt++;
while (--count >= 0)
{
switch (c)
{
case 'c' :
write_string (unctrl (*p++));
break;
case 'p' :
print_number (16, 1, get_number (p, sizeof (char *), 1));
p += sizeof (char *);
break;
case 'd' :
case 'u' :
case 'x' :
print_number (c == 'x' ? 16 : 10, c != 'd',
get_number (p, sizeof (int), c != 'd'));
p += sizeof (int);
break;
case 's' :
write_string (*(char **) p);
p += sizeof (char *);
break;
}
if (count > 0)
write_char (' ');
}
}
else
{
switch (c = *fmt++)
{
case 'c' :
c = va_arg (args, int);
write_string (unctrl (c));
break;
case 'p' :
l = (_POINTER_INT) va_arg (args, char *);
print_number (16, 1, l);
break;
case 'd' :
case 'u' :
case 'x' :
l = va_arg (args, int);
print_number (c == 'x' ? 16 : 10, c != 'd', l);
break;
case 's' :
p = va_arg (args, char *);
write_string (p);
break;
}
}
}
va_end (args);
}
/* Parse a positive decimal integer at S.
FIXME: Was used in earlier version, but not currently used.
Keep for now. */
static char *
parse_number (s, p)
char *s;
long *p;
{
long x = 0;
while (isdigit (*s))
{
x = (x * 10) + (*s - '0');
++s;
}
*p = x;
return s;
}
/* Fetch the number at S of SIZE bytes. */
static long
get_number (s, size, unsigned_p)
char *s;
long size;
int unsigned_p;
{
long x;
unsigned char *p = (unsigned char *) s;
switch (size)
{
case 1 :
x = *p;
if (!unsigned_p)
x = (x ^ 0x80) - 0x80;
return x;
case 2 :
if (big_endian_p)
x = (p[0] << 8) | p[1];
else
x = (p[1] << 8) | p[0];
if (!unsigned_p)
x = (x ^ 0x8000) - 0x8000;
return x;
case 4 :
if (big_endian_p)
x = ((long)p[0] << 24) | ((long)p[1] << 16) | (p[2] << 8) | p[3];
else
x = ((long)p[3] << 24) | ((long)p[2] << 16) | (p[1] << 8) | p[0];
if (!unsigned_p)
x = (x ^ 0x80000000L) - 0x80000000L;
return x;
#if 0 /* FIXME: Is there a standard mechanism for knowing if
long longs exist? */
case 8 :
#endif
default :
return 0;
}
}
/* Print X in base BASE. */
static void
print_number (base, unsigned_p, n)
int base;
int unsigned_p;
long n;
{
static char chars[16] = "0123456789abcdef";
char *p, buf[32];
unsigned long x;
if (!unsigned_p && n < 0)
{
write_char ('-');
x = -n;
}
else
x = n;
p = buf + sizeof (buf);
*--p = '\0';
do
{
*--p = chars[x % base];
x /= base;
}
while (x != 0);
write_string (p);
}
/* Write C to the console.
We go through the file descriptor directly because we can't assume
stdio is working. */
static void
write_char (c)
char c;
{
_write_r (_REENT, CONSOLE_FD, &c, 1);
}
/* Write S to the console.
We go through the file descriptor directly because we can't assume
stdio is working. */
static void
write_string (s)
char *s;
{
_write_r (_REENT, CONSOLE_FD, s, strlen (s));
}

42
agbcc/libc/misc/ffs.c Normal file
View File

@ -0,0 +1,42 @@
/*
FUNCTION
<<ffs>>---find first bit set in a word
INDEX
ffs
ANSI_SYNOPSIS
int ffs(int <[word]>);
TRAD_SYNOPSIS
int ffs(<[word]>);
DESCRIPTION
<<ffs>> returns the first bit set in a word.
RETURNS
<<ffs>> returns 0 if <[c]> is 0, 1 if <[c]> is odd, 2 if <[c]> is a multiple of
2, etc.
PORTABILITY
<<ffs>> is not ANSI C.
No supporting OS subroutines are required. */
int
ffs (word)
int word;
{
int i;
if (!word)
return 0;
i = 0;
for (;;)
{
if (((1 << i++) & word) != 0)
return i;
}
}

146
agbcc/libc/misc/unctrl.c Normal file
View File

@ -0,0 +1,146 @@
/*
FUNCTION
<<unctrl>>---translate characters to upper case
INDEX
unctrl
INDEX
unctrllen
ANSI_SYNOPSIS
#include <unctrl.h>
char *unctrl(int <[c]>);
int unctrllen(int <[c]>);
TRAD_SYNOPSIS
#include <unctrl.h>
char *unctrl(<[c]>);
int unctrllen(<[c]>);
DESCRIPTION
<<unctrl>> is a macro which returns the printable representation of <[c]>
as a string.
<<unctrllen>> is a macro which returns the length of the printable
representation of <[c]>.
RETURNS
<<unctrl>> returns a string of the printable representation of <[c]>.
<<unctrllen>> returns the length of the string which is the printable
representation of <[c]>.
PORTABILITY
<<unctrl>> and <<unctrllen>> are not ANSI C.
No supporting OS subroutines are required.
*/
/*
* Copyright (c) 1981, 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.
*/
#include <_ansi.h>
#ifndef lint
static char sccsid[] = "@(#)unctrl.c 8.1 (Berkeley) 6/4/93";
#endif /* not lint */
_CONST char * _CONST __unctrl[256] = {
"^@", "^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", "^[", "^\\", "^]", "^~", "^_",
" ", "!", "\"", "#", "$", "%", "&", "'",
"(", ")", "*", "+", ",", "-", ".", "/",
"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", "[", "\\", "]", "^", "_",
"`", "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", "{", "|", "}", "~", "^?",
"0x80", "0x81", "0x82", "0x83", "0x84", "0x85", "0x86", "0x87",
"0x88", "0x89", "0x8a", "0x8b", "0x8c", "0x8d", "0x8e", "0x8f",
"0x90", "0x91", "0x92", "0x93", "0x94", "0x95", "0x96", "0x97",
"0x98", "0x99", "0x9a", "0x9b", "0x9c", "0x9d", "0x9e", "0x9f",
"0xa0", "0xa1", "0xa2", "0xa3", "0xa4", "0xa5", "0xa6", "0xa7",
"0xa8", "0xa9", "0xaa", "0xab", "0xac", "0xad", "0xae", "0xaf",
"0xb0", "0xb1", "0xb2", "0xb3", "0xb4", "0xb5", "0xb6", "0xb7",
"0xb8", "0xb9", "0xba", "0xbb", "0xbc", "0xbd", "0xbe", "0xbf",
"0xc0", "0xc1", "0xc2", "0xc3", "0xc4", "0xc5", "0xc6", "0xc7",
"0xc8", "0xc9", "0xca", "0xcb", "0xcc", "0xcd", "0xce", "0xcf",
"0xd0", "0xd1", "0xd2", "0xd3", "0xd4", "0xd5", "0xd6", "0xd7",
"0xd8", "0xd9", "0xda", "0xdb", "0xdc", "0xdd", "0xde", "0xdf",
"0xe0", "0xe1", "0xe2", "0xe3", "0xe4", "0xe5", "0xe6", "0xe7",
"0xe8", "0xe9", "0xea", "0xeb", "0xec", "0xed", "0xee", "0xef",
"0xf0", "0xf1", "0xf2", "0xf3", "0xf4", "0xf5", "0xf6", "0xf7",
"0xf8", "0xf9", "0xfa", "0xfb", "0xfc", "0xfd", "0xfe", "0xff",
};
_CONST char __unctrllen[256] = {
2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 2,
4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4,
};

58
agbcc/libc/reent/closer.c Normal file
View File

@ -0,0 +1,58 @@
/* Reentrant version of close system call. */
#include <reent.h>
#include <unistd.h>
#include <_syslist.h>
/* Some targets provides their own versions of this functions. Those
targets should define REENTRANT_SYSCALLS_PROVIDED in TARGET_CFLAGS. */
#ifdef _REENT_ONLY
#ifndef REENTRANT_SYSCALLS_PROVIDED
#define REENTRANT_SYSCALLS_PROVIDED
#endif
#endif
#ifndef REENTRANT_SYSCALLS_PROVIDED
/* We use the errno variable used by the system dependent layer. */
#undef errno
extern int errno;
/*
FUNCTION
<<_close_r>>---Reentrant version of close
INDEX
_close_r
ANSI_SYNOPSIS
#include <reent.h>
int _close_r(struct _reent *<[ptr]>, int <[fd]>);
TRAD_SYNOPSIS
#include <reent.h>
int _close_r(<[ptr]>, <[fd]>)
struct _reent *<[ptr]>;
int <[fd]>;
DESCRIPTION
This is a reentrant version of <<close>>. It
takes a pointer to the global data block, which holds
<<errno>>.
*/
int
_close_r (ptr, fd)
struct _reent *ptr;
int fd;
{
int ret;
errno = 0;
if ((ret = _close (fd)) == -1 && errno != 0)
ptr->_errno = errno;
return ret;
}
#endif /* ! defined (REENTRANT_SYSCALLS_PROVIDED) */

144
agbcc/libc/reent/execr.c Normal file
View File

@ -0,0 +1,144 @@
/* Reentrant versions of execution system calls. These
implementations just call the usual system calls. */
#include <reent.h>
#include <unistd.h>
#include <_syslist.h>
/* Some targets provides their own versions of these functions. Those
targets should define REENTRANT_SYSCALLS_PROVIDED in TARGET_CFLAGS. */
#ifdef _REENT_ONLY
#ifndef REENTRANT_SYSCALLS_PROVIDED
#define REENTRANT_SYSCALLS_PROVIDED
#endif
#endif
/* If NO_EXEC is defined, we don't need these functions. */
#if defined (REENTRANT_SYSCALLS_PROVIDED) || defined (NO_EXEC)
int _dummy_exec_syscalls = 1;
#else
/* We use the errno variable used by the system dependent layer. */
#undef errno
extern int errno;
/*
FUNCTION
<<_execve_r>>---Reentrant version of execve
INDEX
_execve_r
ANSI_SYNOPSIS
#include <reent.h>
int _execve_r(struct _reent *<[ptr]>, char *<[name]>,
char **<[argv]>, char **<[env]>);
TRAD_SYNOPSIS
#include <reent.h>
int _execve_r(<[ptr]>, <[name]>, <[argv]>, <[env]>)
struct _reent *<[ptr]>;
char *<[name]>;
char **<[argv]>;
char **<[env]>;
DESCRIPTION
This is a reentrant version of <<execve>>. It
takes a pointer to the global data block, which holds
<<errno>>.
*/
int
_execve_r (ptr, name, argv, env)
struct _reent *ptr;
char *name;
char **argv;
char **env;
{
int ret;
errno = 0;
if ((ret = _execve (name, argv, env)) == -1 && errno != 0)
ptr->_errno = errno;
return ret;
}
/*
FUNCTION
<<_fork_r>>---Reentrant version of fork
INDEX
_fork_r
ANSI_SYNOPSIS
#include <reent.h>
int _fork_r(struct _reent *<[ptr]>);
TRAD_SYNOPSIS
#include <reent.h>
int _fork_r(<[ptr]>)
struct _reent *<[ptr]>;
DESCRIPTION
This is a reentrant version of <<fork>>. It
takes a pointer to the global data block, which holds
<<errno>>.
*/
#ifndef NO_FORK
int
_fork_r (ptr)
struct _reent *ptr;
{
int ret;
errno = 0;
if ((ret = _fork ()) == -1 && errno != 0)
ptr->_errno = errno;
return ret;
}
#endif
/*
FUNCTION
<<_wait_r>>---Reentrant version of wait
INDEX
_wait_r
ANSI_SYNOPSIS
#include <reent.h>
int _wait_r(struct _reent *<[ptr]>, int *<[status]>);
TRAD_SYNOPSIS
#include <reent.h>
int _wait_r(<[ptr]>, <[status]>)
struct _reent *<[ptr]>;
int *<[status]>;
DESCRIPTION
This is a reentrant version of <<wait>>. It
takes a pointer to the global data block, which holds
<<errno>>.
*/
int
_wait_r (ptr, status)
struct _reent *ptr;
int *status;
{
int ret;
errno = 0;
if ((ret = _wait (status)) == -1 && errno != 0)
ptr->_errno = errno;
return ret;
}
#endif /* ! defined (REENTRANT_SYSCALLS_PROVIDED) */

66
agbcc/libc/reent/fstatr.c Normal file
View File

@ -0,0 +1,66 @@
/* Reentrant versions of fstat system call. This implementation just
calls the fstat system call. */
#include <reent.h>
#include <unistd.h>
#include <_syslist.h>
/* Some targets provides their own versions of these functions. Those
targets should define REENTRANT_SYSCALLS_PROVIDED in TARGET_CFLAGS. */
#ifdef _REENT_ONLY
#ifndef REENTRANT_SYSCALLS_PROVIDED
#define REENTRANT_SYSCALLS_PROVIDED
#endif
#endif
#ifdef REENTRANT_SYSCALLS_PROVIDED
int _dummy_fstat_syscalls = 1;
#else
/* We use the errno variable used by the system dependent layer. */
#undef errno
extern int errno;
/*
FUNCTION
<<_fstat_r>>---Reentrant version of fstat
INDEX
_fstat_r
ANSI_SYNOPSIS
#include <reent.h>
int _fstat_r(struct _reent *<[ptr]>,
int <[fd]>, struct stat *<[pstat]>);
TRAD_SYNOPSIS
#include <reent.h>
int _fstat_r(<[ptr]>, <[fd]>, <[pstat]>)
struct _reent *<[ptr]>;
int <[fd]>;
struct stat *<[pstat]>;
DESCRIPTION
This is a reentrant version of <<fstat>>. It
takes a pointer to the global data block, which holds
<<errno>>.
*/
int
_fstat_r (ptr, fd, pstat)
struct _reent *ptr;
int fd;
struct stat *pstat;
{
int ret;
errno = 0;
if ((ret = _fstat (fd, pstat)) == -1 && errno != 0)
ptr->_errno = errno;
return ret;
}
#endif /* ! defined (REENTRANT_SYSCALLS_PROVIDED) */

13
agbcc/libc/reent/impure.c Normal file
View File

@ -0,0 +1,13 @@
#include <reent.h>
/* Note that there is a copy of this in sys/reent.h. */
#ifndef __ATTRIBUTE_IMPURE_PTR__
#define __ATTRIBUTE_IMPURE_PTR__
#endif
#ifndef __ATTRIBUTE_IMPURE_DATA__
#define __ATTRIBUTE_IMPURE_DATA__
#endif
static struct _reent __ATTRIBUTE_IMPURE_DATA__ impure_data = _REENT_INIT (impure_data);
struct _reent *__ATTRIBUTE_IMPURE_PTR__ _impure_ptr = &impure_data;

102
agbcc/libc/reent/linkr.c Normal file
View File

@ -0,0 +1,102 @@
/* Reentrant versions of file system calls. These implementations
just call the usual system calls. */
#include <reent.h>
#include <unistd.h>
#include <_syslist.h>
/* Some targets provides their own versions of these functions. Those
targets should define REENTRANT_SYSCALLS_PROVIDED in TARGET_CFLAGS. */
#ifdef _REENT_ONLY
#ifndef REENTRANT_SYSCALLS_PROVIDED
#define REENTRANT_SYSCALLS_PROVIDED
#endif
#endif
#ifdef REENTRANT_SYSCALLS_PROVIDED
int _dummy_link_syscalls = 1;
#else
/* We use the errno variable used by the system dependent layer. */
#undef errno
extern int errno;
/*
FUNCTION
<<_link_r>>---Reentrant version of link
INDEX
_link_r
ANSI_SYNOPSIS
#include <reent.h>
int _link_r(struct _reent *<[ptr]>,
const char *<[old]>, const char *<[new]>);
TRAD_SYNOPSIS
#include <reent.h>
int _link_r(<[ptr]>, <[old]>, <[new]>)
struct _reent *<[ptr]>;
char *<[old]>;
char *<[new]>;
DESCRIPTION
This is a reentrant version of <<link>>. It
takes a pointer to the global data block, which holds
<<errno>>.
*/
int
_link_r (ptr, old, new)
struct _reent *ptr;
_CONST char *old;
_CONST char *new;
{
int ret;
errno = 0;
if ((ret = _link (old, new)) == -1 && errno != 0)
ptr->_errno = errno;
return ret;
}
/*
FUNCTION
<<_unlink_r>>---Reentrant version of unlink
INDEX
_unlink_r
ANSI_SYNOPSIS
#include <reent.h>
int _unlink_r(struct _reent *<[ptr]>, const char *<[file]>);
TRAD_SYNOPSIS
#include <reent.h>
int _unlink_r(<[ptr]>, <[file]>)
struct _reent *<[ptr]>;
char *<[file]>;
DESCRIPTION
This is a reentrant version of <<unlink>>. It
takes a pointer to the global data block, which holds
<<errno>>.
*/
int
_unlink_r (ptr, file)
struct _reent *ptr;
_CONST char *file;
{
int ret;
errno = 0;
if ((ret = _unlink (file)) == -1 && errno != 0)
ptr->_errno = errno;
return ret;
}
#endif /* ! defined (REENTRANT_SYSCALLS_PROVIDED) */

63
agbcc/libc/reent/lseekr.c Normal file
View File

@ -0,0 +1,63 @@
/* Reentrant versions of lseek system call. */
#include <reent.h>
#include <unistd.h>
#include <_syslist.h>
/* Some targets provides their own versions of this functions. Those
targets should define REENTRANT_SYSCALLS_PROVIDED in TARGET_CFLAGS. */
#ifdef _REENT_ONLY
#ifndef REENTRANT_SYSCALLS_PROVIDED
#define REENTRANT_SYSCALLS_PROVIDED
#endif
#endif
#ifndef REENTRANT_SYSCALLS_PROVIDED
/* We use the errno variable used by the system dependent layer. */
#undef errno
extern int errno;
/*
FUNCTION
<<_lseek_r>>---Reentrant version of lseek
INDEX
_lseek_r
ANSI_SYNOPSIS
#include <reent.h>
off_t _lseek_r(struct _reent *<[ptr]>,
int <[fd]>, off_t <[pos]>, int <[whence]>);
TRAD_SYNOPSIS
#include <reent.h>
off_t _lseek_r(<[ptr]>, <[fd]>, <[pos]>, <[whence]>)
struct _reent *<[ptr]>;
int <[fd]>;
off_t <[pos]>;
int <[whence]>;
DESCRIPTION
This is a reentrant version of <<lseek>>. It
takes a pointer to the global data block, which holds
<<errno>>.
*/
off_t
_lseek_r (ptr, fd, pos, whence)
struct _reent *ptr;
int fd;
off_t pos;
int whence;
{
off_t ret;
errno = 0;
if ((ret = _lseek (fd, pos, whence)) == (off_t) -1 && errno != 0)
ptr->_errno = errno;
return ret;
}
#endif /* ! defined (REENTRANT_SYSCALLS_PROVIDED) */

64
agbcc/libc/reent/openr.c Normal file
View File

@ -0,0 +1,64 @@
/* Reentrant versions of open system call. */
#include <reent.h>
#include <unistd.h>
#include <_syslist.h>
/* Some targets provides their own versions of this functions. Those
targets should define REENTRANT_SYSCALLS_PROVIDED in TARGET_CFLAGS. */
#ifdef _REENT_ONLY
#ifndef REENTRANT_SYSCALLS_PROVIDED
#define REENTRANT_SYSCALLS_PROVIDED
#endif
#endif
#ifndef REENTRANT_SYSCALLS_PROVIDED
/* We use the errno variable used by the system dependent layer. */
#undef errno
extern int errno;
/*
FUNCTION
<<_open_r>>---Reentrant version of open
INDEX
_open_r
ANSI_SYNOPSIS
#include <reent.h>
int _open_r(struct _reent *<[ptr]>,
const char *<[file]>, int <[flags]>, int <[mode]>);
TRAD_SYNOPSIS
#include <reent.h>
int _open_r(<[ptr]>, <[file]>, <[flags]>, <[mode]>)
struct _reent *<[ptr]>;
char *<[file]>;
int <[flags]>;
int <[mode]>;
DESCRIPTION
This is a reentrant version of <<open>>. It
takes a pointer to the global data block, which holds
<<errno>>.
*/
int
_open_r (ptr, file, flags, mode)
struct _reent *ptr;
_CONST char *file;
int flags;
int mode;
{
int ret;
errno = 0;
if ((ret = _open (file, flags, mode)) == -1 && errno != 0)
ptr->_errno = errno;
return ret;
}
#endif /* ! defined (REENTRANT_SYSCALLS_PROVIDED) */

63
agbcc/libc/reent/readr.c Normal file
View File

@ -0,0 +1,63 @@
/* Reentrant versions of read system call. */
#include <reent.h>
#include <unistd.h>
#include <_syslist.h>
/* Some targets provides their own versions of this functions. Those
targets should define REENTRANT_SYSCALLS_PROVIDED in TARGET_CFLAGS. */
#ifdef _REENT_ONLY
#ifndef REENTRANT_SYSCALLS_PROVIDED
#define REENTRANT_SYSCALLS_PROVIDED
#endif
#endif
#ifndef REENTRANT_SYSCALLS_PROVIDED
/* We use the errno variable used by the system dependent layer. */
#undef errno
extern int errno;
/*
FUNCTION
<<_read_r>>---Reentrant version of read
INDEX
_read_r
ANSI_SYNOPSIS
#include <reent.h>
long _read_r(struct _reent *<[ptr]>,
int <[fd]>, void *<[buf]>, size_t <[cnt]>);
TRAD_SYNOPSIS
#include <reent.h>
long _read_r(<[ptr]>, <[fd]>, <[buf]>, <[cnt]>)
struct _reent *<[ptr]>;
int <[fd]>;
char *<[buf]>;
size_t <[cnt]>;
DESCRIPTION
This is a reentrant version of <<read>>. It
takes a pointer to the global data block, which holds
<<errno>>.
*/
long
_read_r (ptr, fd, buf, cnt)
struct _reent *ptr;
int fd;
_PTR buf;
size_t cnt;
{
long ret;
errno = 0;
if ((ret = _read (fd, buf, cnt)) == -1 && errno != 0)
ptr->_errno = errno;
return ret;
}
#endif /* ! defined (REENTRANT_SYSCALLS_PROVIDED) */

107
agbcc/libc/reent/reent.c Normal file
View File

@ -0,0 +1,107 @@
/*
FUNCTION
<<reent>>---definition of impure data.
INDEX
reent
DESCRIPTION
This module defines the impure data area used by the
non-rentrant functions, such as strtok.
*/
#include <reent.h>
/* Interim cleanup code */
void
cleanup_glue (ptr, glue)
struct _reent *ptr;
struct _glue *glue;
{
/* Have to reclaim these in reverse order: */
if (glue->_next)
cleanup_glue (ptr, glue->_next);
_free_r (ptr, glue);
}
void
_reclaim_reent (ptr)
struct _reent *ptr;
{
if (ptr != _impure_ptr)
{
/* used by mprec routines. */
if (ptr->_freelist)
{
int i;
for (i = 0; i < 15 /* _Kmax */; i++)
{
struct _Bigint *thisone, *nextone;
nextone = ptr->_freelist[i];
while (nextone)
{
thisone = nextone;
nextone = nextone->_next;
_free_r (ptr, thisone);
}
}
_free_r (ptr, ptr->_freelist);
}
/* atexit stuff */
if ((ptr->_atexit) && (ptr->_atexit != &ptr->_atexit0))
{
struct _atexit *p, *q;
for (p = ptr->_atexit; p != &ptr->_atexit0;)
{
q = p;
p = p->_next;
_free_r (ptr, q);
}
}
if (ptr->_cvtbuf)
_free_r (ptr, ptr->_cvtbuf);
if (ptr->__sdidinit)
{
/* cleanup won't reclaim memory 'coz usually it's run
before the program exits, and who wants to wait for that? */
ptr->__cleanup (ptr);
if (ptr->__sglue._next)
cleanup_glue (ptr, ptr->__sglue._next);
}
/* Malloc memory not reclaimed; no good way to return memory anyway. */
}
}
/*
* Do atexit() processing and cleanup
*
* NOTE: This is to be executed at task exit. It does not tear anything
* down which is used on a global basis.
*/
void
_wrapup_reent(struct _reent *ptr)
{
register struct _atexit *p;
register int n;
if (ptr == 0)
ptr = _REENT;
for (p = ptr->_atexit; p; p = p->_next)
for (n = p->_ind; --n >= 0;)
(*p->_fns[n]) ();
if (ptr->__cleanup)
(*ptr->__cleanup) (ptr);
}

66
agbcc/libc/reent/sbrkr.c Normal file
View File

@ -0,0 +1,66 @@
/* Reentrant versions of sbrk system call. This implementation just
calls the stat system call. */
#include <reent.h>
#include <unistd.h>
#include <_syslist.h>
/* Some targets provides their own versions of these functions. Those
targets should define REENTRANT_SYSCALLS_PROVIDED in TARGET_CFLAGS. */
#ifdef _REENT_ONLY
#ifndef REENTRANT_SYSCALLS_PROVIDED
#define REENTRANT_SYSCALLS_PROVIDED
#endif
#endif
/* If MALLOC_PROVIDED is defined, we don't need this function. */
#if defined (REENTRANT_SYSCALLS_PROVIDED) || defined (MALLOC_PROVIDED)
int _dummy_sbrk_syscalls = 1;
#else
/* We use the errno variable used by the system dependent layer. */
#undef errno
int errno;
/*
FUNCTION
<<_sbrk_r>>---Reentrant version of sbrk
INDEX
_sbrk_r
ANSI_SYNOPSIS
#include <reent.h>
void *_sbrk_r(struct _reent *<[ptr]>, size_t <[incr]>);
TRAD_SYNOPSIS
#include <reent.h>
void *_sbrk_r(<[ptr]>, <[incr]>)
struct _reent *<[ptr]>;
size_t <[incr]>;
DESCRIPTION
This is a reentrant version of <<sbrk>>. It
takes a pointer to the global data block, which holds
<<errno>>.
*/
void *
_sbrk_r (ptr, incr)
struct _reent *ptr;
size_t incr;
{
char *ret;
void *_sbrk(size_t);
errno = 0;
if ((ret = (char *)(_sbrk (incr))) == (void *) -1 && errno != 0)
ptr->_errno = errno;
return ret;
}
#endif /* ! defined (REENTRANT_SYSCALLS_PROVIDED) */

View File

@ -0,0 +1,98 @@
/* Reentrant versions of syscalls need to support signal/raise.
These implementations just call the usual system calls. */
#include <reent.h>
#include <_syslist.h>
/* Some targets provides their own versions of these functions. Those
targets should define REENTRANT_SYSCALLS_PROVIDED in TARGET_CFLAGS. */
#ifdef _REENT_ONLY
#ifndef REENTRANT_SYSCALLS_PROVIDED
#define REENTRANT_SYSCALLS_PROVIDED
#endif
#endif
#ifdef REENTRANT_SYSCALLS_PROVIDED
int _dummy_link_syscalls = 1;
#else
/* We use the errno variable used by the system dependent layer. */
#undef errno
extern int errno;
/*
FUNCTION
<<_kill_r>>---Reentrant version of kill
INDEX
_kill_r
ANSI_SYNOPSIS
#include <reent.h>
int _kill_r(struct _reent *<[ptr]>, int <[pid]>, int <[sig]>);
TRAD_SYNOPSIS
#include <reent.h>
int _kill_r(<[ptr]>, <[pid]>, <[sig]>)
struct _reent *<[ptr]>;
int <[pid]>;
int <[sig]>;
DESCRIPTION
This is a reentrant version of <<kill>>. It
takes a pointer to the global data block, which holds
<<errno>>.
*/
int
_kill_r (ptr, pid, sig)
struct _reent *ptr;
int pid;
int sig;
{
int ret;
errno = 0;
if ((ret = _kill (pid, sig)) == -1 && errno != 0)
ptr->_errno = errno;
return ret;
}
/*
FUNCTION
<<_getpid_r>>---Reentrant version of getpid
INDEX
_getpid_r
ANSI_SYNOPSIS
#include <reent.h>
int _getpid_r(struct _reent *<[ptr]>);
TRAD_SYNOPSIS
#include <reent.h>
int _getpid_r(<[ptr]>)
struct _reent *<[ptr]>;
DESCRIPTION
This is a reentrant version of <<getpid>>. It
takes a pointer to the global data block, which holds
<<errno>>.
We never need <<errno>>, of course, but for consistency we
still must have the reentrant pointer argument.
*/
int
_getpid_r (ptr)
struct _reent *ptr;
{
int ret;
ret = _getpid ();
return ret;
}
#endif /* ! defined (REENTRANT_SYSCALLS_PROVIDED) */

67
agbcc/libc/reent/statr.c Normal file
View File

@ -0,0 +1,67 @@
/* Reentrant versions of stat system call. This implementation just
calls the stat system call. */
#include <reent.h>
#include <unistd.h>
#include <_syslist.h>
/* Some targets provides their own versions of these functions. Those
targets should define REENTRANT_SYSCALLS_PROVIDED in
TARGET_CFLAGS. */
#ifdef _REENT_ONLY
#ifndef REENTRANT_SYSCALLS_PROVIDED
#define REENTRANT_SYSCALLS_PROVIDED
#endif
#endif
#ifdef REENTRANT_SYSCALLS_PROVIDED
int _dummy_stat_syscalls = 1;
#else
/* We use the errno variable used by the system dependent layer. */
#undef errno
extern int errno;
/*
FUNCTION
<<_stat_r>>---Reentrant version of stat
INDEX
_stat_r
ANSI_SYNOPSIS
#include <reent.h>
int _stat_r(struct _reent *<[ptr]>,
const char *<[file]>, struct stat *<[pstat]>);
TRAD_SYNOPSIS
#include <reent.h>
int _stat_r(<[ptr]>, <[file]>, <[pstat]>)
struct _reent *<[ptr]>;
char *<[file]>;
struct stat *<[pstat]>;
DESCRIPTION
This is a reentrant version of <<stat>>. It
takes a pointer to the global data block, which holds
<<errno>>.
*/
int
_stat_r (ptr, file, pstat)
struct _reent *ptr;
_CONST char *file;
struct stat *pstat;
{
int ret;
errno = 0;
if ((ret = _stat (file, pstat)) == -1 && errno != 0)
ptr->_errno = errno;
return ret;
}
#endif /* ! defined (REENTRANT_SYSCALLS_PROVIDED) */

112
agbcc/libc/reent/timer.c Normal file
View File

@ -0,0 +1,112 @@
/* Reentrant versions of times and gettimeofday system calls for the
clock and time ANSI C routines.
This implementation just calls the times/gettimeofday system calls.
Gettimeofday may not be available on all targets. It's presence
here is dubious. Consider it for internal use only. */
#include <reent.h>
#include <time.h>
#include <sys/times.h>
#include <_syslist.h>
/* Some targets provides their own versions of these functions. Those
targets should define REENTRANT_SYSCALLS_PROVIDED in TARGET_CFLAGS. */
#ifdef _REENT_ONLY
#ifndef REENTRANT_SYSCALLS_PROVIDED
#define REENTRANT_SYSCALLS_PROVIDED
#endif
#endif
#ifdef REENTRANT_SYSCALLS_PROVIDED
int _dummy_time_syscalls = 1;
#else
/* We use the errno variable used by the system dependent layer. */
#undef errno
extern int errno;
/*
FUNCTION
<<_times_r>>---Reentrant version of times
INDEX
_times_r
ANSI_SYNOPSIS
#include <reent.h>
#include <sys/times.h>
clock_t _times_r(struct _reent *<[ptr]>, struct tms *<[ptms]>);
TRAD_SYNOPSIS
#include <reent.h>
#include <sys/times.h>
clock_t _times_r(<[ptr]>, <[ptms]>)
struct _reent *<[ptr]>;
struct tms *<[ptms]>;
DESCRIPTION
This is a reentrant version of <<times>>. It
takes a pointer to the global data block, which holds
<<errno>>.
*/
clock_t
_times_r (ptr, ptms)
struct _reent *ptr;
struct tms *ptms;
{
clock_t ret;
ret = _times (ptms);
return ret;
}
/*
FUNCTION
<<_gettimeofday_r>>---Reentrant version of gettimeofday
INDEX
_gettimeofday_r
ANSI_SYNOPSIS
#include <reent.h>
#include <time.h>
int _gettimeofday_r(struct _reent *<[ptr]>,
struct timeval *<[ptimeval]>,
struct timezone *<[ptimezone]>);
TRAD_SYNOPSIS
#include <reent.h>
#include <time.h>
int _gettimeofday_r(<[ptr]>, <[ptimeval]>, <[ptimezone]>)
struct _reent *<[ptr]>;
struct timeval *<[ptimeval]>;
struct timezone *<[ptimezone]>;
DESCRIPTION
This is a reentrant version of <<gettimeofday>>. It
takes a pointer to the global data block, which holds
<<errno>>.
This function is only available for a few targets.
Check libc.a to see if its available on yours.
*/
int
_gettimeofday_r (ptr, ptimeval, ptimezone)
struct _reent *ptr;
struct timeval *ptimeval;
struct timezone *ptimezone;
{
int ret;
errno = 0;
if ((ret = _gettimeofday (ptimeval, ptimezone)) == -1 && errno != 0)
ptr->_errno = errno;
return ret;
}
#endif /* ! defined (REENTRANT_SYSCALLS_PROVIDED) */

63
agbcc/libc/reent/writer.c Normal file
View File

@ -0,0 +1,63 @@
/* Reentrant versions of write system call. */
#include <reent.h>
#include <unistd.h>
#include <_syslist.h>
/* Some targets provides their own versions of this functions. Those
targets should define REENTRANT_SYSCALLS_PROVIDED in TARGET_CFLAGS. */
#ifdef _REENT_ONLY
#ifndef REENTRANT_SYSCALLS_PROVIDED
#define REENTRANT_SYSCALLS_PROVIDED
#endif
#endif
#ifndef REENTRANT_SYSCALLS_PROVIDED
/* We use the errno variable used by the system dependent layer. */
#undef errno
extern int errno;
/*
FUNCTION
<<_write_r>>---Reentrant version of write
INDEX
_write_r
ANSI_SYNOPSIS
#include <reent.h>
long _write_r(struct _reent *<[ptr]>,
int <[fd]>, const void *<[buf]>, size_t <[cnt]>);
TRAD_SYNOPSIS
#include <reent.h>
long _write_r(<[ptr]>, <[fd]>, <[buf]>, <[cnt]>)
struct _reent *<[ptr]>;
int <[fd]>;
char *<[buf]>;
size_t <[cnt]>;
DESCRIPTION
This is a reentrant version of <<write>>. It
takes a pointer to the global data block, which holds
<<errno>>.
*/
long
_write_r (ptr, fd, buf, cnt)
struct _reent *ptr;
int fd;
_CONST _PTR buf;
size_t cnt;
{
long ret;
errno = 0;
if ((ret = _write (fd, buf, cnt)) == -1 && errno != 0)
ptr->_errno = errno;
return ret;
}
#endif /* ! defined (REENTRANT_SYSCALLS_PROVIDED) */

80
agbcc/libc/signal/raise.c Normal file
View File

@ -0,0 +1,80 @@
/* Embedded systems may want the simulated signals if no other form exists,
but UNIX versions will want to use the host facilities.
Define SIMULATED_SIGNALS when you want to use the simulated versions.
*/
/*
FUNCTION
<<raise>>---send a signal
INDEX
raise
INDEX
_raise_r
ANSI_SYNOPSIS
#include <signal.h>
int raise(int <[sig]>);
int _raise_r(void *<[reent]>, int <[sig]>);
TRAD_SYNOPSIS
#include <signal.h>
int raise(<[sig]>)
int <[sig]>;
int _raise_r(<[reent]>, <[sig]>)
char *<[reent]>;
int <[sig]>;
DESCRIPTION
Send the signal <[sig]> (one of the macros from `<<sys/signal.h>>').
This interrupts your program's normal flow of execution, and allows a signal
handler (if you've defined one, using <<signal>>) to take control.
The alternate function <<_raise_r>> is a reentrant version. The extra
argument <[reent]> is a pointer to a reentrancy structure.
RETURNS
The result is <<0>> if <[sig]> was successfully raised, <<1>>
otherwise. However, the return value (since it depends on the normal
flow of execution) may not be visible, unless the signal handler for
<[sig]> terminates with a <<return>> or unless <<SIG_IGN>> is in
effect for this signal.
PORTABILITY
ANSI C requires <<raise>>, but allows the full set of signal numbers
to vary from one implementation to another.
Required OS subroutines: <<getpid>>, <<kill>>.
*/
#ifndef SIGNAL_PROVIDED
int _dummy_raise;
#else
#include <reent.h>
#include <signal.h>
#ifndef _REENT_ONLY
int
_DEFUN (raise, (sig),
int sig)
{
return _raise_r (_REENT, sig);
}
#endif
int
_DEFUN (_raise_r, (reent, sig),
struct _reent *reent _AND
int sig)
{
return _kill_r (reent, _getpid_r (reent), sig);
}
#endif /* SIGNAL_PROVIDED */

269
agbcc/libc/signal/signal.c Normal file
View File

@ -0,0 +1,269 @@
/*
FUNCTION
<<signal>>---specify handler subroutine for a signal
INDEX
signal
INDEX
_signal_r
INDEX
raise
INDEX
_raise_r
ANSI_SYNOPSIS
#include <signal.h>
void ( * signal(int <[sig]>, void(*<[func]>)(int)) )(int);
void ( * _signal_r(void *<[reent]>,
int <[sig]>, void(*<[func]>)(int)) )(int);
int raise (int <[sig]>);
int _raise_r (void *<[reent]>, int <[sig]>);
TRAD_SYNOPSIS
#include <signal.h>
char ( * signal(<[sig]>, <[func]>) )()
int <[sig]>;
char ( * <[func]> )();
char ( * _signal_r(<[reent]>, <[sig]>, <[func]>) )()
char *<[reent]>;
int <[sig]>;
char ( * <[func]> )();
int raise (<[sig]>)()
int <[sig]>;
int _raise_r (<[reent]>, <[sig]>)()
char *<[reent]>;
int <[sig]>;
DESCRIPTION
<<signal, raise>> provide a simple signal/raise implementation for embedded
targets.
<<signal>> allows you to request changed treatment for a particular
signal <[sig]>. You can use one of the predefined macros <<SIG_DFL>>
(select system default handling) or <<SIG_IGN>> (ignore this signal)
as the value of <[func]>; otherwise, <[func]> is a function pointer
that identifies a subroutine in your program as the handler for this signal.
Some of the execution environment for signal handlers is
unpredictable; notably, the only library function required to work
correctly from within a signal handler is @code{signal} itself, and
only when used to redefine the handler for the current signal value.
Static storage is likewise unreliable for signal handlers, with one
exception: if you declare a static storage location as `<<volatile
sig_atomic_t>>', then you may use that location in a signal handler to
store signal values.
If your signal handler terminates using <<return>> (or implicit
return), your program's execution continues at the point
where it was when the signal was raised (whether by your program
itself, or by an external event). Signal handlers can also
use functions such as <<exit>> and <<abort>> to avoid returning.
<<raise>> sends the signal sig to the executing program. It returns zero if
successful, non-zero if unsuccessful.
The alternate functions <<_signal_r, _raise_r>> are the reentrant versions.
The extra argument <[reent]> is a pointer to a reentrancy structure.
@c FIXME: do we have setjmp.h and assoc fns?
RETURNS
If your request for a signal handler cannot be honored, the result is
<<SIG_ERR>>; a specific error number is also recorded in <<errno>>.
Otherwise, the result is the previous handler (a function pointer or
one of the predefined macros).
PORTABILITY
ANSI C requires <<raise>>, <<signal>>.
No supporting OS subroutines are required to link with <<signal>>, but
it will not have any useful effects, except for software generated signals,
without an operating system that can actually raise exceptions.
*/
/*
* signal.c
* Original Author: G. Haley
*
* signal associates the function pointed to by func with the signal sig. When
* a signal occurs, the value of func determines the action taken as follows:
* if func is SIG_DFL, the default handling for that signal will occur; if func
* is SIG_IGN, the signal will be ignored; otherwise, the default handling for
* the signal is restored (SIG_DFL), and the function func is called with sig
* as its argument. Returns the value of func for the previous call to signal
* for the signal sig, or SIG_ERR if the request fails.
*/
/* _init_signal initialises the signal handlers for each signal. This function
is called by crt0 at program startup. */
#ifdef SIGNAL_PROVIDED
int _dummy_simulated_signal;
#else
#include <errno.h>
#include <signal.h>
#include <stddef.h>
#include <stdlib.h>
#include <reent.h>
#include <_syslist.h>
int
_DEFUN (_init_signal_r, (ptr),
struct _reent *ptr)
{
int i;
if (ptr->_sig_func == NULL)
{
ptr->_sig_func = (_sig_func_ptr *)_malloc_r (ptr, sizeof (_sig_func_ptr) * NSIG);
if (ptr->_sig_func == NULL)
return -1;
for (i = 0; i < NSIG; i++)
ptr->_sig_func[i] = SIG_DFL;
}
return 0;
}
_sig_func_ptr
_DEFUN (_signal_r, (ptr, sig, func),
struct _reent *ptr _AND
int sig _AND
_sig_func_ptr func)
{
_sig_func_ptr old_func, *temp;
if (sig < 0 || sig >= NSIG)
{
ptr->_errno = EINVAL;
return SIG_ERR;
}
if (ptr->_sig_func == NULL && _init_signal_r (ptr) != 0)
return SIG_ERR;
old_func = ptr->_sig_func[sig];
ptr->_sig_func[sig] = func;
return old_func;
}
int
_raise_r (ptr, sig)
struct _reent *ptr;
int sig;
{
_sig_func_ptr func;
int result = 0;
if (sig < 0 || sig >= NSIG)
{
ptr->_errno = EINVAL;
return -1;
}
if (ptr->_sig_func == NULL && _init_signal_r (ptr) != 0)
return -1;
switch ((_POINTER_INT) ptr->_sig_func[sig])
{
case SIG_DFL:
return _kill_r (ptr, _getpid_r (ptr), sig);
case SIG_IGN:
break;
case SIG_ERR:
ptr->_errno = EINVAL;
result = 1;
break;
default:
func = ptr->_sig_func[sig];
ptr->_sig_func[sig] = SIG_DFL;
func (sig);
break;
}
return result;
}
int
__sigtramp_r (ptr, sig)
struct _reent *ptr;
int sig;
{
_sig_func_ptr func;
if (sig < 0 || sig >= NSIG)
{
return -1;
}
if (ptr->_sig_func == NULL && _init_signal_r (ptr) != 0)
return -1;
switch ((_POINTER_INT) ptr->_sig_func[sig])
{
case SIG_DFL:
return 1;
case SIG_ERR:
return 2;
case SIG_IGN:
return 3;
default:
func = ptr->_sig_func[sig];
ptr->_sig_func[sig] = SIG_DFL;
func (sig);
return 0;
}
}
#ifndef _REENT_ONLY
int
raise (sig)
int sig;
{
return _raise_r (_REENT, sig);
}
_sig_func_ptr
_DEFUN (signal, (sig, func),
int sig _AND
_sig_func_ptr func)
{
return _signal_r (_REENT, sig, func);
}
int
_init_signal ()
{
return _init_signal_r (_REENT);
}
int
__sigtramp (int sig)
{
return __sigtramp_r (_REENT, sig);
}
#endif
#endif /* !SIGNAL_PROVIDED */

View File

@ -0,0 +1,63 @@
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not 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.
*/
/*
FUNCTION
<<clearerr>>---clear file or stream error indicator
INDEX
clearerr
ANSI_SYNOPSIS
#include <stdio.h>
void clearerr(FILE *<[fp]>);
TRAD_SYNOPSIS
#include <stdio.h>
void clearerr(<[fp]>)
FILE *<[fp]>;
DESCRIPTION
The <<stdio>> functions maintain an error indicator with each file
pointer <[fp]>, to record whether any read or write errors have
occurred on the associated file or stream. Similarly, it maintains an
end-of-file indicator to record whether there is no more data in the
file.
Use <<clearerr>> to reset both of these indicators.
See <<ferror>> and <<feof>> to query the two indicators.
RETURNS
<<clearerr>> does not return a result.
PORTABILITY
ANSI C requires <<clearerr>>.
No supporting OS subroutines are required.
*/
#include <stdio.h>
#undef clearerr
_VOID
_DEFUN (clearerr, (fp),
FILE * fp)
{
__sclearerr (fp);
}

82
agbcc/libc/stdio/fclose.c Normal file
View File

@ -0,0 +1,82 @@
/*
FUNCTION
<<fclose>>---close a file
INDEX
fclose
ANSI_SYNOPSIS
#include <stdio.h>
int fclose(FILE *<[fp]>);
TRAD_SYNOPSIS
#include <stdio.h>
int fclose(<[fp]>)
FILE *<[fp]>;
DESCRIPTION
If the file or stream identified by <[fp]> is open, <<fclose>> closes
it, after first ensuring that any pending data is written (by calling
<<fflush(<[fp]>)>>).
RETURNS
<<fclose>> returns <<0>> if successful (including when <[fp]> is
<<NULL>> or not an open file); otherwise, it returns <<EOF>>.
PORTABILITY
<<fclose>> is required by ANSI C.
Required OS subroutines: <<close>>, <<fstat>>, <<isatty>>, <<lseek>>,
<<read>>, <<sbrk>>, <<write>>.
*/
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not 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.
*/
#include <stdio.h>
#include <stdlib.h>
#include "local.h"
/*
* Close a file.
*/
int
_DEFUN (fclose, (fp),
register FILE * fp)
{
int r;
if (fp == NULL)
return (0); /* on NULL */
CHECK_INIT (fp);
if (fp->_flags == 0) /* not open! */
return (0);
r = fp->_flags & __SWR ? fflush (fp) : 0;
if (fp->_close != NULL && (*fp->_close) (fp->_cookie) < 0)
r = EOF;
if (fp->_flags & __SMBF)
_free_r (fp->_data, (char *) fp->_bf._base);
if (HASUB (fp))
FREEUB (fp);
if (HASLB (fp))
FREELB (fp);
fp->_flags = 0; /* release this FILE for reuse */
return (r);
}

116
agbcc/libc/stdio/fdopen.c Normal file
View File

@ -0,0 +1,116 @@
/*
FUNCTION
<<fdopen>>---turn open file into a stream
INDEX
fdopen
INDEX
_fdopen_r
ANSI_SYNOPSIS
#include <stdio.h>
FILE *fdopen(int <[fd]>, const char *<[mode]>);
FILE *_fdopen_r(void *<[reent]>,
int <[fd]>, const char *<[mode]>);
TRAD_SYNOPSIS
#include <stdio.h>
FILE *fdopen(<[fd]>, <[mode]>)
int <[fd]>;
char *<[mode]>;
FILE *_fdopen_r(<[reent]>, <[fd]>, <[mode]>)
char *<[reent]>;
int <[fd]>;
char *<[mode]>);
DESCRIPTION
<<fdopen>> produces a file descriptor of type <<FILE *>>, from a
descriptor for an already-open file (returned, for example, by the
system subroutine <<open>> rather than by <<fopen>>).
The <[mode]> argument has the same meanings as in <<fopen>>.
RETURNS
File pointer or <<NULL>>, as for <<fopen>>.
PORTABILITY
<<fdopen>> is ANSI.
*/
#include <sys/types.h>
#include <sys/fcntl.h>
#include <stdio.h>
#include <errno.h>
#include "local.h"
#include <_syslist.h>
extern int __sflags ();
FILE *
_DEFUN (_fdopen_r, (ptr, fd, mode),
struct _reent *ptr _AND
int fd _AND
_CONST char *mode)
{
register FILE *fp;
int flags, oflags;
#ifdef F_GETFL
int fdflags, fdmode;
#endif
if ((flags = __sflags (ptr, mode, &oflags)) == 0)
return 0;
/* make sure the mode the user wants is a subset of the actual mode */
#ifdef F_GETFL
if ((fdflags = _fcntl (fd, F_GETFL, 0)) < 0)
return 0;
fdmode = fdflags & O_ACCMODE;
if (fdmode != O_RDWR && (fdmode != (oflags & O_ACCMODE)))
{
ptr->_errno = EBADF;
return 0;
}
#endif
if ((fp = __sfp (ptr)) == 0)
return 0;
fp->_flags = flags;
/*
* If opened for appending, but underlying descriptor
* does not have O_APPEND bit set, assert __SAPP so that
* __swrite() will lseek to end before each write.
*/
if ((oflags & O_APPEND)
#ifdef F_GETFL
&& !(fdflags & O_APPEND)
#endif
)
fp->_flags |= __SAPP;
fp->_file = fd;
fp->_cookie = (_PTR) fp;
#undef _read
#undef _write
#undef _seek
#undef _close
fp->_read = __sread;
fp->_write = __swrite;
fp->_seek = __sseek;
fp->_close = __sclose;
return fp;
}
#ifndef _REENT_ONLY
FILE *
_DEFUN (fdopen, (fd, mode),
int fd _AND
_CONST char *mode)
{
return _fdopen_r (_REENT, fd, mode);
}
#endif

40
agbcc/libc/stdio/feof.c Normal file
View File

@ -0,0 +1,40 @@
/*
FUNCTION
<<feof>>---test for end of file
INDEX
feof
ANSI_SYNOPSIS
#include <stdio.h>
int feof(FILE *<[fp]>);
TRAD_SYNOPSIS
#include <stdio.h>
int feof(<[fp]>)
FILE *<[fp]>;
DESCRIPTION
<<feof>> tests whether or not the end of the file identified by <[fp]>
has been reached.
RETURNS
<<feof>> returns <<0>> if the end of file has not yet been reached; if
at end of file, the result is nonzero.
PORTABILITY
<<feof>> is required by ANSI C.
No supporting OS subroutines are required.
*/
#include <stdio.h>
#undef feof
int
_DEFUN (feof, (fp),
FILE * fp)
{
return __sfeof (fp);
}

67
agbcc/libc/stdio/ferror.c Normal file
View File

@ -0,0 +1,67 @@
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not 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.
*/
/*
FUNCTION
<<ferror>>---test whether read/write error has occurred
INDEX
ferror
ANSI_SYNOPSIS
#include <stdio.h>
int ferror(FILE *<[fp]>);
TRAD_SYNOPSIS
#include <stdio.h>
int ferror(<[fp]>)
FILE *<[fp]>;
DESCRIPTION
The <<stdio>> functions maintain an error indicator with each file
pointer <[fp]>, to record whether any read or write errors have
occurred on the associated file or stream.
Use <<ferror>> to query this indicator.
See <<clearerr>> to reset the error indicator.
RETURNS
<<ferror>> returns <<0>> if no errors have occurred; it returns a
nonzero value otherwise.
PORTABILITY
ANSI C requires <<ferror>>.
No supporting OS subroutines are required.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "%W% (Berkeley) %G%";
#endif /* LIBC_SCCS and not lint */
#include <stdio.h>
/* A subroutine version of the macro ferror. */
#undef ferror
int
_DEFUN (ferror, (fp),
FILE * fp)
{
return __sferror (fp);
}

99
agbcc/libc/stdio/fflush.c Normal file
View File

@ -0,0 +1,99 @@
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not 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.
*/
/*
FUNCTION
<<fflush>>---flush buffered file output
INDEX
fflush
ANSI_SYNOPSIS
#include <stdio.h>
int fflush(FILE *<[fp]>);
TRAD_SYNOPSIS
#include <stdio.h>
int fflush(<[fp]>)
FILE *<[fp]>;
DESCRIPTION
The <<stdio>> output functions can buffer output before delivering it
to the host system, in order to minimize the overhead of system calls.
Use <<fflush>> to deliver any such pending output (for the file
or stream identified by <[fp]>) to the host system.
If <[fp]> is <<NULL>>, <<fflush>> delivers pending output from all
open files.
RETURNS
<<fflush>> returns <<0>> unless it encounters a write error; in that
situation, it returns <<EOF>>.
PORTABILITY
ANSI C requires <<fflush>>.
No supporting OS subroutines are required.
*/
#include <stdio.h>
#include "local.h"
/* Flush a single file, or (if fp is NULL) all files. */
int
_DEFUN (fflush, (fp),
register FILE * fp)
{
register unsigned char *p;
register int n, t;
if (fp == NULL)
return _fwalk (_REENT, fflush);
CHECK_INIT (fp);
t = fp->_flags;
if ((t & __SWR) == 0 || (p = fp->_bf._base) == NULL)
return 0;
n = fp->_p - p; /* write this much */
/*
* Set these immediately to avoid problems with longjmp
* and to allow exchange buffering (via setvbuf) in user
* write function.
*/
fp->_p = p;
fp->_w = t & (__SLBF | __SNBF) ? 0 : fp->_bf._size;
while (n > 0)
{
t = (*fp->_write) (fp->_cookie, (char *) p, n);
if (t <= 0)
{
fp->_flags |= __SERR;
return EOF;
}
p += t;
n -= t;
}
return 0;
}

46
agbcc/libc/stdio/fgetc.c Normal file
View File

@ -0,0 +1,46 @@
/*
FUNCTION
<<fgetc>>---get a character from a file or stream
INDEX
fgetc
ANSI_SYNOPSIS
#include <stdio.h>
int fgetc(FILE *<[fp]>);
TRAD_SYNOPSIS
#include <stdio.h>
int fgetc(<[fp]>)
FILE *<[fp]>;
DESCRIPTION
Use <<fgetc>> to get the next single character from the file or stream
identified by <[fp]>. As a side effect, <<fgetc>> advances the file's
current position indicator.
For a macro version of this function, see <<getc>>.
RETURNS
The next character (read as an <<unsigned char>>, and cast to
<<int>>), unless there is no more data, or the host system reports a
read error; in either of these situations, <<fgetc>> returns <<EOF>>.
You can distinguish the two situations that cause an <<EOF>> result by
using the <<ferror>> and <<feof>> functions.
PORTABILITY
ANSI C requires <<fgetc>>.
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
*/
#include <stdio.h>
int
_DEFUN (fgetc, (fp),
FILE * fp)
{
return __sgetc (fp);
}

View File

@ -0,0 +1,61 @@
/*
FUNCTION
<<fgetpos>>---record position in a stream or file
INDEX
fgetpos
ANSI_SYNOPSIS
#include <stdio.h>
int fgetpos(FILE *<[fp]>, fpos_t *<[pos]>);
TRAD_SYNOPSIS
#include <stdio.h>
int fgetpos(<[fp]>, <[pos]>)
FILE *<[fp]>;
fpos_t *<[pos]>;
DESCRIPTION
Objects of type <<FILE>> can have a ``position'' that records how much
of the file your program has already read. Many of the <<stdio>> functions
depend on this position, and many change it as a side effect.
You can use <<fgetpos>> to report on the current position for a file
identified by <[fp]>; <<fgetpos>> will write a value
representing that position at <<*<[pos]>>>. Later, you can
use this value with <<fsetpos>> to return the file to this
position.
In the current implementation, <<fgetpos>> simply uses a character
count to represent the file position; this is the same number that
would be returned by <<ftell>>.
RETURNS
<<fgetpos>> returns <<0>> when successful. If <<fgetpos>> fails, the
result is <<1>>. Failure occurs on streams that do not support
positioning; the global <<errno>> indicates this condition with the
value <<ESPIPE>>.
PORTABILITY
<<fgetpos>> is required by the ANSI C standard, but the meaning of the
value it records is not specified beyond requiring that it be
acceptable as an argument to <<fsetpos>>. In particular, other
conforming C implementations may return a different result from
<<ftell>> than what <<fgetpos>> writes at <<*<[pos]>>>.
No supporting OS subroutines are required.
*/
#include <stdio.h>
int
_DEFUN (fgetpos, (fp, pos),
FILE * fp _AND
fpos_t * pos)
{
*pos = ftell (fp);
if (*pos != -1)
return 0;
return 1;
}

127
agbcc/libc/stdio/fgets.c Normal file
View File

@ -0,0 +1,127 @@
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not 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.
*/
/*
FUNCTION
<<fgets>>---get character string from a file or stream
INDEX
fgets
ANSI_SYNOPSIS
#include <stdio.h>
char *fgets(char *<[buf]>, int <[n]>, FILE *<[fp]>);
TRAD_SYNOPSIS
#include <stdio.h>
char *fgets(<[buf]>,<[n]>,<[fp]>)
char *<[buf]>;
int <[n]>;
FILE *<[fp]>;
DESCRIPTION
Reads at most <[n-1]> characters from <[fp]> until a newline
is found. The characters including to the newline are stored
in <[buf]>. The buffer is terminated with a 0.
RETURNS
<<fgets>> returns the buffer passed to it, with the data
filled in. If end of file occurs with some data already
accumulated, the data is returned with no other indication. If
no data are read, NULL is returned instead.
PORTABILITY
<<fgets>> should replace all uses of <<gets>>. Note however
that <<fgets>> returns all of the data, while <<gets>> removes
the trailing newline (with no indication that it has done so.)
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
*/
#include <stdio.h>
#include <string.h>
extern int __srefill ();
/*
* Read at most n-1 characters from the given file.
* Stop when a newline has been read, or the count runs out.
* Return first argument, or NULL if no characters were read.
*/
char *
_DEFUN (fgets, (buf, n, fp),
char *buf _AND
int n _AND
FILE * fp)
{
size_t len;
char *s;
unsigned char *p, *t;
if (n < 2) /* sanity check */
return 0;
s = buf;
n--; /* leave space for NUL */
do
{
/*
* If the buffer is empty, refill it.
*/
if ((len = fp->_r) <= 0)
{
if (__srefill (fp))
{
/* EOF: stop with partial or no line */
if (s == buf)
return 0;
break;
}
len = fp->_r;
}
p = fp->_p;
/*
* Scan through at most n bytes of the current buffer,
* looking for '\n'. If found, copy up to and including
* newline, and stop. Otherwise, copy entire chunk
* and loop.
*/
if (len > n)
len = n;
t = (unsigned char *) memchr ((_PTR) p, '\n', len);
if (t != 0)
{
len = ++t - p;
fp->_r -= len;
fp->_p = t;
(void) memcpy ((_PTR) s, (_PTR) p, len);
s[len] = 0;
return (buf);
}
fp->_r -= len;
fp->_p += len;
(void) memcpy ((_PTR) s, (_PTR) p, len);
s += len;
}
while ((n -= len) != 0);
*s = 0;
return buf;
}

40
agbcc/libc/stdio/fileno.c Normal file
View File

@ -0,0 +1,40 @@
/*
FUNCTION
<<fileno>>---return file descriptor associated with stream
INDEX
fileno
ANSI_SYNOPSIS
#include <stdio.h>
int fileno(FILE *<[fp]>);
TRAD_SYNOPSIS
#include <stdio.h>
int fileno(<[fp]>)
FILE *<[fp]>;
DESCRIPTION
You can use <<fileno>> to return the file descriptor identified by <[fp]>.
RETURNS
<<fileno>> returns a non-negative integer when successful.
If <[fp]> is not an open stream, <<fileno>> returns -1.
PORTABILITY
<<fileno>> is not part of ANSI C.
POSIX requires <<fileno>>.
Supporting OS subroutines required: none.
*/
#include <stdio.h>
#include "local.h"
int
_DEFUN (fileno, (f),
FILE * f)
{
CHECK_INIT (f);
return __sfileno (f);
}

152
agbcc/libc/stdio/findfp.c Normal file
View File

@ -0,0 +1,152 @@
/* No user fns here. Pesch 15apr92. */
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not 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.
*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include "local.h"
static void
std (ptr, flags, file, data)
FILE *ptr;
struct _reent *data;
{
ptr->_p = 0;
ptr->_r = 0;
ptr->_w = 0;
ptr->_flags = flags;
ptr->_file = file;
ptr->_bf._base = 0;
ptr->_lbfsize = 0;
ptr->_cookie = ptr;
ptr->_read = __sread;
ptr->_write = __swrite;
ptr->_seek = __sseek;
ptr->_close = __sclose;
ptr->_data = data;
}
struct _glue *
__sfmoreglue (d, n)
struct _reent *d;
register int n;
{
struct _glue *g;
FILE *p;
g = (struct _glue *) _malloc_r (d, sizeof (*g) + n * sizeof (FILE));
if (g == NULL)
return NULL;
p = (FILE *) (g + 1);
g->_next = NULL;
g->_niobs = n;
g->_iobs = p;
memset (p, 0, n * sizeof (FILE));
return g;
}
/*
* Find a free FILE for fopen et al.
*/
FILE *
__sfp (d)
struct _reent *d;
{
FILE *fp;
int n;
struct _glue *g;
if (!d->__sdidinit)
__sinit (d);
for (g = &d->__sglue;; g = g->_next)
{
for (fp = g->_iobs, n = g->_niobs; --n >= 0; fp++)
if (fp->_flags == 0)
goto found;
if (g->_next == NULL &&
(g->_next = __sfmoreglue (d, NDYNAMIC)) == NULL)
break;
}
d->_errno = ENOMEM;
return NULL;
found:
fp->_flags = 1; /* reserve this slot; caller sets real flags */
fp->_p = NULL; /* no current pointer */
fp->_w = 0; /* nothing to read or write */
fp->_r = 0;
fp->_bf._base = NULL; /* no buffer */
fp->_bf._size = 0;
fp->_lbfsize = 0; /* not line buffered */
fp->_file = -1; /* no file */
/* fp->_cookie = <any>; */ /* caller sets cookie, _read/_write etc */
fp->_ub._base = NULL; /* no ungetc buffer */
fp->_ub._size = 0;
fp->_lb._base = NULL; /* no line buffer */
fp->_lb._size = 0;
fp->_data = d;
return fp;
}
/*
* exit() calls _cleanup() through *__cleanup, set whenever we
* open or buffer a file. This chicanery is done so that programs
* that do not use stdio need not link it all in.
*
* The name `_cleanup' is, alas, fairly well known outside stdio.
*/
void
_cleanup_r (ptr)
struct _reent *ptr;
{
/* (void) _fwalk(fclose); */
(void) _fwalk (ptr, fflush); /* `cheating' */
}
#ifndef _REENT_ONLY
void
_cleanup ()
{
_cleanup_r (_REENT);
}
#endif
/*
* __sinit() is called whenever stdio's internal variables must be set up.
*/
void
__sinit (s)
struct _reent *s;
{
/* make sure we clean up on exit */
s->__cleanup = _cleanup_r; /* conservative */
s->__sdidinit = 1;
std (s->__sf + 0, __SRD, 0, s);
std (s->__sf + 1, __SWR | __SLBF, 1, s);
std (s->__sf + 2, __SWR | __SNBF, 2, s);
s->__sglue._next = NULL;
s->__sglue._niobs = 3;
s->__sglue._iobs = &s->__sf[0];
}

View File

@ -0,0 +1,77 @@
/*
FUNCTION
<<fiprintf>>---format output to file (integer only)
INDEX
fiprintf
ANSI_SYNOPSIS
#include <stdio.h>
int fiprintf(FILE *<[fd]>, const char *<[format]>, ...);
TRAD_SYNOPSIS
#include <stdio.h>
int fiprintf(<[fd]>, <[format]> [, <[arg]>, ...]);
FILE *<[fd]>;
char *<[format]>;
DESCRIPTION
<<fiprintf>> is a restricted version of <<fprintf>>: it has the same
arguments and behavior, save that it cannot perform any floating-point
formatting---the <<f>>, <<g>>, <<G>>, <<e>>, and <<F>> type specifiers
are not recognized.
RETURNS
<<fiprintf>> returns the number of bytes in the output string,
save that the concluding <<NULL>> is not counted.
<<fiprintf>> returns when the end of the format string is
encountered. If an error occurs, <<fiprintf>>
returns <<EOF>>.
PORTABILITY
<<fiprintf>> is not required by ANSI C.
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
*/
#include <_ansi.h>
#include <stdio.h>
#ifdef _HAVE_STDC
#include <stdarg.h>
int
fiprintf (FILE * fp, const char *fmt,...)
{
int ret;
va_list ap;
va_start (ap, fmt);
ret = vfiprintf (fp, fmt, ap);
va_end (ap);
return ret;
}
#else
#include <varargs.h>
int
fiprintf (fp, fmt, va_alist)
FILE *fp;
char *fmt;
va_dcl
{
int ret;
va_list ap;
va_start (ap);
ret = vfiprintf (fp, fmt, ap);
va_end (ap);
return ret;
}
#endif

83
agbcc/libc/stdio/flags.c Normal file
View File

@ -0,0 +1,83 @@
/* No user fns here. Pesch 15apr92 */
/*
* Copyright (c) 1990 Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not 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 MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#include <stdio.h>
#include <time.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
/*
* Return the (stdio) flags for a given mode. Store the flags
* to be passed to an open() syscall through *optr.
* Return 0 on error.
*/
int
__sflags (ptr, mode, optr)
struct _reent *ptr;
register char *mode;
int *optr;
{
register int ret, m, o;
switch (mode[0])
{
case 'r': /* open for reading */
ret = __SRD;
m = O_RDONLY;
o = 0;
break;
case 'w': /* open for writing */
ret = __SWR;
m = O_WRONLY;
o = O_CREAT | O_TRUNC;
break;
case 'a': /* open for appending */
ret = __SWR | __SAPP;
m = O_WRONLY;
o = O_CREAT | O_APPEND;
break;
default: /* illegal mode */
ptr->_errno = EINVAL;
return (0);
}
if (mode[1] == '+' || mode[2] == '+')
{
ret = __SRW;
m = O_RDWR;
}
if (mode[1] == 'b' || mode[2] == 'b')
{
#ifdef O_BINARY
m |= O_BINARY;
#endif
}
else if (mode[1] == 't' || mode[2] == 't')
{
#ifdef O_TEXT
m |= O_TEXT;
#endif
}
*optr = m | o;
return ret;
}

View File

@ -0,0 +1,27 @@
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not 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.
*
* %W% (Berkeley) %G%
*/
/*
* Floating point scanf/printf (input/output) definitions.
*/
/* 11-bit exponent (VAX G floating point) is 308 decimal digits */
#define MAXEXP 308
/* 128 bit fraction takes up 39 decimal digits; max reasonable precision */
#define MAXFRACT 39

165
agbcc/libc/stdio/fopen.c Normal file
View File

@ -0,0 +1,165 @@
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not 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.
*/
/*
FUNCTION
<<fopen>>---open a file
INDEX
fopen
INDEX
_fopen_r
ANSI_SYNOPSIS
#include <stdio.h>
FILE *fopen(const char *<[file]>, const char *<[mode]>);
FILE *_fopen_r(void *<[reent]>,
const char *<[file]>, const char *<[mode]>);
TRAD_SYNOPSIS
#include <stdio.h>
FILE *fopen(<[file]>, <[mode]>)
char *<[file]>;
char *<[mode]>;
FILE *_fopen_r(<[reent]>, <[file]>, <[mode]>)
char *<[reent]>;
char *<[file]>;
char *<[mode]>;
DESCRIPTION
<<fopen>> initializes the data structures needed to read or write a
file. Specify the file's name as the string at <[file]>, and the kind
of access you need to the file with the string at <[mode]>.
The alternate function <<_fopen_r>> is a reentrant version.
The extra argument <[reent]> is a pointer to a reentrancy structure.
Three fundamental kinds of access are available: read, write, and append.
<<*<[mode]>>> must begin with one of the three characters `<<r>>',
`<<w>>', or `<<a>>', to select one of these:
o+
o r
Open the file for reading; the operation will fail if the file does
not exist, or if the host system does not permit you to read it.
o w
Open the file for writing @emph{from the beginning} of the file:
effectively, this always creates a new file. If the file whose name you
specified already existed, its old contents are discarded.
o a
Open the file for appending data, that is writing from the end of
file. When you open a file this way, all data always goes to the
current end of file; you cannot change this using <<fseek>>.
o-
Some host systems distinguish between ``binary'' and ``text'' files.
Such systems may perform data transformations on data written to, or
read from, files opened as ``text''.
If your system is one of these, then you can append a `<<b>>' to any
of the three modes above, to specify that you are opening the file as
a binary file (the default is to open the file as a text file).
`<<rb>>', then, means ``read binary''; `<<wb>>', ``write binary''; and
`<<ab>>', ``append binary''.
To make C programs more portable, the `<<b>>' is accepted on all
systems, whether or not it makes a difference.
Finally, you might need to both read and write from the same file.
You can also append a `<<+>>' to any of the three modes, to permit
this. (If you want to append both `<<b>>' and `<<+>>', you can do it
in either order: for example, <<"rb+">> means the same thing as
<<"r+b">> when used as a mode string.)
Use <<"r+">> (or <<"rb+">>) to permit reading and writing anywhere in
an existing file, without discarding any data; <<"w+">> (or <<"wb+">>)
to create a new file (or begin by discarding all data from an old one)
that permits reading and writing anywhere in it; and <<"a+">> (or
<<"ab+">>) to permit reading anywhere in an existing file, but writing
only at the end.
RETURNS
<<fopen>> returns a file pointer which you can use for other file
operations, unless the file you requested could not be opened; in that
situation, the result is <<NULL>>. If the reason for failure was an
invalid string at <[mode]>, <<errno>> is set to <<EINVAL>>.
PORTABILITY
<<fopen>> is required by ANSI C.
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
<<lseek>>, <<open>>, <<read>>, <<sbrk>>, <<write>>.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "%W% (Berkeley) %G%";
#endif /* LIBC_SCCS and not lint */
#include <stdio.h>
#include <errno.h>
#include "local.h"
FILE *
_DEFUN (_fopen_r, (ptr, file, mode),
struct _reent *ptr _AND
_CONST char *file _AND
_CONST char *mode)
{
register FILE *fp;
register int f;
int flags, oflags;
if ((flags = __sflags (ptr, mode, &oflags)) == 0)
return NULL;
if ((fp = __sfp (ptr)) == NULL)
return NULL;
if ((f = _open_r (fp->_data, file, oflags, 0666)) < 0)
{
fp->_flags = 0; /* release */
return NULL;
}
fp->_file = f;
fp->_flags = flags;
fp->_cookie = (_PTR) fp;
fp->_read = __sread;
fp->_write = __swrite;
fp->_seek = __sseek;
fp->_close = __sclose;
if (fp->_flags & __SAPP)
fseek (fp, 0, SEEK_END);
return fp;
}
#ifndef _REENT_ONLY
FILE *
_DEFUN (fopen, (file, mode),
_CONST char *file _AND
_CONST char *mode)
{
return _fopen_r (_REENT, file, mode);
}
#endif

View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not 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.
*/
#include <_ansi.h>
#include <stdio.h>
#ifdef _HAVE_STDC
#include <stdarg.h>
int
fprintf (FILE * fp, const char *fmt,...)
{
int ret;
va_list ap;
va_start (ap, fmt);
ret = vfprintf (fp, fmt, ap);
va_end (ap);
return ret;
}
#else
#include <varargs.h>
int
fprintf (fp, fmt, va_alist)
FILE *fp;
char *fmt;
va_dcl
{
int ret;
va_list ap;
va_start (ap);
ret = vfprintf (fp, fmt, ap);
va_end (ap);
return ret;
}
#endif

51
agbcc/libc/stdio/fputc.c Normal file
View File

@ -0,0 +1,51 @@
/*
FUNCTION
<<fputc>>---write a character on a stream or file
INDEX
fputc
ANSI_SYNOPSIS
#include <stdio.h>
int fputc(int <[ch]>, FILE *<[fp]>);
TRAD_SYNOPSIS
#include <stdio.h>
int fputc(<[ch]>, <[fp]>)
int <[ch]>;
FILE *<[fp]>;
DESCRIPTION
<<fputc>> converts the argument <[ch]> from an <<int>> to an
<<unsigned char>>, then writes it to the file or stream identified by
<[fp]>.
If the file was opened with append mode (or if the stream cannot
support positioning), then the new character goes at the end of the
file or stream. Otherwise, the new character is written at the
current value of the position indicator, and the position indicator
oadvances by one.
For a macro version of this function, see <<putc>>.
RETURNS
If successful, <<fputc>> returns its argument <[ch]>. If an error
intervenes, the result is <<EOF>>. You can use `<<ferror(<[fp]>)>>' to
query for errors.
PORTABILITY
<<fputc>> is required by ANSI C.
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
*/
#include <stdio.h>
int
_DEFUN (fputc, (ch, file),
int ch _AND
FILE * file)
{
return putc (ch, file);
}

71
agbcc/libc/stdio/fputs.c Normal file
View File

@ -0,0 +1,71 @@
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not 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.
*/
/*
FUNCTION
<<fputs>>---write a character string in a file or stream
INDEX
fputs
ANSI_SYNOPSIS
#include <stdio.h>
int fputs(const char *<[s]>, FILE *<[fp]>);
TRAD_SYNOPSIS
#include <stdio.h>
int fputs(<[s]>, <[fp]>)
char *<[s]>;
FILE *<[fp]>;
DESCRIPTION
<<fputs>> writes the string at <[s]> (but without the trailing null)
to the file or stream identified by <[fp]>.
RETURNS
If successful, the result is <<0>>; otherwise, the result is <<EOF>>.
PORTABILITY
ANSI C requires <<fputs>>, but does not specify that the result on
success must be <<0>>; any non-negative value is permitted.
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
*/
#include <stdio.h>
#include <string.h>
#include "fvwrite.h"
/*
* Write the given string to the given file.
*/
int
_DEFUN (fputs, (s, fp),
char _CONST * s _AND
FILE * fp)
{
struct __suio uio;
struct __siov iov;
iov.iov_base = s;
iov.iov_len = uio.uio_resid = strlen (s);
uio.uio_iov = &iov;
uio.uio_iovcnt = 1;
return __sfvwrite (fp, &uio);
}

97
agbcc/libc/stdio/fread.c Normal file
View File

@ -0,0 +1,97 @@
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not 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.
*/
/*
FUNCTION
<<fread>>---read array elements from a file
INDEX
fread
ANSI_SYNOPSIS
#include <stdio.h>
size_t fread(void *<[buf]>, size_t <[size]>, size_t <[count]>,
FILE *<[fp]>);
TRAD_SYNOPSIS
#include <stdio.h>
size_t fread(<[buf]>, <[size]>, <[count]>, <[fp]>)
char *<[buf]>;
size_t <[size]>;
size_t <[count]>;
FILE *<[fp]>;
DESCRIPTION
<<fread>> attempts to copy, from the file or stream identified by
<[fp]>, <[count]> elements (each of size <[size]>) into memory,
starting at <[buf]>. <<fread>> may copy fewer elements than
<[count]> if an error, or end of file, intervenes.
<<fread>> also advances the file position indicator (if any) for
<[fp]> by the number of @emph{characters} actually read.
RETURNS
The result of <<fread>> is the number of elements it succeeded in
reading.
PORTABILITY
ANSI C requires <<fread>>.
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
*/
#include <stdio.h>
#include <string.h>
#include "local.h"
size_t
_DEFUN (fread, (buf, size, count, fp),
_PTR buf _AND
size_t size _AND
size_t count _AND
FILE * fp)
{
register size_t resid;
register char *p;
register int r;
size_t total;
if ((resid = count * size) == 0)
return 0;
if (fp->_r < 0)
fp->_r = 0;
total = resid;
p = buf;
while (resid > (r = fp->_r))
{
(void) memcpy ((void *) p, (void *) fp->_p, (size_t) r);
fp->_p += r;
/* fp->_r = 0 ... done in __srefill */
p += r;
resid -= r;
if (__srefill (fp))
{
/* no more input: return partial result */
return (total - resid) / size;
}
}
(void) memcpy ((void *) p, (void *) fp->_p, resid);
fp->_r -= resid;
fp->_p += resid;
return count;
}

151
agbcc/libc/stdio/freopen.c Normal file
View File

@ -0,0 +1,151 @@
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not 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.
*/
/*
FUNCTION
<<freopen>>---open a file using an existing file descriptor
INDEX
freopen
ANSI_SYNOPSIS
#include <stdio.h>
FILE *freopen(const char *<[file]>, const char *<[mode]>,
FILE *<[fp]>);
TRAD_SYNOPSIS
#include <stdio.h>
FILE *freopen(<[file]>, <[mode]>, <[fp]>)
char *<[file]>;
char *<[mode]>;
FILE *<[fp]>;
DESCRIPTION
Use this variant of <<fopen>> if you wish to specify a particular file
descriptor <[fp]> (notably <<stdin>>, <<stdout>>, or <<stderr>>) for
the file.
If <[fp]> was associated with another file or stream, <<freopen>>
closes that other file or stream (but ignores any errors while closing
it).
<[file]> and <[mode]> are used just as in <<fopen>>.
RETURNS
If successful, the result is the same as the argument <[fp]>. If the
file cannot be opened as specified, the result is <<NULL>>.
PORTABILITY
ANSI C requires <<freopen>>.
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
<<lseek>>, <<open>>, <<read>>, <<sbrk>>, <<write>>.
*/
#include <time.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include "local.h"
/*
* Re-direct an existing, open (probably) file to some other file.
*/
FILE *
_DEFUN (freopen, (file, mode, fp),
_CONST char *file _AND
_CONST char *mode _AND
register FILE *fp)
{
register int f;
int flags, oflags, e;
struct _reent *ptr;
CHECK_INIT (fp);
ptr = fp->_data;
if ((flags = __sflags (ptr, mode, &oflags)) == 0)
{
(void) fclose (fp);
return NULL;
}
/*
* Remember whether the stream was open to begin with, and
* which file descriptor (if any) was associated with it.
* If it was attached to a descriptor, defer closing it,
* so that, e.g., freopen("/dev/stdin", "r", stdin) works.
* This is unnecessary if it was not a Unix file.
*/
if (fp->_flags == 0)
fp->_flags = __SEOF; /* hold on to it */
else
{
if (fp->_flags & __SWR)
(void) fflush (fp);
/* if close is NULL, closing is a no-op, hence pointless */
if (fp->_close != NULL)
(void) (*fp->_close) (fp->_cookie);
}
/*
* Now get a new descriptor to refer to the new file.
*/
f = _open_r (ptr, (char *) file, oflags, 0666);
e = ptr->_errno;
/*
* Finish closing fp. Even if the open succeeded above,
* we cannot keep fp->_base: it may be the wrong size.
* This loses the effect of any setbuffer calls,
* but stdio has always done this before.
*/
if (fp->_flags & __SMBF)
_free_r (ptr, (char *) fp->_bf._base);
fp->_w = 0;
fp->_r = 0;
fp->_p = NULL;
fp->_bf._base = NULL;
fp->_bf._size = 0;
fp->_lbfsize = 0;
if (HASUB (fp))
FREEUB (fp);
fp->_ub._size = 0;
if (HASLB (fp))
FREELB (fp);
fp->_lb._size = 0;
if (f < 0)
{ /* did not get it after all */
fp->_flags = 0; /* set it free */
ptr->_errno = e; /* restore in case _close clobbered */
return NULL;
}
fp->_flags = flags;
fp->_file = f;
fp->_cookie = (_PTR) fp;
fp->_read = __sread;
fp->_write = __swrite;
fp->_seek = __sseek;
fp->_close = __sclose;
return fp;
}

60
agbcc/libc/stdio/fscanf.c Normal file
View File

@ -0,0 +1,60 @@
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not 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.
*/
#include <_ansi.h>
#include <stdio.h>
#ifdef _HAVE_STDC
#include <stdarg.h>
extern int __svfscanf ();
int
fscanf (FILE * fp, const char *fmt, ...)
{
int ret;
va_list ap;
va_start (ap, fmt);
ret = __svfscanf (fp, fmt, ap);
va_end (ap);
return ret;
}
#else
#include <varargs.h>
extern int __svfscanf ();
int
fscanf (fp, fmt, va_alist)
FILE *fp;
char *fmt;
va_dcl
{
int ret;
va_list ap;
va_start (ap);
ret = __svfscanf (fp, fmt, ap);
va_end (ap);
return ret;
}
#endif

310
agbcc/libc/stdio/fseek.c Normal file
View File

@ -0,0 +1,310 @@
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not 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.
*/
/*
FUNCTION
<<fseek>>---set file position
INDEX
fseek
ANSI_SYNOPSIS
#include <stdio.h>
int fseek(FILE *<[fp]>, long <[offset]>, int <[whence]>)
TRAD_SYNOPSIS
#include <stdio.h>
int fseek(<[fp]>, <[offset]>, <[whence]>)
FILE *<[fp]>;
long <[offset]>;
int <[whence]>;
DESCRIPTION
Objects of type <<FILE>> can have a ``position'' that records how much
of the file your program has already read. Many of the <<stdio>> functions
depend on this position, and many change it as a side effect.
You can use <<fseek>> to set the position for the file identified by
<[fp]>. The value of <[offset]> determines the new position, in one
of three ways selected by the value of <[whence]> (defined as macros
in `<<stdio.h>>'):
<<SEEK_SET>>---<[offset]> is the absolute file position (an offset
from the beginning of the file) desired. <[offset]> must be positive.
<<SEEK_CUR>>---<[offset]> is relative to the current file position.
<[offset]> can meaningfully be either positive or negative.
<<SEEK_END>>---<[offset]> is relative to the current end of file.
<[offset]> can meaningfully be either positive (to increase the size
of the file) or negative.
See <<ftell>> to determine the current file position.
RETURNS
<<fseek>> returns <<0>> when successful. If <<fseek>> fails, the
result is <<EOF>>. The reason for failure is indicated in <<errno>>:
either <<ESPIPE>> (the stream identified by <[fp]> doesn't support
repositioning) or <<EINVAL>> (invalid file position).
PORTABILITY
ANSI C requires <<fseek>>.
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
*/
#include <stdio.h>
#include <time.h>
#include <fcntl.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/stat.h>
#include "local.h"
#define POS_ERR (-(fpos_t)1)
/*
* Seek the given file to the given offset.
* `Whence' must be one of the three SEEK_* macros.
*/
int
fseek (fp, offset, whence)
register FILE *fp;
long offset;
int whence;
{
struct _reent *ptr;
fpos_t _EXFUN ((*seekfn), (void *, fpos_t, int));
fpos_t target, curoff;
size_t n;
struct stat st;
int havepos;
/* Make sure stdio is set up. */
CHECK_INIT (fp);
ptr = fp->_data;
/* If we've been doing some writing, and we're in append mode
then we don't really know where the filepos is. */
if (fp->_flags & __SAPP && fp->_flags & __SWR)
{
/* So flush the buffer and seek to the end. */
fflush (fp);
}
/* Have to be able to seek. */
if ((seekfn = fp->_seek) == NULL)
{
ptr->_errno = ESPIPE; /* ??? */
return EOF;
}
/*
* Change any SEEK_CUR to SEEK_SET, and check `whence' argument.
* After this, whence is either SEEK_SET or SEEK_END.
*/
switch (whence)
{
case SEEK_CUR:
/*
* In order to seek relative to the current stream offset,
* we have to first find the current stream offset a la
* ftell (see ftell for details).
*/
fflush(fp); /* may adjust seek offset on append stream */
if (fp->_flags & __SOFF)
curoff = fp->_offset;
else
{
curoff = (*seekfn) (fp->_cookie, (fpos_t) 0, SEEK_CUR);
if (curoff == -1L)
return EOF;
}
if (fp->_flags & __SRD)
{
curoff -= fp->_r;
if (HASUB (fp))
curoff -= fp->_ur;
}
else if (fp->_flags & __SWR && fp->_p != NULL)
curoff += fp->_p - fp->_bf._base;
offset += curoff;
whence = SEEK_SET;
havepos = 1;
break;
case SEEK_SET:
case SEEK_END:
havepos = 0;
break;
default:
ptr->_errno = EINVAL;
return (EOF);
}
/*
* Can only optimise if:
* reading (and not reading-and-writing);
* not unbuffered; and
* this is a `regular' Unix file (and hence seekfn==__sseek).
* We must check __NBF first, because it is possible to have __NBF
* and __SOPT both set.
*/
if (fp->_bf._base == NULL)
__smakebuf (fp);
if (fp->_flags & (__SWR | __SRW | __SNBF | __SNPT))
goto dumb;
if ((fp->_flags & __SOPT) == 0)
{
if (seekfn != __sseek
|| fp->_file < 0
|| _fstat_r (ptr, fp->_file, &st)
|| (st.st_mode & S_IFMT) != S_IFREG)
{
fp->_flags |= __SNPT;
goto dumb;
}
#ifdef HAVE_BLKSIZE
fp->_blksize = st.st_blksize;
#else
fp->_blksize = 1024;
#endif
fp->_flags |= __SOPT;
}
/*
* We are reading; we can try to optimise.
* Figure out where we are going and where we are now.
*/
if (whence == SEEK_SET)
target = offset;
else
{
if (_fstat_r (ptr, fp->_file, &st))
goto dumb;
target = st.st_size + offset;
}
if (!havepos)
{
if (fp->_flags & __SOFF)
curoff = fp->_offset;
else
{
curoff = (*seekfn) (fp->_cookie, 0L, SEEK_CUR);
if (curoff == POS_ERR)
goto dumb;
}
curoff -= fp->_r;
if (HASUB (fp))
curoff -= fp->_ur;
}
/*
* Compute the number of bytes in the input buffer (pretending
* that any ungetc() input has been discarded). Adjust current
* offset backwards by this count so that it represents the
* file offset for the first byte in the current input buffer.
*/
if (HASUB (fp))
{
curoff += fp->_r; /* kill off ungetc */
n = fp->_up - fp->_bf._base;
curoff -= n;
n += fp->_ur;
}
else
{
n = fp->_p - fp->_bf._base;
curoff -= n;
n += fp->_r;
}
/*
* If the target offset is within the current buffer,
* simply adjust the pointers, clear EOF, undo ungetc(),
* and return. (If the buffer was modified, we have to
* skip this; see fgetline.c.)
*/
if ((fp->_flags & __SMOD) == 0 &&
target >= curoff && target < curoff + n)
{
register int o = target - curoff;
fp->_p = fp->_bf._base + o;
fp->_r = n - o;
if (HASUB (fp))
FREEUB (fp);
fp->_flags &= ~__SEOF;
return 0;
}
/*
* The place we want to get to is not within the current buffer,
* but we can still be kind to the kernel copyout mechanism.
* By aligning the file offset to a block boundary, we can let
* the kernel use the VM hardware to map pages instead of
* copying bytes laboriously. Using a block boundary also
* ensures that we only read one block, rather than two.
*/
curoff = target & ~(fp->_blksize - 1);
if ((*seekfn) (fp->_cookie, curoff, SEEK_SET) == POS_ERR)
goto dumb;
fp->_r = 0;
if (HASUB (fp))
FREEUB (fp);
fp->_flags &= ~__SEOF;
n = target - curoff;
if (n)
{
if (__srefill (fp) || fp->_r < n)
goto dumb;
fp->_p += n;
fp->_r -= n;
}
return 0;
/*
* We get here if we cannot optimise the seek ... just
* do it. Allow the seek function to change fp->_bf._base.
*/
dumb:
if (fflush (fp) || (*seekfn) (fp->_cookie, offset, whence) == POS_ERR)
return EOF;
/* success: clear EOF indicator and discard ungetc() data */
if (HASUB (fp))
FREEUB (fp);
fp->_p = fp->_bf._base;
fp->_r = 0;
/* fp->_w = 0; *//* unnecessary (I think...) */
fp->_flags &= ~__SEOF;
return 0;
}

View File

@ -0,0 +1,54 @@
/*
FUNCTION
<<fsetpos>>---restore position of a stream or file
INDEX
fsetpos
ANSI_SYNOPSIS
#include <stdio.h>
int fsetpos(FILE *<[fp]>, const fpos_t *<[pos]>);
TRAD_SYNOPSIS
#include <stdio.h>
int fsetpos(<[fp]>, <[pos]>)
FILE *<[fp]>;
fpos_t *<[pos]>;
DESCRIPTION
Objects of type <<FILE>> can have a ``position'' that records how much
of the file your program has already read. Many of the <<stdio>> functions
depend on this position, and many change it as a side effect.
You can use <<fsetpos>> to return the file identified by <[fp]> to a previous
position <<*<[pos]>>> (after first recording it with <<fgetpos>>).
See <<fseek>> for a similar facility.
RETURNS
<<fgetpos>> returns <<0>> when successful. If <<fgetpos>> fails, the
result is <<1>>. The reason for failure is indicated in <<errno>>:
either <<ESPIPE>> (the stream identified by <[fp]> doesn't support
repositioning) or <<EINVAL>> (invalid file position).
PORTABILITY
ANSI C requires <<fsetpos>>, but does not specify the nature of
<<*<[pos]>>> beyond identifying it as written by <<fgetpos>>.
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
*/
#include <stdio.h>
int
_DEFUN (fsetpos, (iop, pos),
FILE * iop _AND
_CONST fpos_t * pos)
{
int x = fseek (iop, *pos, SEEK_SET);
if (x != 0)
return 1;
return 0;
}

126
agbcc/libc/stdio/ftell.c Normal file
View File

@ -0,0 +1,126 @@
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not 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.
*/
/*
FUNCTION
<<ftell>>---return position in a stream or file
INDEX
ftell
ANSI_SYNOPSIS
#include <stdio.h>
long ftell(FILE *<[fp]>);
TRAD_SYNOPSIS
#include <stdio.h>
long ftell(<[fp]>)
FILE *<[fp]>;
DESCRIPTION
Objects of type <<FILE>> can have a ``position'' that records how much
of the file your program has already read. Many of the <<stdio>> functions
depend on this position, and many change it as a side effect.
The result of <<ftell>> is the current position for a file
identified by <[fp]>. If you record this result, you can later
use it with <<fseek>> to return the file to this
position.
In the current implementation, <<ftell>> simply uses a character
count to represent the file position; this is the same number that
would be recorded by <<fgetpos>>.
RETURNS
<<ftell>> returns the file position, if possible. If it cannot do
this, it returns <<-1L>>. Failure occurs on streams that do not support
positioning; the global <<errno>> indicates this condition with the
value <<ESPIPE>>.
PORTABILITY
<<ftell>> is required by the ANSI C standard, but the meaning of its
result (when successful) is not specified beyond requiring that it be
acceptable as an argument to <<fseek>>. In particular, other
conforming C implementations may return a different result from
<<ftell>> than what <<fgetpos>> records.
No supporting OS subroutines are required.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "%W% (Berkeley) %G%";
#endif /* LIBC_SCCS and not lint */
/*
* ftell: return current offset.
*/
#include <stdio.h>
#include <errno.h>
#include "local.h"
long
_DEFUN (ftell, (fp),
register FILE * fp)
{
fpos_t pos;
/* Ensure stdio is set up. */
CHECK_INIT (fp);
if (fp->_seek == NULL)
{
fp->_data->_errno = ESPIPE;
return -1L;
}
/* Find offset of underlying I/O object, then
adjust for buffered bytes. */
fflush(fp); /* may adjust seek offset on append stream */
if (fp->_flags & __SOFF)
pos = fp->_offset;
else
{
pos = (*fp->_seek) (fp->_cookie, (fpos_t) 0, SEEK_CUR);
if (pos == -1L)
return pos;
}
if (fp->_flags & __SRD)
{
/*
* Reading. Any unread characters (including
* those from ungetc) cause the position to be
* smaller than that in the underlying object.
*/
pos -= fp->_r;
if (HASUB (fp))
pos -= fp->_ur;
}
else if (fp->_flags & __SWR && fp->_p != NULL)
{
/*
* Writing. Any buffered characters cause the
* position to be greater than that in the
* underlying object.
*/
pos += fp->_p - fp->_bf._base;
}
return pos;
}

195
agbcc/libc/stdio/fvwrite.c Normal file
View File

@ -0,0 +1,195 @@
/* No user fns here. Pesch 15apr92. */
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not 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.
*/
#include <stdio.h>
#include <string.h>
#include "local.h"
#include "fvwrite.h"
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define COPY(n) (void) memmove((void *) fp->_p, (void *) p, (size_t) (n))
#define GETIOV(extra_work) \
while (len == 0) \
{ \
extra_work; \
p = iov->iov_base; \
len = iov->iov_len; \
iov++; \
}
/*
* Write some memory regions. Return zero on success, EOF on error.
*
* This routine is large and unsightly, but most of the ugliness due
* to the three different kinds of output buffering is handled here.
*/
int
__sfvwrite (fp, uio)
register FILE *fp;
register struct __suio *uio;
{
register size_t len;
register _CONST char *p;
register struct __siov *iov;
register int w, s;
char *nl;
int nlknown, nldist;
if ((len = uio->uio_resid) == 0)
return 0;
/* make sure we can write */
if (cantwrite (fp))
return EOF;
iov = uio->uio_iov;
len = 0;
if (fp->_flags & __SNBF)
{
/*
* Unbuffered: write up to BUFSIZ bytes at a time.
*/
do
{
GETIOV (;);
w = (*fp->_write) (fp->_cookie, p, MIN (len, BUFSIZ));
if (w <= 0)
goto err;
p += w;
len -= w;
}
while ((uio->uio_resid -= w) != 0);
}
else if ((fp->_flags & __SLBF) == 0)
{
/*
* Fully buffered: fill partially full buffer, if any,
* and then flush. If there is no partial buffer, write
* one _bf._size byte chunk directly (without copying).
*
* String output is a special case: write as many bytes
* as fit, but pretend we wrote everything. This makes
* snprintf() return the number of bytes needed, rather
* than the number used, and avoids its write function
* (so that the write function can be invalid).
*/
do
{
GETIOV (;);
w = fp->_w;
if (fp->_flags & __SSTR)
{
if (len < w)
w = len;
COPY (w); /* copy MIN(fp->_w,len), */
fp->_w -= w;
fp->_p += w;
w = len; /* but pretend copied all */
}
else if (fp->_p > fp->_bf._base && len > w)
{
/* fill and flush */
COPY (w);
/* fp->_w -= w; *//* unneeded */
fp->_p += w;
if (fflush (fp))
goto err;
}
else if (len >= (w = fp->_bf._size))
{
/* write directly */
w = (*fp->_write) (fp->_cookie, p, w);
if (w <= 0)
goto err;
}
else
{
/* fill and done */
w = len;
COPY (w);
fp->_w -= w;
fp->_p += w;
}
p += w;
len -= w;
}
while ((uio->uio_resid -= w) != 0);
}
else
{
/*
* Line buffered: like fully buffered, but we
* must check for newlines. Compute the distance
* to the first newline (including the newline),
* or `infinity' if there is none, then pretend
* that the amount to write is MIN(len,nldist).
*/
nlknown = 0;
do
{
GETIOV (nlknown = 0);
if (!nlknown)
{
nl = memchr ((void *) p, '\n', len);
nldist = nl ? nl + 1 - p : len + 1;
nlknown = 1;
}
s = MIN (len, nldist);
w = fp->_w + fp->_bf._size;
if (fp->_p > fp->_bf._base && s > w)
{
COPY (w);
/* fp->_w -= w; */
fp->_p += w;
if (fflush (fp))
goto err;
}
else if (s >= (w = fp->_bf._size))
{
w = (*fp->_write) (fp->_cookie, p, w);
if (w <= 0)
goto err;
}
else
{
w = s;
COPY (w);
fp->_w -= w;
fp->_p += w;
}
if ((nldist -= w) == 0)
{
/* copied the newline: flush and forget */
if (fflush (fp))
goto err;
nlknown = 0;
}
p += w;
len -= w;
}
while ((uio->uio_resid -= w) != 0);
}
return 0;
err:
fp->_flags |= __SERR;
return EOF;
}

View File

@ -0,0 +1,38 @@
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not 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.
*/
/* %W% (Berkeley) %G% */
#include <_ansi.h>
/*
* I/O descriptors for __sfvwrite().
*/
struct __siov {
_CONST _PTR iov_base;
size_t iov_len;
};
struct __suio {
struct __siov *uio_iov;
int uio_iovcnt;
int uio_resid;
};
extern int _EXFUN(__sfvwrite,(FILE *, struct __suio *));
extern int _EXFUN(__swsetup,(FILE *));

43
agbcc/libc/stdio/fwalk.c Normal file
View File

@ -0,0 +1,43 @@
/* No user fns here. Pesch 15apr92. */
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not 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.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "%W% (Berkeley) %G%";
#endif /* LIBC_SCCS and not lint */
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include "local.h"
int
_fwalk (ptr, function)
struct _reent *ptr;
register int (*function) ();
{
register FILE *fp;
register int n, ret = 0;
register struct _glue *g;
for (g = &ptr->__sglue; g != NULL; g = g->_next)
for (fp = g->_iobs, n = g->_niobs; --n >= 0; fp++)
if (fp->_flags != 0)
ret |= (*function) (fp);
return ret;
}

104
agbcc/libc/stdio/fwrite.c Normal file
View File

@ -0,0 +1,104 @@
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not 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.
*/
/*
FUNCTION
<<fwrite>>---write array elements
INDEX
fwrite
ANSI_SYNOPSIS
#include <stdio.h>
size_t fwrite(const void *<[buf]>, size_t <[size]>,
size_t <[count]>, FILE *<[fp]>);
TRAD_SYNOPSIS
#include <stdio.h>
size_t fwrite(<[buf]>, <[size]>, <[count]>, <[fp]>)
char *<[buf]>;
size_t <[size]>;
size_t <[count]>;
FILE *<[fp]>;
DESCRIPTION
<<fwrite>> attempts to copy, starting from the memory location
<[buf]>, <[count]> elements (each of size <[size]>) into the file or
stream identified by <[fp]>. <<fwrite>> may copy fewer elements than
<[count]> if an error intervenes.
<<fwrite>> also advances the file position indicator (if any) for
<[fp]> by the number of @emph{characters} actually written.
RETURNS
If <<fwrite>> succeeds in writing all the elements you specify, the
result is the same as the argument <[count]>. In any event, the
result is the number of complete elements that <<fwrite>> copied to
the file.
PORTABILITY
ANSI C requires <<fwrite>>.
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "%W% (Berkeley) %G%";
#endif /* LIBC_SCCS and not lint */
#include <stdio.h>
#include <string.h>
#if 0
#include <sys/stdc.h>
#endif
#include "local.h"
#if 1
#include "fvwrite.h"
#endif
/*
* Write `count' objects (each size `size') from memory to the given file.
* Return the number of whole objects written.
*/
size_t
_DEFUN (fwrite, (buf, size, count, fp),
_CONST _PTR buf _AND
size_t size _AND
size_t count _AND
FILE * fp)
{
size_t n;
struct __suio uio;
struct __siov iov;
iov.iov_base = buf;
uio.uio_resid = iov.iov_len = n = count * size;
uio.uio_iov = &iov;
uio.uio_iovcnt = 1;
/*
* The usual case is success (__sfvwrite returns 0);
* skip the divide if this happens, since divides are
* generally slow and since this occurs whenever size==0.
*/
if (__sfvwrite (fp, &uio) == 0)
return count;
return (n - uio.uio_resid) / size;
}

80
agbcc/libc/stdio/getc.c Normal file
View File

@ -0,0 +1,80 @@
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not 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.
*/
/*
FUNCTION
<<getc>>---read a character (macro)
INDEX
getc
ANSI_SYNOPSIS
#include <stdio.h>
int getc(FILE *<[fp]>);
TRAD_SYNOPSIS
#include <stdio.h>
int getc(<[fp]>)
FILE *<[fp]>;
DESCRIPTION
<<getc>> is a macro, defined in <<stdio.h>>. You can use <<getc>>
to get the next single character from the file or stream
identified by <[fp]>. As a side effect, <<getc>> advances the file's
current position indicator.
For a subroutine version of this macro, see <<fgetc>>.
RETURNS
The next character (read as an <<unsigned char>>, and cast to
<<int>>), unless there is no more data, or the host system reports a
read error; in either of these situations, <<getc>> returns <<EOF>>.
You can distinguish the two situations that cause an <<EOF>> result by
using the <<ferror>> and <<feof>> functions.
PORTABILITY
ANSI C requires <<getc>>; it suggests, but does not require, that
<<getc>> be implemented as a macro. The standard explicitly permits
macro implementations of <<getc>> to use the argument more than once;
therefore, in a portable program, you should not use an expression
with side effects as the <<getc>> argument.
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "%W% (Berkeley) %G%";
#endif /* LIBC_SCCS and not lint */
#include <stdio.h>
/*
* A subroutine version of the macro getc.
*/
#undef getc
int
getc (fp)
register FILE *fp;
{
/* CHECK_INIT is called (eventually) by __srefill. */
return __sgetc (fp);
}

View File

@ -0,0 +1,96 @@
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not 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.
*/
/*
FUNCTION
<<getchar>>---read a character (macro)
INDEX
getchar
INDEX
_getchar_r
ANSI_SYNOPSIS
#include <stdio.h>
int getchar(void);
int _getchar_r(void *<[reent]>);
TRAD_SYNOPSIS
#include <stdio.h>
int getchar();
int _getchar_r(<[reent]>)
char * <[reent]>;
DESCRIPTION
<<getchar>> is a macro, defined in <<stdio.h>>. You can use <<getchar>>
to get the next single character from the standard input stream.
As a side effect, <<getchar>> advances the standard input's
current position indicator.
The alternate function <<_getchar_r>> is a reentrant version. The
extra argument <[reent]> is a pointer to a reentrancy structure.
RETURNS
The next character (read as an <<unsigned char>>, and cast to
<<int>>), unless there is no more data, or the host system reports a
read error; in either of these situations, <<getchar>> returns <<EOF>>.
You can distinguish the two situations that cause an <<EOF>> result by
using `<<ferror(stdin)>>' and `<<feof(stdin)>>'.
PORTABILITY
ANSI C requires <<getchar>>; it suggests, but does not require, that
<<getchar>> be implemented as a macro.
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "%W% (Berkeley) %G%";
#endif /* LIBC_SCCS and not lint */
/*
* A subroutine version of the macro getchar.
*/
#include <stdio.h>
#include <reent.h>
#undef getchar
int
_getchar_r (f)
struct _reent *f;
{
return getc (_stdin_r (f));
}
#ifndef _REENT_ONLY
int
getchar ()
{
/* CHECK_INIT is called (eventually) by __srefill. */
return _getchar_r (_REENT);
}
#endif

102
agbcc/libc/stdio/gets.c Normal file
View File

@ -0,0 +1,102 @@
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not 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.
*/
/*
FUNCTION
<<gets>>---get character string (obsolete, use <<fgets>> instead)
INDEX
gets
INDEX
_gets_r
ANSI_SYNOPSIS
#include <stdio.h>
char *gets(char *<[buf]>);
char *_gets_r(void *<[reent]>, char *<[buf]>);
TRAD_SYNOPSIS
#include <stdio.h>
char *gets(<[buf]>)
char *<[buf]>;
char *_gets_r(<[reent]>, <[buf]>)
char *<[reent]>;
char *<[buf]>;
DESCRIPTION
Reads characters from standard input until a newline is found.
The characters up to the newline are stored in <[buf]>. The
newline is discarded, and the buffer is terminated with a 0.
This is a @emph{dangerous} function, as it has no way of checking
the amount of space available in <[buf]>. One of the attacks
used by the Internet Worm of 1988 used this to overrun a
buffer allocated on the stack of the finger daemon and
overwrite the return address, causing the daemon to execute
code downloaded into it over the connection.
The alternate function <<_gets_r>> is a reentrant version. The extra
argument <[reent]> is a pointer to a reentrancy structure.
RETURNS
<<gets>> returns the buffer passed to it, with the data filled
in. If end of file occurs with some data already accumulated,
the data is returned with no other indication. If end of file
occurs with no data in the buffer, NULL is returned.
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
*/
#include <stdio.h>
char *
_gets_r (ptr, buf)
struct _reent *ptr;
char *buf;
{
register int c;
register char *s = buf;
while ((c = _getchar_r (ptr)) != '\n')
if (c == EOF)
if (s == buf)
return NULL;
else
break;
else
*s++ = c;
*s = 0;
return buf;
}
#ifndef _REENT_ONLY
char *
gets (buf)
char *buf;
{
return _gets_r (_REENT, buf);
}
#endif

118
agbcc/libc/stdio/iprintf.c Normal file
View File

@ -0,0 +1,118 @@
/*
FUNCTION
<<iprintf>>---write formatted output (integer only)
INDEX
iprintf
ANSI_SYNOPSIS
#include <stdio.h>
int iprintf(const char *<[format]>, ...);
TRAD_SYNOPSIS
#include <stdio.h>
int iprintf(<[format]> [, <[arg]>, ...])
char *<[format]>;
DESCRIPTION
<<iprintf>> is a restricted version of <<printf>>: it has the same
arguments and behavior, save that it cannot perform any floating-point
formatting: the <<f>>, <<g>>, <<G>>, <<e>>, and <<F>> type specifiers
are not recognized.
RETURNS
<<iprintf>> returns the number of bytes in the output string,
save that the concluding <<NULL>> is not counted.
<<iprintf>> returns when the end of the format string is
encountered. If an error occurs, <<iprintf>>
returns <<EOF>>.
PORTABILITY
<<iprintf>> is not required by ANSI C.
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
*/
#include <_ansi.h>
#include <stdio.h>
#ifndef _REENT_ONLY
#ifdef _HAVE_STDC
#include <stdarg.h>
int
iprintf (const char *fmt,...)
{
int ret;
va_list ap;
va_start (ap, fmt);
_stdout_r (_REENT)->_data = _REENT;
ret = vfiprintf (stdout, fmt, ap);
va_end (ap);
return ret;
}
#else
#include <varargs.h>
int
iprintf (fmt, va_alist)
char *fmt;
va_dcl
{
int ret;
va_list ap;
va_start (ap);
_stdout_r (_REENT)->_data = _REENT;
ret = vfiprintf (stdout, fmt, ap);
va_end (ap);
return ret;
}
#endif /* ! _HAVE_STDC */
#endif /* ! _REENT_ONLY */
#ifdef _HAVE_STDC
#include <stdarg.h>
int
_iprintf_r (struct _reent *ptr, const char *fmt, ...)
{
int ret;
va_list ap;
va_start (ap, fmt);
ret = vfiprintf (_stdout_r (ptr), fmt, ap);
va_end (ap);
return ret;
}
#else
#include <varargs.h>
int
_iprintf_r (data, fmt, va_alist)
char *data;
char *fmt;
va_dcl
{
int ret;
struct _reent *ptr = data;
va_list ap;
va_start (ap);
ret = vfiprintf (_stdout_r (ptr), fmt, ap);
va_end (ap);
return ret;
}
#endif

90
agbcc/libc/stdio/local.h Normal file
View File

@ -0,0 +1,90 @@
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not 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.
*
* %W% (UofMD/Berkeley) %G%
*/
/*
* Information local to this implementation of stdio,
* in particular, macros and private variables.
*/
#include <_ansi.h>
#include <stdarg.h>
#include <reent.h>
#include <unistd.h>
extern int _EXFUN(__svfscanf,(FILE *, _CONST char *,va_list));
extern FILE *_EXFUN(__sfp,(struct _reent *));
extern int _EXFUN(__sflags,(struct _reent *,_CONST char*, int*));
extern int _EXFUN(__srefill,(FILE *));
extern int _EXFUN(__sread,(void *, char *, int));
extern int _EXFUN(__swrite,(void *, char const *, int));
extern fpos_t _EXFUN(__sseek,(void *, fpos_t, int));
extern int _EXFUN(__sclose,(void *));
extern void _EXFUN(__sinit,(struct _reent *));
extern void _EXFUN(_cleanup_r,(struct _reent *));
extern void _EXFUN(__smakebuf,(FILE *));
extern int _EXFUN(_fwalk,(struct _reent *, int (*)(FILE *)));
struct _glue * _EXFUN(__sfmoreglue,(struct _reent *,int n));
extern int _EXFUN(__srefill,(FILE *fp));
/* Called by the main entry point fns to ensure stdio has been initialized. */
#define CHECK_INIT(fp) \
do \
{ \
if ((fp)->_data == 0) \
(fp)->_data = _REENT; \
if (!(fp)->_data->__sdidinit) \
__sinit ((fp)->_data); \
} \
while (0)
/* Return true iff the given FILE cannot be written now. */
#define cantwrite(fp) \
((((fp)->_flags & __SWR) == 0 || (fp)->_bf._base == NULL) && \
__swsetup(fp))
/* Test whether the given stdio file has an active ungetc buffer;
release such a buffer, without restoring ordinary unread data. */
#define HASUB(fp) ((fp)->_ub._base != NULL)
#define FREEUB(fp) { \
if ((fp)->_ub._base != (fp)->_ubuf) \
_free_r(fp->_data, (char *)(fp)->_ub._base); \
(fp)->_ub._base = NULL; \
}
/* Test for an fgetline() buffer. */
#define HASLB(fp) ((fp)->_lb._base != NULL)
#define FREELB(fp) { _free_r(fp->_data,(char *)(fp)->_lb._base); (fp)->_lb._base = NULL; }
/* WARNING: _dcvt is defined in the stdlib directory, not here! */
char *_EXFUN(_dcvt,(struct _reent *, char *, double, int, int, char, int));
char *_EXFUN(_sicvt,(char *, short, char));
char *_EXFUN(_icvt,(char *, int, char));
char *_EXFUN(_licvt,(char *, long, char));
#ifdef __GNUC__
char *_EXFUN(_llicvt,(char *, long long, char));
#endif
#define CVT_BUF_SIZE 128
#define NDYNAMIC 4 /* add four more whenever necessary */

View File

@ -0,0 +1,96 @@
/* No user fns here. Pesch 15apr92. */
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not 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.
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/unistd.h>
#include "local.h"
/*
* Allocate a file buffer, or switch to unbuffered I/O.
* Per the ANSI C standard, ALL tty devices default to line buffered.
*
* As a side effect, we set __SOPT or __SNPT (en/dis-able fseek
* optimization) right after the _fstat() that finds the buffer size.
*/
void
__smakebuf (fp)
register FILE *fp;
{
register size_t size, couldbetty;
register _PTR p;
struct stat st;
if (fp->_flags & __SNBF)
{
fp->_bf._base = fp->_p = fp->_nbuf;
fp->_bf._size = 1;
return;
}
if (fp->_file < 0 || _fstat_r (fp->_data, fp->_file, &st) < 0)
{
couldbetty = 0;
size = BUFSIZ;
/* do not try to optimise fseek() */
fp->_flags |= __SNPT;
}
else
{
couldbetty = (st.st_mode & S_IFMT) == S_IFCHR;
#ifdef HAVE_BLKSIZE
size = st.st_blksize <= 0 ? BUFSIZ : st.st_blksize;
#else
size = BUFSIZ;
#endif
/*
* Optimize fseek() only if it is a regular file.
* (The test for __sseek is mainly paranoia.)
*/
if ((st.st_mode & S_IFMT) == S_IFREG && fp->_seek == __sseek)
{
fp->_flags |= __SOPT;
#ifdef HAVE_BLKSIZE
fp->_blksize = st.st_blksize;
#else
fp->_blksize = 1024;
#endif
}
else
fp->_flags |= __SNPT;
}
if ((p = _malloc_r (fp->_data, size)) == NULL)
{
fp->_flags |= __SNBF;
fp->_bf._base = fp->_p = fp->_nbuf;
fp->_bf._size = 1;
}
else
{
fp->_data->__cleanup = _cleanup_r;
fp->_flags |= __SMBF;
fp->_bf._base = fp->_p = (unsigned char *) p;
fp->_bf._size = size;
if (couldbetty && isatty (fp->_file))
fp->_flags |= __SLBF;
}
}

215
agbcc/libc/stdio/mktemp.c Normal file
View File

@ -0,0 +1,215 @@
/* This is file MKTEMP.C */
/* This file may have been modified by DJ Delorie (Jan 1991). If so,
** these modifications are Coyright (C) 1991 DJ Delorie, 24 Kirsten Ave,
** Rochester NH, 03867-2954, USA.
*/
/*
* Copyright (c) 1987 Regents of the University of California.
* All rights reserved.
*
* 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.
*/
/*
FUNCTION
<<mktemp>>, <<mkstemp>>---generate unused file name
INDEX
mktemp
INDEX
mkstemp
INDEX
_mktemp_r
INDEX
_mkstemp_r
ANSI_SYNOPSIS
#include <stdio.h>
char *mktemp(char *<[path]>);
int mkstemp(char *<[path]>);
char *_mktemp_r(void *<[reent]>, char *<[path]>);
int *_mkstemp_r(void *<[reent]>, char *<[path]>);
TRAD_SYNOPSIS
#include <stdio.h>
char *mktemp(<[path]>)
char *<[path]>;
int mkstemp(<[path]>)
char *<[path]>;
char *_mktemp_r(<[reent]>, <[path]>)
char *<[reent]>;
char *<[path]>;
int _mkstemp_r(<[reent]>, <[path]>)
char *<[reent]>;
char *<[path]>;
DESCRIPTION
<<mktemp>> and <<mkstemp>> attempt to generate a file name that is not
yet in use for any existing file. <<mkstemp>> creates the file and
opens it for reading and writing; <<mktemp>> simply generates the file name.
You supply a simple pattern for the generated file name, as the string
at <[path]>. The pattern should be a valid filename (including path
information if you wish) ending with some number of `<<X>>'
characters. The generated filename will match the leading part of the
name you supply, with the trailing `<<X>>' characters replaced by some
combination of digits and letters.
The alternate functions <<_mktemp_r>> and <<_mkstemp_r>> are reentrant
versions. The extra argument <[reent]> is a pointer to a reentrancy
structure.
RETURNS
<<mktemp>> returns the pointer <[path]> to the modified string
representing an unused filename, unless it could not generate one, or
the pattern you provided is not suitable for a filename; in that case,
it returns <<NULL>>.
<<mkstemp>> returns a file descriptor to the newly created file,
unless it could not generate an unused filename, or the pattern you
provided is not suitable for a filename; in that case, it returns
<<-1>>.
PORTABILITY
ANSI C does not require either <<mktemp>> or <<mkstemp>>; the System
V Interface Definition requires <<mktemp>> as of Issue 2.
Supporting OS subroutines required: <<getpid>>, <<open>>, <<stat>>.
*/
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdio.h>
#include <ctype.h>
#include <reent.h>
static
_DEFUN (_gettemp, (ptr, path, doopen),
struct _reent *ptr _AND
char *path _AND
register int *doopen)
{
register char *start, *trv;
struct stat sbuf;
unsigned int pid;
pid = _getpid_r (ptr);
for (trv = path; *trv; ++trv) /* extra X's get set to 0's */
continue;
while (*--trv == 'X')
{
*trv = (pid % 10) + '0';
pid /= 10;
}
/*
* Check the target directory; if you have six X's and it
* doesn't exist this runs for a *very* long time.
*/
for (start = trv + 1;; --trv)
{
if (trv <= path)
break;
if (*trv == '/')
{
*trv = '\0';
if (_stat_r (ptr, path, &sbuf))
return (0);
if (!(sbuf.st_mode & S_IFDIR))
{
ptr->_errno = ENOTDIR;
return (0);
}
*trv = '/';
break;
}
}
for (;;)
{
if (doopen)
{
if ((*doopen = _open_r (ptr, path, O_CREAT | O_EXCL | O_RDWR, 0600))
>= 0)
return 1;
if (ptr->_errno != EEXIST)
return 0;
}
else if (_stat_r (ptr, path, &sbuf))
return (ptr->_errno == ENOENT ? 1 : 0);
/* tricky little algorithm for backward compatibility */
for (trv = start;;)
{
if (!*trv)
return 0;
if (*trv == 'z')
*trv++ = 'a';
else
{
if (isdigit (*trv))
*trv = 'a';
else
++ * trv;
break;
}
}
}
/*NOTREACHED*/
}
_DEFUN (_mkstemp_r, (ptr, path),
struct _reent *ptr _AND
char *path)
{
int fd;
return (_gettemp (ptr, path, &fd) ? fd : -1);
}
char *
_DEFUN (_mktemp_r, (ptr, path),
struct _reent *ptr _AND
char *path)
{
return (_gettemp (ptr, path, (int *) NULL) ? path : (char *) NULL);
}
#ifndef _REENT_ONLY
_DEFUN (mkstemp, (path),
char *path)
{
int fd;
return (_gettemp (_REENT, path, &fd) ? fd : -1);
}
char *
_DEFUN (mktemp, (path),
char *path)
{
return (_gettemp (_REENT, path, (int *) NULL) ? path : (char *) NULL);
}
#endif /* ! defined (_REENT_ONLY) */

80
agbcc/libc/stdio/perror.c Normal file
View File

@ -0,0 +1,80 @@
/*
FUNCTION
<<perror>>---print an error message on standard error
INDEX
perror
INDEX
_perror_r
ANSI_SYNOPSIS
#include <stdio.h>
void perror(char *<[prefix]>);
void _perror_r(void *<[reent]>, char *<[prefix]>);
TRAD_SYNOPSIS
#include <stdio.h>
void perror(<[prefix]>)
char *<[prefix]>;
void _perror_r(<[reent]>, <[prefix]>)
char *<[reent]>;
char *<[prefix]>;
DESCRIPTION
Use <<perror>> to print (on standard error) an error message
corresponding to the current value of the global variable <<errno>>.
Unless you use <<NULL>> as the value of the argument <[prefix]>, the
error message will begin with the string at <[prefix]>, followed by a
colon and a space (<<: >>). The remainder of the error message is one
of the strings described for <<strerror>>.
The alternate function <<_perror_r>> is a reentrant version. The
extra argument <[reent]> is a pointer to a reentrancy structure.
RETURNS
<<perror>> returns no result.
PORTABILITY
ANSI C requires <<perror>>, but the strings issued vary from one
implementation to another.
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
*/
#include <stddef.h>
#include <stdio.h>
#include <string.h>
void
_DEFUN (_perror_r, (ptr, s),
struct _reent *ptr _AND
_CONST char *s)
{
char *error;
if (s != NULL && *s != '\0')
{
fputs (s, _stderr_r (ptr));
fputs (": ", _stderr_r (ptr));
}
if ((error = strerror (ptr->_errno)) != NULL)
fputs (error, _stderr_r (ptr));
fputc ('\n', _stderr_r (ptr));
}
#ifndef _REENT_ONLY
void
_DEFUN (perror, (s),
_CONST char *s)
{
_perror_r (_REENT, s);
}
#endif

83
agbcc/libc/stdio/printf.c Normal file
View File

@ -0,0 +1,83 @@
#include <_ansi.h>
#include <stdio.h>
#ifdef _HAVE_STDC
#include <stdarg.h>
int
_printf_r (struct _reent *ptr, const char *fmt, ...)
{
int ret;
va_list ap;
va_start (ap, fmt);
ret = _vfprintf_r (ptr, _stdout_r (ptr), fmt, ap);
va_end (ap);
return ret;
}
#else
#include <varargs.h>
int
_printf_r (ptr, fmt, va_alist)
struct _reent *ptr;
char *fmt;
va_dcl
{
int ret;
va_list ap;
va_start (ap);
ret = _vfprintf_r (ptr, _stdout_r (ptr), fmt, ap);
va_end (ap);
return ret;
}
#endif
#ifndef _REENT_ONLY
#ifdef _HAVE_STDC
#include <stdarg.h>
int
printf (const char *fmt, ...)
{
int ret;
va_list ap;
va_start (ap, fmt);
_stdout_r (_REENT)->_data = _REENT;
ret = vfprintf (_stdout_r (_REENT), fmt, ap);
va_end (ap);
return ret;
}
#else
#include <varargs.h>
int
printf (fmt, va_alist)
char *fmt;
va_dcl
{
int ret;
va_list ap;
va_start (ap);
_stdout_r (_REENT)->_data = _REENT;
ret = vfprintf (_stdout_r (_REENT), fmt, ap);
va_end (ap);
return ret;
}
#endif /* ! _HAVE_STDC */
#endif /* ! _REENT_ONLY */

84
agbcc/libc/stdio/putc.c Normal file
View File

@ -0,0 +1,84 @@
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not 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.
*/
/*
FUNCTION
<<putc>>---write a character (macro)
INDEX
putc
ANSI_SYNOPSIS
#include <stdio.h>
int putc(int <[ch]>, FILE *<[fp]>);
TRAD_SYNOPSIS
#include <stdio.h>
int putc(<[ch]>, <[fp]>)
int <[ch]>;
FILE *<[fp]>;
DESCRIPTION
<<putc>> is a macro, defined in <<stdio.h>>. <<putc>>
writes the argument <[ch]> to the file or stream identified by
<[fp]>, after converting it from an <<int>> to an <<unsigned char>>.
If the file was opened with append mode (or if the stream cannot
support positioning), then the new character goes at the end of the
file or stream. Otherwise, the new character is written at the
current value of the position indicator, and the position indicator
advances by one.
For a subroutine version of this macro, see <<fputc>>.
RETURNS
If successful, <<putc>> returns its argument <[ch]>. If an error
intervenes, the result is <<EOF>>. You can use `<<ferror(<[fp]>)>>' to
query for errors.
PORTABILITY
ANSI C requires <<putc>>; it suggests, but does not require, that
<<putc>> be implemented as a macro. The standard explicitly permits
macro implementations of <<putc>> to use the <[fp]> argument more than once;
therefore, in a portable program, you should not use an expression
with side effects as this argument.
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "%W% (Berkeley) %G%";
#endif /* LIBC_SCCS and not lint */
#include <stdio.h>
/*
* A subroutine version of the macro putc.
*/
#undef putc
int
putc (c, fp)
int c;
register FILE *fp;
{
/* CHECK_INIT is (eventually) called by __swbuf. */
return __sputc (c, fp);
}

View File

@ -0,0 +1,94 @@
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not 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.
*/
/*
FUNCTION
<<putchar>>---write a character (macro)
INDEX
putchar
INDEX
_putchar_r
ANSI_SYNOPSIS
#include <stdio.h>
int putchar(int <[ch]>);
int _putchar_r(void *<[reent]>, int <[ch]>);
TRAD_SYNOPSIS
#include <stdio.h>
int putchar(<[ch]>)
int <[ch]>;
int _putchar_r(<[reent]>, <[ch]>)
char *<[reent]>;
int <[ch]>;
DESCRIPTION
<<putchar>> is a macro, defined in <<stdio.h>>. <<putchar>>
writes its argument to the standard output stream,
after converting it from an <<int>> to an <<unsigned char>>.
The alternate function <<_putchar_r>> is a reentrant version. The
extra argument <[reent]> is a pointer to a reentrancy structure.
RETURNS
If successful, <<putchar>> returns its argument <[ch]>. If an error
intervenes, the result is <<EOF>>. You can use `<<ferror(stdin)>>' to
query for errors.
PORTABILITY
ANSI C requires <<putchar>>; it suggests, but does not require, that
<<putchar>> be implemented as a macro.
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "%W% (Berkeley) %G%";
#endif /* LIBC_SCCS and not lint */
/*
* A subroutine version of the macro putchar
*/
#include <stdio.h>
#undef putchar
int
_putchar_r (ptr, c)
struct _reent *ptr;
int c;
{
return __sputc (c, _stdout_r (ptr));
}
#ifndef _REENT_ONLY
int
putchar (c)
int c;
{
/* CHECK_INIT is (eventually) called by __swbuf. */
_putchar_r (_REENT, c);
}
#endif

101
agbcc/libc/stdio/puts.c Normal file
View File

@ -0,0 +1,101 @@
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not 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.
*/
/*
FUNCTION
<<puts>>---write a character string
INDEX
puts
INDEX
_puts_r
ANSI_SYNOPSIS
#include <stdio.h>
int puts(const char *<[s]>);
int _puts_r(void *<[reent]>, const char *<[s]>);
TRAD_SYNOPSIS
#include <stdio.h>
int puts(<[s]>)
char *<[s]>;
int _puts_r(<[reent]>, <[s]>)
char *<[reent]>;
char *<[s]>;
DESCRIPTION
<<puts>> writes the string at <[s]> (followed by a newline, instead of
the trailing null) to the standard output stream.
The alternate function <<_puts_r>> is a reentrant version. The extra
argument <[reent]> is a pointer to a reentrancy structure.
RETURNS
If successful, the result is a nonnegative integer; otherwise, the
result is <<EOF>>.
PORTABILITY
ANSI C requires <<puts>>, but does not specify that the result on
success must be <<0>>; any non-negative value is permitted.
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
<<lseek>>, <<read>>, <<sbrk>>, <<write>>. */
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "%W% (Berkeley) %G%";
#endif /* LIBC_SCCS and not lint */
#include <stdio.h>
#include <string.h>
#include "fvwrite.h"
/*
* Write the given string to stdout, appending a newline.
*/
int
_DEFUN (_puts_r, (ptr, s),
struct _reent *ptr _AND
_CONST char * s)
{
size_t c = strlen (s);
struct __suio uio;
struct __siov iov[2];
iov[0].iov_base = s;
iov[0].iov_len = c;
iov[1].iov_base = "\n";
iov[1].iov_len = 1;
uio.uio_resid = c + 1;
uio.uio_iov = &iov[0];
uio.uio_iovcnt = 2;
return (__sfvwrite (_stdout_r (ptr), &uio) ? EOF : '\n');
}
#ifndef _REENT_ONLY
int
_DEFUN (puts, (s),
char _CONST * s)
{
return _puts_r (_REENT, s);
}
#endif

113
agbcc/libc/stdio/refill.c Normal file
View File

@ -0,0 +1,113 @@
/* No user fns here. Pesch 15apr92. */
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not 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.
*/
#include <stdio.h>
#include "local.h"
#include <stdlib.h>
static int
lflush (fp)
FILE *fp;
{
if ((fp->_flags & (__SLBF | __SWR)) == __SLBF | __SWR)
return fflush (fp);
return 0;
}
/*
* Refill a stdio buffer.
* Return EOF on eof or error, 0 otherwise.
*/
int
_DEFUN (__srefill, (fp),
register FILE * fp)
{
/* make sure stdio is set up */
CHECK_INIT (fp);
fp->_r = 0; /* largely a convenience for callers */
/* SysV does not make this test; take it out for compatibility */
if (fp->_flags & __SEOF)
return EOF;
/* if not already reading, have to be reading and writing */
if ((fp->_flags & __SRD) == 0)
{
if ((fp->_flags & __SRW) == 0)
return EOF;
/* switch to reading */
if (fp->_flags & __SWR)
{
if (fflush (fp))
return EOF;
fp->_flags &= ~__SWR;
fp->_w = 0;
fp->_lbfsize = 0;
}
fp->_flags |= __SRD;
}
else
{
/*
* We were reading. If there is an ungetc buffer,
* we must have been reading from that. Drop it,
* restoring the previous buffer (if any). If there
* is anything in that buffer, return.
*/
if (HASUB (fp))
{
FREEUB (fp);
if ((fp->_r = fp->_ur) != 0)
{
fp->_p = fp->_up;
return 0;
}
}
}
if (fp->_bf._base == NULL)
__smakebuf (fp);
/*
* Before reading from a line buffered or unbuffered file,
* flush all line buffered output files, per the ANSI C
* standard.
*/
if (fp->_flags & (__SLBF | __SNBF))
(void) _fwalk (fp->_data, lflush);
fp->_p = fp->_bf._base;
fp->_r = (*fp->_read) (fp->_cookie, (char *) fp->_p, fp->_bf._size);
fp->_flags &= ~__SMOD; /* buffer contents are again pristine */
if (fp->_r <= 0)
{
if (fp->_r == 0)
fp->_flags |= __SEOF;
else
{
fp->_r = 0;
fp->_flags |= __SERR;
}
return EOF;
}
return 0;
}

69
agbcc/libc/stdio/remove.c Normal file
View File

@ -0,0 +1,69 @@
/*
FUNCTION
<<remove>>---delete a file's name
INDEX
remove
ANSI_SYNOPSIS
#include <stdio.h>
int remove(char *<[filename]>);
int _remove_r(void *<[reent]>, char *<[filename]>);
TRAD_SYNOPSIS
#include <stdio.h>
int remove(<[filename]>)
char *<[filename]>;
int _remove_r(<[reent]>, <[filename]>)
char *<[reent]>;
char *<[filename]>;
DESCRIPTION
Use <<remove>> to dissolve the association between a particular
filename (the string at <[filename]>) and the file it represents.
After calling <<remove>> with a particular filename, you will no
longer be able to open the file by that name.
In this implementation, you may use <<remove>> on an open file without
error; existing file descriptors for the file will continue to access
the file's data until the program using them closes the file.
The alternate function <<_remove_r>> is a reentrant version. The
extra argument <[reent]> is a pointer to a reentrancy structure.
RETURNS
<<remove>> returns <<0>> if it succeeds, <<-1>> if it fails.
PORTABILITY
ANSI C requires <<remove>>, but only specifies that the result on
failure be nonzero. The behavior of <<remove>> when you call it on an
open file may vary among implementations.
Supporting OS subroutine required: <<unlink>>.
*/
#include <stdio.h>
int
_remove_r (ptr, filename)
struct _reent *ptr;
_CONST char *filename;
{
if (_unlink_r (ptr, filename) == -1)
return -1;
return 0;
}
#ifndef _REENT_ONLY
int
remove (filename)
_CONST char *filename;
{
return _remove_r (_REENT, filename);
}
#endif

86
agbcc/libc/stdio/rename.c Normal file
View File

@ -0,0 +1,86 @@
/*
FUNCTION
<<rename>>---rename a file
INDEX
rename
INDEX
_rename_r
ANSI_SYNOPSIS
#include <stdio.h>
int rename(const char *<[old]>, const char *<[new]>);
int _rename_r(void *<[reent]>,
const char *<[old]>, const char *<[new]>);
TRAD_SYNOPSIS
#include <stdio.h>
int rename(<[old]>, <[new]>)
char *<[old]>;
char *<[new]>;
int _rename_r(<[reent]>, <[old]>, <[new]>)
char *<[reent]>;
char *<[old]>;
char *<[new]>;
DESCRIPTION
Use <<rename>> to establish a new name (the string at <[new]>) for a
file now known by the string at <[old]>. After a successful
<<rename>>, the file is no longer accessible by the string at <[old]>.
If <<rename>> fails, the file named <<*<[old]>>> is unaffected. The
conditions for failure depend on the host operating system.
The alternate function <<_rename_r>> is a reentrant version. The
extra argument <[reent]> is a pointer to a reentrancy structure.
RETURNS
The result is either <<0>> (when successful) or <<-1>> (when the file
could not be renamed).
PORTABILITY
ANSI C requires <<rename>>, but only specifies that the result on
failure be nonzero. The effects of using the name of an existing file
as <<*<[new]>>> may vary from one implementation to another.
Supporting OS subroutines required: <<link>>, <<unlink>>, or <<rename>>.
*/
#include <stdio.h>
#include <sys/unistd.h>
#include <reent.h>
int
_rename_r (ptr, old, new)
struct _reent *ptr;
_CONST char *old;
_CONST char *new;
{
#ifdef HAVE_RENAME
return _rename (old,new);
#else
if (_link_r (ptr, old, new) == -1)
return -1;
if (_unlink_r (ptr, old) == -1)
{
/* ??? Should we unlink new? (rhetorical question) */
return -1;
}
#endif
return 0;
}
#ifndef _REENT_ONLY
int
rename (old, new)
_CONST char *old;
_CONST char *new;
{
return _rename_r (_REENT, old, new);
}
#endif

60
agbcc/libc/stdio/rewind.c Normal file
View File

@ -0,0 +1,60 @@
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not 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.
*/
/*
FUNCTION
<<rewind>>---reinitialize a file or stream
INDEX
rewind
ANSI_SYNOPSIS
#include <stdio.h>
void rewind(FILE *<[fp]>);
TRAD_SYNOPSIS
#include <stdio.h>
void rewind(<[fp]>)
FILE *<[fp]>;
DESCRIPTION
<<rewind>> returns the file position indicator (if any) for the file
or stream identified by <[fp]> to the beginning of the file. It also
clears any error indicator and flushes any pending output.
RETURNS
<<rewind>> does not return a result.
PORTABILITY
ANSI C requires <<rewind>>.
No supporting OS subroutines are required.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "%W% (Berkeley) %G%";
#endif /* LIBC_SCCS and not lint */
#include <stdio.h>
void
_DEFUN (rewind, (fp),
register FILE * fp)
{
(void) fseek(fp, 0L, SEEK_SET);
clearerr(fp);
}

43
agbcc/libc/stdio/rget.c Normal file
View File

@ -0,0 +1,43 @@
/* No user fns here. Pesch 15apr92. */
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not 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.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "%W% (Berkeley) %G%";
#endif /* LIBC_SCCS and not lint */
#include <stdio.h>
#include "local.h"
/*
* Handle getc() when the buffer ran out:
* Refill, then return the first character
* in the newly-filled buffer.
*/
int
__srget (fp)
register FILE *fp;
{
if (__srefill (fp) == 0)
{
fp->_r--;
return *fp->_p++;
}
return EOF;
}

75
agbcc/libc/stdio/scanf.c Normal file
View File

@ -0,0 +1,75 @@
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not 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.
*/
#include <_ansi.h>
#include <stdio.h>
#include "local.h"
#ifdef _HAVE_STDC
#include <stdarg.h>
#else
#include <varargs.h>
#endif
#ifndef _REENT_ONLY
int
#ifdef _HAVE_STDC
scanf (const char *fmt, ...)
#else
scanf (fmt, va_alist)
char *fmt;
va_dcl
#endif
{
int ret;
va_list ap;
#ifdef _HAVE_STDC
va_start (ap, fmt);
#else
va_start (ap);
#endif
ret = __svfscanf (_stdin_r (_REENT), fmt, ap);
va_end (ap);
return ret;
}
#endif
int
#ifdef _HAVE_STDC
_scanf_r (struct _reent *ptr, const char *fmt, ...)
#else
_scanf_r (ptr, fmt, va_alist)
struct _reent *ptr;
char *fmt;
va_dcl
#endif
{
int ret;
va_list ap;
#ifdef _HAVE_STDC
va_start (ap, fmt);
#else
va_start (ap);
#endif
ret = __svfscanf (_stdin_r (ptr), fmt, ap);
va_end (ap);
return (ret);
}

79
agbcc/libc/stdio/setbuf.c Normal file
View File

@ -0,0 +1,79 @@
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not 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.
*/
/*
FUNCTION
<<setbuf>>---specify full buffering for a file or stream
INDEX
setbuf
ANSI_SYNOPSIS
#include <stdio.h>
void setbuf(FILE *<[fp]>, char *<[buf]>);
TRAD_SYNOPSIS
#include <stdio.h>
void setbuf(<[fp]>, <[buf]>)
FILE *<[fp]>;
char *<[buf]>;
DESCRIPTION
<<setbuf>> specifies that output to the file or stream identified by <[fp]>
should be fully buffered. All output for this file will go to a
buffer (of size <<BUFSIZ>>, specified in `<<stdio.h>>'). Output will
be passed on to the host system only when the buffer is full, or when
an input operation intervenes.
You may, if you wish, supply your own buffer by passing a pointer to
it as the argument <[buf]>. It must have size <<BUFSIZ>>. You can
also use <<NULL>> as the value of <[buf]>, to signal that the
<<setbuf>> function is to allocate the buffer.
WARNINGS
You may only use <<setbuf>> before performing any file operation other
than opening the file.
If you supply a non-null <[buf]>, you must ensure that the associated
storage continues to be available until you close the stream
identified by <[fp]>.
RETURNS
<<setbuf>> does not return a result.
PORTABILITY
Both ANSI C and the System V Interface Definition (Issue 2) require
<<setbuf>>. However, they differ on the meaning of a <<NULL>> buffer
pointer: the SVID issue 2 specification says that a <<NULL>> buffer
pointer requests unbuffered output. For maximum portability, avoid
<<NULL>> buffer pointers.
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
*/
#include <_ansi.h>
#include <stdio.h>
#include "local.h"
void
_DEFUN (setbuf, (fp, buf),
FILE * fp _AND
char *buf)
{
(void) setvbuf (fp, buf, buf ? _IOFBF : _IONBF, BUFSIZ);
}

186
agbcc/libc/stdio/setvbuf.c Normal file
View File

@ -0,0 +1,186 @@
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not 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.
*/
/*
FUNCTION
<<setvbuf>>---specify file or stream buffering
INDEX
setvbuf
ANSI_SYNOPSIS
#include <stdio.h>
int setvbuf(FILE *<[fp]>, char *<[buf]>,
int <[mode]>, size_t <[size]>);
TRAD_SYNOPSIS
#include <stdio.h>
int setvbuf(<[fp]>, <[buf]>, <[mode]>, <[size]>)
FILE *<[fp]>;
char *<[buf]>;
int <[mode]>;
size_t <[size]>;
DESCRIPTION
Use <<setvbuf>> to specify what kind of buffering you want for the
file or stream identified by <[fp]>, by using one of the following
values (from <<stdio.h>>) as the <[mode]> argument:
o+
o _IONBF
Do not use a buffer: send output directly to the host system for the
file or stream identified by <[fp]>.
o _IOFBF
Use full output buffering: output will be passed on to the host system
only when the buffer is full, or when an input operation intervenes.
o _IOLBF
Use line buffering: pass on output to the host system at every
newline, as well as when the buffer is full, or when an input
operation intervenes.
o-
Use the <[size]> argument to specify how large a buffer you wish. You
can supply the buffer itself, if you wish, by passing a pointer to a
suitable area of memory as <[buf]>. Otherwise, you may pass <<NULL>>
as the <[buf]> argument, and <<setvbuf>> will allocate the buffer.
WARNINGS
You may only use <<setvbuf>> before performing any file operation other
than opening the file.
If you supply a non-null <[buf]>, you must ensure that the associated
storage continues to be available until you close the stream
identified by <[fp]>.
RETURNS
A <<0>> result indicates success, <<EOF>> failure (invalid <[mode]> or
<[size]> can cause failure).
PORTABILITY
Both ANSI C and the System V Interface Definition (Issue 2) require
<<setvbuf>>. However, they differ on the meaning of a <<NULL>> buffer
pointer: the SVID issue 2 specification says that a <<NULL>> buffer
pointer requests unbuffered output. For maximum portability, avoid
<<NULL>> buffer pointers.
Both specifications describe the result on failure only as a
nonzero value.
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
*/
#include <_ansi.h>
#include <stdio.h>
#include <stdlib.h>
#include "local.h"
/*
* Set one of the three kinds of buffering, optionally including a buffer.
*/
int
_DEFUN (setvbuf, (fp, buf, mode, size),
register FILE * fp _AND
char *buf _AND
register int mode _AND
register size_t size)
{
int ret = 0;
CHECK_INIT (fp);
/*
* Verify arguments. The `int' limit on `size' is due to this
* particular implementation.
*/
if ((mode != _IOFBF && mode != _IOLBF && mode != _IONBF) || (int)(_POINTER_INT) size < 0)
return (EOF);
/*
* Write current buffer, if any; drop read count, if any.
* Make sure putc() will not think fp is line buffered.
* Free old buffer if it was from malloc(). Clear line and
* non buffer flags, and clear malloc flag.
*/
(void) fflush (fp);
fp->_r = 0;
fp->_lbfsize = 0;
if (fp->_flags & __SMBF)
_free_r (fp->_data, (void *) fp->_bf._base);
fp->_flags &= ~(__SLBF | __SNBF | __SMBF);
if (mode == _IONBF)
goto nbf;
/*
* Allocate buffer if needed. */
if (buf == NULL)
{
if ((buf = malloc (size)) == NULL)
{
ret = EOF;
/* Try another size... */
buf = malloc (BUFSIZ);
}
if (buf == NULL)
{
/* Can't allocate it, let's try another approach */
nbf:
fp->_flags |= __SNBF;
fp->_w = 0;
fp->_bf._base = fp->_p = fp->_nbuf;
fp->_bf._size = 1;
return (ret);
}
fp->_flags |= __SMBF;
}
/*
* Now put back whichever flag is needed, and fix _lbfsize
* if line buffered. Ensure output flush on exit if the
* stream will be buffered at all.
* If buf is NULL then make _lbfsize 0 to force the buffer
* to be flushed and hence malloced on first use
*/
switch (mode)
{
case _IOLBF:
fp->_flags |= __SLBF;
fp->_lbfsize = buf ? -size : 0;
/* FALLTHROUGH */
case _IOFBF:
/* no flag */
fp->_data->__cleanup = _cleanup_r;
fp->_bf._base = fp->_p = (unsigned char *) buf;
fp->_bf._size = size;
break;
}
/*
* Patch up write count if necessary.
*/
if (fp->_flags & __SWR)
fp->_w = fp->_flags & (__SLBF | __SNBF) ? 0 : size;
return 0;
}

View File

@ -0,0 +1,70 @@
/*
FUNCTION
<<siprintf>>---write formatted output (integer only)
INDEX
siprintf
ANSI_SYNOPSIS
#include <stdio.h>
int siprintf(char *<[str]>, const char *<[format]> [, <[arg]>, ...]);
DESCRIPTION
<<siprintf>> is a restricted version of <<sprintf>>: it has the same
arguments and behavior, save that it cannot perform any floating-point
formatting: the <<f>>, <<g>>, <<G>>, <<e>>, and <<F>> type specifiers
are not recognized.
RETURNS
<<siprintf>> returns the number of bytes in the output string,
save that the concluding <<NULL>> is not counted.
<<siprintf>> returns when the end of the format string is
encountered.
PORTABILITY
<<siprintf>> is not required by ANSI C.
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
*/
#include <stdio.h>
#ifdef _HAVE_STDC
#include <stdarg.h>
#else
#include <varargs.h>
#endif
#include <limits.h>
#include <_ansi.h>
#include <reent.h>
#include "local.h"
int
#ifdef _HAVE_STDC
_DEFUN (siprintf, (str, fmt), char *str _AND _CONST char *fmt _DOTS)
#else
siprintf (str, fmt, va_alist)
char *str;
_CONST char *fmt;
va_dcl
#endif
{
int ret;
va_list ap;
FILE f;
f._flags = __SWR | __SSTR;
f._bf._base = f._p = (unsigned char *) str;
f._bf._size = f._w = INT_MAX;
f._data = _REENT;
#ifdef _HAVE_STDC
va_start (ap, fmt);
#else
va_start (ap);
#endif
ret = vfiprintf (&f, fmt, ap);
va_end (ap);
*f._p = 0;
return (ret);
}

351
agbcc/libc/stdio/sprintf.c Normal file
View File

@ -0,0 +1,351 @@
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not 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.
*/
/*
FUNCTION
<<printf>>, <<fprintf>>, <<sprintf>>---format output
INDEX
fprintf
INDEX
printf
INDEX
sprintf
ANSI_SYNOPSIS
#include <stdio.h>
int printf(const char *<[format]> [, <[arg]>, ...]);
int fprintf(FILE *<[fd]>, const char *<[format]> [, <[arg]>, ...]);
int sprintf(char *<[str]>, const char *<[format]> [, <[arg]>, ...]);
TRAD_SYNOPSIS
#include <stdio.h>
int printf(<[format]> [, <[arg]>, ...])
char *<[format]>;
int fprintf(<[fd]>, <[format]> [, <[arg]>, ...]);
FILE *<[fd]>;
char *<[format]>;
int sprintf(<[str]>, <[format]> [, <[arg]>, ...]);
char *<[str]>;
char *<[format]>;
DESCRIPTION
<<printf>> accepts a series of arguments, applies to each a
format specifier from <<*<[format]>>>, and writes the
formatted data to <<stdout>>, terminated with a null character.
The behavior of <<printf>> is undefined if there are not enough
arguments for the format.
<<printf>> returns when it reaches the end of the format string.
If there are more arguments than the format requires, excess
arguments are ignored.
<<fprintf>> and <<sprintf>> are identical to <<printf>>, other than the
destination of the formatted output: <<fprintf>> sends the
output to a specified file <[fd]>, while <<sprintf>> stores the
output in the specified char array <[str]>. For <<sprintf>>,
the behavior is also undefined if the output <<*<[str]>>>
overlaps with one of the arguments.
<[format]> is a pointer to a charater string containing two types of
objects: ordinary characters (other than <<%>>), which are
copied unchanged to the output, and conversion
specifications, each of which is introduced by <<%>>.
(To include <<%>> in the output, use <<%%>> in the format string.)
A conversion specification has the following form:
. %[<[flags]>][<[width]>][.<[prec]>][<[size]>][<[type]>]
The fields of the conversion specification have the following meanings:
O+
o <[flags]>
an optional sequence of characters which control
output justification, numeric signs, decimal points,
trailing zeroes, and octal and hex prefixes.
The flag characters are minus (<<->>), plus (<<+>>),
space ( ), zero (<<0>>), and sharp (<<#>>). They can
appear in any combination.
o+
o -
The result of the conversion is left justified, and the right is
padded with blanks. If you do not use this flag, the result is right
justified, and padded on the left.
o +
The result of a signed conversion (as determined by <[type]>)
will always begin with a plus or minus sign. (If you do not use
this flag, positive values do not begin with a plus sign.)
o " " (space)
If the first character of a signed conversion specification
is not a sign, or if a signed conversion results in no
characters, the result will begin with a space. If the
space ( ) flag and the plus (<<+>>) flag both appear,
the space flag is ignored.
o 0
If the <[type]> character is <<d>>, <<i>>, <<o>>, <<u>>,
<<x>>, <<X>>, <<e>>, <<E>>, <<f>>, <<g>>, or <<G>>: leading zeroes,
are used to pad the field width (following any indication of sign or
base); no spaces are used for padding. If the zero (<<0>>) and
minus (<<->>) flags both appear, the zero (<<0>>) flag will
be ignored. For <<d>>, <<i>>, <<o>>, <<u>>, <<x>>, and <<X>>
conversions, if a precision <[prec]> is specified, the zero (<<0>>)
flag is ignored.
Note that <<0>> is interpreted as a flag, not as the beginning
of a field width.
o #
The result is to be converted to an alternative form, according
to the next character:
o+
o 0
increases precision to force the first digit
of the result to be a zero.
o x
a non-zero result will have a <<0x>> prefix.
o X
a non-zero result will have a <<0X>> prefix.
o e, E or f
The result will always contain a decimal point
even if no digits follow the point.
(Normally, a decimal point appears only if a
digit follows it.) Trailing zeroes are removed.
o g or G
same as <<e>> or <<E>>, but trailing zeroes
are not removed.
o all others
undefined.
o-
o-
o <[width]>
<[width]> is an optional minimum field width. You can either
specify it directly as a decimal integer, or indirectly by
using instead an asterisk (<<*>>), in which case an <<int>>
argument is used as the field width. Negative field widths
are not supported; if you attempt to specify a negative field
width, it is interpreted as a minus (<<->>) flag followed by a
positive field width.
o <[prec]>
an optional field; if present, it is introduced with `<<.>>'
(a period). This field gives the maximum number of
characters to print in a conversion; the minimum number of
digits of an integer to print, for conversions with <[type]>
<<d>>, <<i>>, <<o>>, <<u>>, <<x>>, and <<X>>; the maximum number of
significant digits, for the <<g>> and <<G>> conversions;
or the number of digits to print after the decimal
point, for <<e>>, <<E>>, and <<f>> conversions. You can specify
the precision either directly as a decimal integer or
indirectly by using an asterisk (<<*>>), in which case
an <<int>> argument is used as the precision. Supplying a negative
precision is equivalent to omitting the precision.
If only a period is specified the precision is zero.
If a precision appears with any other conversion <[type]>
than those listed here, the behavior is undefined.
o <[size]>
<<h>>, <<l>>, and <<L>> are optional size characters which
override the default way that <<printf>> interprets the
data type of the corresponding argument. <<h>> forces
the following <<d>>, <<i>>, <<o>>, <<u>>, <<x>> or <<X>> conversion
<[type]> to apply to a <<short>> or <<unsigned short>>. <<h>> also
forces a following <<n>> <[type]> to apply to
a pointer to a <<short>>. Similarily, an
<<l>> forces the following <<d>>, <<i>>, <<o>>, <<u>>,
<<x>> or <<X>> conversion <[type]> to apply to a <<long>> or
<<unsigned long>>. <<l>> also forces a following <<n>> <[type]> to
apply to a pointer to a <<long>>. If an <<h>>
or an <<l>> appears with another conversion
specifier, the behavior is undefined. <<L>> forces a
following <<e>>, <<E>>, <<f>>, <<g>> or <<G>> conversion <[type]> to
apply to a <<long double>> argument. If <<L>> appears with
any other conversion <[type]>, the behavior is undefined.
o <[type]>
<[type]> specifies what kind of conversion <<printf>> performs.
Here is a table of these:
o+
o %
prints the percent character (<<%>>)
o c
prints <[arg]> as single character
o s
prints characters until precision is reached or a null terminator
is encountered; takes a string pointer
o d
prints a signed decimal integer; takes an <<int>> (same as <<i>>)
o i
prints a signed decimal integer; takes an <<int>> (same as <<d>>)
o o
prints a signed octal integer; takes an <<int>>
o u
prints an unsigned decimal integer; takes an <<int>>
o x
prints an unsigned hexadecimal integer (using <<abcdef>> as
digits beyond <<9>>); takes an <<int>>
o X
prints an unsigned hexadecimal integer (using <<ABCDEF>> as
digits beyond <<9>>); takes an <<int>>
o f
prints a signed value of the form <<[-]9999.9999>>; takes
a floating point number
o e
prints a signed value of the form <<[-]9.9999e[+|-]999>>; takes a
floating point number
o E
prints the same way as <<e>>, but using <<E>> to introduce the
exponent; takes a floating point number
o g
prints a signed value in either <<f>> or <<e>> form, based on given
value and precision---trailing zeros and the decimal point are
printed only if necessary; takes a floating point number
o G
prints the same way as <<g>>, but using <<E>> for the exponent if an
exponent is needed; takes a floating point number
o n
stores (in the same object) a count of the characters written;
takes a pointer to <<int>>
o p
prints a pointer in an implementation-defined format.
This implementation treats the pointer as an
<<unsigned long>> (same as <<Lu>>).
o-
O-
RETURNS
<<sprintf>> returns the number of bytes in the output string,
save that the concluding <<NULL>> is not counted.
<<printf>> and <<fprintf>> return the number of characters transmitted.
If an error occurs, <<printf>> and <<fprintf>> return <<EOF>>. No
error returns occur for <<sprintf>>.
PORTABILITY
The ANSI C standard specifies that implementations must
support at least formatted output of up to 509 characters.
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
*/
#include <stdio.h>
#ifdef _HAVE_STDC
#include <stdarg.h>
#else
#include <varargs.h>
#endif
#include <limits.h>
#include <_ansi.h>
#include "local.h"
int
#ifdef _HAVE_STDC
_DEFUN (_sprintf_r, (ptr, str, fmt), struct _reent *ptr _AND char *str _AND _CONST char *fmt _DOTS)
#else
_sprintf_r (ptr, str, fmt, va_alist)
struct _reent *ptr;
char *str;
_CONST char *fmt;
va_dcl
#endif
{
int ret;
va_list ap;
FILE f;
f._flags = __SWR | __SSTR;
f._bf._base = f._p = (unsigned char *) str;
f._bf._size = f._w = INT_MAX;
f._data = ptr;
#ifdef _HAVE_STDC
va_start (ap, fmt);
#else
va_start (ap);
#endif
ret = vfprintf (&f, fmt, ap);
va_end (ap);
*f._p = 0;
return (ret);
}
#ifndef _REENT_ONLY
int
#ifdef _HAVE_STDC
_DEFUN (sprintf, (str, fmt), char *str _AND _CONST char *fmt _DOTS)
#else
sprintf (str, fmt, va_alist)
char *str;
_CONST char *fmt;
va_dcl
#endif
{
int ret;
va_list ap;
FILE f;
f._flags = __SWR | __SSTR;
f._bf._base = f._p = (unsigned char *) str;
f._bf._size = f._w = INT_MAX;
f._data = _REENT;
#ifdef _HAVE_STDC
va_start (ap, fmt);
#else
va_start (ap);
#endif
ret = vfprintf (&f, fmt, ap);
va_end (ap);
*f._p = 0;
return (ret);
}
#endif

386
agbcc/libc/stdio/sscanf.c Normal file
View File

@ -0,0 +1,386 @@
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not 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.
*/
/*
FUNCTION
<<scanf>>, <<fscanf>>, <<sscanf>>---scan and format input
INDEX
scanf
INDEX
fscanf
INDEX
sscanf
ANSI_SYNOPSIS
#include <stdio.h>
int scanf(const char *<[format]> [, <[arg]>, ...]);
int fscanf(FILE *<[fd]>, const char *<[format]> [, <[arg]>, ...]);
int sscanf(const char *<[str]>, const char *<[format]>
[, <[arg]>, ...]);
TRAD_SYNOPSIS
#include <stdio.h>
int scanf(<[format]> [, <[arg]>, ...])
char *<[format]>;
int fscanf(<[fd]>, <[format]> [, <[arg]>, ...]);
FILE *<[fd]>;
char *<[format]>;
int sscanf(<[str]>, <[format]> [, <[arg]>, ...]);
char *<[str]>;
char *<[format]>;
DESCRIPTION
<<scanf>> scans a series of input fields from standard input,
one character at a time. Each field is interpreted according to
a format specifier passed to <<scanf>> in the format string at
<<*<[format]>>>. <<scanf>> stores the interpreted input from
each field at the address passed to it as the corresponding argument
following <[format]>. You must supply the same number of
format specifiers and address arguments as there are input fields.
There must be sufficient address arguments for the given format
specifiers; if not the results are unpredictable and likely
disasterous. Excess address arguments are merely ignored.
<<scanf>> often produces unexpected results if the input diverges from
an expected pattern. Since the combination of <<gets>> or <<fgets>>
followed by <<sscanf>> is safe and easy, that is the preferred way
to be certain that a program is synchronized with input at the end
of a line.
<<fscanf>> and <<sscanf>> are identical to <<scanf>>, other than the
source of input: <<fscanf>> reads from a file, and <<sscanf>>
from a string.
The string at <<*<[format]>>> is a character sequence composed
of zero or more directives. Directives are composed of
one or more whitespace characters, non-whitespace characters,
and format specifications.
Whitespace characters are blank (<< >>), tab (<<\t>>), or
newline (<<\n>>).
When <<scanf>> encounters a whitespace character in the format string
it will read (but not store) all consecutive whitespace characters
up to the next non-whitespace character in the input.
Non-whitespace characters are all other ASCII characters except the
percent sign (<<%>>). When <<scanf>> encounters a non-whitespace
character in the format string it will read, but not store
a matching non-whitespace character.
Format specifications tell <<scanf>> to read and convert characters
from the input field into specific types of values, and store then
in the locations specified by the address arguments.
Trailing whitespace is left unread unless explicitly
matched in the format string.
The format specifiers must begin with a percent sign (<<%>>)
and have the following form:
. %[*][<[width]>][<[size]>]<[type]>
Each format specification begins with the percent character (<<%>>).
The other fields are:
o+
o *
an optional marker; if present, it suppresses interpretation and
assignment of this input field.
o <[width]>
an optional maximum field width: a decimal integer,
which controls the maximum number of characters that
will be read before converting the current input field. If the
input field has fewer than <[width]> characters, <<scanf>>
reads all the characters in the field, and then
proceeds with the next field and its format specification.
If a whitespace or a non-convertable character occurs
before <[width]> character are read, the characters up
to that character are read, converted, and stored.
Then <<scanf>> proceeds to the next format specification.
o size
<<h>>, <<l>>, and <<L>> are optional size characters which
override the default way that <<scanf>> interprets the
data type of the corresponding argument.
.Modifier Type(s)
. h d, i, o, u, x convert input to short,
. store in short object
.
. h D, I, O, U, X no effect
. e, f, c, s, n, p
.
. l d, i, o, u, x convert input to long,
. store in long object
.
. l e, f, g convert input to double
. store in a double object
.
. l D, I, O, U, X no effect
. c, s, n, p
.
. L d, i, o, u, x convert to long double,
. store in long double
.
. L all others no effect
o <[type]>
A character to specify what kind of conversion
<<scanf>> performs. Here is a table of the conversion
characters:
o+
o %
No conversion is done; the percent character (<<%>>) is stored.
o c
Scans one character. Corresponding <[arg]>: <<(char *arg)>>.
o s
Reads a character string into the array supplied.
Corresponding <[arg]>: <<(char arg[])>>.
o [<[pattern]>]
Reads a non-empty character string into memory
starting at <[arg]>. This area must be large
enough to accept the sequence and a
terminating null character which will be added
automatically. (<[pattern]> is discussed in the paragraph following
this table). Corresponding <[arg]>: <<(char *arg)>>.
o d
Reads a decimal integer into the corresponding <[arg]>: <<(int *arg)>>.
o D
Reads a decimal integer into the corresponding
<[arg]>: <<(long *arg)>>.
o o
Reads an octal integer into the corresponding <[arg]>: <<(int *arg)>>.
o O
Reads an octal integer into the corresponding <[arg]>: <<(long *arg)>>.
o u
Reads an unsigned decimal integer into the corresponding
<[arg]>: <<(unsigned int *arg)>>.
o U
Reads an unsigned decimal integer into the corresponding <[arg]>:
<<(unsigned long *arg)>>.
o x,X
Read a hexadecimal integer into the corresponding <[arg]>:
<<(int *arg)>>.
o e, f, g
Read a floating point number into the corresponding <[arg]>:
<<(float *arg)>>.
o E, F, G
Read a floating point number into the corresponding <[arg]>:
<<(double *arg)>>.
o i
Reads a decimal, octal or hexadecimal integer into the
corresponding <[arg]>: <<(int *arg)>>.
o I
Reads a decimal, octal or hexadecimal integer into the
corresponding <[arg]>: <<(long *arg)>>.
o n
Stores the number of characters read in the corresponding
<[arg]>: <<(int *arg)>>.
o p
Stores a scanned pointer. ANSI C leaves the details
to each implementation; this implementation treats
<<%p>> exactly the same as <<%U>>. Corresponding
<[arg]>: <<(void **arg)>>.
o-
A <[pattern]> of characters surrounded by square brackets can be used
instead of the <<s>> type character. <[pattern]> is a set of
characters which define a search set of possible characters making up
the <<scanf>> input field. If the first character in the brackets is a
caret (<<^>>), the search set is inverted to include all ASCII characters
except those between the brackets. There is also a range facility
which you can use as a shortcut. <<%[0-9] >> matches all decimal digits.
The hyphen must not be the first or last character in the set.
The character prior to the hyphen must be lexically less than the
character after it.
Here are some <[pattern]> examples:
o+
o %[abcd]
matches strings containing only <<a>>, <<b>>, <<c>>, and <<d>>.
o %[^abcd]
matches strings containing any characters except <<a>>, <<b>>,
<<c>>, or <<d>>
o %[A-DW-Z]
matches strings containing <<A>>, <<B>>, <<C>>, <<D>>, <<W>>,
<<X>>, <<Y>>, <<Z>>
o %[z-a]
matches the characters <<z>>, <<->>, and <<a>>
o-
Floating point numbers (for field types <<e>>, <<f>>, <<g>>, <<E>>,
<<F>>, <<G>>) must correspond to the following general form:
. [+/-] ddddd[.]ddd [E|e[+|-]ddd]
where objects inclosed in square brackets are optional, and <<ddd>>
represents decimal, octal, or hexadecimal digits.
o-
RETURNS
<<scanf>> returns the number of input fields successfully
scanned, converted and stored; the return value does
not include scanned fields which were not stored.
If <<scanf>> attempts to read at end-of-file, the return
value is <<EOF>>.
If no fields were stored, the return value is <<0>>.
<<scanf>> might stop scanning a particular field before
reaching the normal field end character, or may
terminate entirely.
<<scanf>> stops scanning and storing the current field
and moves to the next input field (if any)
in any of the following situations:
O+
o The assignment suppressing character (<<*>>) appears
after the <<%>> in the format specification; the current
input field is scanned but not stored.
o <[width]> characters have been read (<[width]> is a
width specification, a positive decimal integer).
o The next character read cannot be converted
under the the current format (for example,
if a <<Z>> is read when the format is decimal).
o The next character in the input field does not appear
in the search set (or does appear in the inverted search set).
O-
When <<scanf>> stops scanning the current input field for one of
these reasons, the next character is considered unread and
used as the first character of the following input field, or the
first character in a subsequent read operation on the input.
<<scanf>> will terminate under the following circumstances:
O+
o The next character in the input field conflicts
with a corresponding non-whitespace character in the
format string.
o The next character in the input field is <<EOF>>.
o The format string has been exhausted.
O-
When the format string contains a character sequence that is
not part of a format specification, the same character
sequence must appear in the input; <<scanf>> will
scan but not store the matched characters. If a
conflict occurs, the first conflicting character remains in the input
as if it had never been read.
PORTABILITY
<<scanf>> is ANSI C.
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
*/
#include <_ansi.h>
#include <reent.h>
#include <stdio.h>
#include <string.h>
#ifdef _HAVE_STDC
#include <stdarg.h>
#else
#include <varargs.h>
#endif
#include "local.h"
/* | ARGSUSED */
/*SUPPRESS 590*/
static
int
eofread (cookie, buf, len)
_PTR cookie;
char *buf;
int len;
{
return 0;
}
#ifdef _HAVE_STDC
int
_DEFUN (sscanf, (str, fmt), _CONST char *str _AND _CONST char *fmt _DOTS)
#else
int
sscanf (str, fmt, va_alist)
_CONST char *str;
_CONST char *fmt;
va_dcl
#endif
{
int ret;
va_list ap;
FILE f;
f._flags = __SRD;
f._bf._base = f._p = (unsigned char *) str;
f._bf._size = f._r = strlen (str);
f._read = eofread;
f._ub._base = NULL;
f._lb._base = NULL;
f._data = _REENT;
#ifdef _HAVE_STDC
va_start (ap, fmt);
#else
va_start (ap);
#endif
ret = __svfscanf (&f, fmt, ap);
va_end (ap);
return ret;
}

92
agbcc/libc/stdio/stdio.c Normal file
View File

@ -0,0 +1,92 @@
/* No user fns here. Pesch 15apr92. */
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not 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.
*/
#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/unistd.h>
#include "local.h"
/*
* Small standard I/O/seek/close functions.
* These maintain the `known seek offset' for seek optimisation.
*/
int
__sread (cookie, buf, n)
_PTR cookie;
char *buf;
int n;
{
register FILE *fp = (FILE *) cookie;
register int ret;
ret = _read_r (fp->_data, fp->_file, buf, n);
/* If the read succeeded, update the current offset. */
if (ret >= 0)
fp->_offset += ret;
else
fp->_flags &= ~__SOFF; /* paranoia */
return ret;
}
int
__swrite (cookie, buf, n)
_PTR cookie;
char _CONST *buf;
int n;
{
register FILE *fp = (FILE *) cookie;
if (fp->_flags & __SAPP)
(void) _lseek_r (fp->_data, fp->_file, (off_t) 0, SEEK_END);
fp->_flags &= ~__SOFF; /* in case O_APPEND mode is set */
return _write_r (fp->_data, fp->_file, buf, n);
}
fpos_t
__sseek (cookie, offset, whence)
_PTR cookie;
fpos_t offset;
int whence;
{
register FILE *fp = (FILE *) cookie;
register off_t ret;
ret = _lseek_r (fp->_data, fp->_file, (off_t) offset, whence);
if (ret == -1L)
fp->_flags &= ~__SOFF;
else
{
fp->_flags |= __SOFF;
fp->_offset = ret;
}
return ret;
}
int
__sclose (cookie)
_PTR cookie;
{
FILE *fp = (FILE *) cookie;
return _close_r (fp->_data, fp->_file);
}

View File

@ -0,0 +1,77 @@
/*
FUNCTION
<<tmpfile>>---create a temporary file
INDEX
tmpfile
INDEX
_tmpfile_r
ANSI_SYNOPSIS
#include <stdio.h>
FILE *tmpfile(void);
FILE *_tmpfile_r(void *<[reent]>);
TRAD_SYNOPSIS
#include <stdio.h>
FILE *tmpfile();
FILE *_tmpfile_r(<[reent]>)
char *<[reent]>;
DESCRIPTION
Create a temporary file (a file which will be deleted automatically),
using a name generated by <<tmpnam>>. The temporary file is opened with
the mode <<"wb+">>, permitting you to read and write anywhere in it
as a binary file (without any data transformations the host system may
perform for text files).
The alternate function <<_tmpfile_r>> is a reentrant version. The
argument <[reent]> is a pointer to a reentrancy structure.
RETURNS
<<tmpfile>> normally returns a pointer to the temporary file. If no
temporary file could be created, the result is NULL, and <<errno>>
records the reason for failure.
PORTABILITY
Both ANSI C and the System V Interface Definition (Issue 2) require
<<tmpfile>>.
Supporting OS subroutines required: <<close>>, <<fstat>>, <<getpid>>,
<<isatty>>, <<lseek>>, <<open>>, <<read>>, <<sbrk>>, <<write>>.
<<tmpfile>> also requires the global pointer <<environ>>.
*/
#include <stdio.h>
#include <errno.h>
FILE *
_DEFUN (_tmpfile_r, (ptr),
struct _reent *ptr)
{
FILE *fp;
int e;
char *f;
char buf[L_tmpnam];
if ((f = _tmpnam_r (ptr, buf)) == NULL)
return NULL;
fp = fopen (f, "wb+");
e = ptr->_errno;
_CAST_VOID remove (f);
ptr->_errno = e;
return fp;
}
#ifndef _REENT_ONLY
FILE *
_DEFUN_VOID (tmpfile)
{
return _tmpfile_r (_REENT);
}
#endif

208
agbcc/libc/stdio/tmpnam.c Normal file
View File

@ -0,0 +1,208 @@
/*
* tmpname.c
* Original Author: G. Haley
*/
/*
FUNCTION
<<tmpnam>>, <<tempnam>>---name for a temporary file
INDEX
tmpnam
INDEX
tempnam
INDEX
_tmpnam_r
INDEX
_tempnam_r
ANSI_SYNOPSIS
#include <stdio.h>
char *tmpnam(char *<[s]>);
char *tempnam(char *<[dir]>, char *<[pfx]>);
char *_tmpnam_r(void *<[reent]>, char *<[s]>);
char *_tempnam_r(void *<[reent]>, char *<[dir]>, char *<[pfx]>);
TRAD_SYNOPSIS
#include <stdio.h>
char *tmpnam(<[s]>)
char *<[s]>;
char *tempnam(<[dir]>, <[pfx]>)
char *<[dir]>;
char *<[pfx]>;
char *_tmpnam_r(<[reent]>, <[s]>)
char *<[reent]>;
char *<[s]>;
char *_tempnam_r(<[reent]>, <[dir]>, <[pfx]>)
char *<[reent]>;
char *<[dir]>;
char *<[pfx]>;
DESCRIPTION
Use either of these functions to generate a name for a temporary file.
The generated name is guaranteed to avoid collision with other files
(for up to <<TMP_MAX>> calls of either function).
<<tmpnam>> generates file names with the value of <<P_tmpdir>>
(defined in `<<stdio.h>>') as the leading directory component of the path.
You can use the <<tmpnam>> argument <[s]> to specify a suitable area
of memory for the generated filename; otherwise, you can call
<<tmpnam(NULL)>> to use an internal static buffer.
<<tempnam>> allows you more control over the generated filename: you
can use the argument <[dir]> to specify the path to a directory for
temporary files, and you can use the argument <[pfx]> to specify a
prefix for the base filename.
If <[dir]> is <<NULL>>, <<tempnam>> will attempt to use the value of
environment variable <<TMPDIR>> instead; if there is no such value,
<<tempnam>> uses the value of <<P_tmpdir>> (defined in `<<stdio.h>>').
If you don't need any particular prefix to the basename of temporary
files, you can pass <<NULL>> as the <[pfx]> argument to <<tempnam>>.
<<_tmpnam_r>> and <<_tempnam_r>> are reentrant versions of <<tmpnam>>
and <<tempnam>> respectively. The extra argument <[reent]> is a
pointer to a reentrancy structure.
WARNINGS
The generated filenames are suitable for temporary files, but do not
in themselves make files temporary. Files with these names must still
be explicitly removed when you no longer want them.
If you supply your own data area <[s]> for <<tmpnam>>, you must ensure
that it has room for at least <<L_tmpnam>> elements of type <<char>>.
RETURNS
Both <<tmpnam>> and <<tempnam>> return a pointer to the newly
generated filename.
PORTABILITY
ANSI C requires <<tmpnam>>, but does not specify the use of
<<P_tmpdir>>. The System V Interface Definition (Issue 2) requires
both <<tmpnam>> and <<tempnam>>.
Supporting OS subroutines required: <<close>>, <<fstat>>, <<getpid>>,
<<isatty>>, <<lseek>>, <<open>>, <<read>>, <<sbrk>>, <<write>>.
The global pointer <<environ>> is also required.
*/
#include <_ansi.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <reent.h>
#include <errno.h>
/* Try to open the file specified, if it can't be opened then try
another one. Return nonzero if successful, otherwise zero. */
static int
worker (ptr, result, part1, part2, part3, part4)
struct _reent *ptr;
char *result;
_CONST char *part1;
_CONST char *part2;
int part3;
int *part4;
{
/* Generate the filename and make sure that there isn't one called
it already. */
while (1)
{
int t;
_sprintf_r (ptr, result, "%s/%s%x.%x", part1, part2, part3, *part4);
(*part4)++;
t = _open_r (ptr, result, O_RDONLY, 0);
if (t == -1)
{
if (ptr->_errno == ENOSYS)
{
result[0] = '0';
return 0;
}
break;
}
_close_r (ptr, t);
}
return 1;
}
char *
_DEFUN (_tmpnam_r, (p, s),
struct _reent *p _AND
char *s)
{
char *result;
int pid;
if (s == NULL)
{
/* ANSI states we must use an internal static buffer if s is NULL */
result = p->_emergency;
}
else
{
result = s;
}
pid = _getpid_r (p);
if (worker (p, result, P_tmpdir, "t", pid, &p->_inc))
{
p->_inc++;
return result;
}
return NULL;
}
char *
_DEFUN (_tempnam_r, (p, dir, pfx),
struct _reent *p _AND
_CONST char *dir _AND
_CONST char *pfx)
{
char *filename;
int length;
_CONST char *prefix = (pfx) ? pfx : "";
if (dir == NULL && (dir = getenv ("TMPDIR")) == NULL)
dir = P_tmpdir;
/* two 8 digit numbers + . / */
length = strlen (dir) + strlen (prefix) + (4 * sizeof (int)) + 2 + 1;
filename = _malloc_r (p, length);
if (filename)
{
if (! worker (p, filename, dir, prefix,
_getpid_r (p) ^ (int) (_POINTER_INT) p, &p->_inc))
return NULL;
}
return filename;
}
#ifndef _REENT_ONLY
char *
_DEFUN (tempnam, (dir, pfx),
_CONST char *dir _AND
_CONST char *pfx)
{
return _tempnam_r (_REENT, dir, pfx);
}
char *
_DEFUN (tmpnam, (s),
char *s)
{
return _tmpnam_r (_REENT, s);
}
#endif

145
agbcc/libc/stdio/ungetc.c Normal file
View File

@ -0,0 +1,145 @@
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not 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.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "%W% (Berkeley) %G%";
#endif /* LIBC_SCCS and not lint */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "local.h"
/*
* Expand the ungetc buffer `in place'. That is, adjust fp->_p when
* the buffer moves, so that it points the same distance from the end,
* and move the bytes in the buffer around as necessary so that they
* are all at the end (stack-style).
*/
/*static*/
int
__submore (fp)
register FILE *fp;
{
register int i;
register unsigned char *p;
if (fp->_ub._base == fp->_ubuf)
{
/*
* Get a new buffer (rather than expanding the old one).
*/
if ((p = (unsigned char *) _malloc_r (fp->_data, (size_t) BUFSIZ)) == NULL)
return EOF;
fp->_ub._base = p;
fp->_ub._size = BUFSIZ;
p += BUFSIZ - sizeof (fp->_ubuf);
for (i = sizeof (fp->_ubuf); --i >= 0;)
p[i] = fp->_ubuf[i];
fp->_p = p;
return 0;
}
i = fp->_ub._size;
p = (unsigned char *) _realloc_r (fp->_data, (_PTR) (fp->_ub._base), i << 1);
if (p == NULL)
return EOF;
(void) memcpy ((void *) (p + i), (void *) p, (size_t) i);
fp->_p = p + i;
fp->_ub._base = p;
fp->_ub._size = i << 1;
return 0;
}
int
ungetc (c, fp)
int c;
register FILE *fp;
{
if (c == EOF)
return (EOF);
/* Ensure stdio has been initialized.
??? Might be able to remove this as some other stdio routine should
have already been called to get the char we are un-getting. */
CHECK_INIT (fp);
/* After ungetc, we won't be at eof anymore */
fp->_flags &= ~__SEOF;
if ((fp->_flags & __SRD) == 0)
{
/*
* Not already reading: no good unless reading-and-writing.
* Otherwise, flush any current write stuff.
*/
if ((fp->_flags & __SRW) == 0)
return EOF;
if (fp->_flags & __SWR)
{
if (fflush (fp))
return EOF;
fp->_flags &= ~__SWR;
fp->_w = 0;
fp->_lbfsize = 0;
}
fp->_flags |= __SRD;
}
c = (unsigned char) c;
/*
* If we are in the middle of ungetc'ing, just continue.
* This may require expanding the current ungetc buffer.
*/
if (HASUB (fp))
{
if (fp->_r >= fp->_ub._size && __submore (fp))
return EOF;
*--fp->_p = c;
fp->_r++;
return c;
}
/*
* If we can handle this by simply backing up, do so,
* but never replace the original character.
* (This makes sscanf() work when scanning `const' data.)
*/
if (fp->_bf._base != NULL && fp->_p > fp->_bf._base && fp->_p[-1] == c)
{
fp->_p--;
fp->_r++;
return c;
}
/*
* Create an ungetc buffer.
* Initially, we will use the `reserve' buffer.
*/
fp->_ur = fp->_r;
fp->_up = fp->_p;
fp->_ub._base = fp->_ubuf;
fp->_ub._size = sizeof (fp->_ubuf);
fp->_ubuf[sizeof (fp->_ubuf) - 1] = c;
fp->_p = &fp->_ubuf[sizeof (fp->_ubuf) - 1];
fp->_r = 1;
return c;
}

921
agbcc/libc/stdio/vfprintf.c Normal file
View File

@ -0,0 +1,921 @@
/*
FUNCTION
<<vprintf>>, <<vfprintf>>, <<vsprintf>>---format argument list
INDEX
vprintf
INDEX
vfprintf
INDEX
vsprintf
ANSI_SYNOPSIS
#include <stdio.h>
#include <stdarg.h>
int vprintf(const char *<[fmt]>, va_list <[list]>);
int vfprintf(FILE *<[fp]>, const char *<[fmt]>, va_list <[list]>);
int vsprintf(char *<[str]>, const char *<[fmt]>, va_list <[list]>);
int _vprintf_r(void *<[reent]>, const char *<[fmt]>,
va_list <[list]>);
int _vfprintf_r(void *<[reent]>, FILE *<[fp]>, const char *<[fmt]>,
va_list <[list]>);
int _vsprintf_r(void *<[reent]>, char *<[str]>, const char *<[fmt]>,
va_list <[list]>);
TRAD_SYNOPSIS
#include <stdio.h>
#include <varargs.h>
int vprintf( <[fmt]>, <[list]>)
char *<[fmt]>;
va_list <[list]>;
int vfprintf(<[fp]>, <[fmt]>, <[list]>)
FILE *<[fp]>;
char *<[fmt]>;
va_list <[list]>;
int vsprintf(<[str]>, <[fmt]>, <[list]>)
char *<[str]>;
char *<[fmt]>;
va_list <[list]>;
int _vprintf_r(<[reent]>, <[fmt]>, <[list]>)
char *<[reent]>;
char *<[fmt]>;
va_list <[list]>;
int _vfprintf_r(<[reent]>, <[fp]>, <[fmt]>, <[list]>)
char *<[reent]>;
FILE *<[fp]>;
char *<[fmt]>;
va_list <[list]>;
int _vsprintf_r(<[reent]>, <[str]>, <[fmt]>, <[list]>)
char *<[reent]>;
char *<[str]>;
char *<[fmt]>;
va_list <[list]>;
DESCRIPTION
<<vprintf>>, <<vfprintf>>, and <<vsprintf>> are (respectively)
variants of <<printf>>, <<fprintf>>, and <<sprintf>>. They differ
only in allowing their caller to pass the variable argument list as a
<<va_list>> object (initialized by <<va_start>>) rather than directly
accepting a variable number of arguments.
RETURNS
The return values are consistent with the corresponding functions:
<<vsprintf>> returns the number of bytes in the output string,
save that the concluding <<NULL>> is not counted.
<<vprintf>> and <<vfprintf>> return the number of characters transmitted.
If an error occurs, <<vprintf>> and <<vfprintf>> return <<EOF>>. No
error returns occur for <<vsprintf>>.
PORTABILITY
ANSI C requires all three functions.
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
*/
/*-
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Chris Torek.
*
* 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: @(#)vfprintf.c 5.50 (Berkeley) 12/16/92";*/
static char *rcsid = "$Id: vfprintf.c,v 1.26 1998/10/20 23:29:23 jjohnstn Exp $";
#endif /* LIBC_SCCS and not lint */
/*
* Actual printf innards.
*
* This code is large and complicated...
*/
#ifdef INTEGER_ONLY
#define VFPRINTF vfiprintf
#define _VFPRINTF_R _vfiprintf_r
#else
#define VFPRINTF vfprintf
#define _VFPRINTF_R _vfprintf_r
#define FLOATING_POINT
#endif
#define _NO_LONGLONG
#if defined WANT_PRINTF_LONG_LONG && defined __GNUC__
# undef _NO_LONGLONG
#endif
#include <_ansi.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <reent.h>
#ifdef _HAVE_STDC
#include <stdarg.h>
#else
#include <varargs.h>
#endif
#include "local.h"
#include "fvwrite.h"
#include "ieeefp.h"
/*
* Flush out all the vectors defined by the given uio,
* then reset it so that it can be reused.
*/
static int
__sprint(fp, uio)
FILE *fp;
register struct __suio *uio;
{
register int err;
if (uio->uio_resid == 0) {
uio->uio_iovcnt = 0;
return (0);
}
err = __sfvwrite(fp, uio);
uio->uio_resid = 0;
uio->uio_iovcnt = 0;
return (err);
}
/*
* Helper function for `fprintf to unbuffered unix file': creates a
* temporary buffer. We only work on write-only files; this avoids
* worries about ungetc buffers and so forth.
*/
static int
__sbprintf(fp, fmt, ap)
register FILE *fp;
const char *fmt;
va_list ap;
{
int ret;
FILE fake;
unsigned char buf[BUFSIZ];
/* copy the important variables */
fake._data = fp->_data;
fake._flags = fp->_flags & ~__SNBF;
fake._file = fp->_file;
fake._cookie = fp->_cookie;
fake._write = fp->_write;
/* set up the buffer */
fake._bf._base = fake._p = buf;
fake._bf._size = fake._w = sizeof(buf);
fake._lbfsize = 0; /* not actually used, but Just In Case */
/* do the work, then copy any error status */
ret = VFPRINTF(&fake, fmt, ap);
if (ret >= 0 && fflush(&fake))
ret = EOF;
if (fake._flags & __SERR)
fp->_flags |= __SERR;
return (ret);
}
#ifdef FLOATING_POINT
#include <locale.h>
#include <math.h>
#include "floatio.h"
#define BUF (MAXEXP+MAXFRACT+1) /* + decimal point */
#define DEFPREC 6
static char *cvt _PARAMS((struct _reent *, double, int, int, char *, int *, int, int *));
static int exponent _PARAMS((char *, int, int));
#else /* no FLOATING_POINT */
#define BUF 40
#endif /* FLOATING_POINT */
/*
* Macros for converting digits to letters and vice versa
*/
#define to_digit(c) ((c) - '0')
#define is_digit(c) ((unsigned)to_digit(c) <= 9)
#define to_char(n) ((n) + '0')
/*
* Flags used during conversion.
*/
#define ALT 0x001 /* alternate form */
#define HEXPREFIX 0x002 /* add 0x or 0X prefix */
#define LADJUST 0x004 /* left adjustment */
#define LONGDBL 0x008 /* long double; unimplemented */
#define LONGINT 0x010 /* long integer */
#define QUADINT 0x020 /* quad integer */
#define SHORTINT 0x040 /* short integer */
#define ZEROPAD 0x080 /* zero (as opposed to blank) pad */
#define FPT 0x100 /* Floating point number */
int
_DEFUN (VFPRINTF, (fp, fmt0, ap),
FILE * fp _AND
_CONST char *fmt0 _AND
va_list ap)
{
return _VFPRINTF_R (fp->_data, fp, fmt0, ap);
}
int
_DEFUN (_VFPRINTF_R, (data, fp, fmt0, ap),
struct _reent *data _AND
FILE * fp _AND
_CONST char *fmt0 _AND
va_list ap)
{
register char *fmt; /* format string */
register int ch; /* character from fmt */
register int n, m; /* handy integers (short term usage) */
register char *cp; /* handy char pointer (short term usage) */
register struct __siov *iovp;/* for PRINT macro */
register int flags; /* flags as above */
int ret; /* return value accumulator */
int width; /* width from format (%8d), or 0 */
int prec; /* precision from format (%.3d), or -1 */
char sign; /* sign prefix (' ', '+', '-', or \0) */
wchar_t wc;
#ifdef FLOATING_POINT
char *decimal_point = localeconv()->decimal_point;
char softsign; /* temporary negative sign for floats */
double _double; /* double precision arguments %[eEfgG] */
int expt; /* integer value of exponent */
int expsize; /* character count for expstr */
int ndig; /* actual number of digits returned by cvt */
char expstr[7]; /* buffer for exponent string */
#endif
#ifndef _NO_LONGLONG
#define quad_t long long
#define u_quad_t unsigned long long
#endif
#ifndef _NO_LONGLONG
u_quad_t _uquad; /* integer arguments %[diouxX] */
#else
u_long _uquad;
#endif
enum { OCT, DEC, HEX } base;/* base for [diouxX] conversion */
int dprec; /* a copy of prec if [diouxX], 0 otherwise */
int realsz; /* field size expanded by dprec */
int size; /* size of converted field or string */
char *xdigs; /* digits for [xX] conversion */
#define NIOV 8
struct __suio uio; /* output information: summary */
struct __siov iov[NIOV];/* ... and individual io vectors */
char buf[BUF]; /* space for %c, %[diouxX], %[eEfgG] */
char ox[2]; /* space for 0x hex-prefix */
int state = 0; /* mbtowc calls from library must not change state */
/*
* Choose PADSIZE to trade efficiency vs. size. If larger printf
* fields occur frequently, increase PADSIZE and make the initialisers
* below longer.
*/
#define PADSIZE 16 /* pad chunk size */
static _CONST char blanks[PADSIZE] =
{' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
static _CONST char zeroes[PADSIZE] =
{'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
/*
* BEWARE, these `goto error' on error, and PAD uses `n'.
*/
#define PRINT(ptr, len) { \
iovp->iov_base = (ptr); \
iovp->iov_len = (len); \
uio.uio_resid += (len); \
iovp++; \
if (++uio.uio_iovcnt >= NIOV) { \
if (__sprint(fp, &uio)) \
goto error; \
iovp = iov; \
} \
}
#define PAD(howmany, with) { \
if ((n = (howmany)) > 0) { \
while (n > PADSIZE) { \
PRINT(with, PADSIZE); \
n -= PADSIZE; \
} \
PRINT(with, n); \
} \
}
#define FLUSH() { \
if (uio.uio_resid && __sprint(fp, &uio)) \
goto error; \
uio.uio_iovcnt = 0; \
iovp = iov; \
}
/*
* To extend shorts properly, we need both signed and unsigned
* argument extraction methods.
*/
#ifndef _NO_LONGLONG
#define SARG() \
(flags&QUADINT ? va_arg(ap, quad_t) : \
flags&LONGINT ? va_arg(ap, long) : \
flags&SHORTINT ? (long)(short)va_arg(ap, int) : \
(long)va_arg(ap, int))
#define UARG() \
(flags&QUADINT ? va_arg(ap, u_quad_t) : \
flags&LONGINT ? va_arg(ap, u_long) : \
flags&SHORTINT ? (u_long)(u_short)va_arg(ap, int) : \
(u_long)va_arg(ap, u_int))
#else
#define SARG() \
(flags&LONGINT ? va_arg(ap, long) : \
flags&SHORTINT ? (long)(short)va_arg(ap, int) : \
(long)va_arg(ap, int))
#define UARG() \
(flags&LONGINT ? va_arg(ap, u_long) : \
flags&SHORTINT ? (u_long)(u_short)va_arg(ap, int) : \
(u_long)va_arg(ap, u_int))
#endif
CHECK_INIT (fp);
/* sorry, fprintf(read_only_file, "") returns EOF, not 0 */
if (cantwrite(fp))
return (EOF);
/* optimise fprintf(stderr) (and other unbuffered Unix files) */
if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) &&
fp->_file >= 0)
return (__sbprintf(fp, fmt0, ap));
fmt = (char *)fmt0;
uio.uio_iov = iovp = iov;
uio.uio_resid = 0;
uio.uio_iovcnt = 0;
ret = 0;
/*
* Scan the format for conversions (`%' character).
*/
for (;;) {
cp = fmt;
while ((n = _mbtowc_r(_REENT, &wc, fmt, MB_CUR_MAX, &state)) > 0) {
fmt += n;
if (wc == '%') {
fmt--;
break;
}
}
if ((m = fmt - cp) != 0) {
PRINT(cp, m);
ret += m;
}
if (n <= 0)
goto done;
fmt++; /* skip over '%' */
flags = 0;
dprec = 0;
width = 0;
prec = -1;
sign = '\0';
rflag: ch = *fmt++;
reswitch: switch (ch) {
case ' ':
/*
* ``If the space and + flags both appear, the space
* flag will be ignored.''
* -- ANSI X3J11
*/
if (!sign)
sign = ' ';
goto rflag;
case '#':
flags |= ALT;
goto rflag;
case '*':
/*
* ``A negative field width argument is taken as a
* - flag followed by a positive field width.''
* -- ANSI X3J11
* They don't exclude field widths read from args.
*/
if ((width = va_arg(ap, int)) >= 0)
goto rflag;
width = -width;
/* FALLTHROUGH */
case '-':
flags |= LADJUST;
goto rflag;
case '+':
sign = '+';
goto rflag;
case '.':
if ((ch = *fmt++) == '*') {
n = va_arg(ap, int);
prec = n < 0 ? -1 : n;
goto rflag;
}
n = 0;
while (is_digit(ch)) {
n = 10 * n + to_digit(ch);
ch = *fmt++;
}
prec = n < 0 ? -1 : n;
goto reswitch;
case '0':
/*
* ``Note that 0 is taken as a flag, not as the
* beginning of a field width.''
* -- ANSI X3J11
*/
flags |= ZEROPAD;
goto rflag;
case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
n = 0;
do {
n = 10 * n + to_digit(ch);
ch = *fmt++;
} while (is_digit(ch));
width = n;
goto reswitch;
#ifdef FLOATING_POINT
case 'L':
flags |= LONGDBL;
goto rflag;
#endif
case 'h':
flags |= SHORTINT;
goto rflag;
case 'l':
if (*fmt == 'l') {
fmt++;
flags |= QUADINT;
} else {
flags |= LONGINT;
}
goto rflag;
case 'q':
flags |= QUADINT;
goto rflag;
case 'c':
*(cp = buf) = va_arg(ap, int);
size = 1;
sign = '\0';
break;
case 'D':
flags |= LONGINT;
/*FALLTHROUGH*/
case 'd':
case 'i':
_uquad = SARG();
#ifndef _NO_LONGLONG
if ((quad_t)_uquad < 0)
#else
if ((long) _uquad < 0)
#endif
{
_uquad = -_uquad;
sign = '-';
}
base = DEC;
goto number;
#ifdef FLOATING_POINT
case 'e':
case 'E':
case 'f':
case 'g':
case 'G':
if (prec == -1) {
prec = DEFPREC;
} else if ((ch == 'g' || ch == 'G') && prec == 0) {
prec = 1;
}
if (flags & LONGDBL) {
_double = (double) va_arg(ap, long double);
} else {
_double = va_arg(ap, double);
}
/* do this before tricky precision changes */
if (isinf(_double)) {
if (_double < 0)
sign = '-';
cp = "Inf";
size = 3;
break;
}
if (isnan(_double)) {
cp = "NaN";
size = 3;
break;
}
flags |= FPT;
cp = cvt(data, _double, prec, flags, &softsign,
&expt, ch, &ndig);
if (ch == 'g' || ch == 'G') {
if (expt <= -4 || expt > prec)
ch = (ch == 'g') ? 'e' : 'E';
else
ch = 'g';
}
if (ch <= 'e') { /* 'e' or 'E' fmt */
--expt;
expsize = exponent(expstr, expt, ch);
size = expsize + ndig;
if (ndig > 1 || flags & ALT)
++size;
} else if (ch == 'f') { /* f fmt */
if (expt > 0) {
size = expt;
if (prec || flags & ALT)
size += prec + 1;
} else /* "0.X" */
size = prec + 2;
} else if (expt >= ndig) { /* fixed g fmt */
size = expt;
if (flags & ALT)
++size;
} else
size = ndig + (expt > 0 ?
1 : 2 - expt);
if (softsign)
sign = '-';
break;
#endif /* FLOATING_POINT */
case 'n':
#ifndef _NO_LONGLONG
if (flags & QUADINT)
*va_arg(ap, quad_t *) = ret;
else
#endif
if (flags & LONGINT)
*va_arg(ap, long *) = ret;
else if (flags & SHORTINT)
*va_arg(ap, short *) = ret;
else
*va_arg(ap, int *) = ret;
continue; /* no output */
case 'O':
flags |= LONGINT;
/*FALLTHROUGH*/
case 'o':
_uquad = UARG();
base = OCT;
goto nosign;
case 'p':
/*
* ``The argument shall be a pointer to void. The
* value of the pointer is converted to a sequence
* of printable characters, in an implementation-
* defined manner.''
* -- ANSI X3J11
*/
/* NOSTRICT */
_uquad = (u_long)(unsigned _POINTER_INT)va_arg(ap, void *);
base = HEX;
xdigs = "0123456789abcdef";
flags |= HEXPREFIX;
ch = 'x';
goto nosign;
case 's':
if ((cp = va_arg(ap, char *)) == NULL)
cp = "(null)";
if (prec >= 0) {
/*
* can't use strlen; can only look for the
* NUL in the first `prec' characters, and
* strlen() will go further.
*/
char *p = memchr(cp, 0, prec);
if (p != NULL) {
size = p - cp;
if (size > prec)
size = prec;
} else
size = prec;
} else
size = strlen(cp);
sign = '\0';
break;
case 'U':
flags |= LONGINT;
/*FALLTHROUGH*/
case 'u':
_uquad = UARG();
base = DEC;
goto nosign;
case 'X':
xdigs = "0123456789ABCDEF";
goto hex;
case 'x':
xdigs = "0123456789abcdef";
hex: _uquad = UARG();
base = HEX;
/* leading 0x/X only if non-zero */
if (flags & ALT && _uquad != 0)
flags |= HEXPREFIX;
/* unsigned conversions */
nosign: sign = '\0';
/*
* ``... diouXx conversions ... if a precision is
* specified, the 0 flag will be ignored.''
* -- ANSI X3J11
*/
number: if ((dprec = prec) >= 0)
flags &= ~ZEROPAD;
/*
* ``The result of converting a zero value with an
* explicit precision of zero is no characters.''
* -- ANSI X3J11
*/
cp = buf + BUF;
if (_uquad != 0 || prec != 0) {
/*
* Unsigned mod is hard, and unsigned mod
* by a constant is easier than that by
* a variable; hence this switch.
*/
switch (base) {
case OCT:
do {
*--cp = to_char(_uquad & 7);
_uquad >>= 3;
} while (_uquad);
/* handle octal leading 0 */
if (flags & ALT && *cp != '0')
*--cp = '0';
break;
case DEC:
/* many numbers are 1 digit */
while (_uquad >= 10) {
*--cp = to_char(_uquad % 10);
_uquad /= 10;
}
*--cp = to_char(_uquad);
break;
case HEX:
do {
*--cp = xdigs[_uquad & 15];
_uquad >>= 4;
} while (_uquad);
break;
default:
cp = "bug in vfprintf: bad base";
size = strlen(cp);
goto skipsize;
}
}
size = buf + BUF - cp;
skipsize:
break;
default: /* "%?" prints ?, unless ? is NUL */
if (ch == '\0')
goto done;
/* pretend it was %c with argument ch */
cp = buf;
*cp = ch;
size = 1;
sign = '\0';
break;
}
/*
* All reasonable formats wind up here. At this point, `cp'
* points to a string which (if not flags&LADJUST) should be
* padded out to `width' places. If flags&ZEROPAD, it should
* first be prefixed by any sign or other prefix; otherwise,
* it should be blank padded before the prefix is emitted.
* After any left-hand padding and prefixing, emit zeroes
* required by a decimal [diouxX] precision, then print the
* string proper, then emit zeroes required by any leftover
* floating precision; finally, if LADJUST, pad with blanks.
*
* Compute actual size, so we know how much to pad.
* size excludes decimal prec; realsz includes it.
*/
realsz = dprec > size ? dprec : size;
if (sign)
realsz++;
else if (flags & HEXPREFIX)
realsz+= 2;
/* right-adjusting blank padding */
if ((flags & (LADJUST|ZEROPAD)) == 0)
PAD(width - realsz, blanks);
/* prefix */
if (sign) {
PRINT(&sign, 1);
} else if (flags & HEXPREFIX) {
ox[0] = '0';
ox[1] = ch;
PRINT(ox, 2);
}
/* right-adjusting zero padding */
if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD)
PAD(width - realsz, zeroes);
/* leading zeroes from decimal precision */
PAD(dprec - size, zeroes);
/* the string or number proper */
#ifdef FLOATING_POINT
if ((flags & FPT) == 0) {
PRINT(cp, size);
} else { /* glue together f_p fragments */
if (ch >= 'f') { /* 'f' or 'g' */
if (_double == 0) {
/* kludge for __dtoa irregularity */
PRINT("0", 1);
if (expt < ndig || (flags & ALT) != 0) {
PRINT(decimal_point, 1);
PAD(ndig - 1, zeroes);
}
} else if (expt <= 0) {
PRINT("0", 1);
PRINT(decimal_point, 1);
PAD(-expt, zeroes);
PRINT(cp, ndig);
} else if (expt >= ndig) {
PRINT(cp, ndig);
PAD(expt - ndig, zeroes);
if (flags & ALT)
PRINT(".", 1);
} else {
PRINT(cp, expt);
cp += expt;
PRINT(".", 1);
PRINT(cp, ndig-expt);
}
} else { /* 'e' or 'E' */
if (ndig > 1 || flags & ALT) {
ox[0] = *cp++;
ox[1] = '.';
PRINT(ox, 2);
if (_double || flags & ALT == 0) {
PRINT(cp, ndig-1);
} else /* 0.[0..] */
/* __dtoa irregularity */
PAD(ndig - 1, zeroes);
} else /* XeYYY */
PRINT(cp, 1);
PRINT(expstr, expsize);
}
}
#else
PRINT(cp, size);
#endif
/* left-adjusting padding (always blank) */
if (flags & LADJUST)
PAD(width - realsz, blanks);
/* finally, adjust ret */
ret += width > realsz ? width : realsz;
FLUSH(); /* copy out the I/O vectors */
}
done:
FLUSH();
error:
return (__sferror(fp) ? EOF : ret);
/* NOTREACHED */
}
#ifdef FLOATING_POINT
extern char *_dtoa_r _PARAMS((struct _reent *, double, int,
int, int *, int *, char **));
static char *
cvt(data, value, ndigits, flags, sign, decpt, ch, length)
struct _reent *data;
double value;
int ndigits, flags, *decpt, ch, *length;
char *sign;
{
int mode, dsgn;
char *digits, *bp, *rve;
__ieee_double_shape_type tmp;
if (ch == 'f') {
mode = 3; /* ndigits after the decimal point */
} else {
/* To obtain ndigits after the decimal point for the 'e'
* and 'E' formats, round to ndigits + 1 significant
* figures.
*/
if (ch == 'e' || ch == 'E') {
ndigits++;
}
mode = 2; /* ndigits significant digits */
}
tmp.value = value;
if (tmp.number.sign) { /* this will check for < 0 and -0.0 */
value = -value;
*sign = '-';
} else
*sign = '\000';
digits = _dtoa_r(data, value, mode, ndigits, decpt, &dsgn, &rve);
if ((ch != 'g' && ch != 'G') || flags & ALT) { /* Print trailing zeros */
bp = digits + ndigits;
if (ch == 'f') {
if (*digits == '0' && value)
*decpt = -ndigits + 1;
bp += *decpt;
}
if (value == 0) /* kludge for __dtoa irregularity */
rve = bp;
while (rve < bp)
*rve++ = '0';
}
*length = rve - digits;
return (digits);
}
static int
exponent(p0, exp, fmtch)
char *p0;
int exp, fmtch;
{
register char *p, *t;
char expbuf[MAXEXP];
p = p0;
*p++ = fmtch;
if (exp < 0) {
exp = -exp;
*p++ = '-';
}
else
*p++ = '+';
t = expbuf + MAXEXP;
if (exp > 9) {
do {
*--t = to_char(exp % 10);
} while ((exp /= 10) > 9);
*--t = to_char(exp);
for (; t < expbuf + MAXEXP; *p++ = *t++);
}
else {
*p++ = '0';
*p++ = to_char(exp);
}
return (p - p0);
}
#endif /* FLOATING_POINT */

905
agbcc/libc/stdio/vfscanf.c Normal file
View File

@ -0,0 +1,905 @@
/* No user fns here. Pesch 15apr92. */
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not 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.
*/
#include <_ansi.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef _HAVE_STDC
#include <stdarg.h>
#else
#include <varargs.h>
#endif
#include "local.h"
#ifndef NO_FLOATING_POINT
#define FLOATING_POINT
#endif
#ifdef FLOATING_POINT
#include "floatio.h"
#define BUF (MAXEXP+MAXFRACT+3) /* 3 = sign + decimal point + NUL */
#else
#define BUF 40
#endif
/*
* Flags used during conversion.
*/
#define LONG 0x01 /* l: long or double */
#define LONGDBL 0x02 /* L: long double; unimplemented */
#define SHORT 0x04 /* h: short */
#define SUPPRESS 0x08 /* suppress assignment */
#define POINTER 0x10 /* weird %p pointer (`fake hex') */
#define NOSKIP 0x20 /* do not skip blanks */
/*
* The following are used in numeric conversions only:
* SIGNOK, NDIGITS, DPTOK, and EXPOK are for floating point;
* SIGNOK, NDIGITS, PFXOK, and NZDIGITS are for integral.
*/
#define SIGNOK 0x40 /* +/- is (still) legal */
#define NDIGITS 0x80 /* no digits detected */
#define DPTOK 0x100 /* (float) decimal point is still legal */
#define EXPOK 0x200 /* (float) exponent (e+3, etc) still legal */
#define PFXOK 0x100 /* 0x prefix is (still) legal */
#define NZDIGITS 0x200 /* no zero digits detected */
/*
* Conversion types.
*/
#define CT_CHAR 0 /* %c conversion */
#define CT_CCL 1 /* %[...] conversion */
#define CT_STRING 2 /* %s conversion */
#define CT_INT 3 /* integer, i.e., strtol or strtoul */
#define CT_FLOAT 4 /* floating, i.e., strtod */
#if 0
#define u_char unsigned char
#endif
#define u_char char
#define u_long unsigned long
/*static*/ u_char *__sccl ();
/*
* vfscanf
*/
#define BufferEmpty (fp->_r <= 0 && __srefill(fp))
int
__svfscanf (fp, fmt0, ap)
register FILE *fp;
char _CONST *fmt0;
va_list ap;
{
register u_char *fmt = (u_char *) fmt0;
register int c; /* character from format, or conversion */
register size_t width; /* field width, or 0 */
register char *p; /* points into all kinds of strings */
register int n; /* handy integer */
register int flags; /* flags as defined above */
register char *p0; /* saves original value of p when necessary */
int nassigned; /* number of fields assigned */
int nread; /* number of characters consumed from fp */
int base = 0; /* base argument to strtol/strtoul */
int nbytes = 1; /* number of bytes read from fmt string */
wchar_t wc; /* wchar to use to read format string */
u_long (*ccfn) () = 0; /* conversion function (strtol/strtoul) */
char ccltab[256]; /* character class table for %[...] */
char buf[BUF]; /* buffer for numeric conversions */
char *lptr; /* literal pointer */
int state = 0; /* value to keep track of multibyte state */
short *sp;
int *ip;
float *flp;
_LONG_DOUBLE *ldp;
double *dp;
long *lp;
/* `basefix' is used to avoid `if' tests in the integer scanner */
static _CONST short basefix[17] =
{10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
nassigned = 0;
nread = 0;
for (;;)
{
#ifndef MB_CAPABLE
wc = *fmt;
#else
nbytes = _mbtowc_r (_REENT, &wc, fmt, MB_CUR_MAX, &state);
#endif
fmt += nbytes;
if (wc == 0)
return nassigned;
if (nbytes == 1 && isspace (wc))
{
for (;;)
{
if (BufferEmpty)
return nassigned;
if (!isspace (*fp->_p))
break;
nread++, fp->_r--, fp->_p++;
}
continue;
}
if (wc != '%')
goto literal;
width = 0;
flags = 0;
/*
* switch on the format. continue if done; break once format
* type is derived.
*/
again:
c = *fmt++;
switch (c)
{
case '%':
literal:
lptr = fmt - nbytes;
for (n = 0; n < nbytes; ++n)
{
if (BufferEmpty)
goto input_failure;
if (*fp->_p != *lptr)
goto match_failure;
fp->_r--, fp->_p++;
nread++;
++lptr;
}
continue;
case '*':
flags |= SUPPRESS;
goto again;
case 'l':
flags |= LONG;
goto again;
case 'L':
flags |= LONGDBL;
goto again;
case 'h':
flags |= SHORT;
goto again;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
width = width * 10 + c - '0';
goto again;
/*
* Conversions. Those marked `compat' are for
* 4.[123]BSD compatibility.
*
* (According to ANSI, E and X formats are supposed to
* the same as e and x. Sorry about that.)
*/
case 'D': /* compat */
flags |= LONG;
/* FALLTHROUGH */
case 'd':
c = CT_INT;
ccfn = (u_long (*)())strtol;
base = 10;
break;
case 'i':
c = CT_INT;
ccfn = (u_long (*)())strtol;
base = 0;
break;
case 'O': /* compat */
flags |= LONG;
/* FALLTHROUGH */
case 'o':
c = CT_INT;
ccfn = strtoul;
base = 8;
break;
case 'u':
c = CT_INT;
ccfn = strtoul;
base = 10;
break;
case 'X': /* compat XXX */
case 'x':
flags |= PFXOK; /* enable 0x prefixing */
c = CT_INT;
ccfn = strtoul;
base = 16;
break;
#ifdef FLOATING_POINT
case 'E': /* compat XXX */
case 'G': /* compat XXX */
/* ANSI says that E,G and X behave the same way as e,g,x */
/* FALLTHROUGH */
case 'e':
case 'f':
case 'g':
c = CT_FLOAT;
break;
#endif
case 's':
c = CT_STRING;
break;
case '[':
fmt = __sccl (ccltab, fmt);
flags |= NOSKIP;
c = CT_CCL;
break;
case 'c':
flags |= NOSKIP;
c = CT_CHAR;
break;
case 'p': /* pointer format is like hex */
flags |= POINTER | PFXOK;
c = CT_INT;
ccfn = strtoul;
base = 16;
break;
case 'n':
if (flags & SUPPRESS) /* ??? */
continue;
if (flags & SHORT)
{
sp = va_arg (ap, short *);
*sp = nread;
}
else if (flags & LONG)
{
lp = va_arg (ap, long *);
*lp = nread;
}
else
{
ip = va_arg (ap, int *);
*ip = nread;
}
continue;
/*
* Disgusting backwards compatibility hacks. XXX
*/
case '\0': /* compat */
return EOF;
default: /* compat */
if (isupper (c))
flags |= LONG;
c = CT_INT;
ccfn = (u_long (*)())strtol;
base = 10;
break;
}
/*
* We have a conversion that requires input.
*/
if (BufferEmpty)
goto input_failure;
/*
* Consume leading white space, except for formats that
* suppress this.
*/
if ((flags & NOSKIP) == 0)
{
while (isspace (*fp->_p))
{
nread++;
if (--fp->_r > 0)
fp->_p++;
else
#ifndef CYGNUS_NEC
if (__srefill (fp))
#endif
goto input_failure;
}
/*
* Note that there is at least one character in the
* buffer, so conversions that do not set NOSKIP ca
* no longer result in an input failure.
*/
}
/*
* Do the conversion.
*/
switch (c)
{
case CT_CHAR:
/* scan arbitrary characters (sets NOSKIP) */
if (width == 0)
width = 1;
if (flags & SUPPRESS)
{
size_t sum = 0;
for (;;)
{
if ((n = fp->_r) < width)
{
sum += n;
width -= n;
fp->_p += n;
#ifndef CYGNUS_NEC
if (__srefill (fp))
{
#endif
if (sum == 0)
goto input_failure;
break;
#ifndef CYGNUS_NEC
}
#endif
}
else
{
sum += width;
fp->_r -= width;
fp->_p += width;
break;
}
}
nread += sum;
}
else
{
#ifdef CYGNUS_NEC
/* Kludge city for the moment */
char *dest = va_arg (ap, char *);
int n = width;
if (fp->_r == 0)
goto input_failure;
while (n && fp->_r)
{
*dest++ = *(fp->_p++);
n--;
fp->_r--;
nread++;
}
#else
size_t r = fread ((_PTR) va_arg (ap, char *), 1, width, fp);
if (r == 0)
goto input_failure;
nread += r;
#endif
nassigned++;
}
break;
case CT_CCL:
/* scan a (nonempty) character class (sets NOSKIP) */
if (width == 0)
width = ~0; /* `infinity' */
/* take only those things in the class */
if (flags & SUPPRESS)
{
n = 0;
while (ccltab[*fp->_p])
{
n++, fp->_r--, fp->_p++;
if (--width == 0)
break;
if (BufferEmpty)
{
if (n == 0)
goto input_failure;
break;
}
}
if (n == 0)
goto match_failure;
}
else
{
p0 = p = va_arg (ap, char *);
while (ccltab[*fp->_p])
{
fp->_r--;
*p++ = *fp->_p++;
if (--width == 0)
break;
if (BufferEmpty)
{
if (p == p0)
goto input_failure;
break;
}
}
n = p - p0;
if (n == 0)
goto match_failure;
*p = 0;
nassigned++;
}
nread += n;
break;
case CT_STRING:
/* like CCL, but zero-length string OK, & no NOSKIP */
if (width == 0)
width = ~0;
if (flags & SUPPRESS)
{
n = 0;
while (!isspace (*fp->_p))
{
n++, fp->_r--, fp->_p++;
if (--width == 0)
break;
if (BufferEmpty)
break;
}
nread += n;
}
else
{
p0 = p = va_arg (ap, char *);
while (!isspace (*fp->_p))
{
fp->_r--;
*p++ = *fp->_p++;
if (--width == 0)
break;
if (BufferEmpty)
break;
}
*p = 0;
nread += p - p0;
nassigned++;
}
continue;
case CT_INT:
/* scan an integer as if by strtol/strtoul */
#ifdef hardway
if (width == 0 || width > sizeof (buf) - 1)
width = sizeof (buf) - 1;
#else
/* size_t is unsigned, hence this optimisation */
if (--width > sizeof (buf) - 2)
width = sizeof (buf) - 2;
width++;
#endif
flags |= SIGNOK | NDIGITS | NZDIGITS;
for (p = buf; width; width--)
{
c = *fp->_p;
/*
* Switch on the character; `goto ok' if we
* accept it as a part of number.
*/
switch (c)
{
/*
* The digit 0 is always legal, but is special.
* For %i conversions, if no digits (zero or nonzero)
* have been scanned (only signs), we will have base==0.
* In that case, we should set it to 8 and enable 0x
* prefixing. Also, if we have not scanned zero digits
* before this, do not turn off prefixing (someone else
* will turn it off if we have scanned any nonzero digits).
*/
case '0':
if (base == 0)
{
base = 8;
flags |= PFXOK;
}
if (flags & NZDIGITS)
flags &= ~(SIGNOK | NZDIGITS | NDIGITS);
else
flags &= ~(SIGNOK | PFXOK | NDIGITS);
goto ok;
/* 1 through 7 always legal */
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
base = basefix[base];
flags &= ~(SIGNOK | PFXOK | NDIGITS);
goto ok;
/* digits 8 and 9 ok iff decimal or hex */
case '8':
case '9':
base = basefix[base];
if (base <= 8)
break; /* not legal here */
flags &= ~(SIGNOK | PFXOK | NDIGITS);
goto ok;
/* letters ok iff hex */
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
/* no need to fix base here */
if (base <= 10)
break; /* not legal here */
flags &= ~(SIGNOK | PFXOK | NDIGITS);
goto ok;
/* sign ok only as first character */
case '+':
case '-':
if (flags & SIGNOK)
{
flags &= ~SIGNOK;
goto ok;
}
break;
/* x ok iff flag still set & 2nd char */
case 'x':
case 'X':
if (flags & PFXOK && p == buf + 1)
{
base = 16;/* if %i */
flags &= ~PFXOK;
goto ok;
}
break;
}
/*
* If we got here, c is not a legal character
* for a number. Stop accumulating digits.
*/
break;
ok:
/*
* c is legal: store it and look at the next.
*/
*p++ = c;
if (--fp->_r > 0)
fp->_p++;
else
#ifndef CYGNUS_NEC
if (__srefill (fp))
#endif
break; /* EOF */
}
/*
* If we had only a sign, it is no good; push back the sign.
* If the number ends in `x', it was [sign] '0' 'x', so push back
* the x and treat it as [sign] '0'.
*/
if (flags & NDIGITS)
{
if (p > buf)
_CAST_VOID ungetc (*(u_char *)-- p, fp);
goto match_failure;
}
c = ((u_char *) p)[-1];
if (c == 'x' || c == 'X')
{
--p;
/*(void)*/ ungetc (c, fp);
}
if ((flags & SUPPRESS) == 0)
{
u_long res;
*p = 0;
res = (*ccfn) (buf, (char **) NULL, base);
if (flags & POINTER)
*(va_arg (ap, _PTR *)) = (_PTR) (unsigned _POINTER_INT) res;
else if (flags & SHORT)
{
sp = va_arg (ap, short *);
*sp = res;
}
else if (flags & LONG)
{
lp = va_arg (ap, long *);
*lp = res;
}
else
{
ip = va_arg (ap, int *);
*ip = res;
}
nassigned++;
}
nread += p - buf;
break;
#ifdef FLOATING_POINT
case CT_FLOAT:
/* scan a floating point number as if by strtod */
#ifdef hardway
if (width == 0 || width > sizeof (buf) - 1)
width = sizeof (buf) - 1;
#else
/* size_t is unsigned, hence this optimisation */
if (--width > sizeof (buf) - 2)
width = sizeof (buf) - 2;
width++;
#endif
flags |= SIGNOK | NDIGITS | DPTOK | EXPOK;
for (p = buf; width; width--)
{
c = *fp->_p;
/*
* This code mimicks the integer conversion
* code, but is much simpler.
*/
switch (c)
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
flags &= ~(SIGNOK | NDIGITS);
goto fok;
case '+':
case '-':
if (flags & SIGNOK)
{
flags &= ~SIGNOK;
goto fok;
}
break;
case '.':
if (flags & DPTOK)
{
flags &= ~(SIGNOK | DPTOK);
goto fok;
}
break;
case 'e':
case 'E':
/* no exponent without some digits */
if ((flags & (NDIGITS | EXPOK)) == EXPOK)
{
flags =
(flags & ~(EXPOK | DPTOK)) |
SIGNOK | NDIGITS;
goto fok;
}
break;
}
break;
fok:
*p++ = c;
if (--fp->_r > 0)
fp->_p++;
else
#ifndef CYGNUS_NEC
if (__srefill (fp))
#endif
break; /* EOF */
}
/*
* If no digits, might be missing exponent digits
* (just give back the exponent) or might be missing
* regular digits, but had sign and/or decimal point.
*/
if (flags & NDIGITS)
{
if (flags & EXPOK)
{
/* no digits at all */
while (p > buf)
ungetc (*(u_char *)-- p, fp);
goto match_failure;
}
/* just a bad exponent (e and maybe sign) */
c = *(u_char *)-- p;
if (c != 'e' && c != 'E')
{
_CAST_VOID ungetc (c, fp); /* sign */
c = *(u_char *)-- p;
}
_CAST_VOID ungetc (c, fp);
}
if ((flags & SUPPRESS) == 0)
{
double res;
*p = 0;
res = atof (buf);
if (flags & LONG)
{
dp = va_arg (ap, double *);
*dp = res;
}
else if (flags & LONGDBL)
{
ldp = va_arg (ap, _LONG_DOUBLE *);
*ldp = res;
}
else
{
flp = va_arg (ap, float *);
*flp = res;
}
nassigned++;
}
nread += p - buf;
break;
#endif /* FLOATING_POINT */
}
}
input_failure:
return nassigned ? nassigned : -1;
match_failure:
return nassigned;
}
/*
* Fill in the given table from the scanset at the given format
* (just after `['). Return a pointer to the character past the
* closing `]'. The table has a 1 wherever characters should be
* considered part of the scanset.
*/
/*static*/
u_char *
__sccl (tab, fmt)
register char *tab;
register u_char *fmt;
{
register int c, n, v;
/* first `clear' the whole table */
c = *fmt++; /* first char hat => negated scanset */
if (c == '^')
{
v = 1; /* default => accept */
c = *fmt++; /* get new first char */
}
else
v = 0; /* default => reject */
/* should probably use memset here */
for (n = 0; n < 256; n++)
tab[n] = v;
if (c == 0)
return fmt - 1; /* format ended before closing ] */
/*
* Now set the entries corresponding to the actual scanset to the
* opposite of the above.
*
* The first character may be ']' (or '-') without being special; the
* last character may be '-'.
*/
v = 1 - v;
for (;;)
{
tab[c] = v; /* take character c */
doswitch:
n = *fmt++; /* and examine the next */
switch (n)
{
case 0: /* format ended too soon */
return fmt - 1;
case '-':
/*
* A scanset of the form [01+-] is defined as `the digit 0, the
* digit 1, the character +, the character -', but the effect of a
* scanset such as [a-zA-Z0-9] is implementation defined. The V7
* Unix scanf treats `a-z' as `the letters a through z', but treats
* `a-a' as `the letter a, the character -, and the letter a'.
*
* For compatibility, the `-' is not considerd to define a range if
* the character following it is either a close bracket (required by
* ANSI) or is not numerically greater than the character we just
* stored in the table (c).
*/
n = *fmt;
if (n == ']' || n < c)
{
c = '-';
break; /* resume the for(;;) */
}
fmt++;
do
{ /* fill in the range */
tab[++c] = v;
}
while (c < n);
#if 1 /* XXX another disgusting compatibility hack */
/*
* Alas, the V7 Unix scanf also treats formats such
* as [a-c-e] as `the letters a through e'. This too
* is permitted by the standard....
*/
goto doswitch;
#else
c = *fmt++;
if (c == 0)
return fmt - 1;
if (c == ']')
return fmt;
#endif
break;
case ']': /* end of scanset */
return fmt;
default: /* just another character */
c = n;
break;
}
}
/* NOTREACHED */
}

View File

@ -0,0 +1,35 @@
/* doc in vfprintf.c */
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not 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.
*/
#include <_ansi.h>
#include <stdio.h>
#ifdef _HAVE_STDC
#include <stdarg.h>
#else
#include <varargs.h>
#endif
int
vprintf (fmt, ap)
char _CONST *fmt;
va_list ap;
{
return vfprintf (stdout, fmt, ap);
}

View File

@ -0,0 +1,50 @@
/* doc in vfprintf.c */
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not 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.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "%W% (Berkeley) %G%";
#endif /* LIBC_SCCS and not lint */
#include <_ansi.h>
#include <reent.h>
#include <stdio.h>
#include <limits.h>
#ifdef _HAVE_STDC
#include <stdarg.h>
#else
#include <varargs.h>
#endif
int
vsprintf (str, fmt, ap)
char *str;
char _CONST *fmt;
va_list ap;
{
int ret;
FILE f;
f._flags = __SWR | __SSTR;
f._bf._base = f._p = (unsigned char *) str;
f._bf._size = f._w = INT_MAX;
f._data = _REENT;
ret = vfprintf (&f, fmt, ap);
*f._p = 0;
return ret;
}

81
agbcc/libc/stdio/wbuf.c Normal file
View File

@ -0,0 +1,81 @@
/* No user fns here. Pesch 15apr92. */
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not 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.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "%W% (Berkeley) %G%";
#endif /* LIBC_SCCS and not lint */
#include <stdio.h>
#include "local.h"
#include "fvwrite.h"
/*
* Write the given character into the (probably full) buffer for
* the given file. Flush the buffer out if it is or becomes full,
* or if c=='\n' and the file is line buffered.
*/
int
__swbuf (c, fp)
register int c;
register FILE *fp;
{
register int n;
/* Ensure stdio has been initialized. */
CHECK_INIT (fp);
/*
* In case we cannot write, or longjmp takes us out early,
* make sure _w is 0 (if fully- or un-buffered) or -_bf._size
* (if line buffered) so that we will get called again.
* If we did not do this, a sufficient number of putc()
* calls might wrap _w from negative to positive.
*/
fp->_w = fp->_lbfsize;
if (cantwrite (fp))
return EOF;
c = (unsigned char) c;
/*
* If it is completely full, flush it out. Then, in any case,
* stuff c into the buffer. If this causes the buffer to fill
* completely, or if c is '\n' and the file is line buffered,
* flush it (perhaps a second time). The second flush will always
* happen on unbuffered streams, where _bf._size==1; fflush()
* guarantees that putc() will always call wbuf() by setting _w
* to 0, so we need not do anything else.
*/
n = fp->_p - fp->_bf._base;
if (n >= fp->_bf._size)
{
if (fflush (fp))
return EOF;
n = 0;
}
fp->_w--;
*fp->_p++ = c;
if (++n == fp->_bf._size || (fp->_flags & __SLBF && c == '\n'))
if (fflush (fp))
return EOF;
return c;
}

79
agbcc/libc/stdio/wsetup.c Normal file
View File

@ -0,0 +1,79 @@
/* No user fns here. Pesch 15apr92. */
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not 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.
*/
#include <stdio.h>
#include <stdlib.h>
#include "local.h"
/*
* Various output routines call wsetup to be sure it is safe to write,
* because either _flags does not include __SWR, or _buf is NULL.
* _wsetup returns 0 if OK to write, nonzero otherwise.
*/
int
_DEFUN (__swsetup, (fp),
register FILE * fp)
{
/* Make sure stdio is set up. */
CHECK_INIT (fp);
/*
* If we are not writing, we had better be reading and writing.
*/
if ((fp->_flags & __SWR) == 0)
{
if ((fp->_flags & __SRW) == 0)
return EOF;
if (fp->_flags & __SRD)
{
/* clobber any ungetc data */
if (HASUB (fp))
FREEUB (fp);
fp->_flags &= ~(__SRD | __SEOF);
fp->_r = 0;
fp->_p = fp->_bf._base;
}
fp->_flags |= __SWR;
}
/*
* Make a buffer if necessary, then set _w.
*/
/* NOT NEEDED FOR CYGNUS SPRINTF ONLY jpg */
if (fp->_bf._base == NULL)
__smakebuf (fp);
if (fp->_flags & __SLBF)
{
/*
* It is line buffered, so make _lbfsize be -_bufsize
* for the putc() macro. We will change _lbfsize back
* to 0 whenever we turn off __SWR.
*/
fp->_w = 0;
fp->_lbfsize = -fp->_bf._size;
}
else
fp->_w = fp->_flags & __SNBF ? 0 : fp->_bf._size;
return 0;
}

View File

@ -0,0 +1,44 @@
/*
* return (*acc) scaled by 10**dexp.
*/
#include <_ansi.h>
#include <reent.h>
#include "std.h"
#define abs(x) (((x) < 0) ? -(x) : (x))
double
_DEFUN (__adjust, (ptr, acc, dexp, sign),
struct _reent *ptr _AND
double *acc _AND
int dexp _AND
int sign)
/* *acc the 64 bit accumulator */
/* dexp decimal exponent */
/* sign sign flag */
{
double r;
if (dexp > MAXE)
{
ptr->_errno = ERANGE;
return (sign) ? -HUGE_VAL : HUGE_VAL;
}
else if (dexp < MINE)
{
ptr->_errno = ERANGE;
return 0.0;
}
r = *acc;
if (sign)
r = -r;
if (dexp == 0)
return r;
if (dexp < 0)
return r / __exp10 (abs (dexp));
else
return r * __exp10 (dexp);
}

View File

@ -0,0 +1,29 @@
/*
* compute 10**x by successive squaring.
*/
#include <_ansi.h>
double
_DEFUN (__exp10, (x),
unsigned x)
{
static _CONST double powtab[] =
{1.0,
10.0,
100.0,
1000.0,
10000.0};
if (x < (sizeof (powtab) / sizeof (double)))
return powtab[x];
else if (x & 1)
{
return 10.0 * __exp10 (x - 1);
}
else
{
double n = __exp10 (x / 2);
return n * n;
}
}

View File

@ -0,0 +1,23 @@
/*
* [atw] multiply 64 bit accumulator by 10 and add digit.
* The KA/CA way to do this should be to use
* a 64-bit integer internally and use "adjust" to
* convert it to float at the end of processing.
*/
#include <_ansi.h>
int
_DEFUN (__ten_mul, (acc, digit),
double *acc _AND
int digit)
{
/*
* [atw] Crude, but effective (at least on a KB)...
*/
*acc *= 10;
*acc += digit;
return 0; /* no overflow */
}

66
agbcc/libc/stdlib/abort.c Normal file
View File

@ -0,0 +1,66 @@
/* NetWare can not use this implementation of abort. It provides its
own version of abort in clib.nlm. If we can not use clib.nlm, then
we must write abort in sys/netware. */
#ifdef ABORT_PROVIDED
int _dummy_abort = 1;
#else
/*
FUNCTION
<<abort>>---abnormal termination of a program
INDEX
abort
ANSI_SYNOPSIS
#include <stdlib.h>
void abort(void);
TRAD_SYNOPSIS
#include <stdlib.h>
void abort();
DESCRIPTION
Use <<abort>> to signal that your program has detected a condition it
cannot deal with. Normally, <<abort>> ends your program's execution.
Before terminating your program, <<abort>> raises the exception <<SIGABRT>>
(using `<<raise(SIGABRT)>>'). If you have used <<signal>> to register
an exception handler for this condition, that handler has the
opportunity to retain control, thereby avoiding program termination.
In this implementation, <<abort>> does not perform any stream- or
file-related cleanup (the host environment may do so; if not, you can
arrange for your program to do its own cleanup with a <<SIGABRT>>
exception handler).
RETURNS
<<abort>> does not return to its caller.
PORTABILITY
ANSI C requires <<abort>>.
Supporting OS subroutines required: <<getpid>>, <<kill>>.
*/
#include <stdlib.h>
#include <signal.h>
_VOID
_DEFUN_VOID (abort)
{
#ifdef ABORT_MESSAGE
write (2, "Abort called\n", sizeof ("Abort called\n")-1);
#endif
while (1)
{
raise (SIGABRT);
_exit (1);
}
}
#endif

43
agbcc/libc/stdlib/abs.c Normal file
View File

@ -0,0 +1,43 @@
/*
FUNCTION
<<abs>>---integer absolute value (magnitude)
INDEX
abs
ANSI_SYNOPSIS
#include <stdlib.h>
int abs(int <[i]>);
TRAD_SYNOPSIS
#include <stdlib.h>
int abs(<[i]>)
int <[i]>;
DESCRIPTION
<<abs>> returns
@tex
$|x|$,
@end tex
the absolute value of <[i]> (also called the magnitude
of <[i]>). That is, if <[i]> is negative, the result is the opposite
of <[i]>, but if <[i]> is nonnegative the result is <[i]>.
The similar function <<labs>> uses and returns <<long>> rather than <<int>> values.
RETURNS
The result is a nonnegative integer.
PORTABILITY
<<abs>> is ANSI.
No supporting OS subroutines are required.
*/
#include <stdlib.h>
int
_DEFUN (abs, (i), int i)
{
return (i < 0) ? -i : i;
}

View File

@ -0,0 +1,62 @@
/*
FUNCTION
<<assert>>---Macro for Debugging Diagnostics
INDEX
assert
ANSI_SYNOPSIS
#include <assert.h>
void assert(int <[expression]>);
TRAD_SYNOPSIS
#include <assert.h>
assert(<[expression]>)
int <[expression]>;
DESCRIPTION
Use this macro to embed debuggging diagnostic statements in
your programs. The argument <[expression]> should be an
expression which evaluates to true (nonzero) when your program
is working as you intended.
When <[expression]> evaluates to false (zero), <<assert>>
calls <<abort>>, after first printing a message showing what
failed and where:
. Assertion failed: <[expression]>, file <[filename]>, line <[lineno]>
The macro is defined to permit you to turn off all uses of
<<assert>> at compile time by defining <<NDEBUG>> as a
preprocessor variable. If you do this, the <<assert>> macro
expands to
. (void(0))
RETURNS
<<assert>> does not return a value.
PORTABILITY
The <<assert>> macro is required by ANSI, as is the behavior
when <<NDEBUG>> is defined.
Supporting OS subroutines required (only if enabled): <<close>>, <<fstat>>,
<<getpid>>, <<isatty>>, <<kill>>, <<lseek>>, <<read>>, <<sbrk>>, <<write>>.
*/
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
void
_DEFUN (__assert, (file, line, failedexpr),
const char *file _AND
int line _AND
const char *failedexpr)
{
(void)fiprintf(stderr,
"assertion \"%s\" failed: file \"%s\", line %d\n",
failedexpr, file, line);
abort();
/* NOTREACHED */
}

View File

@ -0,0 +1,80 @@
/*
* Copyright (c) 1990 Regents of the University of California.
* All rights reserved.
*
* %sccs.include.redist.c%
*/
/*
FUNCTION
<<atexit>>---request execution of functions at program exit
INDEX
atexit
ANSI_SYNOPSIS
#include <stdlib.h>
int atexit(void (*<[function]>)(void);
TRAD_SYNOPSIS
#include <stdlib.h>
int atexit((<[function]>)
void (*<[function]>)();
DESCRIPTION
You can use <<atexit>> to enroll functions in a list of functions that
will be called when your program terminates normally. The argument is
a pointer to a user-defined function (which must not require arguments and
must not return a result).
The functions are kept in a LIFO stack; that is, the last function
enrolled by <<atexit>> will be the first to execute when your program
exits.
There is no built-in limit to the number of functions you can enroll
in this list; however, after every group of 32 functions is enrolled,
<<atexit>> will call <<malloc>> to get space for the next part of the
list. The initial list of 32 functions is statically allocated, so
you can always count on at least that many slots available.
RETURNS
<<atexit>> returns <<0>> if it succeeds in enrolling your function,
<<-1>> if it fails (possible only if no space was available for
<<malloc>> to extend the list of functions).
PORTABILITY
<<atexit>> is required by the ANSI standard, which also specifies that
implementations must support enrolling at least 32 functions.
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
*/
#include <stddef.h>
#include <stdlib.h>
#include <reent.h>
/*
* Register a function to be performed at exit.
*/
int
_DEFUN (atexit,
(fn),
_VOID _EXFUN ((*fn), (_VOID)))
{
register struct _atexit *p;
if ((p = _REENT->_atexit) == NULL)
_REENT->_atexit = p = &_REENT->_atexit0;
if (p->_ind >= _ATEXIT_SIZE)
{
if ((p = (struct _atexit *) malloc (sizeof *p)) == NULL)
return -1;
p->_ind = 0;
p->_next = _REENT->_atexit;
_REENT->_atexit = p;
}
p->_fns[p->_ind++] = fn;
return 0;
}

View File

@ -0,0 +1,13 @@
/*
* %G% (UofMD) %D%
*/
#define ATEXIT_SIZE 32 /* must be at least 32 to guarantee ANSI conformance */
struct atexit {
struct atexit *next; /* next in list */
int ind; /* next index in this table */
void (*fns[ATEXIT_SIZE])(); /* the table itself */
};
struct atexit *__atexit; /* points to head of LIFO stack */

72
agbcc/libc/stdlib/atof.c Normal file
View File

@ -0,0 +1,72 @@
/*
FUNCTION
<<atof>>, <<atoff>>---string to double or float
INDEX
atof
INDEX
atoff
ANSI_SYNOPSIS
#include <stdlib.h>
double atof(const char *<[s]>);
float atoff(const char *<[s]>);
TRAD_SYNOPSIS
#include <stdlib.h>
double atof(<[s]>)
char *<[s]>;
float atoff(<[s]>)
char *<[s]>;
DESCRIPTION
<<atof>> converts the initial portion of a string to a <<double>>.
<<atoff>> converts the initial portion of a string to a <<float>>.
The functions parse the character string <[s]>,
locating a substring which can be converted to a floating point
value. The substring must match the format:
. [+|-]<[digits]>[.][<[digits]>][(e|E)[+|-]<[digits]>]
The substring converted is the longest initial
fragment of <[s]> that has the expected format, beginning with
the first non-whitespace character. The substring
is empty if <<str>> is empty, consists entirely
of whitespace, or if the first non-whitespace character is
something other than <<+>>, <<->>, <<.>>, or a digit.
<<atof(<[s]>)>> is implemented as <<strtod(<[s]>, NULL)>>.
<<atoff(<[s]>)>> is implemented as <<strtodf(<[s]>, NULL)>>.
RETURNS
<<atof>> returns the converted substring value, if any, as a
<<double>>; or <<0.0>>, if no conversion could be performed.
If the correct value is out of the range of representable values, plus
or minus <<HUGE_VAL>> is returned, and <<ERANGE>> is stored in
<<errno>>.
If the correct value would cause underflow, <<0.0>> is returned
and <<ERANGE>> is stored in <<errno>>.
<<atoff>> obeys the same rules as <<atof>>, except that it
returns a <<float>>.
PORTABILITY
<<atof>> is ANSI C. <<atof>>, <<atoi>>, and <<atol>> are subsumed by <<strod>>
and <<strol>>, but are used extensively in existing code. These functions are
less reliable, but may be faster if the argument is verified to be in a valid
range.
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
*/
#include <stdlib.h>
#include <_ansi.h>
double
_DEFUN (atof, (s),
_CONST char *s)
{
return strtod (s, NULL);
}

View File

@ -0,0 +1,9 @@
#include <stdlib.h>
#include <_ansi.h>
float
_DEFUN (atoff, (s),
_CONST char *s)
{
return strtodf (s, NULL);
}

54
agbcc/libc/stdlib/atoi.c Normal file
View File

@ -0,0 +1,54 @@
/*
FUNCTION
<<atoi>>, <<atol>>---string to integer
INDEX
atoi
INDEX
atol
ANSI_SYNOPSIS
#include <stdlib.h>
int atoi(const char *<[s]>);
long atol(const char *<[s]>);
TRAD_SYNOPSIS
#include <stdlib.h>
int atoi(<[s]>)
char *<[s]>;
long atol(<[s]>)
char *<[s]>;
DESCRIPTION
<<atoi>> converts the initial portion of a string to an <<int>>.
<<atol>> converts the initial portion of a string to a <<long>>.
<<atoi(s)>> is implemented as <<(int)strtol(s, NULL, 10).>>
<<atol(s)>> is implemented as <<strtol(s, NULL, 10).>>
RETURNS
The functions return the converted value, if any. If no conversion was
made, <<0>> is returned.
PORTABILITY
<<atoi>> is ANSI.
No supporting OS subroutines are required.
*/
/*
* Andy Wilson, 2-Oct-89.
*/
#include <stdlib.h>
#include <_ansi.h>
int
_DEFUN (atoi, (s),
_CONST char *s)
{
return (int) strtol (s, NULL, 10);
}

12
agbcc/libc/stdlib/atol.c Normal file
View File

@ -0,0 +1,12 @@
/*
* Andy Wilson, 2-Oct-89.
*/
#include <stdlib.h>
#include <_ansi.h>
long
_DEFUN (atol, (s), _CONST char *s)
{
return strtol (s, NULL, 10);
}

100
agbcc/libc/stdlib/bsearch.c Normal file
View File

@ -0,0 +1,100 @@
/*
* bsearch.c
* Original Author: G. Haley
* Rewritten by: G. Noer
*
* Searches an array of nmemb members, the initial member of which is pointed
* to by base, for a member that matches the object pointed to by key. The
* contents of the array shall be in ascending order according to a comparison
* function pointed to by compar. The function shall return an integer less
* than, equal to or greater than zero if the first argument is considered to be
* respectively less than, equal to or greater than the second. Returns a
* pointer to the matching member of the array, or a null pointer if no match
* is found.
*/
/*
FUNCTION
<<bsearch>>---binary search
INDEX
bsearch
ANSI_SYNOPSIS
#include <stdlib.h>
void *bsearch(const void *<[key]>, const void *<[base]>,
size_t <[nmemb]>, size_t <[size]>,
int (*<[compar]>)(const void *, const void *));
TRAD_SYNOPSIS
#include <stdlib.h>
char *bsearch(<[key]>, <[base]>, <[nmemb]>, <[size]>, <[compar]>)
char *<[key]>;
char *<[base]>;
size_t <[nmemb]>, <[size]>;
int (*<[compar]>)();
DESCRIPTION
<<bsearch>> searches an array beginning at <[base]> for any element
that matches <[key]>, using binary search. <[nmemb]> is the element
count of the array; <[size]> is the size of each element.
The array must be sorted in ascending order with respect to the
comparison function <[compar]> (which you supply as the last argument of
<<bsearch>>).
You must define the comparison function <<(*<[compar]>)>> to have two
arguments; its result must be negative if the first argument is
less than the second, zero if the two arguments match, and
positive if the first argument is greater than the second (where
``less than'' and ``greater than'' refer to whatever arbitrary
ordering is appropriate).
RETURNS
Returns a pointer to an element of <[array]> that matches <[key]>. If
more than one matching element is available, the result may point to
any of them.
PORTABILITY
<<bsearch>> is ANSI.
No supporting OS subroutines are required.
*/
#include <stdlib.h>
_PTR
_DEFUN (bsearch, (key, base, nmemb, size, compar),
_CONST _PTR key _AND
_CONST _PTR base _AND
size_t nmemb _AND
size_t size _AND
int _EXFUN ((*compar), (const _PTR, const _PTR)))
{
_PTR current;
size_t lower = 0;
size_t upper = nmemb;
size_t index;
int result;
if (nmemb == 0 || size == 0)
return NULL;
while (lower < upper)
{
index = (lower + upper) / 2;
current = (_PTR) (((char *) base) + (index * size));
result = compar (key, current);
if (result < 0)
upper = index;
else if (result > 0)
lower = index + 1;
else
return current;
}
return NULL;
}

View File

@ -0,0 +1,65 @@
/*
FUNCTION
<<calloc>>---allocate space for arrays
INDEX
calloc
INDEX
_calloc_r
ANSI_SYNOPSIS
#include <stdlib.h>
void *calloc(size_t <[n]>, size_t <[s]>);
void *calloc_r(void *<[reent]>, size_t <n>, <size_t> <[s]>);
TRAD_SYNOPSIS
#include <stdlib.h>
char *calloc(<[n]>, <[s]>)
size_t <[n]>, <[s]>;
char *_calloc_r(<[reent]>, <[n]>, <[s]>)
char *<[reent]>;
size_t <[n]>;
size_t <[s]>;
DESCRIPTION
Use <<calloc>> to request a block of memory sufficient to hold an
array of <[n]> elements, each of which has size <[s]>.
The memory allocated by <<calloc>> comes out of the same memory pool
used by <<malloc>>, but the memory block is initialized to all zero
bytes. (To avoid the overhead of initializing the space, use
<<malloc>> instead.)
The alternate function <<_calloc_r>> is reentrant.
The extra argument <[reent]> is a pointer to a reentrancy structure.
RETURNS
If successful, a pointer to the newly allocated space.
If unsuccessful, <<NULL>>.
PORTABILITY
<<calloc>> is ANSI.
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
*/
#include <string.h>
#include <stdlib.h>
#ifndef _REENT_ONLY
_PTR
_DEFUN (calloc, (n, size),
size_t n _AND
size_t size)
{
return _calloc_r (_REENT, n, size);
}
#endif

132
agbcc/libc/stdlib/div.c Normal file
View File

@ -0,0 +1,132 @@
/*
FUNCTION
<<div>>---divide two integers
INDEX
div
ANSI_SYNOPSIS
#include <stdlib.h>
div_t div(int <[n]>, int <[d]>);
TRAD_SYNOPSIS
#include <stdlib.h>
div_t div(<[n]>, <[d]>)
int <[n]>, <[d]>;
DESCRIPTION
Divide
@tex
$n/d$,
@end tex
@ifinfo
<[n]>/<[d]>,
@end ifinfo
returning quotient and remainder as two integers in a structure <<div_t>>.
RETURNS
The result is represented with the structure
. typedef struct
. {
. int quot;
. int rem;
. } div_t;
where the <<quot>> field represents the quotient, and <<rem>> the
remainder. For nonzero <[d]>, if `<<<[r]> = div(<[n]>,<[d]>);>>' then
<[n]> equals `<<<[r]>.rem + <[d]>*<[r]>.quot>>'.
To divide <<long>> rather than <<int>> values, use the similar
function <<ldiv>>.
PORTABILITY
<<div>> is ANSI.
No supporting OS subroutines are required.
*/
/*
* Copyright (c) 1990 Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Chris Torek.
*
* 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.
*/
#include <_ansi.h>
#include <stdlib.h> /* div_t */
div_t
_DEFUN (div, (num, denom),
int num _AND
int denom)
{
div_t r;
r.quot = num / denom;
r.rem = num % denom;
/*
* The ANSI standard says that |r.quot| <= |n/d|, where
* n/d is to be computed in infinite precision. In other
* words, we should always truncate the quotient towards
* 0, never -infinity or +infinity.
*
* Machine division and remainer may work either way when
* one or both of n or d is negative. If only one is
* negative and r.quot has been truncated towards -inf,
* r.rem will have the same sign as denom and the opposite
* sign of num; if both are negative and r.quot has been
* truncated towards -inf, r.rem will be positive (will
* have the opposite sign of num). These are considered
* `wrong'.
*
* If both are num and denom are positive, r will always
* be positive.
*
* This all boils down to:
* if num >= 0, but r.rem < 0, we got the wrong answer.
* In that case, to get the right answer, add 1 to r.quot and
* subtract denom from r.rem.
* if num < 0, but r.rem > 0, we also have the wrong answer.
* In this case, to get the right answer, subtract 1 from r.quot and
* add denom to r.rem.
*/
if (num >= 0 && r.rem < 0) {
++r.quot;
r.rem -= denom;
}
else if (num < 0 && r.rem > 0) {
--r.quot;
r.rem += denom;
}
return (r);
}

854
agbcc/libc/stdlib/dtoa.c Normal file
View File

@ -0,0 +1,854 @@
/****************************************************************
*
* The author of this software is David M. Gay.
*
* Copyright (c) 1991 by AT&T.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose without fee is hereby granted, provided that this entire notice
* is included in all copies of any software which is or includes a copy
* or modification of this software and in all copies of the supporting
* documentation for such software.
*
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
* OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
*
***************************************************************/
/* Please send bug reports to
David M. Gay
AT&T Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-2070
U.S.A.
dmg@research.att.com or research!dmg
*/
#include <_ansi.h>
#include <stdlib.h>
#include <reent.h>
#include <string.h>
#include "mprec.h"
static int
_DEFUN (quorem,
(b, S),
_Bigint * b _AND _Bigint * S)
{
int n;
Long borrow, y;
ULong carry, q, ys;
ULong *bx, *bxe, *sx, *sxe;
#ifdef Pack_32
Long z;
ULong si, zs;
#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 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 >> 16;
Sign_Extend (borrow, y);
z = (*bx >> 16) - (zs & 0xffff) + borrow;
borrow = z >> 16;
Sign_Extend (borrow, z);
Storeinc (bx, z, y);
#else
ys = *sx++ * q + carry;
carry = ys >> 16;
y = *bx - (ys & 0xffff) + borrow;
borrow = y >> 16;
Sign_Extend (borrow, y);
*bx++ = y & 0xffff;
#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 Pack_32
si = *sx++;
ys = (si & 0xffff) + carry;
zs = (si >> 16) + (ys >> 16);
carry = zs >> 16;
y = (*bx & 0xffff) - (ys & 0xffff) + borrow;
borrow = y >> 16;
Sign_Extend (borrow, y);
z = (*bx >> 16) - (zs & 0xffff) + borrow;
borrow = z >> 16;
Sign_Extend (borrow, z);
Storeinc (bx, z, y);
#else
ys = *sx++ + carry;
carry = ys >> 16;
y = *bx - (ys & 0xffff) + borrow;
borrow = y >> 16;
Sign_Extend (borrow, y);
*bx++ = y & 0xffff;
#endif
}
while (sx <= sxe);
bx = b->_x;
bxe = bx + n;
if (!*bxe)
{
while (--bxe > bx && !*bxe)
--n;
b->_wds = n;
}
}
return q;
}
/* 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 *
_DEFUN (_dtoa_r,
(ptr, _d, mode, ndigits, decpt, sign, rve),
struct _reent *ptr _AND
double _d _AND
int mode _AND
int ndigits _AND
int *decpt _AND
int *sign _AND
char **rve)
{
/* 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-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, be, dig, i, ieps, ilim, ilim0, ilim1, j, j1, k, k0,
k_check, leftright, m2, m5, s2, s5, spec_case, try_quick;
union double_union d, d2, eps;
Long L;
#ifndef Sudden_Underflow
int denorm;
ULong x;
#endif
_Bigint *b, *b1, *delta, *mlo, *mhi, *S;
double ds;
char *s, *s0;
d.d = _d;
if (ptr->_result)
{
ptr->_result->_k = ptr->_result_k;
ptr->_result->_maxwds = 1 << ptr->_result_k;
Bfree (ptr, ptr->_result);
ptr->_result = 0;
}
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;
s =
#ifdef IEEE_Arith
!word1 (d) && !(word0 (d) & 0xfffff) ? "Infinity" :
#endif
"NaN";
if (rve)
*rve =
#ifdef IEEE_Arith
s[3] ? s + 8 :
#endif
s + 3;
return s;
}
#endif
#ifdef IBM
d.d += 0; /* normalize */
#endif
if (!d.d)
{
*decpt = 1;
s = "0";
if (rve)
*rve = s + 1;
return s;
}
b = d2b (ptr, d.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)))
{
#endif
d2.d = d.d;
word0 (d2) &= Frac_mask1;
word0 (d2) |= Exp_11;
#ifdef IBM
if (j = 11 - hi0bits (word0 (d2) & Frac_mask))
d2.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.)
*/
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;
d2.d = x;
word0 (d2) -= 31 * Exp_msk1; /* adjust exponent */
i -= (Bias + (P - 1) - 1) + 1;
denorm = 1;
}
#endif
ds = (d2.d - 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 (d.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 = 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;
}
j = sizeof (ULong);
for (ptr->_result_k = 0; sizeof (_Bigint) - sizeof (ULong) + j <= i;
j <<= 1)
ptr->_result_k++;
ptr->_result = Balloc (ptr, ptr->_result_k);
s = s0 = (char *) ptr->_result;
if (ilim >= 0 && ilim <= Quick_max && try_quick)
{
/* Try to get by with floating-point arithmetic. */
i = 0;
d2.d = d.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;
d.d /= bigtens[n_bigtens - 1];
ieps++;
}
for (; j; j >>= 1, i++)
if (j & 1)
{
ieps++;
ds *= bigtens[i];
}
d.d /= ds;
}
else if (j1 = -k)
{
d.d *= tens[j1 & 0xf];
for (j = j1 >> 4; j; j >>= 1, i++)
if (j & 1)
{
ieps++;
d.d *= bigtens[i];
}
}
if (k_check && d.d < 1. && ilim > 0)
{
if (ilim1 <= 0)
goto fast_failed;
ilim = ilim1;
k--;
d.d *= 10.;
ieps++;
}
eps.d = ieps * d.d + 7.;
word0 (eps) -= (P - 1) * Exp_msk1;
if (ilim == 0)
{
S = mhi = 0;
d.d -= 5.;
if (d.d > eps.d)
goto one_digit;
if (d.d < -eps.d)
goto no_digits;
goto fast_failed;
}
#ifndef No_leftright
if (leftright)
{
/* Use Steele & White method of only
* generating digits needed.
*/
eps.d = 0.5 / tens[ilim - 1] - eps.d;
for (i = 0;;)
{
L = d.d;
d.d -= L;
*s++ = '0' + (int) L;
if (d.d < eps.d)
goto ret1;
if (1. - d.d < eps.d)
goto bump_up;
if (++i >= ilim)
break;
eps.d *= 10.;
d.d *= 10.;
}
}
else
{
#endif
/* Generate ilim digits, then fix them up. */
eps.d *= tens[ilim - 1];
for (i = 1;; i++, d.d *= 10.)
{
L = d.d;
d.d -= L;
*s++ = '0' + (int) L;
if (i == ilim)
{
if (d.d > 0.5 + eps.d)
goto bump_up;
else if (d.d < 0.5 - eps.d)
{
while (*--s == '0');
s++;
goto ret1;
}
break;
}
}
#ifndef No_leftright
}
#endif
fast_failed:
s = s0;
d.d = d2.d;
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 || d.d <= 5 * ds)
goto no_digits;
goto one_digit;
}
for (i = 1;; i++)
{
L = d.d / ds;
d.d -= L * ds;
#ifdef Check_FLT_ROUNDS
/* If FLT_ROUNDS == 2, L will usually be high by 1 */
if (d.d < 0)
{
L--;
d.d += ds;
}
#endif
*s++ = '0' + (int) L;
if (i == ilim)
{
d.d += d.d;
if (d.d > ds || d.d == ds && L & 1)
{
bump_up:
while (*--s == '9')
if (s == s0)
{
k++;
*s = '0';
break;
}
++*s++;
}
break;
}
if (!(d.d *= 10.))
break;
}
goto ret1;
}
m2 = b2;
m5 = b5;
mhi = mlo = 0;
if (leftright)
{
if (mode < 2)
{
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
}
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 (ptr, 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 (ptr, mhi, m5);
b1 = mult (ptr, mhi, b);
Bfree (ptr, b);
b = b1;
}
if (j = b5 - m5)
b = pow5mult (ptr, b, j);
}
else
b = pow5mult (ptr, b, b5);
}
S = i2b (ptr, 1);
if (s5 > 0)
S = pow5mult (ptr, S, s5);
/* Check for special case that d is a normalized power of 2. */
if (mode < 2)
{
if (!word1 (d) && !(word0 (d) & Bndry_mask)
#ifndef Sudden_Underflow
&& word0 (d) & Exp_mask
#endif
)
{
/* The special case */
b2 += Log2P;
s2 += Log2P;
spec_case = 1;
}
else
spec_case = 0;
}
/* 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)
i = 32 - i;
#else
if (i = ((s5 ? 32 - hi0bits (S->_x[S->_wds - 1]) : 1) + s2) & 0xf)
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 (ptr, b, b2);
if (s2 > 0)
S = lshift (ptr, S, s2);
if (k_check)
{
if (cmp (b, S) < 0)
{
k--;
b = multadd (ptr, b, 10, 0); /* we botched the k estimate */
if (leftright)
mhi = multadd (ptr, mhi, 10, 0);
ilim = ilim1;
}
}
if (ilim <= 0 && mode > 2)
{
if (ilim < 0 || cmp (b, S = multadd (ptr, 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 (ptr, mhi, m2);
/* Compute mlo -- check for special case
* that d is a normalized power of 2.
*/
mlo = mhi;
if (spec_case)
{
mhi = Balloc (ptr, mhi->_k);
Bcopy (mhi, mlo);
mhi = lshift (ptr, 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 (ptr, S, mhi);
j1 = delta->_sign ? 1 : cmp (b, delta);
Bfree (ptr, delta);
#ifndef ROUND_BIASED
if (j1 == 0 && !mode && !(word1 (d) & 1))
{
if (dig == '9')
goto round_9_up;
if (j > 0)
dig++;
*s++ = dig;
goto ret;
}
#endif
if (j < 0 || j == 0 && !mode
#ifndef ROUND_BIASED
&& !(word1 (d) & 1)
#endif
)
{
if (j1 > 0)
{
b = lshift (ptr, b, 1);
j1 = cmp (b, S);
if ((j1 > 0 || j1 == 0 && dig & 1)
&& dig++ == '9')
goto round_9_up;
}
*s++ = dig;
goto ret;
}
if (j1 > 0)
{
if (dig == '9')
{ /* possible if i == 1 */
round_9_up:
*s++ = '9';
goto roundoff;
}
*s++ = dig + 1;
goto ret;
}
*s++ = dig;
if (i == ilim)
break;
b = multadd (ptr, b, 10, 0);
if (mlo == mhi)
mlo = mhi = multadd (ptr, mhi, 10, 0);
else
{
mlo = multadd (ptr, mlo, 10, 0);
mhi = multadd (ptr, mhi, 10, 0);
}
}
}
else
for (i = 1;; i++)
{
*s++ = dig = quorem (b, S) + '0';
if (i >= ilim)
break;
b = multadd (ptr, b, 10, 0);
}
/* Round off last digit */
b = lshift (ptr, 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
{
while (*--s == '0');
s++;
}
ret:
Bfree (ptr, S);
if (mhi)
{
if (mlo && mlo != mhi)
Bfree (ptr, mlo);
Bfree (ptr, mhi);
}
ret1:
Bfree (ptr, b);
*s = 0;
*decpt = k + 1;
if (rve)
*rve = s;
return s0;
}

View File

@ -0,0 +1,23 @@
#include <_ansi.h>
#include <stdlib.h>
#include <reent.h>
#include <string.h>
/* Nothing in newlib actually *calls* dtoa, they all call _dtoa_r, so this
is a safe way of providing it to the user. */
#ifndef NO_REENT
char *
_DEFUN (__dtoa,
(d, mode, ndigits, decpt, sign, rve),
double d _AND
int mode _AND
int ndigits _AND
int *decpt _AND
int *sign _AND
char **rve)
{
return _dtoa_r (_REENT, d, mode, ndigits, decpt, sign, rve);
}
#endif

469
agbcc/libc/stdlib/ecvtbuf.c Normal file
View File

@ -0,0 +1,469 @@
/*
FUNCTION
<<ecvtbuf>>, <<fcvtbuf>>---double or float to string
INDEX
ecvtbuf
INDEX
fcvtbuf
ANSI_SYNOPSIS
#include <stdio.h>
char *ecvtbuf(double <[val]>, int <[chars]>, int *<[decpt]>,
int *<[sgn]>, char *<[buf]>);
char *fcvtbuf(double <[val]>, int <[decimals]>, int *<[decpt]>,
int *<[sgn]>, char *<[buf]>);
TRAD_SYNOPSIS
#include <stdio.h>
char *ecvtbuf(<[val]>, <[chars]>, <[decpt]>, <[sgn]>, <[buf]>);
double <[val]>;
int <[chars]>;
int *<[decpt]>;
int *<[sgn]>;
char *<[buf]>;
char *fcvtbuf(<[val]>, <[decimals]>, <[decpt]>, <[sgn]>, <[buf]>);
double <[val]>;
int <[decimals]>;
int *<[decpt]>;
int *<[sgn]>;
char *<[buf]>;
DESCRIPTION
<<ecvtbuf>> and <<fcvtbuf>> produce (null-terminated) strings
of digits representating the <<double>> number <[val]>.
The only difference between <<ecvtbuf>> and <<fcvtbuf>> is the
interpretation of the second argument (<[chars]> or
<[decimals]>). For <<ecvtbuf>>, the second argument <[chars]>
specifies the total number of characters to write (which is
also the number of significant digits in the formatted string,
since these two functions write only digits). For <<fcvtbuf>>,
the second argument <[decimals]> specifies the number of
characters to write after the decimal point; all digits for
the integer part of <[val]> are always included.
Since <<ecvtbuf>> and <<fcvtbuf>> write only digits in the
output string, they record the location of the decimal point
in <<*<[decpt]>>>, and the sign of the number in <<*<[sgn]>>>.
After formatting a number, <<*<[decpt]>>> contains the number
of digits to the left of the decimal point. <<*<[sgn]>>>
contains <<0>> if the number is positive, and <<1>> if it is
negative. For both functions, you supply a pointer <[buf]> to
an area of memory to hold the converted string.
RETURNS
Both functions return a pointer to <[buf]>, the string
containing a character representation of <[val]>.
PORTABILITY
Neither function is ANSI C.
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
*/
#include <_ansi.h>
#include <stdlib.h>
#include <string.h>
#include <reent.h>
#include "mprec.h"
#include "local.h"
static void
_DEFUN (print_f, (ptr, buf, invalue, ndigit, type, dot, mode),
struct _reent *ptr _AND
char *buf _AND
double invalue _AND
int ndigit _AND
char type _AND
int dot _AND
int mode)
{
int decpt;
int sign;
char *p, *start, *end;
start = p = _dtoa_r (ptr, invalue, mode, ndigit, &decpt, &sign, &end);
if (decpt == 9999)
{
strcpy (buf, p);
return;
}
while (*p && decpt > 0)
{
*buf++ = *p++;
decpt--;
}
/* Even if not in buffer */
while (decpt > 0)
{
*buf++ = '0';
decpt--;
}
if (dot || *p)
{
if (p == start)
*buf++ = '0';
*buf++ = '.';
while (decpt < 0 && ndigit > 0)
{
*buf++ = '0';
decpt++;
ndigit--;
}
/* Print rest of stuff */
while (*p && ndigit > 0)
{
*buf++ = *p++;
ndigit--;
}
/* And trailing zeros */
while (ndigit > 0)
{
*buf++ = '0';
ndigit--;
}
}
*buf++ = 0;
}
/* Print number in e format with width chars after.
TYPE is one of 'e' or 'E'. It may also be one of 'g' or 'G' indicating
that _gcvt is calling us and we should remove trailing zeroes.
WIDTH is the number of digits of precision after the decimal point. */
static void
_DEFUN (print_e, (ptr, buf, invalue, width, type, dot),
struct _reent *ptr _AND
char *buf _AND
double invalue _AND
int width _AND
char type _AND
int dot)
{
int dp;
int sign;
char *end;
char *p;
int decpt;
int top;
int ndigit = width;
p = _dtoa_r (ptr, invalue, 2, width + 1, &decpt, &sign, &end);
if (decpt == 9999)
{
strcpy (buf, p);
return;
}
*buf++ = *p++;
if (dot || ndigit != 0)
*buf++ = '.';
while (*p && ndigit > 0)
{
*buf++ = *p++;
ndigit--;
}
/* Add trailing zeroes to fill out to ndigits unless this is 'g' format.
Also, convert g/G to e/E. */
if (type == 'g')
type = 'e';
else if (type == 'G')
type = 'E';
else
{
while (ndigit > 0)
{
*buf++ = '0';
ndigit--;
}
}
/* Add the exponent. */
*buf++ = type;
decpt--;
if (decpt < 0)
{
*buf++ = '-';
decpt = -decpt;
}
else
{
*buf++ = '+';
}
if (decpt > 99)
{
int top = decpt / 100;
*buf++ = top + '0';
decpt -= top * 100;
}
top = decpt / 10;
*buf++ = top + '0';
decpt -= top * 10;
*buf++ = decpt + '0';
*buf++ = 0;
}
#ifndef _REENT_ONLY
/* Undocumented behaviour: when given NULL as a buffer, return a
pointer to static space in the rent structure. This is only to
support ecvt and fcvt, which aren't ANSI anyway. */
char *
_DEFUN (fcvtbuf, (invalue, ndigit, decpt, sign, fcvt_buf),
double invalue _AND
int ndigit _AND
int *decpt _AND
int *sign _AND
char *fcvt_buf)
{
char *save;
char *p;
char *end;
int done = 0;
if (fcvt_buf == NULL)
{
if (_REENT->_cvtlen <= ndigit)
{
if ((fcvt_buf = (char *) _realloc_r (_REENT, _REENT->_cvtbuf,
ndigit + 1)) == NULL)
return NULL;
_REENT->_cvtlen = ndigit + 1;
_REENT->_cvtbuf = fcvt_buf;
}
fcvt_buf = _REENT->_cvtbuf ;
}
save = fcvt_buf;
if (invalue < 1.0 && invalue > -1.0)
{
p = _dtoa_r (_REENT, invalue, 2, ndigit, decpt, sign, &end);
}
else
{
p = _dtoa_r (_REENT, invalue, 3, ndigit, decpt, sign, &end);
}
/* Now copy */
while (p < end)
{
*fcvt_buf++ = *p++;
done++;
}
/* And unsuppress the trailing zeroes */
while (done < ndigit)
{
*fcvt_buf++ = '0';
done++;
}
*fcvt_buf++ = 0;
return save;
}
char *
_DEFUN (ecvtbuf, (invalue, ndigit, decpt, sign, fcvt_buf),
double invalue _AND
int ndigit _AND
int *decpt _AND
int *sign _AND
char *fcvt_buf)
{
char *save;
char *p;
char *end;
int done = 0;
if (fcvt_buf == NULL)
{
if (_REENT->_cvtlen <= ndigit)
{
if ((fcvt_buf = (char *) _realloc_r (_REENT, _REENT->_cvtbuf,
ndigit + 1)) == NULL)
return NULL;
_REENT->_cvtlen = ndigit + 1;
_REENT->_cvtbuf = fcvt_buf;
}
fcvt_buf = _REENT->_cvtbuf ;
}
save = fcvt_buf;
p = _dtoa_r (_REENT, invalue, 2, ndigit, decpt, sign, &end);
/* Now copy */
while (p < end)
{
*fcvt_buf++ = *p++;
done++;
}
/* And unsuppress the trailing zeroes */
while (done < ndigit)
{
*fcvt_buf++ = '0';
done++;
}
*fcvt_buf++ = 0;
return save;
}
#endif
char *
_DEFUN (_gcvt, (ptr, invalue, ndigit, buf, type, dot),
struct _reent *ptr _AND
double invalue _AND
int ndigit _AND
char *buf _AND
char type _AND
int dot)
{
char *save = buf;
if (invalue < 0)
{
invalue = -invalue;
}
if (invalue == 0)
{
*buf++ = '0';
*buf = '\0';
}
else
/* Which one to print ?
ANSI says that anything with more that 4 zeros after the . or more
than precision digits before is printed in e with the qualification
that trailing zeroes are removed from the fraction portion. */
if (0.0001 >= invalue || invalue >= _mprec_log10 (ndigit))
{
/* We subtract 1 from ndigit because in the 'e' format the precision is
the number of digits after the . but in 'g' format it is the number
of significant digits.
We defer changing type to e/E so that print_e() can know it's us
calling and thus should remove trailing zeroes. */
print_e (ptr, buf, invalue, ndigit - 1, type, dot);
}
else
{
int decpt;
int sign;
char *end;
char *p;
if (invalue < 1.0)
{
/* what we want is ndigits after the point */
p = _dtoa_r (ptr, invalue, 3, ndigit, &decpt, &sign, &end);
}
else
{
p = _dtoa_r (ptr, invalue, 2, ndigit, &decpt, &sign, &end);
}
if (decpt == 9999)
{
strcpy (buf, p);
return save;
}
while (*p && decpt > 0)
{
*buf++ = *p++;
decpt--;
ndigit--;
}
/* Even if not in buffer */
while (decpt > 0 && ndigit > 0)
{
*buf++ = '0';
decpt--;
ndigit--;
}
if (dot || *p)
{
if (buf == save)
*buf++ = '0';
*buf++ = '.';
while (decpt < 0 && ndigit > 0)
{
*buf++ = '0';
decpt++;
ndigit--;
}
/* Print rest of stuff */
while (*p && ndigit > 0)
{
*buf++ = *p++;
ndigit--;
}
/* And trailing zeros */
if (dot)
{
while (ndigit > 0)
{
*buf++ = '0';
ndigit--;
}
}
}
*buf++ = 0;
}
return save;
}
char *
_DEFUN (_dcvt, (ptr, buffer, invalue, precision, width, type, dot),
struct _reent *ptr _AND
char *buffer _AND
double invalue _AND
int precision _AND
int width _AND
char type _AND
int dot)
{
switch (type)
{
case 'f':
case 'F':
print_f (ptr, buffer, invalue, precision, type, precision == 0 ? dot : 1, 3);
break;
case 'g':
case 'G':
if (precision == 0)
precision = 1;
_gcvt (ptr, invalue, precision, buffer, type, dot);
break;
case 'e':
case 'E':
print_e (ptr, buffer, invalue, precision, type, dot);
}
return buffer;
}

202
agbcc/libc/stdlib/efgcvt.c Normal file
View File

@ -0,0 +1,202 @@
/*
FUNCTION
<<ecvt>>,<<ecvtf>>,<<fcvt>>,<<fcvtf>>---double or float to string
INDEX
ecvt
INDEX
fcvt
ANSI_SYNOPSIS
#include <stdlib.h>
char *ecvt(double <[val]>, int <[chars]>, int *<[decpt]>, int *<[sgn]>);
char *ecvtf(float <[val]>, int <[chars]>, int *<[decpt]>, int *<[sgn]>);
char *fcvt(double <[val]>, int <[decimals]>,
int *<[decpt]>, int *<[sgn]>);
char *fcvtf(float <[val]>, int <[decimals]>,
int *<[decpt]>, int *<[sgn]>);
TRAD_SYNOPSIS
#include <stdlib.h>
char *ecvt(<[val]>, <[chars]>, <[decpt]>, <[sgn]>);
double <[val]>;
int <[chars]>;
int *<[decpt]>;
int *<[sgn]>;
char *ecvtf(<[val]>, <[chars]>, <[decpt]>, <[sgn]>);
float <[val]>;
int <[chars]>;
int *<[decpt]>;
int *<[sgn]>;
char *fcvt(<[val]>, <[decimals]>, <[decpt]>, <[sgn]>);
double <[val]>;
int <[decimals]>;
int *<[decpt]>;
int *<[sgn]>;
char *fcvtf(<[val]>, <[decimals]>, <[decpt]>, <[sgn]>);
float <[val]>;
int <[decimals]>;
int *<[decpt]>;
int *<[sgn]>;
DESCRIPTION
<<ecvt>> and <<fcvt>> produce (null-terminated) strings of digits
representating the <<double>> number <[val]>.
<<ecvtf>> and <<fcvtf>> produce the corresponding character
representations of <<float>> numbers.
(The <<stdlib>> functions <<ecvtbuf>> and <<fcvtbuf>> are reentrant
versions of <<ecvt>> and <<fcvt>>.)
The only difference between <<ecvt>> and <<fcvt>> is the
interpretation of the second argument (<[chars]> or <[decimals]>).
For <<ecvt>>, the second argument <[chars]> specifies the total number
of characters to write (which is also the number of significant digits
in the formatted string, since these two functions write only digits).
For <<fcvt>>, the second argument <[decimals]> specifies the number of
characters to write after the decimal point; all digits for the integer
part of <[val]> are always included.
Since <<ecvt>> and <<fcvt>> write only digits in the output string,
they record the location of the decimal point in <<*<[decpt]>>>, and
the sign of the number in <<*<[sgn]>>>. After formatting a number,
<<*<[decpt]>>> contains the number of digits to the left of the
decimal point. <<*<[sgn]>>> contains <<0>> if the number is positive,
and <<1>> if it is negative.
RETURNS
All four functions return a pointer to the new string containing a
character representation of <[val]>.
PORTABILITY
None of these functions are ANSI C.
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
NEWPAGE
FUNCTION
<<gvcvt>>, <<gcvtf>>---format double or float as string
INDEX
gcvt
INDEX
gcvtf
ANSI_SYNOPSIS
#include <stdlib.h>
char *gcvt(double <[val]>, int <[precision]>, char *<[buf]>);
char *gcvtf(float <[val]>, int <[precision]>, char *<[buf]>);
TRAD_SYNOPSIS
#include <stdlib.h>
char *gcvt(<[val]>, <[precision]>, <[buf]>);
double <[val]>;
int <[precision]>;
char *<[buf]>;
char *gcvtf(<[val]>, <[precision]>, <[buf]>);
float <[val]>;
int <[precision]>;
char *<[buf]>;
DESCRIPTION
<<gcvt>> writes a fully formatted number as a null-terminated
string in the buffer <<*<[buf]>>>. <<gdvtf>> produces corresponding
character representations of <<float>> numbers.
<<gcvt>> uses the same rules as the <<printf>> format
`<<%.<[precision]>g>>'---only negative values are signed (with
`<<->>'), and either exponential or ordinary decimal-fraction format
is chosen depending on the number of significant digits (specified by
<[precision]>).
RETURNS
The result is a pointer to the formatted representation of <[val]>
(the same as the argument <[buf]>).
PORTABILITY
Neither function is ANSI C.
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
*/
#include <_ansi.h>
#include <reent.h>
#include <stdio.h>
#include <stdlib.h>
#include "local.h"
char *
_DEFUN (fcvt, (d, ndigit, decpt, sign),
double d _AND
int ndigit _AND
int *decpt _AND
int *sign)
{
return fcvtbuf (d, ndigit, decpt, sign, NULL);
}
char *
_DEFUN (fcvtf, (d, ndigit, decpt, sign),
float d _AND
int ndigit _AND
int *decpt _AND
int *sign)
{
return fcvt ((float) d, ndigit, decpt, sign);
}
char *
_DEFUN (gcvtf, (d, ndigit, buf),
float d _AND
int ndigit _AND
char *buf)
{
double asd = d;
return gcvt (asd, ndigit, buf);
}
char *
_DEFUN (ecvt, (d, ndigit, decpt, sign),
double d _AND
int ndigit _AND
int *decpt _AND
int *sign)
{
return ecvtbuf (d, ndigit, decpt, sign, NULL);
}
char *
_DEFUN (ecvtf, (d, ndigit, decpt, sign),
float d _AND
int ndigit _AND
int *decpt _AND
int *sign)
{
return ecvt ((double) d, ndigit, decpt, sign);
}
char *
_DEFUN (gcvt, (d, ndigit, buf),
double d _AND
int ndigit _AND
char *buf)
{
char *tbuf = buf;
if (d < 0) {
*buf = '-';
buf++;
ndigit--;
}
return (_gcvt (_REENT, d, ndigit, buf, 'g', 0) ? tbuf : 0);
}

View File

@ -0,0 +1,23 @@
/* Copyright (c) 1995, 1996 Cygnus Support.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* at Cygnus Support, Inc. Cygnus Support, Inc. may not 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.
*/
/* Provide a definition of `environ' if crt0.o doesn't. */
static char *initial_env[] = { 0 };
/* Posix says `environ' is a pointer to a null terminated list of pointers.
Hence `environ' itself is never NULL. */
char **environ = &initial_env[0];

View File

@ -0,0 +1,26 @@
/* This is an implementation of the __eprintf function which is
compatible with the assert.h which is distributed with gcc.
This function is provided because in some cases libgcc.a will not
provide __eprintf. This will happen if inhibit_libc is defined,
which is done because at the time that libgcc2.c is compiled, the
correct <stdio.h> may not be available. newlib provides its own
copy of assert.h, which calls __assert, not __eprintf. However, in
some cases you may accidentally wind up compiling with the gcc
assert.h. In such a case, this __eprintf will be used if there
does not happen to be one in libgcc2.c. */
#include <stdlib.h>
#include <stdio.h>
void
__eprintf (format, file, line, expression)
const char *format;
const char *file;
unsigned int line;
const char *expression;
{
(void) fiprintf (stderr, format, file, line, expression);
abort ();
/*NOTREACHED*/
}

73
agbcc/libc/stdlib/exit.c Normal file
View File

@ -0,0 +1,73 @@
/*
* Copyright (c) 1990 Regents of the University of California.
* All rights reserved.
*
* %sccs.include.redist.c%
*/
/*
FUNCTION
<<exit>>---end program execution
INDEX
exit
ANSI_SYNOPSIS
#include <stdlib.h>
void exit(int <[code]>);
TRAD_SYNOPSIS
#include <stdlib.h>
void exit(<[code]>)
int <[code]>;
DESCRIPTION
Use <<exit>> to return control from a program to the host operating
environment. Use the argument <[code]> to pass an exit status to the
operating environment: two particular values, <<EXIT_SUCCESS>> and
<<EXIT_FAILURE>>, are defined in `<<stdlib.h>>' to indicate success or
failure in a portable fashion.
<<exit>> does two kinds of cleanup before ending execution of your
program. First, it calls all application-defined cleanup functions
you have enrolled with <<atexit>>. Second, files and streams are
cleaned up: any pending output is delivered to the host system, each
open file or stream is closed, and files created by <<tmpfile>> are
deleted.
RETURNS
<<exit>> does not return to its caller.
PORTABILITY
ANSI C requires <<exit>>, and specifies that <<EXIT_SUCCESS>> and
<<EXIT_FAILURE>> must be defined.
Supporting OS subroutines required: <<_exit>>.
*/
#include <stdlib.h>
#include <unistd.h> /* for _exit() declaration */
#include <reent.h>
#ifndef _REENT_ONLY
/*
* Exit, flushing stdio buffers if necessary.
*/
void
_DEFUN (exit, (code),
int code)
{
register struct _atexit *p;
register int n;
for (p = _REENT->_atexit; p; p = p->_next)
for (n = p->_ind; --n >= 0;)
(*p->_fns[n]) ();
if (_REENT->__cleanup)
(*_REENT->__cleanup) (_REENT);
_exit (code);
}
#endif

121
agbcc/libc/stdlib/getenv.c Normal file
View File

@ -0,0 +1,121 @@
/*
FUNCTION
<<getenv>>---look up environment variable
INDEX
getenv
INDEX
environ
ANSI_SYNOPSIS
#include <stdlib.h>
char *getenv(const char *<[name]>);
TRAD_SYNOPSIS
#include <stdlib.h>
char *getenv(<[name]>)
char *<[name]>;
DESCRIPTION
<<getenv>> searches the list of environment variable names and values
(using the global pointer `<<char **environ>>') for a variable whose
name matches the string at <[name]>. If a variable name matches,
<<getenv>> returns a pointer to the associated value.
RETURNS
A pointer to the (string) value of the environment variable, or
<<NULL>> if there is no such environment variable.
PORTABILITY
<<getenv>> is ANSI, but the rules for properly forming names of environment
variables vary from one system to another.
<<getenv>> requires a global pointer <<environ>>.
*/
/* This file may have been modified by DJ Delorie (Jan 1991). If so,
** these modifications are Coyright (C) 1991 DJ Delorie, 24 Kirsten Ave,
** Rochester NH, 03867-2954, USA.
*/
/*
* Copyright (c) 1987 Regents of the University of California.
* All rights reserved.
*
* 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.
*/
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
extern char **environ;
/*
* _findenv --
* Returns pointer to value associated with name, if any, else NULL.
* Sets offset to be the offset of the name/value combination in the
* environmental array, for use by setenv(3) and unsetenv(3).
* Explicitly removes '=' in argument name.
*
* This routine *should* be a static; don't use it.
*/
char *
_DEFUN (_findenv, (name, offset),
register _CONST char *name _AND
int *offset)
{
register int len;
register char **p;
_CONST char *c;
/* In some embedded systems, this does not get set. This protects
newlib from dereferencing a bad pointer. */
if (!environ)
return NULL;
c = name;
len = 0;
while (*c && *c != '=')
{
c++;
len++;
}
for (p = environ; *p; ++p)
if (!strncmp (*p, name, len))
if (*(c = *p + len) == '=')
{
*offset = p - environ;
return (char *) (++c);
}
return NULL;
}
/*
* getenv --
* Returns ptr to value associated with name, if any, else NULL.
*/
char *
_DEFUN (getenv, (name),
_CONST char *name)
{
int offset;
char *_findenv ();
return _findenv (name, &offset);
}

117
agbcc/libc/stdlib/getopt.c Normal file
View File

@ -0,0 +1,117 @@
/*
* Copyright (c) 1987, 1993, 1994
* 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.
*/
#if defined(LIBC_SCCS) && !defined(lint)
/* static char sccsid[] = "from: @(#)getopt.c 8.2 (Berkeley) 4/2/94"; */
static char *rcsid = "$Id: getopt.c,v 1.2 1998/01/21 22:27:05 billm Exp $";
#endif /* LIBC_SCCS and not lint */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int opterr = 1, /* if error message should be printed */
optind = 1, /* index into parent argv vector */
optopt, /* character checked for validity */
optreset; /* reset getopt */
char *optarg; /* argument associated with option */
#define BADCH (int)'?'
#define BADARG (int)':'
#define EMSG ""
/*
* getopt --
* Parse argc/argv argument vector.
*/
int
getopt(nargc, nargv, ostr)
int nargc;
char * const *nargv;
const char *ostr;
{
static char *place = EMSG; /* option letter processing */
char *oli; /* option letter list index */
if (optreset || !*place) { /* update scanning pointer */
optreset = 0;
if (optind >= nargc || *(place = nargv[optind]) != '-') {
place = EMSG;
return (-1);
}
if (place[1] && *++place == '-') { /* found "--" */
++optind;
place = EMSG;
return (-1);
}
} /* option letter okay? */
if ((optopt = (int)*place++) == (int)':' ||
!(oli = strchr(ostr, optopt))) {
/*
* if the user didn't specify '-' as an option,
* assume it means -1.
*/
if (optopt == (int)'-')
return (-1);
if (!*place)
++optind;
if (opterr && *ostr != ':')
(void)fprintf(stderr,
"%s: illegal option -- %c\n", nargv[0], optopt);
return (BADCH);
}
if (*++oli != ':') { /* don't need argument */
optarg = NULL;
if (!*place)
++optind;
}
else { /* need an argument */
if (*place) /* no white space */
optarg = place;
else if (nargc <= ++optind) { /* no arg */
place = EMSG;
if (*ostr == ':')
return (BADARG);
if (opterr)
(void)fprintf(stderr,
"%s: option requires an argument -- %c\n",
nargv[0], optopt);
return (BADCH);
}
else /* white space */
optarg = nargv[optind];
place = EMSG;
++optind;
}
return (optopt); /* dump back option letter */
}

49
agbcc/libc/stdlib/labs.c Normal file
View File

@ -0,0 +1,49 @@
/*
FUNCTION
<<labs>>---long integer absolute value
INDEX
labs
ANSI_SYNOPSIS
#include <stdlib.h>
long labs(long <[i]>);
TRAD_SYNOPSIS
#include <stdlib.h>
long labs(<[i]>)
long <[i]>;
DESCRIPTION
<<labs>> returns
@tex
$|x|$,
@end tex
the absolute value of <[i]> (also called the magnitude
of <[i]>). That is, if <[i]> is negative, the result is the opposite
of <[i]>, but if <[i]> is nonnegative the result is <[i]>.
The similar function <<abs>> uses and returns <<int>> rather than
<<long>> values.
RETURNS
The result is a nonnegative long integer.
PORTABILITY
<<labs>> is ANSI.
No supporting OS subroutine calls are required.
*/
#include <stdlib.h>
long
_DEFUN (labs, (x),
long x)
{
if (x < 0)
{
x = -x;
}
return x;
}

109
agbcc/libc/stdlib/ldiv.c Normal file
View File

@ -0,0 +1,109 @@
/*
FUNCTION
<<ldiv>>---divide two long integers
INDEX
ldiv
ANSI_SYNOPSIS
#include <stdlib.h>
ldiv_t ldiv(long <[n]>, long <[d]>);
TRAD_SYNOPSIS
#include <stdlib.h>
ldiv_t ldiv(<[n]>, <[d]>)
long <[n]>, <[d]>;
DESCRIPTION
Divide
@tex
$n/d$,
@end tex
@ifinfo
<[n]>/<[d]>,
@end ifinfo
returning quotient and remainder as two long integers in a structure <<ldiv_t>>.
RETURNS
The result is represented with the structure
. typedef struct
. {
. long quot;
. long rem;
. } ldiv_t;
where the <<quot>> field represents the quotient, and <<rem>> the
remainder. For nonzero <[d]>, if `<<<[r]> = ldiv(<[n]>,<[d]>);>>' then
<[n]> equals `<<<[r]>.rem + <[d]>*<[r]>.quot>>'.
To divide <<int>> rather than <<long>> values, use the similar
function <<div>>.
PORTABILITY
<<ldiv>> is ANSI.
No supporting OS subroutines are required.
*/
/*
* Copyright (c) 1990 Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Chris Torek.
*
* 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.
*/
#include <_ansi.h>
#include <stdlib.h> /* ldiv_t */
ldiv_t
_DEFUN (ldiv, (num, denom),
long num _AND
long denom)
{
ldiv_t r;
/* see div.c for comments */
r.quot = num / denom;
r.rem = num % denom;
if (num >= 0 && r.rem < 0) {
++r.quot;
r.rem -= denom;
}
else if (num < 0 && r.rem > 0) {
--r.quot;
r.rem += denom;
}
return (r);
}

View File

@ -0,0 +1,8 @@
/* Misc. local definitions for libc/stdlib */
#ifndef _LOCAL_H_
#define _LOCAL_H_
char * _EXFUN(_gcvt,(struct _reent *, double , int , char *, char, int));
#endif

View File

@ -0,0 +1,18 @@
/* malign.c -- a wrapper for memalign_r. */
#include <_ansi.h>
#include <reent.h>
#include <stdlib.h>
#include <malloc.h>
#ifndef _REENT_ONLY
_PTR
_DEFUN (memalign, (align, nbytes),
size_t align _AND
size_t nbytes)
{
return _memalign_r (_REENT, align, nbytes);
}
#endif

206
agbcc/libc/stdlib/malloc.c Normal file
View File

@ -0,0 +1,206 @@
/* VxWorks provides its own version of malloc, and we can't use this
one because VxWorks does not provide sbrk. So we have a hook to
not compile this code. */
/* The routines here are simple cover fns to the routines that do the real
work (the reentrant versions). */
/* FIXME: Does the warning below (see WARNINGS) about non-reentrancy still
apply? A first guess would be "no", but how about reentrancy in the *same*
thread? */
#ifdef MALLOC_PROVIDED
int _dummy_malloc = 1;
#else
/*
FUNCTION
<<malloc>>, <<realloc>>, <<free>>---manage memory
INDEX
malloc
INDEX
realloc
INDEX
free
INDEX
memalign
INDEX
malloc_usable_size
INDEX
_malloc_r
INDEX
_realloc_r
INDEX
_free_r
INDEX
_memalign_r
INDEX
_malloc_usable_size_r
ANSI_SYNOPSIS
#include <stdlib.h>
void *malloc(size_t <[nbytes]>);
void *realloc(void *<[aptr]>, size_t <[nbytes]>);
void free(void *<[aptr]>);
void *memalign(size_t <[align]>, size_t <[nbytes]>);
size_t malloc_usable_size(void *<[aptr]>);
void *_malloc_r(void *<[reent]>, size_t <[nbytes]>);
void *_realloc_r(void *<[reent]>,
void *<[aptr]>, size_t <[nbytes]>);
void _free_r(void *<[reent]>, void *<[aptr]>);
void *_memalign_r(void *<[reent]>,
size_t <[align]>, size_t <[nbytes]>);
size_t _malloc_usable_size_r(void *<[reent]>, void *<[aptr]>);
TRAD_SYNOPSIS
#include <stdlib.h>
char *malloc(<[nbytes]>)
size_t <[nbytes]>;
char *realloc(<[aptr]>, <[nbytes]>)
char *<[aptr]>;
size_t <[nbytes]>;
void free(<[aptr]>)
char *<[aptr]>;
char *memalign(<[align]>, <[nbytes]>)
size_t <[align]>;
size_t <[nbytes]>;
size_t malloc_usable_size(<[aptr]>)
char *<[aptr]>;
char *_malloc_r(<[reent]>,<[nbytes]>)
char *<[reent]>;
size_t <[nbytes]>;
char *_realloc_r(<[reent]>, <[aptr]>, <[nbytes]>)
char *<[reent]>;
char *<[aptr]>;
size_t <[nbytes]>;
void _free_r(<[reent]>, <[aptr]>)
char *<[reent]>;
char *<[aptr]>;
char *_memalign_r(<[reent]>, <[align]>, <[nbytes]>)
char *<[reent]>;
size_t <[align]>;
size_t <[nbytes]>;
size_t malloc_usable_size(<[reent]>, <[aptr]>)
char *<[reent]>;
char *<[aptr]>;
DESCRIPTION
These functions manage a pool of system memory.
Use <<malloc>> to request allocation of an object with at least
<[nbytes]> bytes of storage available. If the space is available,
<<malloc>> returns a pointer to a newly allocated block as its result.
If you already have a block of storage allocated by <<malloc>>, but
you no longer need all the space allocated to it, you can make it
smaller by calling <<realloc>> with both the object pointer and the
new desired size as arguments. <<realloc>> guarantees that the
contents of the smaller object match the beginning of the original object.
Similarly, if you need more space for an object, use <<realloc>> to
request the larger size; again, <<realloc>> guarantees that the
beginning of the new, larger object matches the contents of the
original object.
When you no longer need an object originally allocated by <<malloc>>
or <<realloc>> (or the related function <<calloc>>), return it to the
memory storage pool by calling <<free>> with the address of the object
as the argument. You can also use <<realloc>> for this purpose by
calling it with <<0>> as the <[nbytes]> argument.
The <<memalign>> function returns a block of size <[nbytes]> aligned
to a <[align]> boundary. The <[align]> argument must be a power of
two.
The <<malloc_usable_size>> function takes a pointer to a block
allocated by <<malloc>>. It returns the amount of space that is
available in the block. This may or may not be more than the size
requested from <<malloc>>, due to alignment or minimum size
constraints.
The alternate functions <<_malloc_r>>, <<_realloc_r>>, <<_free_r>>,
<<_memalign_r>>, and <<_malloc_usable_size_r>> are reentrant versions.
The extra argument <[reent]> is a pointer to a reentrancy structure.
If you have multiple threads of execution which may call any of these
routines, or if any of these routines may be called reentrantly, then
you must provide implementations of the <<__malloc_lock>> and
<<__malloc_unlock>> functions for your system. See the documentation
for those functions.
These functions operate by calling the function <<_sbrk_r>> or
<<sbrk>>, which allocates space. You may need to provide one of these
functions for your system. <<_sbrk_r>> is called with a positive
value to allocate more space, and with a negative value to release
previously allocated space if it is no longer required.
@xref{Stubs}.
RETURNS
<<malloc>> returns a pointer to the newly allocated space, if
successful; otherwise it returns <<NULL>>. If your application needs
to generate empty objects, you may use <<malloc(0)>> for this purpose.
<<realloc>> returns a pointer to the new block of memory, or <<NULL>>
if a new block could not be allocated. <<NULL>> is also the result
when you use `<<realloc(<[aptr]>,0)>>' (which has the same effect as
`<<free(<[aptr]>)>>'). You should always check the result of
<<realloc>>; successful reallocation is not guaranteed even when
you request a smaller object.
<<free>> does not return a result.
<<memalign>> returns a pointer to the newly allocated space.
<<malloc_usable_size>> returns the usable size.
PORTABILITY
<<malloc>>, <<realloc>>, and <<free>> are specified by the ANSI C
standard, but other conforming implementations of <<malloc>> may
behave differently when <[nbytes]> is zero.
<<memalign>> is part of SVR4.
<<malloc_usable_size>> is not portable.
Supporting OS subroutines required: <<sbrk>>. */
#include <_ansi.h>
#include <reent.h>
#include <stdlib.h>
#include <malloc.h>
#ifndef _REENT_ONLY
_PTR
_DEFUN (malloc, (nbytes),
size_t nbytes) /* get a block */
{
return _malloc_r (_REENT, nbytes);
}
void
_DEFUN (free, (aptr),
_PTR aptr)
{
_free_r (_REENT, aptr);
}
#endif
#endif /* ! defined (MALLOC_PROVIDED) */

3620
agbcc/libc/stdlib/mallocr.c Normal file
View File

@ -0,0 +1,3620 @@
/* ---------- To make a malloc.h, start cutting here ------------ */
/*
A version of malloc/free/realloc written by Doug Lea and released to the
public domain. Send questions/comments/complaints/performance data
to dl@cs.oswego.edu
* VERSION 2.6.4 Thu Nov 28 07:54:55 1996 Doug Lea (dl at gee)
Note: There may be an updated version of this malloc obtainable at
ftp://g.oswego.edu/pub/misc/malloc.c
Check before installing!
* Why use this malloc?
This is not the fastest, most space-conserving, most portable, or
most tunable malloc ever written. However it is among the fastest
while also being among the most space-conserving, portable and tunable.
Consistent balance across these factors results in a good general-purpose
allocator. For a high-level description, see
http://g.oswego.edu/dl/html/malloc.html
* Synopsis of public routines
(Much fuller descriptions are contained in the program documentation below.)
malloc(size_t n);
Return a pointer to a newly allocated chunk of at least n bytes, or null
if no space is available.
free(Void_t* p);
Release the chunk of memory pointed to by p, or no effect if p is null.
realloc(Void_t* p, size_t n);
Return a pointer to a chunk of size n that contains the same data
as does chunk p up to the minimum of (n, p's size) bytes, or null
if no space is available. The returned pointer may or may not be
the same as p. If p is null, equivalent to malloc. Unless the
#define REALLOC_ZERO_BYTES_FREES below is set, realloc with a
size argument of zero (re)allocates a minimum-sized chunk.
memalign(size_t alignment, size_t n);
Return a pointer to a newly allocated chunk of n bytes, aligned
in accord with the alignment argument, which must be a power of
two.
valloc(size_t n);
Equivalent to memalign(pagesize, n), where pagesize is the page
size of the system (or as near to this as can be figured out from
all the includes/defines below.)
pvalloc(size_t n);
Equivalent to valloc(minimum-page-that-holds(n)), that is,
round up n to nearest pagesize.
calloc(size_t unit, size_t quantity);
Returns a pointer to quantity * unit bytes, with all locations
set to zero.
cfree(Void_t* p);
Equivalent to free(p).
malloc_trim(size_t pad);
Release all but pad bytes of freed top-most memory back
to the system. Return 1 if successful, else 0.
malloc_usable_size(Void_t* p);
Report the number usable allocated bytes associated with allocated
chunk p. This may or may not report more bytes than were requested,
due to alignment and minimum size constraints.
malloc_stats();
Prints brief summary statistics on stderr.
mallinfo()
Returns (by copy) a struct containing various summary statistics.
mallopt(int parameter_number, int parameter_value)
Changes one of the tunable parameters described below. Returns
1 if successful in changing the parameter, else 0.
* Vital statistics:
Alignment: 8-byte
8 byte alignment is currently hardwired into the design. This
seems to suffice for all current machines and C compilers.
Assumed pointer representation: 4 or 8 bytes
Code for 8-byte pointers is untested by me but has worked
reliably by Wolfram Gloger, who contributed most of the
changes supporting this.
Assumed size_t representation: 4 or 8 bytes
Note that size_t is allowed to be 4 bytes even if pointers are 8.
Minimum overhead per allocated chunk: 4 or 8 bytes
Each malloced chunk has a hidden overhead of 4 bytes holding size
and status information.
Minimum allocated size: 4-byte ptrs: 16 bytes (including 4 overhead)
8-byte ptrs: 24/32 bytes (including, 4/8 overhead)
When a chunk is freed, 12 (for 4byte ptrs) or 20 (for 8 byte
ptrs but 4 byte size) or 24 (for 8/8) additional bytes are
needed; 4 (8) for a trailing size field
and 8 (16) bytes for free list pointers. Thus, the minimum
allocatable size is 16/24/32 bytes.
Even a request for zero bytes (i.e., malloc(0)) returns a
pointer to something of the minimum allocatable size.
Maximum allocated size: 4-byte size_t: 2^31 - 8 bytes
8-byte size_t: 2^63 - 16 bytes
It is assumed that (possibly signed) size_t bit values suffice to
represent chunk sizes. `Possibly signed' is due to the fact
that `size_t' may be defined on a system as either a signed or
an unsigned type. To be conservative, values that would appear
as negative numbers are avoided.
Requests for sizes with a negative sign bit will return a
minimum-sized chunk.
Maximum overhead wastage per allocated chunk: normally 15 bytes
Alignnment demands, plus the minimum allocatable size restriction
make the normal worst-case wastage 15 bytes (i.e., up to 15
more bytes will be allocated than were requested in malloc), with
two exceptions:
1. Because requests for zero bytes allocate non-zero space,
the worst case wastage for a request of zero bytes is 24 bytes.
2. For requests >= mmap_threshold that are serviced via
mmap(), the worst case wastage is 8 bytes plus the remainder
from a system page (the minimal mmap unit); typically 4096 bytes.
* Limitations
Here are some features that are NOT currently supported
* No user-definable hooks for callbacks and the like.
* No automated mechanism for fully checking that all accesses
to malloced memory stay within their bounds.
* No support for compaction.
* Synopsis of compile-time options:
People have reported using previous versions of this malloc on all
versions of Unix, sometimes by tweaking some of the defines
below. It has been tested most extensively on Solaris and
Linux. It is also reported to work on WIN32 platforms.
People have also reported adapting this malloc for use in
stand-alone embedded systems.
The implementation is in straight, hand-tuned ANSI C. Among other
consequences, it uses a lot of macros. Because of this, to be at
all usable, this code should be compiled using an optimizing compiler
(for example gcc -O2) that can simplify expressions and control
paths.
__STD_C (default: derived from C compiler defines)
Nonzero if using ANSI-standard C compiler, a C++ compiler, or
a C compiler sufficiently close to ANSI to get away with it.
DEBUG (default: NOT defined)
Define to enable debugging. Adds fairly extensive assertion-based
checking to help track down memory errors, but noticeably slows down
execution.
SEPARATE_OBJECTS (default: NOT defined)
Define this to compile into separate .o files. You must then
compile malloc.c several times, defining a DEFINE_* macro each
time. The list of DEFINE_* macros appears below.
MALLOC_LOCK (default: NOT defined)
MALLOC_UNLOCK (default: NOT defined)
Define these to C expressions which are run to lock and unlock
the malloc data structures. Calls may be nested; that is,
MALLOC_LOCK may be called more than once before the corresponding
MALLOC_UNLOCK calls. MALLOC_LOCK must avoid waiting for a lock
that it already holds.
MALLOC_ALIGNMENT (default: NOT defined)
Define this to 16 if you need 16 byte alignment instead of 8 byte alignment
which is the normal default.
SIZE_T_SMALLER_THAN_LONG (default: NOT defined)
Define this when the platform you are compiling has sizeof(long) > sizeof(size_t).
The option causes some extra code to be generated to handle operations
that use size_t operands and have long results.
REALLOC_ZERO_BYTES_FREES (default: NOT defined)
Define this if you think that realloc(p, 0) should be equivalent
to free(p). Otherwise, since malloc returns a unique pointer for
malloc(0), so does realloc(p, 0).
HAVE_MEMCPY (default: defined)
Define if you are not otherwise using ANSI STD C, but still
have memcpy and memset in your C library and want to use them.
Otherwise, simple internal versions are supplied.
USE_MEMCPY (default: 1 if HAVE_MEMCPY is defined, 0 otherwise)
Define as 1 if you want the C library versions of memset and
memcpy called in realloc and calloc (otherwise macro versions are used).
At least on some platforms, the simple macro versions usually
outperform libc versions.
HAVE_MMAP (default: defined as 1)
Define to non-zero to optionally make malloc() use mmap() to
allocate very large blocks.
HAVE_MREMAP (default: defined as 0 unless Linux libc set)
Define to non-zero to optionally make realloc() use mremap() to
reallocate very large blocks.
malloc_getpagesize (default: derived from system #includes)
Either a constant or routine call returning the system page size.
HAVE_USR_INCLUDE_MALLOC_H (default: NOT defined)
Optionally define if you are on a system with a /usr/include/malloc.h
that declares struct mallinfo. It is not at all necessary to
define this even if you do, but will ensure consistency.
INTERNAL_SIZE_T (default: size_t)
Define to a 32-bit type (probably `unsigned int') if you are on a
64-bit machine, yet do not want or need to allow malloc requests of
greater than 2^31 to be handled. This saves space, especially for
very small chunks.
INTERNAL_LINUX_C_LIB (default: NOT defined)
Defined only when compiled as part of Linux libc.
Also note that there is some odd internal name-mangling via defines
(for example, internally, `malloc' is named `mALLOc') needed
when compiling in this case. These look funny but don't otherwise
affect anything.
INTERNAL_NEWLIB (default: NOT defined)
Defined only when compiled as part of the Cygnus newlib
distribution.
WIN32 (default: undefined)
Define this on MS win (95, nt) platforms to compile in sbrk emulation.
LACKS_UNISTD_H (default: undefined)
Define this if your system does not have a <unistd.h>.
MORECORE (default: sbrk)
The name of the routine to call to obtain more memory from the system.
MORECORE_FAILURE (default: -1)
The value returned upon failure of MORECORE.
MORECORE_CLEARS (default 1)
True (1) if the routine mapped to MORECORE zeroes out memory (which
holds for sbrk).
DEFAULT_TRIM_THRESHOLD
DEFAULT_TOP_PAD
DEFAULT_MMAP_THRESHOLD
DEFAULT_MMAP_MAX
Default values of tunable parameters (described in detail below)
controlling interaction with host system routines (sbrk, mmap, etc).
These values may also be changed dynamically via mallopt(). The
preset defaults are those that give best performance for typical
programs/systems.
*/
/* Preliminaries */
#ifndef __STD_C
#ifdef __STDC__
#define __STD_C 1
#else
#if __cplusplus
#define __STD_C 1
#else
#define __STD_C 0
#endif /*__cplusplus*/
#endif /*__STDC__*/
#endif /*__STD_C*/
#ifndef Void_t
#if __STD_C
#define Void_t void
#else
#define Void_t char
#endif
#endif /*Void_t*/
#if __STD_C
#include <stddef.h> /* for size_t */
#else
#include <sys/types.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h> /* needed for malloc_stats */
/*
Compile-time options
*/
/*
Special defines for Cygnus newlib distribution.
*/
#ifdef INTERNAL_NEWLIB
#include <sys/config.h>
/*
In newlib, all the publically visible routines take a reentrancy
pointer. We don't currently do anything much with it, but we do
pass it to the lock routine.
*/
#include <reent.h>
#define POINTER_UINT unsigned _POINTER_INT
#define SEPARATE_OBJECTS
#define HAVE_MMAP 0
#define MORECORE(size) _sbrk_r(reent_ptr, (size))
#define MORECORE_CLEARS 0
#define MALLOC_LOCK __malloc_lock(reent_ptr)
#define MALLOC_UNLOCK __malloc_unlock(reent_ptr)
#ifndef _WIN32
#ifdef SMALL_MEMORY
#define malloc_getpagesize (128)
#else
#define malloc_getpagesize (4096)
#endif
#endif
#if __STD_C
extern void __malloc_lock(struct _reent *);
extern void __malloc_unlock(struct _reent *);
#else
extern void __malloc_lock();
extern void __malloc_unlock();
#endif
#if __STD_C
#define RARG struct _reent *reent_ptr,
#define RONEARG struct _reent *reent_ptr
#else
#define RARG reent_ptr
#define RONEARG reent_ptr
#define RDECL struct _reent *reent_ptr;
#endif
#define RCALL reent_ptr,
#define RONECALL reent_ptr
#else /* ! INTERNAL_NEWLIB */
#define POINTER_UINT unsigned long
#define RARG
#define RONEARG
#define RDECL
#define RCALL
#define RONECALL
#endif /* ! INTERNAL_NEWLIB */
/*
Debugging:
Because freed chunks may be overwritten with link fields, this
malloc will often die when freed memory is overwritten by user
programs. This can be very effective (albeit in an annoying way)
in helping track down dangling pointers.
If you compile with -DDEBUG, a number of assertion checks are
enabled that will catch more memory errors. You probably won't be
able to make much sense of the actual assertion errors, but they
should help you locate incorrectly overwritten memory. The
checking is fairly extensive, and will slow down execution
noticeably. Calling malloc_stats or mallinfo with DEBUG set will
attempt to check every non-mmapped allocated and free chunk in the
course of computing the summmaries. (By nature, mmapped regions
cannot be checked very much automatically.)
Setting DEBUG may also be helpful if you are trying to modify
this code. The assertions in the check routines spell out in more
detail the assumptions and invariants underlying the algorithms.
*/
#if DEBUG
#include <assert.h>
#else
#define assert(x) ((void)0)
#endif
/*
SEPARATE_OBJECTS should be defined if you want each function to go
into a separate .o file. You must then compile malloc.c once per
function, defining the appropriate DEFINE_ macro. See below for the
list of macros.
*/
#ifndef SEPARATE_OBJECTS
#define DEFINE_MALLOC
#define DEFINE_FREE
#define DEFINE_REALLOC
#define DEFINE_CALLOC
#define DEFINE_CFREE
#define DEFINE_MEMALIGN
#define DEFINE_VALLOC
#define DEFINE_PVALLOC
#define DEFINE_MALLINFO
#define DEFINE_MALLOC_STATS
#define DEFINE_MALLOC_USABLE_SIZE
#define DEFINE_MALLOPT
#define STATIC static
#else
#define STATIC
#endif
/*
Define MALLOC_LOCK and MALLOC_UNLOCK to C expressions to run to
lock and unlock the malloc data structures. MALLOC_LOCK may be
called recursively.
*/
#ifndef MALLOC_LOCK
#define MALLOC_LOCK
#endif
#ifndef MALLOC_UNLOCK
#define MALLOC_UNLOCK
#endif
/*
INTERNAL_SIZE_T is the word-size used for internal bookkeeping
of chunk sizes. On a 64-bit machine, you can reduce malloc
overhead by defining INTERNAL_SIZE_T to be a 32 bit `unsigned int'
at the expense of not being able to handle requests greater than
2^31. This limitation is hardly ever a concern; you are encouraged
to set this. However, the default version is the same as size_t.
*/
#ifndef INTERNAL_SIZE_T
#define INTERNAL_SIZE_T size_t
#endif
/*
Following is needed on implementations whereby long > size_t.
The problem is caused because the code performs subtractions of
size_t values and stores the result in long values. In the case
where long > size_t and the first value is actually less than
the second value, the resultant value is positive. For example,
(long)(x - y) where x = 0 and y is 1 ends up being 0x00000000FFFFFFFF
which is 2*31 - 1 instead of 0xFFFFFFFFFFFFFFFF. This is due to the
fact that assignment from unsigned to signed won't sign extend.
*/
#ifdef SIZE_T_SMALLER_THAN_LONG
#define long_sub_size_t(x, y) ( (x < y) ? -((long)(y - x)) : (x - y) );
#else
#define long_sub_size_t(x, y) ( (long)(x - y) )
#endif
/*
REALLOC_ZERO_BYTES_FREES should be set if a call to
realloc with zero bytes should be the same as a call to free.
Some people think it should. Otherwise, since this malloc
returns a unique pointer for malloc(0), so does realloc(p, 0).
*/
/* #define REALLOC_ZERO_BYTES_FREES */
/*
WIN32 causes an emulation of sbrk to be compiled in
mmap-based options are not currently supported in WIN32.
*/
/* #define WIN32 */
#ifdef WIN32
#define MORECORE wsbrk
#define HAVE_MMAP 0
#endif
/*
HAVE_MEMCPY should be defined if you are not otherwise using
ANSI STD C, but still have memcpy and memset in your C library
and want to use them in calloc and realloc. Otherwise simple
macro versions are defined here.
USE_MEMCPY should be defined as 1 if you actually want to
have memset and memcpy called. People report that the macro
versions are often enough faster than libc versions on many
systems that it is better to use them.
*/
#define HAVE_MEMCPY
#ifndef USE_MEMCPY
#ifdef HAVE_MEMCPY
#define USE_MEMCPY 1
#else
#define USE_MEMCPY 0
#endif
#endif
#if (__STD_C || defined(HAVE_MEMCPY))
#if __STD_C
void* memset(void*, int, size_t);
void* memcpy(void*, const void*, size_t);
#else
Void_t* memset();
Void_t* memcpy();
#endif
#endif
#if USE_MEMCPY
/* The following macros are only invoked with (2n+1)-multiples of
INTERNAL_SIZE_T units, with a positive integer n. This is exploited
for fast inline execution when n is small. */
#define MALLOC_ZERO(charp, nbytes) \
do { \
INTERNAL_SIZE_T mzsz = (nbytes); \
if(mzsz <= 9*sizeof(mzsz)) { \
INTERNAL_SIZE_T* mz = (INTERNAL_SIZE_T*) (charp); \
if(mzsz >= 5*sizeof(mzsz)) { *mz++ = 0; \
*mz++ = 0; \
if(mzsz >= 7*sizeof(mzsz)) { *mz++ = 0; \
*mz++ = 0; \
if(mzsz >= 9*sizeof(mzsz)) { *mz++ = 0; \
*mz++ = 0; }}} \
*mz++ = 0; \
*mz++ = 0; \
*mz = 0; \
} else memset((charp), 0, mzsz); \
} while(0)
#define MALLOC_COPY(dest,src,nbytes) \
do { \
INTERNAL_SIZE_T mcsz = (nbytes); \
if(mcsz <= 9*sizeof(mcsz)) { \
INTERNAL_SIZE_T* mcsrc = (INTERNAL_SIZE_T*) (src); \
INTERNAL_SIZE_T* mcdst = (INTERNAL_SIZE_T*) (dest); \
if(mcsz >= 5*sizeof(mcsz)) { *mcdst++ = *mcsrc++; \
*mcdst++ = *mcsrc++; \
if(mcsz >= 7*sizeof(mcsz)) { *mcdst++ = *mcsrc++; \
*mcdst++ = *mcsrc++; \
if(mcsz >= 9*sizeof(mcsz)) { *mcdst++ = *mcsrc++; \
*mcdst++ = *mcsrc++; }}} \
*mcdst++ = *mcsrc++; \
*mcdst++ = *mcsrc++; \
*mcdst = *mcsrc ; \
} else memcpy(dest, src, mcsz); \
} while(0)
#else /* !USE_MEMCPY */
/* Use Duff's device for good zeroing/copying performance. */
#define MALLOC_ZERO(charp, nbytes) \
do { \
INTERNAL_SIZE_T* mzp = (INTERNAL_SIZE_T*)(charp); \
long mctmp = (nbytes)/sizeof(INTERNAL_SIZE_T), mcn; \
if (mctmp < 8) mcn = 0; else { mcn = (mctmp-1)/8; mctmp %= 8; } \
switch (mctmp) { \
case 0: for(;;) { *mzp++ = 0; \
case 7: *mzp++ = 0; \
case 6: *mzp++ = 0; \
case 5: *mzp++ = 0; \
case 4: *mzp++ = 0; \
case 3: *mzp++ = 0; \
case 2: *mzp++ = 0; \
case 1: *mzp++ = 0; if(mcn <= 0) break; mcn--; } \
} \
} while(0)
#define MALLOC_COPY(dest,src,nbytes) \
do { \
INTERNAL_SIZE_T* mcsrc = (INTERNAL_SIZE_T*) src; \
INTERNAL_SIZE_T* mcdst = (INTERNAL_SIZE_T*) dest; \
long mctmp = (nbytes)/sizeof(INTERNAL_SIZE_T), mcn; \
if (mctmp < 8) mcn = 0; else { mcn = (mctmp-1)/8; mctmp %= 8; } \
switch (mctmp) { \
case 0: for(;;) { *mcdst++ = *mcsrc++; \
case 7: *mcdst++ = *mcsrc++; \
case 6: *mcdst++ = *mcsrc++; \
case 5: *mcdst++ = *mcsrc++; \
case 4: *mcdst++ = *mcsrc++; \
case 3: *mcdst++ = *mcsrc++; \
case 2: *mcdst++ = *mcsrc++; \
case 1: *mcdst++ = *mcsrc++; if(mcn <= 0) break; mcn--; } \
} \
} while(0)
#endif
/*
Define HAVE_MMAP to optionally make malloc() use mmap() to
allocate very large blocks. These will be returned to the
operating system immediately after a free().
*/
#ifndef HAVE_MMAP
#define HAVE_MMAP 1
#endif
/*
Define HAVE_MREMAP to make realloc() use mremap() to re-allocate
large blocks. This is currently only possible on Linux with
kernel versions newer than 1.3.77.
*/
#ifndef HAVE_MREMAP
#ifdef INTERNAL_LINUX_C_LIB
#define HAVE_MREMAP 1
#else
#define HAVE_MREMAP 0
#endif
#endif
#if HAVE_MMAP
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
#define MAP_ANONYMOUS MAP_ANON
#endif
#endif /* HAVE_MMAP */
/*
Access to system page size. To the extent possible, this malloc
manages memory from the system in page-size units.
The following mechanics for getpagesize were adapted from
bsd/gnu getpagesize.h
*/
#ifndef LACKS_UNISTD_H
# include <unistd.h>
#endif
#ifndef malloc_getpagesize
# ifdef _SC_PAGESIZE /* some SVR4 systems omit an underscore */
# ifndef _SC_PAGE_SIZE
# define _SC_PAGE_SIZE _SC_PAGESIZE
# endif
# endif
# ifdef _SC_PAGE_SIZE
# define malloc_getpagesize sysconf(_SC_PAGE_SIZE)
# else
# if defined(BSD) || defined(DGUX) || defined(HAVE_GETPAGESIZE)
extern size_t getpagesize();
# define malloc_getpagesize getpagesize()
# else
# include <sys/param.h>
# ifdef EXEC_PAGESIZE
# define malloc_getpagesize EXEC_PAGESIZE
# else
# ifdef NBPG
# ifndef CLSIZE
# define malloc_getpagesize NBPG
# else
# define malloc_getpagesize (NBPG * CLSIZE)
# endif
# else
# ifdef NBPC
# define malloc_getpagesize NBPC
# else
# ifdef PAGESIZE
# define malloc_getpagesize PAGESIZE
# else
# define malloc_getpagesize (4096) /* just guess */
# endif
# endif
# endif
# endif
# endif
# endif
#endif
/*
This version of malloc supports the standard SVID/XPG mallinfo
routine that returns a struct containing the same kind of
information you can get from malloc_stats. It should work on
any SVID/XPG compliant system that has a /usr/include/malloc.h
defining struct mallinfo. (If you'd like to install such a thing
yourself, cut out the preliminary declarations as described above
and below and save them in a malloc.h file. But there's no
compelling reason to bother to do this.)
The main declaration needed is the mallinfo struct that is returned
(by-copy) by mallinfo(). The SVID/XPG malloinfo struct contains a
bunch of fields, most of which are not even meaningful in this
version of malloc. Some of these fields are are instead filled by
mallinfo() with other numbers that might possibly be of interest.
HAVE_USR_INCLUDE_MALLOC_H should be set if you have a
/usr/include/malloc.h file that includes a declaration of struct
mallinfo. If so, it is included; else an SVID2/XPG2 compliant
version is declared below. These must be precisely the same for
mallinfo() to work.
*/
/* #define HAVE_USR_INCLUDE_MALLOC_H */
#if HAVE_USR_INCLUDE_MALLOC_H
#include "/usr/include/malloc.h"
#else
/* SVID2/XPG mallinfo structure */
struct mallinfo {
int arena; /* total space allocated from system */
int ordblks; /* number of non-inuse chunks */
int smblks; /* unused -- always zero */
int hblks; /* number of mmapped regions */
int hblkhd; /* total space in mmapped regions */
int usmblks; /* unused -- always zero */
int fsmblks; /* unused -- always zero */
int uordblks; /* total allocated space */
int fordblks; /* total non-inuse space */
int keepcost; /* top-most, releasable (via malloc_trim) space */
};
/* SVID2/XPG mallopt options */
#define M_MXFAST 1 /* UNUSED in this malloc */
#define M_NLBLKS 2 /* UNUSED in this malloc */
#define M_GRAIN 3 /* UNUSED in this malloc */
#define M_KEEP 4 /* UNUSED in this malloc */
#endif
/* mallopt options that actually do something */
#define M_TRIM_THRESHOLD -1
#define M_TOP_PAD -2
#define M_MMAP_THRESHOLD -3
#define M_MMAP_MAX -4
#ifndef DEFAULT_TRIM_THRESHOLD
#define DEFAULT_TRIM_THRESHOLD (128L * 1024L)
#endif
/*
M_TRIM_THRESHOLD is the maximum amount of unused top-most memory
to keep before releasing via malloc_trim in free().
Automatic trimming is mainly useful in long-lived programs.
Because trimming via sbrk can be slow on some systems, and can
sometimes be wasteful (in cases where programs immediately
afterward allocate more large chunks) the value should be high
enough so that your overall system performance would improve by
releasing.
The trim threshold and the mmap control parameters (see below)
can be traded off with one another. Trimming and mmapping are
two different ways of releasing unused memory back to the
system. Between these two, it is often possible to keep
system-level demands of a long-lived program down to a bare
minimum. For example, in one test suite of sessions measuring
the XF86 X server on Linux, using a trim threshold of 128K and a
mmap threshold of 192K led to near-minimal long term resource
consumption.
If you are using this malloc in a long-lived program, it should
pay to experiment with these values. As a rough guide, you
might set to a value close to the average size of a process
(program) running on your system. Releasing this much memory
would allow such a process to run in memory. Generally, it's
worth it to tune for trimming rather tham memory mapping when a
program undergoes phases where several large chunks are
allocated and released in ways that can reuse each other's
storage, perhaps mixed with phases where there are no such
chunks at all. And in well-behaved long-lived programs,
controlling release of large blocks via trimming versus mapping
is usually faster.
However, in most programs, these parameters serve mainly as
protection against the system-level effects of carrying around
massive amounts of unneeded memory. Since frequent calls to
sbrk, mmap, and munmap otherwise degrade performance, the default
parameters are set to relatively high values that serve only as
safeguards.
The default trim value is high enough to cause trimming only in
fairly extreme (by current memory consumption standards) cases.
It must be greater than page size to have any useful effect. To
disable trimming completely, you can set to (unsigned long)(-1);
*/
#ifndef DEFAULT_TOP_PAD
#define DEFAULT_TOP_PAD (0)
#endif
/*
M_TOP_PAD is the amount of extra `padding' space to allocate or
retain whenever sbrk is called. It is used in two ways internally:
* When sbrk is called to extend the top of the arena to satisfy
a new malloc request, this much padding is added to the sbrk
request.
* When malloc_trim is called automatically from free(),
it is used as the `pad' argument.
In both cases, the actual amount of padding is rounded
so that the end of the arena is always a system page boundary.
The main reason for using padding is to avoid calling sbrk so
often. Having even a small pad greatly reduces the likelihood
that nearly every malloc request during program start-up (or
after trimming) will invoke sbrk, which needlessly wastes
time.
Automatic rounding-up to page-size units is normally sufficient
to avoid measurable overhead, so the default is 0. However, in
systems where sbrk is relatively slow, it can pay to increase
this value, at the expense of carrying around more memory than
the program needs.
*/
#ifndef DEFAULT_MMAP_THRESHOLD
#define DEFAULT_MMAP_THRESHOLD (128 * 1024)
#endif
/*
M_MMAP_THRESHOLD is the request size threshold for using mmap()
to service a request. Requests of at least this size that cannot
be allocated using already-existing space will be serviced via mmap.
(If enough normal freed space already exists it is used instead.)
Using mmap segregates relatively large chunks of memory so that
they can be individually obtained and released from the host
system. A request serviced through mmap is never reused by any
other request (at least not directly; the system may just so
happen to remap successive requests to the same locations).
Segregating space in this way has the benefit that mmapped space
can ALWAYS be individually released back to the system, which
helps keep the system level memory demands of a long-lived
program low. Mapped memory can never become `locked' between
other chunks, as can happen with normally allocated chunks, which
menas that even trimming via malloc_trim would not release them.
However, it has the disadvantages that:
1. The space cannot be reclaimed, consolidated, and then
used to service later requests, as happens with normal chunks.
2. It can lead to more wastage because of mmap page alignment
requirements
3. It causes malloc performance to be more dependent on host
system memory management support routines which may vary in
implementation quality and may impose arbitrary
limitations. Generally, servicing a request via normal
malloc steps is faster than going through a system's mmap.
All together, these considerations should lead you to use mmap
only for relatively large requests.
*/
#ifndef DEFAULT_MMAP_MAX
#if HAVE_MMAP
#define DEFAULT_MMAP_MAX (64)
#else
#define DEFAULT_MMAP_MAX (0)
#endif
#endif
/*
M_MMAP_MAX is the maximum number of requests to simultaneously
service using mmap. This parameter exists because:
1. Some systems have a limited number of internal tables for
use by mmap.
2. In most systems, overreliance on mmap can degrade overall
performance.
3. If a program allocates many large regions, it is probably
better off using normal sbrk-based allocation routines that
can reclaim and reallocate normal heap memory. Using a
small value allows transition into this mode after the
first few allocations.
Setting to 0 disables all use of mmap. If HAVE_MMAP is not set,
the default value is 0, and attempts to set it to non-zero values
in mallopt will fail.
*/
/*
Special defines for linux libc
Except when compiled using these special defines for Linux libc
using weak aliases, this malloc is NOT designed to work in
multithreaded applications. No semaphores or other concurrency
control are provided to ensure that multiple malloc or free calls
don't run at the same time, which could be disasterous. A single
semaphore could be used across malloc, realloc, and free (which is
essentially the effect of the linux weak alias approach). It would
be hard to obtain finer granularity.
*/
#ifdef INTERNAL_LINUX_C_LIB
#if __STD_C
Void_t * __default_morecore_init (ptrdiff_t);
Void_t *(*__morecore)(ptrdiff_t) = __default_morecore_init;
#else
Void_t * __default_morecore_init ();
Void_t *(*__morecore)() = __default_morecore_init;
#endif
#define MORECORE (*__morecore)
#define MORECORE_FAILURE 0
#define MORECORE_CLEARS 1
#else /* INTERNAL_LINUX_C_LIB */
#ifndef INTERNAL_NEWLIB
#if __STD_C
extern Void_t* sbrk(ptrdiff_t);
#else
extern Void_t* sbrk();
#endif
#endif
#ifndef MORECORE
#define MORECORE sbrk
#endif
#ifndef MORECORE_FAILURE
#define MORECORE_FAILURE -1
#endif
#ifndef MORECORE_CLEARS
#define MORECORE_CLEARS 1
#endif
#endif /* INTERNAL_LINUX_C_LIB */
#if defined(INTERNAL_LINUX_C_LIB) && defined(__ELF__)
#define cALLOc __libc_calloc
#define fREe __libc_free
#define mALLOc __libc_malloc
#define mEMALIGn __libc_memalign
#define rEALLOc __libc_realloc
#define vALLOc __libc_valloc
#define pvALLOc __libc_pvalloc
#define mALLINFo __libc_mallinfo
#define mALLOPt __libc_mallopt
#pragma weak calloc = __libc_calloc
#pragma weak free = __libc_free
#pragma weak cfree = __libc_free
#pragma weak malloc = __libc_malloc
#pragma weak memalign = __libc_memalign
#pragma weak realloc = __libc_realloc
#pragma weak valloc = __libc_valloc
#pragma weak pvalloc = __libc_pvalloc
#pragma weak mallinfo = __libc_mallinfo
#pragma weak mallopt = __libc_mallopt
#else
#ifdef INTERNAL_NEWLIB
#define cALLOc _calloc_r
#define fREe _free_r
#define mALLOc _malloc_r
#define mEMALIGn _memalign_r
#define rEALLOc _realloc_r
#define vALLOc _valloc_r
#define pvALLOc _pvalloc_r
#define mALLINFo _mallinfo_r
#define mALLOPt _mallopt_r
#define malloc_stats _malloc_stats_r
#define malloc_trim _malloc_trim_r
#define malloc_usable_size _malloc_usable_size_r
#define malloc_update_mallinfo __malloc_update_mallinfo
#define malloc_av_ __malloc_av_
#define malloc_current_mallinfo __malloc_current_mallinfo
#define malloc_max_sbrked_mem __malloc_max_sbrked_mem
#define malloc_max_total_mem __malloc_max_total_mem
#define malloc_sbrk_base __malloc_sbrk_base
#define malloc_top_pad __malloc_top_pad
#define malloc_trim_threshold __malloc_trim_threshold
#else /* ! INTERNAL_NEWLIB */
#define cALLOc calloc
#define fREe free
#define mALLOc malloc
#define mEMALIGn memalign
#define rEALLOc realloc
#define vALLOc valloc
#define pvALLOc pvalloc
#define mALLINFo mallinfo
#define mALLOPt mallopt
#endif /* ! INTERNAL_NEWLIB */
#endif
/* Public routines */
#if __STD_C
Void_t* mALLOc(RARG size_t);
void fREe(RARG Void_t*);
Void_t* rEALLOc(RARG Void_t*, size_t);
Void_t* mEMALIGn(RARG size_t, size_t);
Void_t* vALLOc(RARG size_t);
Void_t* pvALLOc(RARG size_t);
Void_t* cALLOc(RARG size_t, size_t);
void cfree(Void_t*);
int malloc_trim(RARG size_t);
size_t malloc_usable_size(RARG Void_t*);
void malloc_stats(RONEARG);
int mALLOPt(RARG int, int);
struct mallinfo mALLINFo(RONEARG);
#else
Void_t* mALLOc();
void fREe();
Void_t* rEALLOc();
Void_t* mEMALIGn();
Void_t* vALLOc();
Void_t* pvALLOc();
Void_t* cALLOc();
void cfree();
int malloc_trim();
size_t malloc_usable_size();
void malloc_stats();
int mALLOPt();
struct mallinfo mALLINFo();
#endif
#ifdef __cplusplus
}; /* end of extern "C" */
#endif
/* ---------- To make a malloc.h, end cutting here ------------ */
/*
Emulation of sbrk for WIN32
All code within the ifdef WIN32 is untested by me.
*/
#ifdef WIN32
#define AlignPage(add) (((add) + (malloc_getpagesize-1)) &
~(malloc_getpagesize-1))
/* resrve 64MB to insure large contiguous space */
#define RESERVED_SIZE (1024*1024*64)
#define NEXT_SIZE (2048*1024)
#define TOP_MEMORY ((unsigned long)2*1024*1024*1024)
struct GmListElement;
typedef struct GmListElement GmListElement;
struct GmListElement
{
GmListElement* next;
void* base;
};
static GmListElement* head = 0;
static unsigned int gNextAddress = 0;
static unsigned int gAddressBase = 0;
static unsigned int gAllocatedSize = 0;
static
GmListElement* makeGmListElement (void* bas)
{
GmListElement* this;
this = (GmListElement*)(void*)LocalAlloc (0, sizeof (GmListElement));
ASSERT (this);
if (this)
{
this->base = bas;
this->next = head;
head = this;
}
return this;
}
void gcleanup ()
{
BOOL rval;
ASSERT ( (head == NULL) || (head->base == (void*)gAddressBase));
if (gAddressBase && (gNextAddress - gAddressBase))
{
rval = VirtualFree ((void*)gAddressBase,
gNextAddress - gAddressBase,
MEM_DECOMMIT);
ASSERT (rval);
}
while (head)
{
GmListElement* next = head->next;
rval = VirtualFree (head->base, 0, MEM_RELEASE);
ASSERT (rval);
LocalFree (head);
head = next;
}
}
static
void* findRegion (void* start_address, unsigned long size)
{
MEMORY_BASIC_INFORMATION info;
while ((unsigned long)start_address < TOP_MEMORY)
{
VirtualQuery (start_address, &info, sizeof (info));
if (info.State != MEM_FREE)
start_address = (char*)info.BaseAddress + info.RegionSize;
else if (info.RegionSize >= size)
return start_address;
else
start_address = (char*)info.BaseAddress + info.RegionSize;
}
return NULL;
}
void* wsbrk (long size)
{
void* tmp;
if (size > 0)
{
if (gAddressBase == 0)
{
gAllocatedSize = max (RESERVED_SIZE, AlignPage (size));
gNextAddress = gAddressBase =
(unsigned int)VirtualAlloc (NULL, gAllocatedSize,
MEM_RESERVE, PAGE_NOACCESS);
} else if (AlignPage (gNextAddress + size) > (gAddressBase +
gAllocatedSize))
{
long new_size = max (NEXT_SIZE, AlignPage (size));
void* new_address = (void*)(gAddressBase+gAllocatedSize);
do
{
new_address = findRegion (new_address, new_size);
if (new_address == 0)
return (void*)-1;
gAddressBase = gNextAddress =
(unsigned int)VirtualAlloc (new_address, new_size,
MEM_RESERVE, PAGE_NOACCESS);
// repeat in case of race condition
// The region that we found has been snagged
// by another thread
}
while (gAddressBase == 0);
ASSERT (new_address == (void*)gAddressBase);
gAllocatedSize = new_size;
if (!makeGmListElement ((void*)gAddressBase))
return (void*)-1;
}
if ((size + gNextAddress) > AlignPage (gNextAddress))
{
void* res;
res = VirtualAlloc ((void*)AlignPage (gNextAddress),
(size + gNextAddress -
AlignPage (gNextAddress)),
MEM_COMMIT, PAGE_READWRITE);
if (res == 0)
return (void*)-1;
}
tmp = (void*)gNextAddress;
gNextAddress = (unsigned int)tmp + size;
return tmp;
}
else if (size < 0)
{
unsigned int alignedGoal = AlignPage (gNextAddress + size);
/* Trim by releasing the virtual memory */
if (alignedGoal >= gAddressBase)
{
VirtualFree ((void*)alignedGoal, gNextAddress - alignedGoal,
MEM_DECOMMIT);
gNextAddress = gNextAddress + size;
return (void*)gNextAddress;
}
else
{
VirtualFree ((void*)gAddressBase, gNextAddress - gAddressBase,
MEM_DECOMMIT);
gNextAddress = gAddressBase;
return (void*)-1;
}
}
else
{
return (void*)gNextAddress;
}
}
#endif
/*
Type declarations
*/
struct malloc_chunk
{
INTERNAL_SIZE_T prev_size; /* Size of previous chunk (if free). */
INTERNAL_SIZE_T size; /* Size in bytes, including overhead. */
struct malloc_chunk* fd; /* double links -- used only if free. */
struct malloc_chunk* bk;
};
typedef struct malloc_chunk* mchunkptr;
/*
malloc_chunk details:
(The following includes lightly edited explanations by Colin Plumb.)
Chunks of memory are maintained using a `boundary tag' method as
described in e.g., Knuth or Standish. (See the paper by Paul
Wilson ftp://ftp.cs.utexas.edu/pub/garbage/allocsrv.ps for a
survey of such techniques.) Sizes of free chunks are stored both
in the front of each chunk and at the end. This makes
consolidating fragmented chunks into bigger chunks very fast. The
size fields also hold bits representing whether chunks are free or
in use.
An allocated chunk looks like this:
chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Size of previous chunk, if allocated | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Size of chunk, in bytes |P|
mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| User data starts here... .
. .
. (malloc_usable_space() bytes) .
. |
nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Size of chunk |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Where "chunk" is the front of the chunk for the purpose of most of
the malloc code, but "mem" is the pointer that is returned to the
user. "Nextchunk" is the beginning of the next contiguous chunk.
Chunks always begin on even word boundries, so the mem portion
(which is returned to the user) is also on an even word boundary, and
thus double-word aligned.
Free chunks are stored in circular doubly-linked lists, and look like this:
chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Size of previous chunk |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
`head:' | Size of chunk, in bytes |P|
mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Forward pointer to next chunk in list |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Back pointer to previous chunk in list |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Unused space (may be 0 bytes long) .
. .
. |
nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
`foot:' | Size of chunk, in bytes |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
The P (PREV_INUSE) bit, stored in the unused low-order bit of the
chunk size (which is always a multiple of two words), is an in-use
bit for the *previous* chunk. If that bit is *clear*, then the
word before the current chunk size contains the previous chunk
size, and can be used to find the front of the previous chunk.
(The very first chunk allocated always has this bit set,
preventing access to non-existent (or non-owned) memory.)
Note that the `foot' of the current chunk is actually represented
as the prev_size of the NEXT chunk. (This makes it easier to
deal with alignments etc).
The two exceptions to all this are
1. The special chunk `top', which doesn't bother using the
trailing size field since there is no
next contiguous chunk that would have to index off it. (After
initialization, `top' is forced to always exist. If it would
become less than MINSIZE bytes long, it is replenished via
malloc_extend_top.)
2. Chunks allocated via mmap, which have the second-lowest-order
bit (IS_MMAPPED) set in their size fields. Because they are
never merged or traversed from any other chunk, they have no
foot size or inuse information.
Available chunks are kept in any of several places (all declared below):
* `av': An array of chunks serving as bin headers for consolidated
chunks. Each bin is doubly linked. The bins are approximately
proportionally (log) spaced. There are a lot of these bins
(128). This may look excessive, but works very well in
practice. All procedures maintain the invariant that no
consolidated chunk physically borders another one. Chunks in
bins are kept in size order, with ties going to the
approximately least recently used chunk.
The chunks in each bin are maintained in decreasing sorted order by
size. This is irrelevant for the small bins, which all contain
the same-sized chunks, but facilitates best-fit allocation for
larger chunks. (These lists are just sequential. Keeping them in
order almost never requires enough traversal to warrant using
fancier ordered data structures.) Chunks of the same size are
linked with the most recently freed at the front, and allocations
are taken from the back. This results in LRU or FIFO allocation
order, which tends to give each chunk an equal opportunity to be
consolidated with adjacent freed chunks, resulting in larger free
chunks and less fragmentation.
* `top': The top-most available chunk (i.e., the one bordering the
end of available memory) is treated specially. It is never
included in any bin, is used only if no other chunk is
available, and is released back to the system if it is very
large (see M_TRIM_THRESHOLD).
* `last_remainder': A bin holding only the remainder of the
most recently split (non-top) chunk. This bin is checked
before other non-fitting chunks, so as to provide better
locality for runs of sequentially allocated chunks.
* Implicitly, through the host system's memory mapping tables.
If supported, requests greater than a threshold are usually
serviced via calls to mmap, and then later released via munmap.
*/
/* sizes, alignments */
#define SIZE_SZ (sizeof(INTERNAL_SIZE_T))
#ifndef MALLOC_ALIGNMENT
#define MALLOC_ALIGN 8
#define MALLOC_ALIGNMENT (SIZE_SZ + SIZE_SZ)
#else
#define MALLOC_ALIGN MALLOC_ALIGNMENT
#endif
#define MALLOC_ALIGN_MASK (MALLOC_ALIGNMENT - 1)
#define MINSIZE (sizeof(struct malloc_chunk))
/* conversion from malloc headers to user pointers, and back */
#define chunk2mem(p) ((Void_t*)((char*)(p) + 2*SIZE_SZ))
#define mem2chunk(mem) ((mchunkptr)((char*)(mem) - 2*SIZE_SZ))
/* pad request bytes into a usable size */
#define request2size(req) \
(((long)((req) + (SIZE_SZ + MALLOC_ALIGN_MASK)) < \
(long)(MINSIZE + MALLOC_ALIGN_MASK)) ? ((MINSIZE + MALLOC_ALIGN_MASK) & ~(MALLOC_ALIGN_MASK)) : \
(((req) + (SIZE_SZ + MALLOC_ALIGN_MASK)) & ~(MALLOC_ALIGN_MASK)))
/* Check if m has acceptable alignment */
#define aligned_OK(m) (((unsigned long)((m)) & (MALLOC_ALIGN_MASK)) == 0)
/*
Physical chunk operations
*/
/* size field is or'ed with PREV_INUSE when previous adjacent chunk in use */
#define PREV_INUSE 0x1
/* size field is or'ed with IS_MMAPPED if the chunk was obtained with mmap() */
#define IS_MMAPPED 0x2
/* Bits to mask off when extracting size */
#define SIZE_BITS (PREV_INUSE|IS_MMAPPED)
/* Ptr to next physical malloc_chunk. */
#define next_chunk(p) ((mchunkptr)( ((char*)(p)) + ((p)->size & ~PREV_INUSE) ))
/* Ptr to previous physical malloc_chunk */
#define prev_chunk(p)\
((mchunkptr)( ((char*)(p)) - ((p)->prev_size) ))
/* Treat space at ptr + offset as a chunk */
#define chunk_at_offset(p, s) ((mchunkptr)(((char*)(p)) + (s)))
/*
Dealing with use bits
*/
/* extract p's inuse bit */
#define inuse(p)\
((((mchunkptr)(((char*)(p))+((p)->size & ~PREV_INUSE)))->size) & PREV_INUSE)
/* extract inuse bit of previous chunk */
#define prev_inuse(p) ((p)->size & PREV_INUSE)
/* check for mmap()'ed chunk */
#define chunk_is_mmapped(p) ((p)->size & IS_MMAPPED)
/* set/clear chunk as in use without otherwise disturbing */
#define set_inuse(p)\
((mchunkptr)(((char*)(p)) + ((p)->size & ~PREV_INUSE)))->size |= PREV_INUSE
#define clear_inuse(p)\
((mchunkptr)(((char*)(p)) + ((p)->size & ~PREV_INUSE)))->size &= ~(PREV_INUSE)
/* check/set/clear inuse bits in known places */
#define inuse_bit_at_offset(p, s)\
(((mchunkptr)(((char*)(p)) + (s)))->size & PREV_INUSE)
#define set_inuse_bit_at_offset(p, s)\
(((mchunkptr)(((char*)(p)) + (s)))->size |= PREV_INUSE)
#define clear_inuse_bit_at_offset(p, s)\
(((mchunkptr)(((char*)(p)) + (s)))->size &= ~(PREV_INUSE))
/*
Dealing with size fields
*/
/* Get size, ignoring use bits */
#define chunksize(p) ((p)->size & ~(SIZE_BITS))
/* Set size at head, without disturbing its use bit */
#define set_head_size(p, s) ((p)->size = (((p)->size & PREV_INUSE) | (s)))
/* Set size/use ignoring previous bits in header */
#define set_head(p, s) ((p)->size = (s))
/* Set size at footer (only when chunk is not in use) */
#define set_foot(p, s) (((mchunkptr)((char*)(p) + (s)))->prev_size = (s))
/*
Bins
The bins, `av_' are an array of pairs of pointers serving as the
heads of (initially empty) doubly-linked lists of chunks, laid out
in a way so that each pair can be treated as if it were in a
malloc_chunk. (This way, the fd/bk offsets for linking bin heads
and chunks are the same).
Bins for sizes < 512 bytes contain chunks of all the same size, spaced
8 bytes apart. Larger bins are approximately logarithmically
spaced. (See the table below.) The `av_' array is never mentioned
directly in the code, but instead via bin access macros.
Bin layout:
64 bins of size 8
32 bins of size 64
16 bins of size 512
8 bins of size 4096
4 bins of size 32768
2 bins of size 262144
1 bin of size what's left
There is actually a little bit of slop in the numbers in bin_index
for the sake of speed. This makes no difference elsewhere.
The special chunks `top' and `last_remainder' get their own bins,
(this is implemented via yet more trickery with the av_ array),
although `top' is never properly linked to its bin since it is
always handled specially.
*/
#ifdef SEPARATE_OBJECTS
#define av_ malloc_av_
#endif
#define NAV 128 /* number of bins */
typedef struct malloc_chunk* mbinptr;
/* access macros */
#define bin_at(i) ((mbinptr)((char*)&(av_[2*(i) + 2]) - 2*SIZE_SZ))
#define next_bin(b) ((mbinptr)((char*)(b) + 2 * sizeof(mbinptr)))
#define prev_bin(b) ((mbinptr)((char*)(b) - 2 * sizeof(mbinptr)))
/*
The first 2 bins are never indexed. The corresponding av_ cells are instead
used for bookkeeping. This is not to save space, but to simplify
indexing, maintain locality, and avoid some initialization tests.
*/
#define top (bin_at(0)->fd) /* The topmost chunk */
#define last_remainder (bin_at(1)) /* remainder from last split */
/*
Because top initially points to its own bin with initial
zero size, thus forcing extension on the first malloc request,
we avoid having any special code in malloc to check whether
it even exists yet. But we still need to in malloc_extend_top.
*/
#define initial_top ((mchunkptr)(bin_at(0)))
/* Helper macro to initialize bins */
#define IAV(i) bin_at(i), bin_at(i)
#ifdef DEFINE_MALLOC
STATIC mbinptr av_[NAV * 2 + 2] = {
0, 0,
IAV(0), IAV(1), IAV(2), IAV(3), IAV(4), IAV(5), IAV(6), IAV(7),
IAV(8), IAV(9), IAV(10), IAV(11), IAV(12), IAV(13), IAV(14), IAV(15),
IAV(16), IAV(17), IAV(18), IAV(19), IAV(20), IAV(21), IAV(22), IAV(23),
IAV(24), IAV(25), IAV(26), IAV(27), IAV(28), IAV(29), IAV(30), IAV(31),
IAV(32), IAV(33), IAV(34), IAV(35), IAV(36), IAV(37), IAV(38), IAV(39),
IAV(40), IAV(41), IAV(42), IAV(43), IAV(44), IAV(45), IAV(46), IAV(47),
IAV(48), IAV(49), IAV(50), IAV(51), IAV(52), IAV(53), IAV(54), IAV(55),
IAV(56), IAV(57), IAV(58), IAV(59), IAV(60), IAV(61), IAV(62), IAV(63),
IAV(64), IAV(65), IAV(66), IAV(67), IAV(68), IAV(69), IAV(70), IAV(71),
IAV(72), IAV(73), IAV(74), IAV(75), IAV(76), IAV(77), IAV(78), IAV(79),
IAV(80), IAV(81), IAV(82), IAV(83), IAV(84), IAV(85), IAV(86), IAV(87),
IAV(88), IAV(89), IAV(90), IAV(91), IAV(92), IAV(93), IAV(94), IAV(95),
IAV(96), IAV(97), IAV(98), IAV(99), IAV(100), IAV(101), IAV(102), IAV(103),
IAV(104), IAV(105), IAV(106), IAV(107), IAV(108), IAV(109), IAV(110), IAV(111),
IAV(112), IAV(113), IAV(114), IAV(115), IAV(116), IAV(117), IAV(118), IAV(119),
IAV(120), IAV(121), IAV(122), IAV(123), IAV(124), IAV(125), IAV(126), IAV(127)
};
#else
extern mbinptr av_[NAV * 2 + 2];
#endif
/* field-extraction macros */
#define first(b) ((b)->fd)
#define last(b) ((b)->bk)
/*
Indexing into bins
*/
#define bin_index(sz) \
(((((unsigned long)(sz)) >> 9) == 0) ? (((unsigned long)(sz)) >> 3): \
((((unsigned long)(sz)) >> 9) <= 4) ? 56 + (((unsigned long)(sz)) >> 6): \
((((unsigned long)(sz)) >> 9) <= 20) ? 91 + (((unsigned long)(sz)) >> 9): \
((((unsigned long)(sz)) >> 9) <= 84) ? 110 + (((unsigned long)(sz)) >> 12): \
((((unsigned long)(sz)) >> 9) <= 340) ? 119 + (((unsigned long)(sz)) >> 15): \
((((unsigned long)(sz)) >> 9) <= 1364) ? 124 + (((unsigned long)(sz)) >> 18): \
126)
/*
bins for chunks < 512 are all spaced SMALLBIN_WIDTH bytes apart, and hold
identically sized chunks. This is exploited in malloc.
*/
#define MAX_SMALLBIN_SIZE 512
#define SMALLBIN_WIDTH 8
#define SMALLBIN_WIDTH_BITS 3
#define MAX_SMALLBIN (MAX_SMALLBIN_SIZE / SMALLBIN_WIDTH) - 1
#define smallbin_index(sz) (((unsigned long)(sz)) >> SMALLBIN_WIDTH_BITS)
/*
Requests are `small' if both the corresponding and the next bin are small
*/
#define is_small_request(nb) (nb < MAX_SMALLBIN_SIZE - SMALLBIN_WIDTH)
/*
To help compensate for the large number of bins, a one-level index
structure is used for bin-by-bin searching. `binblocks' is a
one-word bitvector recording whether groups of BINBLOCKWIDTH bins
have any (possibly) non-empty bins, so they can be skipped over
all at once during during traversals. The bits are NOT always
cleared as soon as all bins in a block are empty, but instead only
when all are noticed to be empty during traversal in malloc.
*/
#define BINBLOCKWIDTH 4 /* bins per block */
#define binblocks (bin_at(0)->size) /* bitvector of nonempty blocks */
/* bin<->block macros */
#define idx2binblock(ix) ((unsigned long)1 << (ix / BINBLOCKWIDTH))
#define mark_binblock(ii) (binblocks |= idx2binblock(ii))
#define clear_binblock(ii) (binblocks &= ~(idx2binblock(ii)))
/* Other static bookkeeping data */
#ifdef SEPARATE_OBJECTS
#define trim_threshold malloc_trim_threshold
#define top_pad malloc_top_pad
#define n_mmaps_max malloc_n_mmaps_max
#define mmap_threshold malloc_mmap_threshold
#define sbrk_base malloc_sbrk_base
#define max_sbrked_mem malloc_max_sbrked_mem
#define max_total_mem malloc_max_total_mem
#define current_mallinfo malloc_current_mallinfo
#define n_mmaps malloc_n_mmaps
#define max_n_mmaps malloc_max_n_mmaps
#define mmapped_mem malloc_mmapped_mem
#define max_mmapped_mem malloc_max_mmapped_mem
#endif
/* variables holding tunable values */
#ifdef DEFINE_MALLOC
STATIC unsigned long trim_threshold = DEFAULT_TRIM_THRESHOLD;
STATIC unsigned long top_pad = DEFAULT_TOP_PAD;
#if HAVE_MMAP
STATIC unsigned int n_mmaps_max = DEFAULT_MMAP_MAX;
STATIC unsigned long mmap_threshold = DEFAULT_MMAP_THRESHOLD;
#endif
/* The first value returned from sbrk */
STATIC char* sbrk_base = (char*)(-1);
/* The maximum memory obtained from system via sbrk */
STATIC unsigned long max_sbrked_mem = 0;
/* The maximum via either sbrk or mmap */
STATIC unsigned long max_total_mem = 0;
/* internal working copy of mallinfo */
STATIC struct mallinfo current_mallinfo = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
#if HAVE_MMAP
/* Tracking mmaps */
STATIC unsigned int n_mmaps = 0;
STATIC unsigned int max_n_mmaps = 0;
STATIC unsigned long mmapped_mem = 0;
STATIC unsigned long max_mmapped_mem = 0;
#endif
#else /* ! DEFINE_MALLOC */
extern unsigned long trim_threshold;
extern unsigned long top_pad;
#if HAVE_MMAP
extern unsigned int n_mmaps_max;
extern unsigned long mmap_threshold;
#endif
extern char* sbrk_base;
extern unsigned long max_sbrked_mem;
extern unsigned long max_total_mem;
extern struct mallinfo current_mallinfo;
#if HAVE_MMAP
extern unsigned int n_mmaps;
extern unsigned int max_n_mmaps;
extern unsigned long mmapped_mem;
extern unsigned long max_mmapped_mem;
#endif
#endif /* ! DEFINE_MALLOC */
/* The total memory obtained from system via sbrk */
#define sbrked_mem (current_mallinfo.arena)
/*
Debugging support
*/
#if DEBUG
/*
These routines make a number of assertions about the states
of data structures that should be true at all times. If any
are not true, it's very likely that a user program has somehow
trashed memory. (It's also possible that there is a coding error
in malloc. In which case, please report it!)
*/
#if __STD_C
static void do_check_chunk(mchunkptr p)
#else
static void do_check_chunk(p) mchunkptr p;
#endif
{
INTERNAL_SIZE_T sz = p->size & ~PREV_INUSE;
/* No checkable chunk is mmapped */
assert(!chunk_is_mmapped(p));
/* Check for legal address ... */
assert((char*)p >= sbrk_base);
if (p != top)
assert((char*)p + sz <= (char*)top);
else
assert((char*)p + sz <= sbrk_base + sbrked_mem);
}
#if __STD_C
static void do_check_free_chunk(mchunkptr p)
#else
static void do_check_free_chunk(p) mchunkptr p;
#endif
{
INTERNAL_SIZE_T sz = p->size & ~PREV_INUSE;
mchunkptr next = chunk_at_offset(p, sz);
do_check_chunk(p);
/* Check whether it claims to be free ... */
assert(!inuse(p));
/* Unless a special marker, must have OK fields */
if ((long)sz >= (long)MINSIZE)
{
assert((sz & MALLOC_ALIGN_MASK) == 0);
assert(aligned_OK(chunk2mem(p)));
/* ... matching footer field */
assert(next->prev_size == sz);
/* ... and is fully consolidated */
assert(prev_inuse(p));
assert (next == top || inuse(next));
/* ... and has minimally sane links */
assert(p->fd->bk == p);
assert(p->bk->fd == p);
}
else /* markers are always of size SIZE_SZ */
assert(sz == SIZE_SZ);
}
#if __STD_C
static void do_check_inuse_chunk(mchunkptr p)
#else
static void do_check_inuse_chunk(p) mchunkptr p;
#endif
{
mchunkptr next = next_chunk(p);
do_check_chunk(p);
/* Check whether it claims to be in use ... */
assert(inuse(p));
/* ... and is surrounded by OK chunks.
Since more things can be checked with free chunks than inuse ones,
if an inuse chunk borders them and debug is on, it's worth doing them.
*/
if (!prev_inuse(p))
{
mchunkptr prv = prev_chunk(p);
assert(next_chunk(prv) == p);
do_check_free_chunk(prv);
}
if (next == top)
{
assert(prev_inuse(next));
assert(chunksize(next) >= MINSIZE);
}
else if (!inuse(next))
do_check_free_chunk(next);
}
#if __STD_C
static void do_check_malloced_chunk(mchunkptr p, INTERNAL_SIZE_T s)
#else
static void do_check_malloced_chunk(p, s) mchunkptr p; INTERNAL_SIZE_T s;
#endif
{
INTERNAL_SIZE_T sz = p->size & ~PREV_INUSE;
long room = long_sub_size_t(sz, s);
do_check_inuse_chunk(p);
/* Legal size ... */
assert((long)sz >= (long)MINSIZE);
assert((sz & MALLOC_ALIGN_MASK) == 0);
assert(room >= 0);
assert(room < (long)MINSIZE);
/* ... and alignment */
assert(aligned_OK(chunk2mem(p)));
/* ... and was allocated at front of an available chunk */
assert(prev_inuse(p));
}
#define check_free_chunk(P) do_check_free_chunk(P)
#define check_inuse_chunk(P) do_check_inuse_chunk(P)
#define check_chunk(P) do_check_chunk(P)
#define check_malloced_chunk(P,N) do_check_malloced_chunk(P,N)
#else
#define check_free_chunk(P)
#define check_inuse_chunk(P)
#define check_chunk(P)
#define check_malloced_chunk(P,N)
#endif
/*
Macro-based internal utilities
*/
/*
Linking chunks in bin lists.
Call these only with variables, not arbitrary expressions, as arguments.
*/
/*
Place chunk p of size s in its bin, in size order,
putting it ahead of others of same size.
*/
#define frontlink(P, S, IDX, BK, FD) \
{ \
if (S < MAX_SMALLBIN_SIZE) \
{ \
IDX = smallbin_index(S); \
mark_binblock(IDX); \
BK = bin_at(IDX); \
FD = BK->fd; \
P->bk = BK; \
P->fd = FD; \
FD->bk = BK->fd = P; \
} \
else \
{ \
IDX = bin_index(S); \
BK = bin_at(IDX); \
FD = BK->fd; \
if (FD == BK) mark_binblock(IDX); \
else \
{ \
while (FD != BK && S < chunksize(FD)) FD = FD->fd; \
BK = FD->bk; \
} \
P->bk = BK; \
P->fd = FD; \
FD->bk = BK->fd = P; \
} \
}
/* take a chunk off a list */
#define unlink(P, BK, FD) \
{ \
BK = P->bk; \
FD = P->fd; \
FD->bk = BK; \
BK->fd = FD; \
} \
/* Place p as the last remainder */
#define link_last_remainder(P) \
{ \
last_remainder->fd = last_remainder->bk = P; \
P->fd = P->bk = last_remainder; \
}
/* Clear the last_remainder bin */
#define clear_last_remainder \
(last_remainder->fd = last_remainder->bk = last_remainder)
/* Routines dealing with mmap(). */
#if HAVE_MMAP
#ifdef DEFINE_MALLOC
#if __STD_C
static mchunkptr mmap_chunk(size_t size)
#else
static mchunkptr mmap_chunk(size) size_t size;
#endif
{
size_t page_mask = malloc_getpagesize - 1;
mchunkptr p;
#ifndef MAP_ANONYMOUS
static int fd = -1;
#endif
if(n_mmaps >= n_mmaps_max) return 0; /* too many regions */
/* For mmapped chunks, the overhead is one SIZE_SZ unit larger, because
* there is no following chunk whose prev_size field could be used.
*/
size = (size + SIZE_SZ + page_mask) & ~page_mask;
#ifdef MAP_ANONYMOUS
p = (mchunkptr)mmap(0, size, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
#else /* !MAP_ANONYMOUS */
if (fd < 0)
{
fd = open("/dev/zero", O_RDWR);
if(fd < 0) return 0;
}
p = (mchunkptr)mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
#endif
if(p == (mchunkptr)-1) return 0;
n_mmaps++;
if (n_mmaps > max_n_mmaps) max_n_mmaps = n_mmaps;
/* We demand that eight bytes into a page must be 8-byte aligned. */
assert(aligned_OK(chunk2mem(p)));
/* The offset to the start of the mmapped region is stored
* in the prev_size field of the chunk; normally it is zero,
* but that can be changed in memalign().
*/
p->prev_size = 0;
set_head(p, size|IS_MMAPPED);
mmapped_mem += size;
if ((unsigned long)mmapped_mem > (unsigned long)max_mmapped_mem)
max_mmapped_mem = mmapped_mem;
if ((unsigned long)(mmapped_mem + sbrked_mem) > (unsigned long)max_total_mem)
max_total_mem = mmapped_mem + sbrked_mem;
return p;
}
#endif /* DEFINE_MALLOC */
#ifdef SEPARATE_OBJECTS
#define munmap_chunk malloc_munmap_chunk
#endif
#ifdef DEFINE_FREE
#if __STD_C
STATIC void munmap_chunk(mchunkptr p)
#else
STATIC void munmap_chunk(p) mchunkptr p;
#endif
{
INTERNAL_SIZE_T size = chunksize(p);
int ret;
assert (chunk_is_mmapped(p));
assert(! ((char*)p >= sbrk_base && (char*)p < sbrk_base + sbrked_mem));
assert((n_mmaps > 0));
assert(((p->prev_size + size) & (malloc_getpagesize-1)) == 0);
n_mmaps--;
mmapped_mem -= (size + p->prev_size);
ret = munmap((char *)p - p->prev_size, size + p->prev_size);
/* munmap returns non-zero on failure */
assert(ret == 0);
}
#else /* ! DEFINE_FREE */
#if __STD_C
extern void munmap_chunk(mchunkptr);
#else
extern void munmap_chunk();
#endif
#endif /* ! DEFINE_FREE */
#if HAVE_MREMAP
#ifdef DEFINE_REALLOC
#if __STD_C
static mchunkptr mremap_chunk(mchunkptr p, size_t new_size)
#else
static mchunkptr mremap_chunk(p, new_size) mchunkptr p; size_t new_size;
#endif
{
size_t page_mask = malloc_getpagesize - 1;
INTERNAL_SIZE_T offset = p->prev_size;
INTERNAL_SIZE_T size = chunksize(p);
char *cp;
assert (chunk_is_mmapped(p));
assert(! ((char*)p >= sbrk_base && (char*)p < sbrk_base + sbrked_mem));
assert((n_mmaps > 0));
assert(((size + offset) & (malloc_getpagesize-1)) == 0);
/* Note the extra SIZE_SZ overhead as in mmap_chunk(). */
new_size = (new_size + offset + SIZE_SZ + page_mask) & ~page_mask;
cp = (char *)mremap((char *)p - offset, size + offset, new_size, 1);
if (cp == (char *)-1) return 0;
p = (mchunkptr)(cp + offset);
assert(aligned_OK(chunk2mem(p)));
assert((p->prev_size == offset));
set_head(p, (new_size - offset)|IS_MMAPPED);
mmapped_mem -= size + offset;
mmapped_mem += new_size;
if ((unsigned long)mmapped_mem > (unsigned long)max_mmapped_mem)
max_mmapped_mem = mmapped_mem;
if ((unsigned long)(mmapped_mem + sbrked_mem) > (unsigned long)max_total_mem)
max_total_mem = mmapped_mem + sbrked_mem;
return p;
}
#endif /* DEFINE_REALLOC */
#endif /* HAVE_MREMAP */
#endif /* HAVE_MMAP */
#ifdef DEFINE_MALLOC
/*
Extend the top-most chunk by obtaining memory from system.
Main interface to sbrk (but see also malloc_trim).
*/
#if __STD_C
static void malloc_extend_top(RARG INTERNAL_SIZE_T nb)
#else
static void malloc_extend_top(RARG nb) RDECL INTERNAL_SIZE_T nb;
#endif
{
char* brk; /* return value from sbrk */
INTERNAL_SIZE_T front_misalign; /* unusable bytes at front of sbrked space */
INTERNAL_SIZE_T correction; /* bytes for 2nd sbrk call */
char* new_brk; /* return of 2nd sbrk call */
INTERNAL_SIZE_T top_size; /* new size of top chunk */
mchunkptr old_top = top; /* Record state of old top */
INTERNAL_SIZE_T old_top_size = chunksize(old_top);
char* old_end = (char*)(chunk_at_offset(old_top, old_top_size));
/* Pad request with top_pad plus minimal overhead */
INTERNAL_SIZE_T sbrk_size = nb + top_pad + MINSIZE;
unsigned long pagesz = malloc_getpagesize;
/* If not the first time through, round to preserve page boundary */
/* Otherwise, we need to correct to a page size below anyway. */
/* (We also correct below if an intervening foreign sbrk call.) */
if (sbrk_base != (char*)(-1))
sbrk_size = (sbrk_size + (pagesz - 1)) & ~(pagesz - 1);
brk = (char*)(MORECORE (sbrk_size));
/* Fail if sbrk failed or if a foreign sbrk call killed our space */
if (brk == (char*)(MORECORE_FAILURE) ||
(brk < old_end && old_top != initial_top))
return;
sbrked_mem += sbrk_size;
if (brk == old_end) /* can just add bytes to current top */
{
top_size = sbrk_size + old_top_size;
set_head(top, top_size | PREV_INUSE);
}
else
{
if (sbrk_base == (char*)(-1)) /* First time through. Record base */
sbrk_base = brk;
else /* Someone else called sbrk(). Count those bytes as sbrked_mem. */
sbrked_mem += brk - (char*)old_end;
/* Guarantee alignment of first new chunk made from this space */
front_misalign = (POINTER_UINT)chunk2mem(brk) & MALLOC_ALIGN_MASK;
if (front_misalign > 0)
{
correction = (MALLOC_ALIGNMENT) - front_misalign;
brk += correction;
}
else
correction = 0;
/* Guarantee the next brk will be at a page boundary */
correction += pagesz - ((POINTER_UINT)(brk + sbrk_size) & (pagesz - 1));
/* Allocate correction */
new_brk = (char*)(MORECORE (correction));
if (new_brk == (char*)(MORECORE_FAILURE)) return;
sbrked_mem += correction;
top = (mchunkptr)brk;
top_size = new_brk - brk + correction;
set_head(top, top_size | PREV_INUSE);
if (old_top != initial_top)
{
/* There must have been an intervening foreign sbrk call. */
/* A double fencepost is necessary to prevent consolidation */
/* If not enough space to do this, then user did something very wrong */
if (old_top_size < MINSIZE)
{
set_head(top, PREV_INUSE); /* will force null return from malloc */
return;
}
/* Also keep size a multiple of MALLOC_ALIGNMENT */
old_top_size = (old_top_size - 3*SIZE_SZ) & ~MALLOC_ALIGN_MASK;
set_head_size(old_top, old_top_size);
chunk_at_offset(old_top, old_top_size )->size =
SIZE_SZ|PREV_INUSE;
chunk_at_offset(old_top, old_top_size + SIZE_SZ)->size =
SIZE_SZ|PREV_INUSE;
/* If possible, release the rest. */
if (old_top_size >= MINSIZE)
fREe(RCALL chunk2mem(old_top));
}
}
if ((unsigned long)sbrked_mem > (unsigned long)max_sbrked_mem)
max_sbrked_mem = sbrked_mem;
#if HAVE_MMAP
if ((unsigned long)(mmapped_mem + sbrked_mem) > (unsigned long)max_total_mem)
max_total_mem = mmapped_mem + sbrked_mem;
#else
if ((unsigned long)(sbrked_mem) > (unsigned long)max_total_mem)
max_total_mem = sbrked_mem;
#endif
/* We always land on a page boundary */
assert(((unsigned long)((char*)top + top_size) & (pagesz - 1)) == 0);
}
#endif /* DEFINE_MALLOC */
/* Main public routines */
#ifdef DEFINE_MALLOC
/*
Malloc Algorthim:
The requested size is first converted into a usable form, `nb'.
This currently means to add 4 bytes overhead plus possibly more to
obtain 8-byte alignment and/or to obtain a size of at least
MINSIZE (currently 16 bytes), the smallest allocatable size.
(All fits are considered `exact' if they are within MINSIZE bytes.)
From there, the first successful of the following steps is taken:
1. The bin corresponding to the request size is scanned, and if
a chunk of exactly the right size is found, it is taken.
2. The most recently remaindered chunk is used if it is big
enough. This is a form of (roving) first fit, used only in
the absence of exact fits. Runs of consecutive requests use
the remainder of the chunk used for the previous such request
whenever possible. This limited use of a first-fit style
allocation strategy tends to give contiguous chunks
coextensive lifetimes, which improves locality and can reduce
fragmentation in the long run.
3. Other bins are scanned in increasing size order, using a
chunk big enough to fulfill the request, and splitting off
any remainder. This search is strictly by best-fit; i.e.,
the smallest (with ties going to approximately the least
recently used) chunk that fits is selected.
4. If large enough, the chunk bordering the end of memory
(`top') is split off. (This use of `top' is in accord with
the best-fit search rule. In effect, `top' is treated as
larger (and thus less well fitting) than any other available
chunk since it can be extended to be as large as necessary
(up to system limitations).
5. If the request size meets the mmap threshold and the
system supports mmap, and there are few enough currently
allocated mmapped regions, and a call to mmap succeeds,
the request is allocated via direct memory mapping.
6. Otherwise, the top of memory is extended by
obtaining more space from the system (normally using sbrk,
but definable to anything else via the MORECORE macro).
Memory is gathered from the system (in system page-sized
units) in a way that allows chunks obtained across different
sbrk calls to be consolidated, but does not require
contiguous memory. Thus, it should be safe to intersperse
mallocs with other sbrk calls.
All allocations are made from the the `lowest' part of any found
chunk. (The implementation invariant is that prev_inuse is
always true of any allocated chunk; i.e., that each allocated
chunk borders either a previously allocated and still in-use chunk,
or the base of its memory arena.)
*/
#if __STD_C
Void_t* mALLOc(RARG size_t bytes)
#else
Void_t* mALLOc(RARG bytes) RDECL size_t bytes;
#endif
{
mchunkptr victim; /* inspected/selected chunk */
INTERNAL_SIZE_T victim_size; /* its size */
int idx; /* index for bin traversal */
mbinptr bin; /* associated bin */
mchunkptr remainder; /* remainder from a split */
long remainder_size; /* its size */
int remainder_index; /* its bin index */
unsigned long block; /* block traverser bit */
int startidx; /* first bin of a traversed block */
mchunkptr fwd; /* misc temp for linking */
mchunkptr bck; /* misc temp for linking */
mbinptr q; /* misc temp */
INTERNAL_SIZE_T nb = request2size(bytes); /* padded request size; */
MALLOC_LOCK;
/* Check for exact match in a bin */
if (is_small_request(nb)) /* Faster version for small requests */
{
idx = smallbin_index(nb);
/* No traversal or size check necessary for small bins. */
q = bin_at(idx);
victim = last(q);
#if MALLOC_ALIGN != 16
/* Also scan the next one, since it would have a remainder < MINSIZE */
if (victim == q)
{
q = next_bin(q);
victim = last(q);
}
#endif
if (victim != q)
{
victim_size = chunksize(victim);
unlink(victim, bck, fwd);
set_inuse_bit_at_offset(victim, victim_size);
check_malloced_chunk(victim, nb);
MALLOC_UNLOCK;
return chunk2mem(victim);
}
idx += 2; /* Set for bin scan below. We've already scanned 2 bins. */
}
else
{
idx = bin_index(nb);
bin = bin_at(idx);
for (victim = last(bin); victim != bin; victim = victim->bk)
{
victim_size = chunksize(victim);
remainder_size = long_sub_size_t(victim_size, nb);
if (remainder_size >= (long)MINSIZE) /* too big */
{
--idx; /* adjust to rescan below after checking last remainder */
break;
}
else if (remainder_size >= 0) /* exact fit */
{
unlink(victim, bck, fwd);
set_inuse_bit_at_offset(victim, victim_size);
check_malloced_chunk(victim, nb);
MALLOC_UNLOCK;
return chunk2mem(victim);
}
}
++idx;
}
/* Try to use the last split-off remainder */
if ( (victim = last_remainder->fd) != last_remainder)
{
victim_size = chunksize(victim);
remainder_size = long_sub_size_t(victim_size, nb);
if (remainder_size >= (long)MINSIZE) /* re-split */
{
remainder = chunk_at_offset(victim, nb);
set_head(victim, nb | PREV_INUSE);
link_last_remainder(remainder);
set_head(remainder, remainder_size | PREV_INUSE);
set_foot(remainder, remainder_size);
check_malloced_chunk(victim, nb);
MALLOC_UNLOCK;
return chunk2mem(victim);
}
clear_last_remainder;
if (remainder_size >= 0) /* exhaust */
{
set_inuse_bit_at_offset(victim, victim_size);
check_malloced_chunk(victim, nb);
MALLOC_UNLOCK;
return chunk2mem(victim);
}
/* Else place in bin */
frontlink(victim, victim_size, remainder_index, bck, fwd);
}
/*
If there are any possibly nonempty big-enough blocks,
search for best fitting chunk by scanning bins in blockwidth units.
*/
if ( (block = idx2binblock(idx)) <= binblocks)
{
/* Get to the first marked block */
if ( (block & binblocks) == 0)
{
/* force to an even block boundary */
idx = (idx & ~(BINBLOCKWIDTH - 1)) + BINBLOCKWIDTH;
block <<= 1;
while ((block & binblocks) == 0)
{
idx += BINBLOCKWIDTH;
block <<= 1;
}
}
/* For each possibly nonempty block ... */
for (;;)
{
startidx = idx; /* (track incomplete blocks) */
q = bin = bin_at(idx);
/* For each bin in this block ... */
do
{
/* Find and use first big enough chunk ... */
for (victim = last(bin); victim != bin; victim = victim->bk)
{
victim_size = chunksize(victim);
remainder_size = long_sub_size_t(victim_size, nb);
if (remainder_size >= (long)MINSIZE) /* split */
{
remainder = chunk_at_offset(victim, nb);
set_head(victim, nb | PREV_INUSE);
unlink(victim, bck, fwd);
link_last_remainder(remainder);
set_head(remainder, remainder_size | PREV_INUSE);
set_foot(remainder, remainder_size);
check_malloced_chunk(victim, nb);
MALLOC_UNLOCK;
return chunk2mem(victim);
}
else if (remainder_size >= 0) /* take */
{
set_inuse_bit_at_offset(victim, victim_size);
unlink(victim, bck, fwd);
check_malloced_chunk(victim, nb);
MALLOC_UNLOCK;
return chunk2mem(victim);
}
}
bin = next_bin(bin);
#if MALLOC_ALIGN == 16
if (idx < MAX_SMALLBIN)
{
bin = next_bin(bin);
++idx;
}
#endif
} while ((++idx & (BINBLOCKWIDTH - 1)) != 0);
/* Clear out the block bit. */
do /* Possibly backtrack to try to clear a partial block */
{
if ((startidx & (BINBLOCKWIDTH - 1)) == 0)
{
binblocks &= ~block;
break;
}
--startidx;
q = prev_bin(q);
} while (first(q) == q);
/* Get to the next possibly nonempty block */
if ( (block <<= 1) <= binblocks && (block != 0) )
{
while ((block & binblocks) == 0)
{
idx += BINBLOCKWIDTH;
block <<= 1;
}
}
else
break;
}
}
/* Try to use top chunk */
/* Require that there be a remainder, ensuring top always exists */
remainder_size = long_sub_size_t(chunksize(top), nb);
if (chunksize(top) < nb || remainder_size < (long)MINSIZE)
{
#if HAVE_MMAP
/* If big and would otherwise need to extend, try to use mmap instead */
if ((unsigned long)nb >= (unsigned long)mmap_threshold &&
(victim = mmap_chunk(nb)) != 0)
{
MALLOC_UNLOCK;
return chunk2mem(victim);
}
#endif
/* Try to extend */
malloc_extend_top(RCALL nb);
remainder_size = long_sub_size_t(chunksize(top), nb);
if (chunksize(top) < nb || remainder_size < (long)MINSIZE)
{
MALLOC_UNLOCK;
return 0; /* propagate failure */
}
}
victim = top;
set_head(victim, nb | PREV_INUSE);
top = chunk_at_offset(victim, nb);
set_head(top, remainder_size | PREV_INUSE);
check_malloced_chunk(victim, nb);
MALLOC_UNLOCK;
return chunk2mem(victim);
}
#endif /* DEFINE_MALLOC */
#ifdef DEFINE_FREE
/*
free() algorithm :
cases:
1. free(0) has no effect.
2. If the chunk was allocated via mmap, it is release via munmap().
3. If a returned chunk borders the current high end of memory,
it is consolidated into the top, and if the total unused
topmost memory exceeds the trim threshold, malloc_trim is
called.
4. Other chunks are consolidated as they arrive, and
placed in corresponding bins. (This includes the case of
consolidating with the current `last_remainder').
*/
#if __STD_C
void fREe(RARG Void_t* mem)
#else
void fREe(RARG mem) RDECL Void_t* mem;
#endif
{
mchunkptr p; /* chunk corresponding to mem */
INTERNAL_SIZE_T hd; /* its head field */
INTERNAL_SIZE_T sz; /* its size */
int idx; /* its bin index */
mchunkptr next; /* next contiguous chunk */
INTERNAL_SIZE_T nextsz; /* its size */
INTERNAL_SIZE_T prevsz; /* size of previous contiguous chunk */
mchunkptr bck; /* misc temp for linking */
mchunkptr fwd; /* misc temp for linking */
int islr; /* track whether merging with last_remainder */
if (mem == 0) /* free(0) has no effect */
return;
MALLOC_LOCK;
p = mem2chunk(mem);
hd = p->size;
#if HAVE_MMAP
if (hd & IS_MMAPPED) /* release mmapped memory. */
{
munmap_chunk(p);
MALLOC_UNLOCK;
return;
}
#endif
check_inuse_chunk(p);
sz = hd & ~PREV_INUSE;
next = chunk_at_offset(p, sz);
nextsz = chunksize(next);
if (next == top) /* merge with top */
{
sz += nextsz;
if (!(hd & PREV_INUSE)) /* consolidate backward */
{
prevsz = p->prev_size;
p = chunk_at_offset(p, -prevsz);
sz += prevsz;
unlink(p, bck, fwd);
}
set_head(p, sz | PREV_INUSE);
top = p;
if ((unsigned long)(sz) >= (unsigned long)trim_threshold)
malloc_trim(RCALL top_pad);
MALLOC_UNLOCK;
return;
}
set_head(next, nextsz); /* clear inuse bit */
islr = 0;
if (!(hd & PREV_INUSE)) /* consolidate backward */
{
prevsz = p->prev_size;
p = chunk_at_offset(p, -prevsz);
sz += prevsz;
if (p->fd == last_remainder) /* keep as last_remainder */
islr = 1;
else
unlink(p, bck, fwd);
}
if (!(inuse_bit_at_offset(next, nextsz))) /* consolidate forward */
{
sz += nextsz;
if (!islr && next->fd == last_remainder) /* re-insert last_remainder */
{
islr = 1;
link_last_remainder(p);
}
else
unlink(next, bck, fwd);
}
set_head(p, sz | PREV_INUSE);
set_foot(p, sz);
if (!islr)
frontlink(p, sz, idx, bck, fwd);
MALLOC_UNLOCK;
}
#endif /* DEFINE_FREE */
#ifdef DEFINE_REALLOC
/*
Realloc algorithm:
Chunks that were obtained via mmap cannot be extended or shrunk
unless HAVE_MREMAP is defined, in which case mremap is used.
Otherwise, if their reallocation is for additional space, they are
copied. If for less, they are just left alone.
Otherwise, if the reallocation is for additional space, and the
chunk can be extended, it is, else a malloc-copy-free sequence is
taken. There are several different ways that a chunk could be
extended. All are tried:
* Extending forward into following adjacent free chunk.
* Shifting backwards, joining preceding adjacent space
* Both shifting backwards and extending forward.
* Extending into newly sbrked space
Unless the #define REALLOC_ZERO_BYTES_FREES is set, realloc with a
size argument of zero (re)allocates a minimum-sized chunk.
If the reallocation is for less space, and the new request is for
a `small' (<512 bytes) size, then the newly unused space is lopped
off and freed.
The old unix realloc convention of allowing the last-free'd chunk
to be used as an argument to realloc is no longer supported.
I don't know of any programs still relying on this feature,
and allowing it would also allow too many other incorrect
usages of realloc to be sensible.
*/
#if __STD_C
Void_t* rEALLOc(RARG Void_t* oldmem, size_t bytes)
#else
Void_t* rEALLOc(RARG oldmem, bytes) RDECL Void_t* oldmem; size_t bytes;
#endif
{
INTERNAL_SIZE_T nb; /* padded request size */
mchunkptr oldp; /* chunk corresponding to oldmem */
INTERNAL_SIZE_T oldsize; /* its size */
mchunkptr newp; /* chunk to return */
INTERNAL_SIZE_T newsize; /* its size */
Void_t* newmem; /* corresponding user mem */
mchunkptr next; /* next contiguous chunk after oldp */
INTERNAL_SIZE_T nextsize; /* its size */
mchunkptr prev; /* previous contiguous chunk before oldp */
INTERNAL_SIZE_T prevsize; /* its size */
mchunkptr remainder; /* holds split off extra space from newp */
INTERNAL_SIZE_T remainder_size; /* its size */
mchunkptr bck; /* misc temp for linking */
mchunkptr fwd; /* misc temp for linking */
#ifdef REALLOC_ZERO_BYTES_FREES
if (bytes == 0) { fREe(RCALL oldmem); return 0; }
#endif
/* realloc of null is supposed to be same as malloc */
if (oldmem == 0) return mALLOc(RCALL bytes);
MALLOC_LOCK;
newp = oldp = mem2chunk(oldmem);
newsize = oldsize = chunksize(oldp);
nb = request2size(bytes);
#if HAVE_MMAP
if (chunk_is_mmapped(oldp))
{
#if HAVE_MREMAP
newp = mremap_chunk(oldp, nb);
if(newp)
{
MALLOC_UNLOCK;
return chunk2mem(newp);
}
#endif
/* Note the extra SIZE_SZ overhead. */
if(oldsize - SIZE_SZ >= nb)
{
MALLOC_UNLOCK;
return oldmem; /* do nothing */
}
/* Must alloc, copy, free. */
newmem = mALLOc(RCALL bytes);
if (newmem == 0)
{
MALLOC_UNLOCK;
return 0; /* propagate failure */
}
MALLOC_COPY(newmem, oldmem, oldsize - 2*SIZE_SZ);
munmap_chunk(oldp);
MALLOC_UNLOCK;
return newmem;
}
#endif
check_inuse_chunk(oldp);
if ((long)(oldsize) < (long)(nb))
{
/* Try expanding forward */
next = chunk_at_offset(oldp, oldsize);
if (next == top || !inuse(next))
{
nextsize = chunksize(next);
/* Forward into top only if a remainder */
if (next == top)
{
if ((long)(nextsize + newsize) >= (long)(nb + MINSIZE))
{
newsize += nextsize;
top = chunk_at_offset(oldp, nb);
set_head(top, (newsize - nb) | PREV_INUSE);
set_head_size(oldp, nb);
MALLOC_UNLOCK;
return chunk2mem(oldp);
}
}
/* Forward into next chunk */
else if (((long)(nextsize + newsize) >= (long)(nb)))
{
unlink(next, bck, fwd);
newsize += nextsize;
goto split;
}
}
else
{
next = 0;
nextsize = 0;
}
/* Try shifting backwards. */
if (!prev_inuse(oldp))
{
prev = prev_chunk(oldp);
prevsize = chunksize(prev);
/* try forward + backward first to save a later consolidation */
if (next != 0)
{
/* into top */
if (next == top)
{
if ((long)(nextsize + prevsize + newsize) >= (long)(nb + MINSIZE))
{
unlink(prev, bck, fwd);
newp = prev;
newsize += prevsize + nextsize;
newmem = chunk2mem(newp);
MALLOC_COPY(newmem, oldmem, oldsize - SIZE_SZ);
top = chunk_at_offset(newp, nb);
set_head(top, (newsize - nb) | PREV_INUSE);
set_head_size(newp, nb);
MALLOC_UNLOCK;
return newmem;
}
}
/* into next chunk */
else if (((long)(nextsize + prevsize + newsize) >= (long)(nb)))
{
unlink(next, bck, fwd);
unlink(prev, bck, fwd);
newp = prev;
newsize += nextsize + prevsize;
newmem = chunk2mem(newp);
MALLOC_COPY(newmem, oldmem, oldsize - SIZE_SZ);
goto split;
}
}
/* backward only */
if (prev != 0 && (long)(prevsize + newsize) >= (long)nb)
{
unlink(prev, bck, fwd);
newp = prev;
newsize += prevsize;
newmem = chunk2mem(newp);
MALLOC_COPY(newmem, oldmem, oldsize - SIZE_SZ);
goto split;
}
}
/* Must allocate */
newmem = mALLOc (RCALL bytes);
if (newmem == 0) /* propagate failure */
{
MALLOC_UNLOCK;
return 0;
}
/* Avoid copy if newp is next chunk after oldp. */
/* (This can only happen when new chunk is sbrk'ed.) */
if ( (newp = mem2chunk(newmem)) == next_chunk(oldp))
{
newsize += chunksize(newp);
newp = oldp;
goto split;
}
/* Otherwise copy, free, and exit */
MALLOC_COPY(newmem, oldmem, oldsize - SIZE_SZ);
fREe(RCALL oldmem);
MALLOC_UNLOCK;
return newmem;
}
split: /* split off extra room in old or expanded chunk */
remainder_size = long_sub_size_t(newsize, nb);
if (remainder_size >= (long)MINSIZE) /* split off remainder */
{
remainder = chunk_at_offset(newp, nb);
set_head_size(newp, nb);
set_head(remainder, remainder_size | PREV_INUSE);
set_inuse_bit_at_offset(remainder, remainder_size);
fREe(RCALL chunk2mem(remainder)); /* let free() deal with it */
}
else
{
set_head_size(newp, newsize);
set_inuse_bit_at_offset(newp, newsize);
}
check_inuse_chunk(newp);
MALLOC_UNLOCK;
return chunk2mem(newp);
}
#endif /* DEFINE_REALLOC */
#ifdef DEFINE_MEMALIGN
/*
memalign algorithm:
memalign requests more than enough space from malloc, finds a spot
within that chunk that meets the alignment request, and then
possibly frees the leading and trailing space.
The alignment argument must be a power of two. This property is not
checked by memalign, so misuse may result in random runtime errors.
8-byte alignment is guaranteed by normal malloc calls, so don't
bother calling memalign with an argument of 8 or less.
Overreliance on memalign is a sure way to fragment space.
*/
#if __STD_C
Void_t* mEMALIGn(RARG size_t alignment, size_t bytes)
#else
Void_t* mEMALIGn(RARG alignment, bytes) RDECL size_t alignment; size_t bytes;
#endif
{
INTERNAL_SIZE_T nb; /* padded request size */
char* m; /* memory returned by malloc call */
mchunkptr p; /* corresponding chunk */
char* brk; /* alignment point within p */
mchunkptr newp; /* chunk to return */
INTERNAL_SIZE_T newsize; /* its size */
INTERNAL_SIZE_T leadsize; /* leading space befor alignment point */
mchunkptr remainder; /* spare room at end to split off */
long remainder_size; /* its size */
/* If need less alignment than we give anyway, just relay to malloc */
if (alignment <= MALLOC_ALIGNMENT) return mALLOc(RCALL bytes);
/* Otherwise, ensure that it is at least a minimum chunk size */
if (alignment < MINSIZE) alignment = MINSIZE;
/* Call malloc with worst case padding to hit alignment. */
nb = request2size(bytes);
m = (char*)(mALLOc(RCALL nb + alignment + MINSIZE));
if (m == 0) return 0; /* propagate failure */
MALLOC_LOCK;
p = mem2chunk(m);
if ((((unsigned long)(m)) % alignment) == 0) /* aligned */
{
#if HAVE_MMAP
if(chunk_is_mmapped(p))
{
MALLOC_UNLOCK;
return chunk2mem(p); /* nothing more to do */
}
#endif
}
else /* misaligned */
{
/*
Find an aligned spot inside chunk.
Since we need to give back leading space in a chunk of at
least MINSIZE, if the first calculation places us at
a spot with less than MINSIZE leader, we can move to the
next aligned spot -- we've allocated enough total room so that
this is always possible.
*/
brk = (char*)mem2chunk(((unsigned long)(m + alignment - 1)) & -alignment);
if ((long)(brk - (char*)(p)) < (long)MINSIZE) brk = brk + alignment;
newp = (mchunkptr)brk;
leadsize = brk - (char*)(p);
newsize = chunksize(p) - leadsize;
#if HAVE_MMAP
if(chunk_is_mmapped(p))
{
newp->prev_size = p->prev_size + leadsize;
set_head(newp, newsize|IS_MMAPPED);
MALLOC_UNLOCK;
return chunk2mem(newp);
}
#endif
/* give back leader, use the rest */
set_head(newp, newsize | PREV_INUSE);
set_inuse_bit_at_offset(newp, newsize);
set_head_size(p, leadsize);
fREe(RCALL chunk2mem(p));
p = newp;
assert (newsize >= nb && (((unsigned long)(chunk2mem(p))) % alignment) == 0);
}
/* Also give back spare room at the end */
remainder_size = long_sub_size_t(chunksize(p), nb);
if (remainder_size >= (long)MINSIZE)
{
remainder = chunk_at_offset(p, nb);
set_head(remainder, remainder_size | PREV_INUSE);
set_head_size(p, nb);
fREe(RCALL chunk2mem(remainder));
}
check_inuse_chunk(p);
MALLOC_UNLOCK;
return chunk2mem(p);
}
#endif /* DEFINE_MEMALIGN */
#ifdef DEFINE_VALLOC
/*
valloc just invokes memalign with alignment argument equal
to the page size of the system (or as near to this as can
be figured out from all the includes/defines above.)
*/
#if __STD_C
Void_t* vALLOc(RARG size_t bytes)
#else
Void_t* vALLOc(RARG bytes) RDECL size_t bytes;
#endif
{
return mEMALIGn (RCALL malloc_getpagesize, bytes);
}
#endif /* DEFINE_VALLOC */
#ifdef DEFINE_PVALLOC
/*
pvalloc just invokes valloc for the nearest pagesize
that will accommodate request
*/
#if __STD_C
Void_t* pvALLOc(RARG size_t bytes)
#else
Void_t* pvALLOc(RARG bytes) RDECL size_t bytes;
#endif
{
size_t pagesize = malloc_getpagesize;
return mEMALIGn (RCALL pagesize, (bytes + pagesize - 1) & ~(pagesize - 1));
}
#endif /* DEFINE_PVALLOC */
#ifdef DEFINE_CALLOC
/*
calloc calls malloc, then zeroes out the allocated chunk.
*/
#if __STD_C
Void_t* cALLOc(RARG size_t n, size_t elem_size)
#else
Void_t* cALLOc(RARG n, elem_size) RDECL size_t n; size_t elem_size;
#endif
{
mchunkptr p;
INTERNAL_SIZE_T csz;
INTERNAL_SIZE_T sz = n * elem_size;
#if MORECORE_CLEARS
mchunkptr oldtop;
INTERNAL_SIZE_T oldtopsize;
#endif
Void_t* mem;
/* check if expand_top called, in which case don't need to clear */
#if MORECORE_CLEARS
MALLOC_LOCK;
oldtop = top;
oldtopsize = chunksize(top);
#endif
mem = mALLOc (RCALL sz);
if (mem == 0)
{
#if MORECORE_CLEARS
MALLOC_UNLOCK;
#endif
return 0;
}
else
{
p = mem2chunk(mem);
/* Two optional cases in which clearing not necessary */
#if HAVE_MMAP
if (chunk_is_mmapped(p))
{
#if MORECORE_CLEARS
MALLOC_UNLOCK;
#endif
return mem;
}
#endif
csz = chunksize(p);
#if MORECORE_CLEARS
if (p == oldtop && csz > oldtopsize)
{
/* clear only the bytes from non-freshly-sbrked memory */
csz = oldtopsize;
}
MALLOC_UNLOCK;
#endif
MALLOC_ZERO(mem, csz - SIZE_SZ);
return mem;
}
}
#endif /* DEFINE_CALLOC */
#ifdef DEFINE_CFREE
/*
cfree just calls free. It is needed/defined on some systems
that pair it with calloc, presumably for odd historical reasons.
*/
#if !defined(INTERNAL_LINUX_C_LIB) || !defined(__ELF__)
#if !defined(INTERNAL_NEWLIB) || !defined(_REENT_ONLY)
#if __STD_C
void cfree(Void_t *mem)
#else
void cfree(mem) Void_t *mem;
#endif
{
#ifdef INTERNAL_NEWLIB
fREe(_REENT, mem);
#else
fREe(mem);
#endif
}
#endif
#endif
#endif /* DEFINE_CFREE */
#ifdef DEFINE_FREE
/*
Malloc_trim gives memory back to the system (via negative
arguments to sbrk) if there is unused memory at the `high' end of
the malloc pool. You can call this after freeing large blocks of
memory to potentially reduce the system-level memory requirements
of a program. However, it cannot guarantee to reduce memory. Under
some allocation patterns, some large free blocks of memory will be
locked between two used chunks, so they cannot be given back to
the system.
The `pad' argument to malloc_trim represents the amount of free
trailing space to leave untrimmed. If this argument is zero,
only the minimum amount of memory to maintain internal data
structures will be left (one page or less). Non-zero arguments
can be supplied to maintain enough trailing space to service
future expected allocations without having to re-obtain memory
from the system.
Malloc_trim returns 1 if it actually released any memory, else 0.
*/
#if __STD_C
int malloc_trim(RARG size_t pad)
#else
int malloc_trim(RARG pad) RDECL size_t pad;
#endif
{
long top_size; /* Amount of top-most memory */
long extra; /* Amount to release */
char* current_brk; /* address returned by pre-check sbrk call */
char* new_brk; /* address returned by negative sbrk call */
unsigned long pagesz = malloc_getpagesize;
MALLOC_LOCK;
top_size = chunksize(top);
extra = ((top_size - pad - MINSIZE + (pagesz-1)) / pagesz - 1) * pagesz;
if (extra < (long)pagesz) /* Not enough memory to release */
{
MALLOC_UNLOCK;
return 0;
}
else
{
/* Test to make sure no one else called sbrk */
current_brk = (char*)(MORECORE (0));
if (current_brk != (char*)(top) + top_size)
{
MALLOC_UNLOCK;
return 0; /* Apparently we don't own memory; must fail */
}
else
{
new_brk = (char*)(MORECORE (-extra));
if (new_brk == (char*)(MORECORE_FAILURE)) /* sbrk failed? */
{
/* Try to figure out what we have */
current_brk = (char*)(MORECORE (0));
top_size = current_brk - (char*)top;
if (top_size >= (long)MINSIZE) /* if not, we are very very dead! */
{
sbrked_mem = current_brk - sbrk_base;
set_head(top, top_size | PREV_INUSE);
}
check_chunk(top);
MALLOC_UNLOCK;
return 0;
}
else
{
/* Success. Adjust top accordingly. */
set_head(top, (top_size - extra) | PREV_INUSE);
sbrked_mem -= extra;
check_chunk(top);
MALLOC_UNLOCK;
return 1;
}
}
}
}
#endif /* DEFINE_FREE */
#ifdef DEFINE_MALLOC_USABLE_SIZE
/*
malloc_usable_size:
This routine tells you how many bytes you can actually use in an
allocated chunk, which may be more than you requested (although
often not). You can use this many bytes without worrying about
overwriting other allocated objects. Not a particularly great
programming practice, but still sometimes useful.
*/
#if __STD_C
size_t malloc_usable_size(RARG Void_t* mem)
#else
size_t malloc_usable_size(RARG mem) RDECL Void_t* mem;
#endif
{
mchunkptr p;
if (mem == 0)
return 0;
else
{
p = mem2chunk(mem);
if(!chunk_is_mmapped(p))
{
if (!inuse(p)) return 0;
#if DEBUG
MALLOC_LOCK;
check_inuse_chunk(p);
MALLOC_UNLOCK;
#endif
return chunksize(p) - SIZE_SZ;
}
return chunksize(p) - 2*SIZE_SZ;
}
}
#endif /* DEFINE_MALLOC_USABLE_SIZE */
#ifdef DEFINE_MALLINFO
/* Utility to update current_mallinfo for malloc_stats and mallinfo() */
STATIC void malloc_update_mallinfo()
{
int i;
mbinptr b;
mchunkptr p;
#if DEBUG
mchunkptr q;
#endif
INTERNAL_SIZE_T avail = chunksize(top);
int navail = ((long)(avail) >= (long)MINSIZE)? 1 : 0;
for (i = 1; i < NAV; ++i)
{
b = bin_at(i);
for (p = last(b); p != b; p = p->bk)
{
#if DEBUG
check_free_chunk(p);
for (q = next_chunk(p);
q < top && inuse(q) && (long)(chunksize(q)) >= (long)MINSIZE;
q = next_chunk(q))
check_inuse_chunk(q);
#endif
avail += chunksize(p);
navail++;
}
}
current_mallinfo.ordblks = navail;
current_mallinfo.uordblks = sbrked_mem - avail;
current_mallinfo.fordblks = avail;
#if HAVE_MMAP
current_mallinfo.hblks = n_mmaps;
current_mallinfo.hblkhd = mmapped_mem;
#endif
current_mallinfo.keepcost = chunksize(top);
}
#else /* ! DEFINE_MALLINFO */
#if __STD_C
extern void malloc_update_mallinfo(void);
#else
extern void malloc_update_mallinfo();
#endif
#endif /* ! DEFINE_MALLINFO */
#ifdef DEFINE_MALLOC_STATS
/*
malloc_stats:
Prints on stderr the amount of space obtain from the system (both
via sbrk and mmap), the maximum amount (which may be more than
current if malloc_trim and/or munmap got called), the maximum
number of simultaneous mmap regions used, and the current number
of bytes allocated via malloc (or realloc, etc) but not yet
freed. (Note that this is the number of bytes allocated, not the
number requested. It will be larger than the number requested
because of alignment and bookkeeping overhead.)
*/
#if __STD_C
void malloc_stats(RONEARG)
#else
void malloc_stats(RONEARG) RDECL
#endif
{
unsigned long local_max_total_mem;
int local_sbrked_mem;
struct mallinfo local_mallinfo;
#if HAVE_MMAP
unsigned long local_mmapped_mem, local_max_n_mmaps;
#endif
FILE *fp;
MALLOC_LOCK;
malloc_update_mallinfo();
local_max_total_mem = max_total_mem;
local_sbrked_mem = sbrked_mem;
local_mallinfo = current_mallinfo;
#if HAVE_MMAP
local_mmapped_mem = mmapped_mem;
local_max_n_mmaps = max_n_mmaps;
#endif
MALLOC_UNLOCK;
#ifdef INTERNAL_NEWLIB
fp = _stderr_r(reent_ptr);
#define fprintf fiprintf
#else
fp = stderr;
#endif
fprintf(fp, "max system bytes = %10u\n",
(unsigned int)(local_max_total_mem));
#if HAVE_MMAP
fprintf(fp, "system bytes = %10u\n",
(unsigned int)(local_sbrked_mem + local_mmapped_mem));
fprintf(fp, "in use bytes = %10u\n",
(unsigned int)(local_mallinfo.uordblks + local_mmapped_mem));
#else
fprintf(fp, "system bytes = %10u\n",
(unsigned int)local_sbrked_mem);
fprintf(fp, "in use bytes = %10u\n",
(unsigned int)local_mallinfo.uordblks);
#endif
#if HAVE_MMAP
fprintf(fp, "max mmap regions = %10u\n",
(unsigned int)local_max_n_mmaps);
#endif
}
#endif /* DEFINE_MALLOC_STATS */
#ifdef DEFINE_MALLINFO
/*
mallinfo returns a copy of updated current mallinfo.
*/
#if __STD_C
struct mallinfo mALLINFo(RONEARG)
#else
struct mallinfo mALLINFo(RONEARG) RDECL
#endif
{
struct mallinfo ret;
MALLOC_LOCK;
malloc_update_mallinfo();
ret = current_mallinfo;
MALLOC_UNLOCK;
return ret;
}
#endif /* DEFINE_MALLINFO */
#ifdef DEFINE_MALLOPT
/*
mallopt:
mallopt is the general SVID/XPG interface to tunable parameters.
The format is to provide a (parameter-number, parameter-value) pair.
mallopt then sets the corresponding parameter to the argument
value if it can (i.e., so long as the value is meaningful),
and returns 1 if successful else 0.
See descriptions of tunable parameters above.
*/
#if __STD_C
int mALLOPt(RARG int param_number, int value)
#else
int mALLOPt(RARG param_number, value) RDECL int param_number; int value;
#endif
{
MALLOC_LOCK;
switch(param_number)
{
case M_TRIM_THRESHOLD:
trim_threshold = value; MALLOC_UNLOCK; return 1;
case M_TOP_PAD:
top_pad = value; MALLOC_UNLOCK; return 1;
case M_MMAP_THRESHOLD:
#if HAVE_MMAP
mmap_threshold = value;
#endif
MALLOC_UNLOCK;
return 1;
case M_MMAP_MAX:
#if HAVE_MMAP
n_mmaps_max = value; MALLOC_UNLOCK; return 1;
#else
MALLOC_UNLOCK; return value == 0;
#endif
default:
MALLOC_UNLOCK;
return 0;
}
}
#endif /* DEFINE_MALLOPT */
/*
History:
V2.6.3 Sun May 19 08:17:58 1996 Doug Lea (dl at gee)
* Added pvalloc, as recommended by H.J. Liu
* Added 64bit pointer support mainly from Wolfram Gloger
* Added anonymously donated WIN32 sbrk emulation
* Malloc, calloc, getpagesize: add optimizations from Raymond Nijssen
* malloc_extend_top: fix mask error that caused wastage after
foreign sbrks
* Add linux mremap support code from HJ Liu
V2.6.2 Tue Dec 5 06:52:55 1995 Doug Lea (dl at gee)
* Integrated most documentation with the code.
* Add support for mmap, with help from
Wolfram Gloger (Gloger@lrz.uni-muenchen.de).
* Use last_remainder in more cases.
* Pack bins using idea from colin@nyx10.cs.du.edu
* Use ordered bins instead of best-fit threshhold
* Eliminate block-local decls to simplify tracing and debugging.
* Support another case of realloc via move into top
* Fix error occuring when initial sbrk_base not word-aligned.
* Rely on page size for units instead of SBRK_UNIT to
avoid surprises about sbrk alignment conventions.
* Add mallinfo, mallopt. Thanks to Raymond Nijssen
(raymond@es.ele.tue.nl) for the suggestion.
* Add `pad' argument to malloc_trim and top_pad mallopt parameter.
* More precautions for cases where other routines call sbrk,
courtesy of Wolfram Gloger (Gloger@lrz.uni-muenchen.de).
* Added macros etc., allowing use in linux libc from
H.J. Lu (hjl@gnu.ai.mit.edu)
* Inverted this history list
V2.6.1 Sat Dec 2 14:10:57 1995 Doug Lea (dl at gee)
* Re-tuned and fixed to behave more nicely with V2.6.0 changes.
* Removed all preallocation code since under current scheme
the work required to undo bad preallocations exceeds
the work saved in good cases for most test programs.
* No longer use return list or unconsolidated bins since
no scheme using them consistently outperforms those that don't
given above changes.
* Use best fit for very large chunks to prevent some worst-cases.
* Added some support for debugging
V2.6.0 Sat Nov 4 07:05:23 1995 Doug Lea (dl at gee)
* Removed footers when chunks are in use. Thanks to
Paul Wilson (wilson@cs.texas.edu) for the suggestion.
V2.5.4 Wed Nov 1 07:54:51 1995 Doug Lea (dl at gee)
* Added malloc_trim, with help from Wolfram Gloger
(wmglo@Dent.MED.Uni-Muenchen.DE).
V2.5.3 Tue Apr 26 10:16:01 1994 Doug Lea (dl at g)
V2.5.2 Tue Apr 5 16:20:40 1994 Doug Lea (dl at g)
* realloc: try to expand in both directions
* malloc: swap order of clean-bin strategy;
* realloc: only conditionally expand backwards
* Try not to scavenge used bins
* Use bin counts as a guide to preallocation
* Occasionally bin return list chunks in first scan
* Add a few optimizations from colin@nyx10.cs.du.edu
V2.5.1 Sat Aug 14 15:40:43 1993 Doug Lea (dl at g)
* faster bin computation & slightly different binning
* merged all consolidations to one part of malloc proper
(eliminating old malloc_find_space & malloc_clean_bin)
* Scan 2 returns chunks (not just 1)
* Propagate failure in realloc if malloc returns 0
* Add stuff to allow compilation on non-ANSI compilers
from kpv@research.att.com
V2.5 Sat Aug 7 07:41:59 1993 Doug Lea (dl at g.oswego.edu)
* removed potential for odd address access in prev_chunk
* removed dependency on getpagesize.h
* misc cosmetics and a bit more internal documentation
* anticosmetics: mangled names in macros to evade debugger strangeness
* tested on sparc, hp-700, dec-mips, rs6000
with gcc & native cc (hp, dec only) allowing
Detlefs & Zorn comparison study (in SIGPLAN Notices.)
Trial version Fri Aug 28 13:14:29 1992 Doug Lea (dl at g.oswego.edu)
* Based loosely on libg++-1.2X malloc. (It retains some of the overall
structure of old version, but most details differ.)
*/

View File

@ -0,0 +1,20 @@
#ifndef _MBCTYPE_H_
#define _MBCTYPE_H_
/* escape character used for JIS encoding */
#define ESC_CHAR 0x1b
/* functions used to support SHIFT_JIS, EUC-JP, and JIS multibyte encodings */
int _EXFUN(_issjis1, (int c));
int _EXFUN(_issjis2, (int c));
int _EXFUN(_iseucjp, (int c));
int _EXFUN(_isjis, (int c));
#define _issjis1(c) ((c) >= 0x81 && (c) <= 0x9f || (c) >= 0xe0 && (c) <= 0xef)
#define _issjis2(c) ((c) >= 0x40 && (c) <= 0x7e || (c) >= 0x80 && (c) <= 0xfc)
#define _iseucjp(c) ((c) >= 0xa1 && (c) <= 0xfe)
#define _isjis(c) ((c) >= 0x21 && (c) <= 0x7e)
#endif /* _MBCTYPE_H_ */

63
agbcc/libc/stdlib/mblen.c Normal file
View File

@ -0,0 +1,63 @@
/*
FUNCTION
<<mblen>>---minimal multibyte length function
INDEX
mblen
ANSI_SYNOPSIS
#include <stdlib.h>
int mblen(const char *<[s]>, size_t <[n]>);
TRAD_SYNOPSIS
#include <stdlib.h>
int mblen(<[s]>, <[n]>)
const char *<[s]>;
size_t <[n]>;
DESCRIPTION
When MB_CAPABLE is not defined, this is a minimal ANSI-conforming
implementation of <<mblen>>. In this case, the
only ``multi-byte character sequences'' recognized are single bytes,
and thus <<1>> is returned unless <[s]> is the null pointer or
has a length of 0 or is the empty string.
When MB_CAPABLE is defined, this routine calls <<_mbtowc_r>> to perform
the conversion, passing a state variable to allow state dependent
decoding. The result is based on the locale setting which may
be restricted to a defined set of locales.
RETURNS
This implementation of <<mblen>> returns <<0>> if
<[s]> is <<NULL>> or the empty string; it returns <<1>> if not MB_CAPABLE or
the character is a single-byte character; it returns <<-1>>
if the multi-byte character is invalid; otherwise it returns
the number of bytes in the multibyte character.
PORTABILITY
<<mblen>> is required in the ANSI C standard. However, the precise
effects vary with the locale.
<<mblen>> requires no supporting OS subroutines.
*/
#include <stdlib.h>
int
_DEFUN (mblen, (s, n),
const char *s _AND
size_t n)
{
#ifdef MB_CAPABLE
static int state;
return _mbtowc_r (_REENT, NULL, s, n, &state);
#else /* not MB_CAPABLE */
if (s == NULL || *s == '\0')
return 0;
if (n == 0)
return -1;
return 1;
#endif /* not MB_CAPABLE */
}

View File

@ -0,0 +1,76 @@
/*
FUNCTION
<<mbstowcs>>---minimal multibyte string to wide char converter
INDEX
mbstowcs
ANSI_SYNOPSIS
#include <stdlib.h>
int mbstowcs(wchar_t *<[pwc]>, const char *<[s]>, size_t <[n]>);
TRAD_SYNOPSIS
#include <stdlib.h>
int mbstowcs(<[pwc]>, <[s]>, <[n]>)
wchar_t *<[pwc]>;
const char *<[s]>;
size_t <[n]>;
DESCRIPTION
When MB_CAPABLE is not defined, this is a minimal ANSI-conforming
implementation of <<mbstowcs>>. In this case, the
only ``multi-byte character sequences'' recognized are single bytes,
and they are ``converted'' to wide-char versions simply by byte
extension.
When MB_CAPABLE is defined, this routine calls <<_mbstowcs_r>> to perform
the conversion, passing a state variable to allow state dependent
decoding. The result is based on the locale setting which may
be restricted to a defined set of locales.
RETURNS
This implementation of <<mbstowcs>> returns <<0>> if
<[s]> is <<NULL>> or is the empty string;
it returns <<-1>> if MB_CAPABLE and one of the
multi-byte characters is invalid or incomplete;
otherwise it returns the minimum of: <<n>> or the
number of multi-byte characters in <<s>> plus 1 (to
compensate for the nul character).
If the return value is -1, the state of the <<pwc>> string is
indeterminate. If the input has a length of 0, the output
string will be modified to contain a wchar_t nul terminator.
PORTABILITY
<<mbstowcs>> is required in the ANSI C standard. However, the precise
effects vary with the locale.
<<mbstowcs>> requires no supporting OS subroutines.
*/
#include <stdlib.h>
size_t
_DEFUN (mbstowcs, (pwcs, s, n),
wchar_t *pwcs _AND
const char *s _AND
size_t n)
{
#ifdef MB_CAPABLE
int state = 0;
return _mbstowcs_r (_REENT, pwcs, s, n, &state);
#else /* not MB_CAPABLE */
int count = 0;
if (n != 0) {
do {
if ((*pwcs++ = (wchar_t) *s++) == 0)
break;
count++;
} while (--n != 0);
}
return count;
#endif /* not MB_CAPABLE */
}

View File

@ -0,0 +1,29 @@
#include <stdlib.h>
size_t
_DEFUN (_mbstowcs_r, (reent, pwcs, s, n, state),
struct _reent *r _AND
wchar_t *pwcs _AND
const char *s _AND
size_t n _AND
int *state)
{
wchar_t *ptr = pwcs;
size_t max = n;
char *t = (char *)s;
int bytes;
while (n > 0)
{
bytes = _mbtowc_r (r, ptr, t, MB_CUR_MAX, state);
if (bytes == -1)
return -1;
else if (bytes == 0)
return ptr - pwcs;
t += bytes;
++ptr;
--n;
}
return max;
}

View File

@ -0,0 +1,77 @@
/*
FUNCTION
<<mbtowc>>---minimal multibyte to wide char converter
INDEX
mbtowc
ANSI_SYNOPSIS
#include <stdlib.h>
int mbtowc(wchar_t *<[pwc]>, const char *<[s]>, size_t <[n]>);
TRAD_SYNOPSIS
#include <stdlib.h>
int mbtowc(<[pwc]>, <[s]>, <[n]>)
wchar_t *<[pwc]>;
const char *<[s]>;
size_t <[n]>;
DESCRIPTION
When MB_CAPABLE is not defined, this is a minimal ANSI-conforming
implementation of <<mbtowc>>. In this case,
only ``multi-byte character sequences'' recognized are single bytes,
and they are ``converted'' to themselves.
Each call to <<mbtowc>> copies one character from <<*<[s]>>> to
<<*<[pwc]>>>, unless <[s]> is a null pointer. The argument n
is ignored.
When MB_CAPABLE is defined, this routine calls <<_mbtowc_r>> to perform
the conversion, passing a state variable to allow state dependent
decoding. The result is based on the locale setting which may
be restricted to a defined set of locales.
RETURNS
This implementation of <<mbtowc>> returns <<0>> if
<[s]> is <<NULL>> or is the empty string;
it returns <<1>> if not MB_CAPABLE or
the character is a single-byte character; it returns <<-1>>
if n is <<0>> or the multi-byte character is invalid;
otherwise it returns the number of bytes in the multibyte character.
If the return value is -1, no changes are made to the <<pwc>>
output string. If the input is the empty string, a wchar_t nul
is placed in the output string and 0 is returned. If the input
has a length of 0, no changes are made to the <<pwc>> output string.
PORTABILITY
<<mbtowc>> is required in the ANSI C standard. However, the precise
effects vary with the locale.
<<mbtowc>> requires no supporting OS subroutines.
*/
#include <stdlib.h>
int
_DEFUN (mbtowc, (pwc, s, n),
wchar_t *pwc _AND
const char *s _AND
size_t n)
{
#ifdef MB_CAPABLE
static int state;
return _mbtowc_r (_REENT, pwc, s, n, &state);
#else /* not MB_CAPABLE */
if (s == NULL)
return 0;
if (n == 0)
return -1;
if (pwc)
*pwc = (wchar_t) *s;
return (*s != '\0');
#endif /* not MB_CAPABLE */
}

View File

@ -0,0 +1,206 @@
#include <stdlib.h>
#include <locale.h>
#include "mbctype.h"
#ifdef MB_CAPABLE
typedef enum { ESCAPE, DOLLAR, BRACKET, AT, B, J,
NUL, JIS_CHAR, OTHER, JIS_C_NUM } JIS_CHAR_TYPE;
typedef enum { ASCII, A_ESC, A_ESC_DL, JIS, JIS_1, JIS_2, J_ESC, J_ESC_BR,
J2_ESC, J2_ESC_BR, DONE, INV, JIS_S_NUM } JIS_STATE;
typedef enum { COPY_A, COPY_J, COPY_J2, MAKE_A, MAKE_J, NOOP, EMPTY, ERROR } JIS_ACTION;
/**************************************************************************************
* state/action tables for processing JIS encoding
* Where possible, switches to JIS are grouped with proceding JIS characters and switches
* to ASCII are grouped with preceding JIS characters. Thus, maximum returned length
* is 2 (switch to JIS) + 2 (JIS characters) + 2 (switch back to ASCII) = 6.
*************************************************************************************/
static JIS_STATE JIS_state_table[JIS_S_NUM][JIS_C_NUM] = {
/* ESCAPE DOLLAR BRACKET AT B J NUL JIS_CHAR OTHER */
/* ASCII */ { A_ESC, DONE, DONE, DONE, DONE, DONE, DONE, DONE, DONE },
/* A_ESC */ { DONE, A_ESC_DL, DONE, DONE, DONE, DONE, DONE, DONE, DONE },
/* A_ESC_DL */{ DONE, DONE, DONE, JIS, JIS, DONE, DONE, DONE, DONE },
/* JIS */ { J_ESC, JIS_1, JIS_1, JIS_1, JIS_1, JIS_1, INV, JIS_1, INV },
/* JIS_1 */ { INV, JIS_2, JIS_2, JIS_2, JIS_2, JIS_2, INV, JIS_2, INV },
/* JIS_2 */ { J2_ESC, DONE, DONE, DONE, DONE, DONE, INV, DONE, DONE },
/* J_ESC */ { INV, INV, J_ESC_BR, INV, INV, INV, INV, INV, INV },
/* J_ESC_BR */{ INV, INV, INV, INV, ASCII, ASCII, INV, INV, INV },
/* J2_ESC */ { INV, INV, J2_ESC_BR,INV, INV, INV, INV, INV, INV },
/* J2_ESC_BR*/{ INV, INV, INV, INV, DONE, DONE, INV, INV, INV },
};
static JIS_ACTION JIS_action_table[JIS_S_NUM][JIS_C_NUM] = {
/* ESCAPE DOLLAR BRACKET AT B J NUL JIS_CHAR OTHER */
/* ASCII */ { NOOP, COPY_A, COPY_A, COPY_A, COPY_A, COPY_A, EMPTY, COPY_A, COPY_A},
/* A_ESC */ { COPY_A, NOOP, COPY_A, COPY_A, COPY_A, COPY_A, COPY_A, COPY_A, COPY_A},
/* A_ESC_DL */{ COPY_A, COPY_A, COPY_A, MAKE_J, MAKE_J, COPY_A, COPY_A, COPY_A, COPY_A},
/* JIS */ { NOOP, NOOP, NOOP, NOOP, NOOP, NOOP, ERROR, NOOP, ERROR },
/* JIS_1 */ { ERROR, NOOP, NOOP, NOOP, NOOP, NOOP, ERROR, NOOP, ERROR },
/* JIS_2 */ { NOOP, COPY_J2, COPY_J2, COPY_J2, COPY_J2, COPY_J2, ERROR, COPY_J2, COPY_J2},
/* J_ESC */ { ERROR, ERROR, NOOP, ERROR, ERROR, ERROR, ERROR, ERROR, ERROR },
/* J_ESC_BR */{ ERROR, ERROR, ERROR, ERROR, NOOP, NOOP, ERROR, ERROR, ERROR },
/* J2_ESC */ { ERROR, ERROR, NOOP, ERROR, ERROR, ERROR, ERROR, ERROR, ERROR },
/* J2_ESC_BR*/{ ERROR, ERROR, ERROR, ERROR, COPY_J, COPY_J, ERROR, ERROR, ERROR },
};
#endif /* MB_CAPABLE */
int
_DEFUN (_mbtowc_r, (r, pwc, s, n, state),
struct _reent *r _AND
wchar_t *pwc _AND
const char *s _AND
size_t n _AND
int *state)
{
wchar_t dummy;
unsigned char *t = (unsigned char *)s;
if (pwc == NULL)
pwc = &dummy;
if (s != NULL && n == 0)
return -1;
#ifdef MB_CAPABLE
if (r->_current_locale == NULL ||
(strlen (r->_current_locale) <= 1))
{ /* fall-through */ }
else if (!strcmp (r->_current_locale, "C-SJIS"))
{
int char1 = *t;
if (s == NULL)
return 0; /* not state-dependent */
if (_issjis1 (char1))
{
int char2 = t[1];
if (n <= 1)
return -1;
if (_issjis2 (char2))
{
*pwc = (((wchar_t)*t) << 8) + (wchar_t)(*(t+1));
return 2;
}
else
return -1;
}
}
else if (!strcmp (r->_current_locale, "C-EUCJP"))
{
int char1 = *t;
if (s == NULL)
return 0; /* not state-dependent */
if (_iseucjp (char1))
{
int char2 = t[1];
if (n <= 1)
return -1;
if (_iseucjp (char2))
{
*pwc = (((wchar_t)*t) << 8) + (wchar_t)(*(t+1));
return 2;
}
else
return -1;
}
}
else if (!strcmp (r->_current_locale, "C-JIS"))
{
JIS_STATE curr_state;
JIS_ACTION action;
JIS_CHAR_TYPE ch;
unsigned char *ptr;
int i, curr_ch;
if (s == NULL)
{
*state = 0;
return 1; /* state-dependent */
}
curr_state = (*state == 0 ? ASCII : JIS);
ptr = t;
for (i = 0; i < n; ++i)
{
curr_ch = t[i];
switch (curr_ch)
{
case ESC_CHAR:
ch = ESCAPE;
break;
case '$':
ch = DOLLAR;
break;
case '@':
ch = AT;
break;
case '(':
ch = BRACKET;
break;
case 'B':
ch = B;
break;
case 'J':
ch = J;
break;
case '\0':
ch = NUL;
break;
default:
if (_isjis (curr_ch))
ch = JIS_CHAR;
else
ch = OTHER;
}
action = JIS_action_table[curr_state][ch];
curr_state = JIS_state_table[curr_state][ch];
switch (action)
{
case NOOP:
break;
case EMPTY:
*state = 0;
*pwc = (wchar_t)0;
return i;
case COPY_A:
*state = 0;
*pwc = (wchar_t)*ptr;
return (i + 1);
case COPY_J:
*state = 0;
*pwc = (((wchar_t)*ptr) << 8) + (wchar_t)(*(ptr+1));
return (i + 1);
case COPY_J2:
*state = 1;
*pwc = (((wchar_t)*ptr) << 8) + (wchar_t)(*(ptr+1));
return (ptr - t) + 2;
case MAKE_A:
case MAKE_J:
ptr = (char *)(t + i + 1);
break;
case ERROR:
default:
return -1;
}
}
return -1; /* n < bytes needed */
}
#endif /* MB_CAPABLE */
/* otherwise this must be the "C" locale or unknown locale */
if (s == NULL)
return 0; /* not state-dependent */
*pwc = (wchar_t)*t;
if (*t == '\0')
return 0;
return 1;
}

50
agbcc/libc/stdlib/mlock.c Normal file
View File

@ -0,0 +1,50 @@
/*
FUNCTION
<<__malloc_lock>>, <<__malloc_unlock>>--lock malloc pool
INDEX
__malloc_lock
INDEX
__malloc_unlock
ANSI_SYNOPSIS
#include <malloc.h>
void __malloc_lock (void *<[reent]>);
void __malloc_unlock (void *<[reent]>);
TRAD_SYNOPSIS
void __malloc_lock(<[reent]>)
char *<[reent]>;
void __malloc_unlock(<[reent]>)
char *<[reent]>;
DESCRIPTION
The <<malloc>> family of routines call these functions when they need
to lock the memory pool. The version of these routines supplied in
the library does not do anything. If multiple threads of execution
can call <<malloc>>, or if <<malloc>> can be called reentrantly, then
you need to define your own versions of these functions in order to
safely lock the memory pool during a call. If you do not, the memory
pool may become corrupted.
A call to <<malloc>> may call <<__malloc_lock>> recursively; that is,
the sequence of calls may go <<__malloc_lock>>, <<__malloc_lock>>,
<<__malloc_unlock>>, <<__malloc_unlock>>. Any implementation of these
routines must be careful to avoid causing a thread to wait for a lock
that it already holds.
*/
#include <malloc.h>
void
__malloc_lock (ptr)
struct _reent *ptr;
{
}
void
__malloc_unlock (ptr)
struct _reent *ptr;
{
}

978
agbcc/libc/stdlib/mprec.c Normal file
View File

@ -0,0 +1,978 @@
/****************************************************************
*
* The author of this software is David M. Gay.
*
* Copyright (c) 1991 by AT&T.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose without fee is hereby granted, provided that this entire notice
* is included in all copies of any software which is or includes a copy
* or modification of this software and in all copies of the supporting
* documentation for such software.
*
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
* OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
*
***************************************************************/
/* Please send bug reports to
David M. Gay
AT&T Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-2070
U.S.A.
dmg@research.att.com or research!dmg
*/
/* 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 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.
* #define Unsigned_Shifts if >> does treats its left operand as unsigned.
* #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 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.
*/
#include <_ansi.h>
#include <stdlib.h>
#include <string.h>
#include <reent.h>
#include "mprec.h"
/* reent.c knows this value */
#define _Kmax 15
_Bigint *
_DEFUN (Balloc, (ptr, k), struct _reent *ptr _AND int k)
{
int x;
_Bigint *rv ;
if (ptr->_freelist == NULL)
{
/* Allocate a list of pointers to the mprec objects */
ptr->_freelist = (struct _Bigint **) _calloc_r (ptr,
sizeof (struct _Bigint *),
_Kmax + 1);
if (ptr->_freelist == NULL)
{
return NULL;
}
}
if (rv = ptr->_freelist[k])
{
ptr->_freelist[k] = rv->_next;
}
else
{
x = 1 << k;
/* Allocate an mprec Bigint and stick in in the freelist */
rv = (_Bigint *) _calloc_r (ptr,
1,
sizeof (_Bigint) +
(x-1) * sizeof(rv->_x));
if (rv == NULL) return NULL;
rv->_k = k;
rv->_maxwds = x;
}
rv->_sign = rv->_wds = 0;
return rv;
}
void
_DEFUN (Bfree, (ptr, v), struct _reent *ptr _AND _Bigint * v)
{
if (v)
{
v->_next = ptr->_freelist[v->_k];
ptr->_freelist[v->_k] = v;
}
}
_Bigint *
_DEFUN (multadd, (ptr, b, m, a),
struct _reent *ptr _AND
_Bigint * b _AND
int m _AND
int a)
{
int i, wds;
ULong *x, y;
#ifdef Pack_32
ULong xi, z;
#endif
_Bigint *b1;
wds = b->_wds;
x = b->_x;
i = 0;
do
{
#ifdef Pack_32
xi = *x;
y = (xi & 0xffff) * m + a;
z = (xi >> 16) * m + (y >> 16);
a = (int) (z >> 16);
*x++ = (z << 16) + (y & 0xffff);
#else
y = *x * m + a;
a = (int) (y >> 16);
*x++ = y & 0xffff;
#endif
}
while (++i < wds);
if (a)
{
if (wds >= b->_maxwds)
{
b1 = Balloc (ptr, b->_k + 1);
Bcopy (b1, b);
Bfree (ptr, b);
b = b1;
}
b->_x[wds++] = a;
b->_wds = wds;
}
return b;
}
_Bigint *
_DEFUN (s2b, (ptr, s, nd0, nd, y9),
struct _reent * ptr _AND
_CONST char *s _AND
int nd0 _AND
int nd _AND
ULong y9)
{
_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 (ptr, k);
b->_x[0] = y9;
b->_wds = 1;
#else
b = Balloc (ptr, 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 (ptr, b, 10, *s++ - '0');
while (++i < nd0);
s++;
}
else
s += 10;
for (; i < nd; i++)
b = multadd (ptr, b, 10, *s++ - '0');
return b;
}
int
_DEFUN (hi0bits,
(x), register ULong x)
{
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;
}
int
_DEFUN (lo0bits, (y), ULong *y)
{
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 *
_DEFUN (i2b, (ptr, i), struct _reent * ptr _AND int i)
{
_Bigint *b;
b = Balloc (ptr, 1);
b->_x[0] = i;
b->_wds = 1;
return b;
}
_Bigint *
_DEFUN (mult, (ptr, a, b), struct _reent * ptr _AND _Bigint * a _AND _Bigint * b)
{
_Bigint *c;
int k, wa, wb, wc;
ULong carry, y, z;
ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
#ifdef Pack_32
ULong z2;
#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 (ptr, 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 Pack_32
for (; xb < xbe; xb++, xc0++)
{
if (y = *xb & 0xffff)
{
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)
{
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++)
{
x = xa;
xc = xc0;
carry = 0;
do
{
z = *x++ * y + *xc + carry;
carry = z >> 16;
*xc++ = z & 0xffff;
}
while (x < xae);
*xc = carry;
}
}
#endif
for (xc0 = c->_x, xc = xc0 + wc; wc > 0 && !*--xc; --wc);
c->_wds = wc;
return c;
}
_Bigint *
_DEFUN (pow5mult,
(ptr, b, k), struct _reent * ptr _AND _Bigint * b _AND int k)
{
_Bigint *b1, *p5, *p51;
int i;
static _CONST int p05[3] = {5, 25, 125};
if (i = k & 3)
b = multadd (ptr, b, p05[i - 1], 0);
if (!(k >>= 2))
return b;
if (!(p5 = ptr->_p5s))
{
/* first time */
p5 = ptr->_p5s = i2b (ptr, 625);
p5->_next = 0;
}
for (;;)
{
if (k & 1)
{
b1 = mult (ptr, b, p5);
Bfree (ptr, b);
b = b1;
}
if (!(k >>= 1))
break;
if (!(p51 = p5->_next))
{
p51 = p5->_next = mult (ptr, p5, p5);
p51->_next = 0;
}
p5 = p51;
}
return b;
}
_Bigint *
_DEFUN (lshift, (ptr, b, k), struct _reent * ptr _AND _Bigint * b _AND int k)
{
int i, k1, n, n1;
_Bigint *b1;
ULong *x, *x1, *xe, z;
#ifdef Pack_32
n = k >> 5;
#else
n = k >> 4;
#endif
k1 = b->_k;
n1 = n + b->_wds + 1;
for (i = b->_maxwds; n1 > i; i <<= 1)
k1++;
b1 = Balloc (ptr, k1);
x1 = b1->_x;
for (i = 0; i < n; i++)
*x1++ = 0;
x = b->_x;
xe = x + b->_wds;
#ifdef Pack_32
if (k &= 0x1f)
{
k1 = 32 - k;
z = 0;
do
{
*x1++ = *x << k | z;
z = *x++ >> k1;
}
while (x < xe);
if (*x1 = z)
++n1;
}
#else
if (k &= 0xf)
{
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 (ptr, b);
return b1;
}
int
_DEFUN (cmp, (a, b), _Bigint * a _AND _Bigint * b)
{
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 *
_DEFUN (diff, (ptr, a, b), struct _reent * ptr _AND
_Bigint * a _AND _Bigint * b)
{
_Bigint *c;
int i, wa, wb;
Long borrow, y; /* We need signed shifts here. */
ULong *xa, *xae, *xb, *xbe, *xc;
#ifdef Pack_32
Long z;
#endif
i = cmp (a, b);
if (!i)
{
c = Balloc (ptr, 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 (ptr, 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 Pack_32
do
{
y = (*xa & 0xffff) - (*xb & 0xffff) + borrow;
borrow = y >> 16;
Sign_Extend (borrow, y);
z = (*xa++ >> 16) - (*xb++ >> 16) + borrow;
borrow = z >> 16;
Sign_Extend (borrow, z);
Storeinc (xc, z, y);
}
while (xb < xbe);
while (xa < xae)
{
y = (*xa & 0xffff) + borrow;
borrow = y >> 16;
Sign_Extend (borrow, y);
z = (*xa++ >> 16) + borrow;
borrow = z >> 16;
Sign_Extend (borrow, z);
Storeinc (xc, z, y);
}
#else
do
{
y = *xa++ - *xb++ + borrow;
borrow = y >> 16;
Sign_Extend (borrow, y);
*xc++ = y & 0xffff;
}
while (xb < xbe);
while (xa < xae)
{
y = *xa++ + borrow;
borrow = y >> 16;
Sign_Extend (borrow, y);
*xc++ = y & 0xffff;
}
#endif
while (!*--xc)
wa--;
c->_wds = wa;
return c;
}
double
_DEFUN (ulp, (_x), double _x)
{
union double_union x, a;
register Long L;
x.d = _x;
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;
#ifndef _DOUBLE_IS_32BITS
word1 (a) = 0;
#endif
#ifndef Sudden_Underflow
}
else
{
L = -L >> Exp_shift;
if (L < Exp_shift)
{
word0 (a) = 0x80000 >> L;
#ifndef _DOUBLE_IS_32BITS
word1 (a) = 0;
#endif
}
else
{
word0 (a) = 0;
L -= Exp_shift;
#ifndef _DOUBLE_IS_32BITS
word1 (a) = L >= 31 ? 1 : 1 << 31 - L;
#endif
}
}
#endif
return a.d;
}
double
_DEFUN (b2d, (a, e),
_Bigint * a _AND int *e)
{
ULong *xa, *xa0, w, y, z;
int k;
union double_union 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;
#ifndef _DOUBLE_IS_32BITS
d1 = y << (32 - Ebits) + k | w >> Ebits - k;
#endif
goto ret_d;
}
z = xa > xa0 ? *--xa : 0;
if (k -= Ebits)
{
d0 = Exp_1 | y << k | z >> 32 - k;
y = xa > xa0 ? *--xa : 0;
#ifndef _DOUBLE_IS_32BITS
d1 = z << k | y >> 32 - k;
#endif
}
else
{
d0 = Exp_1 | y;
#ifndef _DOUBLE_IS_32BITS
d1 = z;
#endif
}
#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;
#else
#undef d0
#undef d1
#endif
return d.d;
}
_Bigint *
_DEFUN (d2b,
(ptr, _d, e, bits),
struct _reent * ptr _AND
double _d _AND
int *e _AND
int *bits)
{
union double_union d;
_Bigint *b;
int de, i, k;
ULong *x, y, z;
#ifdef VAX
ULong d0, d1;
d.d = _d;
d0 = word0 (d) >> 16 | word0 (d) << 16;
d1 = word1 (d) >> 16 | word1 (d) << 16;
#else
#define d0 word0(d)
#define d1 word1(d)
d.d = _d;
#endif
#ifdef Pack_32
b = Balloc (ptr, 1);
#else
b = Balloc (ptr, 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))
z |= Exp_msk1;
#endif
#ifdef Pack_32
#ifndef _DOUBLE_IS_32BITS
if (y = d1)
{
if (k = lo0bits (&y))
{
x[0] = y | z << 32 - k;
z >>= k;
}
else
x[0] = y;
i = b->_wds = (x[1] = z) ? 2 : 1;
}
else
#endif
{
#ifdef DEBUG
if (!z)
Bug ("Zero passed to d2b");
#endif
k = lo0bits (&z);
x[0] = z;
i = b->_wds = 1;
#ifndef _DOUBLE_IS_32BITS
k += 32;
#endif
}
#else
if (y = d1)
{
if (k = lo0bits (&y))
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
double
_DEFUN (ratio, (a, b), _Bigint * a _AND _Bigint * b)
{
union double_union da, db;
int k, ka, kb;
da.d = b2d (a, &ka);
db.d = b2d (b, &kb);
#ifdef Pack_32
k = ka - kb + 32 * (a->_wds - b->_wds);
#else
k = ka - kb + 16 * (a->_wds - b->_wds);
#endif
#ifdef IBM
if (k > 0)
{
word0 (da) += (k >> 2) * Exp_msk1;
if (k &= 3)
da.d *= 1 << k;
}
else
{
k = -k;
word0 (db) += (k >> 2) * Exp_msk1;
if (k &= 3)
db.d *= 1 << k;
}
#else
if (k > 0)
word0 (da) += k * Exp_msk1;
else
{
k = -k;
word0 (db) += k * Exp_msk1;
}
#endif
return da.d / db.d;
}
_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, 1e23, 1e24
};
#if !defined(_DOUBLE_IS_32BITS) && !defined(__v800)
_CONST double bigtens[] =
{1e16, 1e32, 1e64, 1e128, 1e256};
_CONST double tinytens[] =
{1e-16, 1e-32, 1e-64, 1e-128, 1e-256};
#else
_CONST double bigtens[] =
{1e16, 1e32};
_CONST double tinytens[] =
{1e-16, 1e-32};
#endif
double
_DEFUN (_mprec_log10, (dig),
int dig)
{
double v = 1.0;
if (dig < 24)
return tens[dig];
while (dig > 0)
{
v *= 10;
dig--;
}
return v;
}

313
agbcc/libc/stdlib/mprec.h Normal file
View File

@ -0,0 +1,313 @@
/****************************************************************
*
* The author of this software is David M. Gay.
*
* Copyright (c) 1991 by AT&T.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose without fee is hereby granted, provided that this entire notice
* is included in all copies of any software which is or includes a copy
* or modification of this software and in all copies of the supporting
* documentation for such software.
*
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
* OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
*
***************************************************************/
/* Please send bug reports to
David M. Gay
AT&T Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-2070
U.S.A.
dmg@research.att.com or research!dmg
*/
#include <ieeefp.h>
#include <math.h>
#include <float.h>
#include <errno.h>
#include <sys/config.h>
#ifdef __IEEE_LITTLE_ENDIAN
#define IEEE_8087
#endif
#ifdef __IEEE_BIG_ENDIAN
#define IEEE_MC68k
#endif
#ifdef __Z8000__
#define Just_16
#endif
#ifdef DEBUG
#include "stdio.h"
#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);}
#endif
#ifdef Unsigned_Shifts
#define Sign_Extend(a,b) if (b < 0) a |= (__uint32_t)0xffff0000;
#else
#define Sign_Extend(a,b) /*no-op*/
#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
/* If we are going to examine or modify specific bits in a double using
the word0 and/or word1 macros, then we must wrap the double inside
a union. This is necessary to avoid undefined behavior according to
the ANSI C spec. */
union double_union
{
double d;
__uint32_t i[2];
};
#ifdef IEEE_8087
#define word0(x) (x.i[1])
#define word1(x) (x.i[0])
#else
#define word0(x) (x.i[0])
#define word1(x) (x.i[1])
#endif
/* 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) */
#if defined(IEEE_8087) + defined(IEEE_MC68k)
#if defined (_DOUBLE_IS_32BITS)
#define Exp_shift 23
#define Exp_shift1 23
#define Exp_msk1 ((__uint32_t)0x00800000L)
#define Exp_msk11 ((__uint32_t)0x00800000L)
#define Exp_mask ((__uint32_t)0x7f800000L)
#define P 24
#define Bias 127
#if 0
#define IEEE_Arith /* it is, but the code doesn't handle IEEE singles yet */
#endif
#define Emin (-126)
#define Exp_1 ((__uint32_t)0x3f800000L)
#define Exp_11 ((__uint32_t)0x3f800000L)
#define Ebits 8
#define Frac_mask ((__uint32_t)0x007fffffL)
#define Frac_mask1 ((__uint32_t)0x007fffffL)
#define Ten_pmax 10
#define Sign_bit ((__uint32_t)0x80000000L)
#define Ten_pmax 10
#define Bletch 2
#define Bndry_mask ((__uint32_t)0x007fffffL)
#define Bndry_mask1 ((__uint32_t)0x007fffffL)
#define LSB 1
#define Sign_bit ((__uint32_t)0x80000000L)
#define Log2P 1
#define Tiny0 0
#define Tiny1 1
#define Quick_max 5
#define Int_max 6
#define Infinite(x) (word0(x) == ((__uint32_t)0x7f800000L))
#undef word0
#undef word1
#define word0(x) (x.i[0])
#define word1(x) 0
#else
#define Exp_shift 20
#define Exp_shift1 20
#define Exp_msk1 ((__uint32_t)0x100000L)
#define Exp_msk11 ((__uint32_t)0x100000L)
#define Exp_mask ((__uint32_t)0x7ff00000L)
#define P 53
#define Bias 1023
#define IEEE_Arith
#define Emin (-1022)
#define Exp_1 ((__uint32_t)0x3ff00000L)
#define Exp_11 ((__uint32_t)0x3ff00000L)
#define Ebits 11
#define Frac_mask ((__uint32_t)0xfffffL)
#define Frac_mask1 ((__uint32_t)0xfffffL)
#define Ten_pmax 22
#define Bletch 0x10
#define Bndry_mask ((__uint32_t)0xfffffL)
#define Bndry_mask1 ((__uint32_t)0xfffffL)
#define LSB 1
#define Sign_bit ((__uint32_t)0x80000000L)
#define Log2P 1
#define Tiny0 0
#define Tiny1 1
#define Quick_max 14
#define Int_max 14
#define Infinite(x) (word0(x) == ((__uint32_t)0x7ff00000L)) /* sufficient test for here */
#endif
#else
#undef Sudden_Underflow
#define Sudden_Underflow
#ifdef IBM
#define Exp_shift 24
#define Exp_shift1 24
#define Exp_msk1 ((__uint32_t)0x1000000L)
#define Exp_msk11 ((__uint32_t)0x1000000L)
#define Exp_mask ((__uint32_t)0x7f000000L)
#define P 14
#define Bias 65
#define Exp_1 ((__uint32_t)0x41000000L)
#define Exp_11 ((__uint32_t)0x41000000L)
#define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */
#define Frac_mask ((__uint32_t)0xffffffL)
#define Frac_mask1 ((__uint32_t)0xffffffL)
#define Bletch 4
#define Ten_pmax 22
#define Bndry_mask ((__uint32_t)0xefffffL)
#define Bndry_mask1 ((__uint32_t)0xffffffL)
#define LSB 1
#define Sign_bit ((__uint32_t)0x80000000L)
#define Log2P 4
#define Tiny0 ((__uint32_t)0x100000L)
#define Tiny1 0
#define Quick_max 14
#define Int_max 15
#else /* VAX */
#define Exp_shift 23
#define Exp_shift1 7
#define Exp_msk1 0x80
#define Exp_msk11 ((__uint32_t)0x800000L)
#define Exp_mask ((__uint32_t)0x7f80L)
#define P 56
#define Bias 129
#define Exp_1 ((__uint32_t)0x40800000L)
#define Exp_11 ((__uint32_t)0x4080L)
#define Ebits 8
#define Frac_mask ((__uint32_t)0x7fffffL)
#define Frac_mask1 ((__uint32_t)0xffff007fL)
#define Ten_pmax 24
#define Bletch 2
#define Bndry_mask ((__uint32_t)0xffff007fL)
#define Bndry_mask1 ((__uint32_t)0xffff007fL)
#define LSB ((__uint32_t)0x10000L)
#define Sign_bit ((__uint32_t)0x8000L)
#define Log2P 1
#define Tiny0 0x80
#define Tiny1 0
#define Quick_max 15
#define Int_max 15
#endif
#endif
#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 ((__uint32_t)0xffffffffL)
#ifndef Just_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.
*/
#ifndef Pack_32
#define Pack_32
#endif
#endif
#ifdef __cplusplus
extern "C" double strtod(const char *s00, char **se);
extern "C" char *dtoa(double d, int mode, int ndigits,
int *decpt, int *sign, char **rve);
#endif
typedef struct _Bigint _Bigint;
#define Balloc _Balloc
#define Bfree _Bfree
#define multadd _multadd
#define s2b _s2b
#define lo0bits _lo0bits
#define hi0bits _hi0bits
#define i2b _i2b
#define mult _multiply
#define pow5mult _pow5mult
#define lshift _lshift
#define cmp __mcmp
#define diff __mdiff
#define ulp _ulp
#define b2d _b2d
#define d2b _d2b
#define ratio _ratio
#define tens __mprec_tens
#define bigtens __mprec_bigtens
#define tinytens __mprec_tinytens
struct _reent ;
double _EXFUN(ulp,(double x));
double _EXFUN(b2d,(_Bigint *a , int *e));
_Bigint * _EXFUN(Balloc,(struct _reent *p, int k));
void _EXFUN(Bfree,(struct _reent *p, _Bigint *v));
_Bigint * _EXFUN(multadd,(struct _reent *p, _Bigint *, int, int));
_Bigint * _EXFUN(s2b,(struct _reent *, const char*, int, int, ULong));
_Bigint * _EXFUN(i2b,(struct _reent *,int));
_Bigint * _EXFUN(mult, (struct _reent *, _Bigint *, _Bigint *));
_Bigint * _EXFUN(pow5mult, (struct _reent *, _Bigint *, int k));
int _EXFUN(hi0bits,(ULong));
int _EXFUN(lo0bits,(ULong *));
_Bigint * _EXFUN(d2b,(struct _reent *p, double d, int *e, int *bits));
_Bigint * _EXFUN(lshift,(struct _reent *p, _Bigint *b, int k));
_Bigint * _EXFUN(diff,(struct _reent *p, _Bigint *a, _Bigint *b));
int _EXFUN(cmp,(_Bigint *a, _Bigint *b));
double _EXFUN(ratio,(_Bigint *a, _Bigint *b));
#define Bcopy(x,y) memcpy((char *)&x->_sign, (char *)&y->_sign, y->_wds*sizeof(Long) + 2*sizeof(int))
#if defined(_DOUBLE_IS_32BITS) && defined(__v800)
#define n_bigtens 2
#else
#define n_bigtens 5
#endif
extern _CONST double tinytens[];
extern _CONST double bigtens[];
extern _CONST double tens[];
double _EXFUN(_mprec_log10,(int));

17
agbcc/libc/stdlib/msize.c Normal file
View File

@ -0,0 +1,17 @@
/* msize.c -- a wrapper for malloc_usable_size. */
#include <_ansi.h>
#include <reent.h>
#include <stdlib.h>
#include <malloc.h>
#ifndef _REENT_ONLY
size_t
_DEFUN (malloc_usable_size, (ptr),
_PTR ptr)
{
return _malloc_usable_size_r (_REENT, ptr);
}
#endif

151
agbcc/libc/stdlib/mstats.c Normal file
View File

@ -0,0 +1,151 @@
/* VxWorks provides its own version of malloc, and we can't use this
one because VxWorks does not provide sbrk. So we have a hook to
not compile this code. */
#ifdef MALLOC_PROVIDED
int _dummy_mstats = 1;
#else
/*
FUNCTION
<<mallinfo>>, <<malloc_stats>>, <<mallopt>>--malloc support
INDEX
mallinfo
INDEX
malloc_stats
INDEX
mallopt
INDEX
_mallinfo_r
INDEX
_malloc_stats_r
INDEX
_mallopt_r
ANSI_SYNOPSIS
#include <malloc.h>
struct mallinfo mallinfo(void);
void malloc_stats(void);
int mallopt(int <[parameter]>, <[value]>);
struct mallinfo _mallinfo_r(void *<[reent]>);
void _malloc_stats_r(void *<[reent]>);
int _mallopt_r(void *<[reent]>, int <[parameter]>, <[value]>);
TRAD_SYNOPSIS
#include <malloc.h>
struct mallinfo mallinfo();
void malloc_stats();
int mallopt(<[parameter]>, <[value]>)
int <[parameter]>;
int <[value]>;
struct mallinfo _mallinfo_r(<[reent]>);
char *<[reent]>;
void _malloc_stats_r(<[reent]>);
char *<[reent]>;
int _mallopt_r(<[reent]>, <[parameter]>, <[value]>)
char *<[reent]>;
int <[parameter]>;
int <[value]>;
DESCRIPTION
<<mallinfo>> returns a structure describing the current state of
memory allocation. The structure is defined in malloc.h. The
following fields are defined: <<arena>> is the total amount of space
in the heap; <<ordblks>> is the number of chunks which are not in use;
<<uordblks>> is the total amount of space allocated by <<malloc>>;
<<fordblks>> is the total amount of space not in use; <<keepcost>> is
the size of the top most memory block.
<<malloc_stats>> print some statistics about memory allocation on
standard error.
<<mallopt>> takes a parameter and a value. The parameters are defined
in malloc.h, and may be one of the following: <<M_TRIM_THRESHOLD>>
sets the maximum amount of unused space in the top most block before
releasing it back to the system in <<free>> (the space is released by
calling <<_sbrk_r>> with a negative argument); <<M_TOP_PAD>> is the
amount of padding to allocate whenever <<_sbrk_r>> is called to
allocate more space.
The alternate functions <<_mallinfo_r>>, <<_malloc_stats_r>>, and
<<_mallopt_r>> are reentrant versions. The extra argument <[reent]>
is a pointer to a reentrancy structure.
RETURNS
<<mallinfo>> returns a mallinfo structure. The structure is defined
in malloc.h.
<<malloc_stats>> does not return a result.
<<mallopt>> returns zero if the parameter could not be set, or
non-zero if it could be set.
PORTABILITY
<<mallinfo>> and <<mallopt>> are provided by SVR4, but <<mallopt>>
takes different parameters on different systems. <<malloc_stats>> is
not portable.
*/
#include <_ansi.h>
#include <reent.h>
#include <stdlib.h>
#include <malloc.h>
#include <stdio.h>
#ifndef _REENT_ONLY
struct mallinfo
_DEFUN_VOID (mallinfo)
{
return _mallinfo_r (_REENT);
}
void
_DEFUN_VOID (malloc_stats)
{
_malloc_stats_r (_REENT);
}
int
_DEFUN (mallopt, (p, v),
int p _AND
int v)
{
return _mallopt_r (_REENT, p, v);
}
#endif
/* mstats is now compatibility code. It used to be real, for a
previous version of the malloc routines. It now just calls
malloc_stats. */
void
_DEFUN (_mstats_r, (ptr, s),
struct _reent *ptr _AND
char *s)
{
fiprintf (_stderr_r (ptr), "Memory allocation statistics %s\n", s);
_malloc_stats_r (ptr);
}
#ifndef _REENT_ONLY
void
_DEFUN (mstats, (s),
char *s)
{
_mstats_r (_REENT, s);
}
#endif
#endif /* ! defined (MALLOC_PROVIDED) */

17
agbcc/libc/stdlib/mtrim.c Normal file
View File

@ -0,0 +1,17 @@
/* mtrim.c -- a wrapper for malloc_trim. */
#include <_ansi.h>
#include <reent.h>
#include <stdlib.h>
#include <malloc.h>
#ifndef _REENT_ONLY
int
_DEFUN (malloc_trim, (pad),
size_t pad)
{
return _malloc_trim_r (_REENT, pad);
}
#endif

View File

@ -0,0 +1,46 @@
/* This file may have been modified by DJ Delorie (Jan 1991). If so,
** these modifications are Coyright (C) 1991 DJ Delorie, 24 Kirsten Ave,
** Rochester NH, 03867-2954, USA.
*/
/*-
* Copyright (c) 1988 The Regents of the University of California.
* All rights reserved.
*
* 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.
*/
#include <stdlib.h>
#include <string.h>
int
_DEFUN (putenv, (str),
_CONST char *str)
{
register char *p, *equal;
int rval;
if (!(p = strdup (str)))
return 1;
if (!(equal = index (p, '=')))
{
(void) free (p);
return 1;
}
*equal = '\0';
rval = setenv (p, equal + 1, 1);
(void) free (p);
return rval;
}

222
agbcc/libc/stdlib/qsort.c Normal file
View File

@ -0,0 +1,222 @@
/*
FUNCTION
<<qsort>>---sort an array
INDEX
qsort
ANSI_SYNOPSIS
#include <stdlib.h>
void qsort(void *<[base]>, size_t <[nmemb]>, size_t <[size]>,
int (*<[compar]>)(const void *, const void *) );
TRAD_SYNOPSIS
#include <stdlib.h>
qsort(<[base]>, <[nmemb]>, <[size]>, <[compar]> )
char *<[base]>;
size_t <[nmemb]>;
size_t <[size]>;
int (*<[compar]>)();
DESCRIPTION
<<qsort>> sorts an array (beginning at <[base]>) of <[nmemb]> objects.
<[size]> describes the size of each element of the array.
You must supply a pointer to a comparison function, using the argument
shown as <[compar]>. (This permits sorting objects of unknown
properties.) Define the comparison function to accept two arguments,
each a pointer to an element of the array starting at <[base]>. The
result of <<(*<[compar]>)>> must be negative if the first argument is
less than the second, zero if the two arguments match, and positive if
the first argument is greater than the second (where ``less than'' and
``greater than'' refer to whatever arbitrary ordering is appropriate).
The array is sorted in place; that is, when <<qsort>> returns, the
array elements beginning at <[base]> have been reordered.
RETURNS
<<qsort>> does not return a result.
PORTABILITY
<<qsort>> is required by ANSI (without specifying the sorting algorithm).
*/
/*-
* Copyright (c) 1992, 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.
*/
#include <_ansi.h>
#include <stdlib.h>
#ifndef __GNUC__
#define inline
#endif
static inline char *med3 _PARAMS((char *, char *, char *, int (*)()));
static inline void swapfunc _PARAMS((char *, char *, int, int));
#define min(a, b) (a) < (b) ? a : b
/*
* Qsort routine from Bentley & McIlroy's "Engineering a Sort Function".
*/
#define swapcode(TYPE, parmi, parmj, n) { \
long i = (n) / sizeof (TYPE); \
register TYPE *pi = (TYPE *) (parmi); \
register TYPE *pj = (TYPE *) (parmj); \
do { \
register TYPE t = *pi; \
*pi++ = *pj; \
*pj++ = t; \
} while (--i > 0); \
}
#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \
es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1;
static inline void
_DEFUN(swapfunc, (a, b, n, swaptype),
char *a _AND
char *b _AND
int n _AND
int swaptype)
{
if(swaptype <= 1)
swapcode(long, a, b, n)
else
swapcode(char, a, b, n)
}
#define swap(a, b) \
if (swaptype == 0) { \
long t = *(long *)(a); \
*(long *)(a) = *(long *)(b); \
*(long *)(b) = t; \
} else \
swapfunc(a, b, es, swaptype)
#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype)
static inline char *
_DEFUN(med3, (a, b, c, cmp),
char *a _AND
char *b _AND
char *c _AND
int (*cmp)())
{
return cmp(a, b) < 0 ?
(cmp(b, c) < 0 ? b : (cmp(a, c) < 0 ? c : a ))
:(cmp(b, c) > 0 ? b : (cmp(a, c) < 0 ? a : c ));
}
void
_DEFUN(qsort, (a, n, es, cmp),
void *a _AND
size_t n _AND
size_t es _AND
int (*cmp)())
{
char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
int d, r, swaptype, swap_cnt;
loop: SWAPINIT(a, es);
swap_cnt = 0;
if (n < 7) {
for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es)
for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
pl -= es)
swap(pl, pl - es);
return;
}
pm = (char *) a + (n / 2) * es;
if (n > 7) {
pl = a;
pn = (char *) a + (n - 1) * es;
if (n > 40) {
d = (n / 8) * es;
pl = med3(pl, pl + d, pl + 2 * d, cmp);
pm = med3(pm - d, pm, pm + d, cmp);
pn = med3(pn - 2 * d, pn - d, pn, cmp);
}
pm = med3(pl, pm, pn, cmp);
}
swap(a, pm);
pa = pb = (char *) a + es;
pc = pd = (char *) a + (n - 1) * es;
for (;;) {
while (pb <= pc && (r = cmp(pb, a)) <= 0) {
if (r == 0) {
swap_cnt = 1;
swap(pa, pb);
pa += es;
}
pb += es;
}
while (pb <= pc && (r = cmp(pc, a)) >= 0) {
if (r == 0) {
swap_cnt = 1;
swap(pc, pd);
pd -= es;
}
pc -= es;
}
if (pb > pc)
break;
swap(pb, pc);
swap_cnt = 1;
pb += es;
pc -= es;
}
if (swap_cnt == 0) { /* Switch to insertion sort */
for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es)
for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
pl -= es)
swap(pl, pl - es);
return;
}
pn = (char *) a + n * es;
r = min(pa - (char *)a, pb - pa);
vecswap(a, pb - r, r);
r = min(pd - pc, pn - pd - es);
vecswap(pb, pn - r, r);
if ((r = pb - pa) > es)
qsort(a, r / es, es, cmp);
if ((r = pd - pc) > es) {
/* Iterate rather than recurse to save stack space */
a = pn - r;
n = r / es;
goto loop;
}
/* qsort(pn - r, r / es, es, cmp);*/
}

86
agbcc/libc/stdlib/rand.c Normal file
View File

@ -0,0 +1,86 @@
/*
FUNCTION
<<rand>>, <<srand>>---pseudo-random numbers
INDEX
rand
INDEX
srand
INDEX
rand_r
ANSI_SYNOPSIS
#include <stdlib.h>
int rand(void);
void srand(unsigned int <[seed]>);
int rand_r(unsigned int *<[seed]>);
TRAD_SYNOPSIS
#include <stdlib.h>
int rand();
void srand(<[seed]>)
unsigned int <[seed]>;
void rand_r(<[seed]>)
unsigned int *<[seed]>;
DESCRIPTION
<<rand>> returns a different integer each time it is called; each
integer is chosen by an algorithm designed to be unpredictable, so
that you can use <<rand>> when you require a random number.
The algorithm depends on a static variable called the ``random seed'';
starting with a given value of the random seed always produces the
same sequence of numbers in successive calls to <<rand>>.
You can set the random seed using <<srand>>; it does nothing beyond
storing its argument in the static variable used by <<rand>>. You can
exploit this to make the pseudo-random sequence less predictable, if
you wish, by using some other unpredictable value (often the least
significant parts of a time-varying value) as the random seed before
beginning a sequence of calls to <<rand>>; or, if you wish to ensure
(for example, while debugging) that successive runs of your program
use the same ``random'' numbers, you can use <<srand>> to set the same
random seed at the outset.
RETURNS
<<rand>> returns the next pseudo-random integer in sequence; it is a
number between <<0>> and <<RAND_MAX>> (inclusive).
<<srand>> does not return a result.
NOTES
<<rand>> and <<srand>> are unsafe for multi-thread applications.
<<rand_r>> is MT-Safe and should be used instead.
PORTABILITY
<<rand>> is required by ANSI, but the algorithm for pseudo-random
number generation is not specified; therefore, even if you use
the same random seed, you cannot expect the same sequence of results
on two different systems.
<<rand>> requires no supporting OS subroutines.
*/
#ifndef _REENT_ONLY
#include <stdlib.h>
#include <reent.h>
void
_DEFUN (srand, (seed), unsigned int seed)
{
_REENT->_new._reent._rand_next = seed;
}
int
_DEFUN_VOID (rand)
{
return ((_REENT->_new._reent._rand_next =
_REENT->_new._reent._rand_next * 1103515245 + 12345 )
& RAND_MAX );
}
#endif /* _REENT_ONLY */

View File

@ -0,0 +1,7 @@
#include <stdlib.h>
int
_DEFUN (rand_r, (seed), unsigned int *seed)
{
return (((*seed) = (*seed) * 1103515245 + 12345) & RAND_MAX);
}

View File

@ -0,0 +1,18 @@
/* realloc.c -- a wrapper for realloc_r. */
#include <_ansi.h>
#include <reent.h>
#include <stdlib.h>
#include <malloc.h>
#ifndef _REENT_ONLY
_PTR
_DEFUN (realloc, (ap, nbytes),
_PTR ap _AND
size_t nbytes)
{
return _realloc_r (_REENT, ap, nbytes);
}
#endif

113
agbcc/libc/stdlib/setenv.c Normal file
View File

@ -0,0 +1,113 @@
/* This file may have been modified by DJ Delorie (Jan 1991). If so,
** these modifications are Coyright (C) 1991 DJ Delorie, 24 Kirsten Ave,
** Rochester NH, 03867-2954, USA.
*/
/*
* Copyright (c) 1987 Regents of the University of California.
* All rights reserved.
*
* 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.
*/
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
/* _findenv is defined in getenv.c. */
extern char *_findenv _PARAMS ((const char *, int *));
/*
* setenv --
* Set the value of the environmental variable "name" to be
* "value". If rewrite is set, replace any current value.
*/
int
_DEFUN (setenv, (name, value, rewrite),
_CONST char *name _AND
_CONST char *value _AND
int rewrite)
{
extern char **environ;
static int alloced; /* if allocated space before */
register char *C;
int l_value, offset;
if (*value == '=') /* no `=' in value */
++value;
l_value = strlen (value);
if ((C = _findenv (name, &offset)))
{ /* find if already exists */
if (!rewrite)
return 0;
if (strlen (C) >= l_value)
{ /* old larger; copy over */
while (*C++ = *value++);
return 0;
}
}
else
{ /* create new slot */
register int cnt;
register char **P;
for (P = environ, cnt = 0; *P; ++P, ++cnt);
if (alloced)
{ /* just increase size */
environ = (char **) realloc ((char *) environ,
(size_t) (sizeof (char *) * (cnt + 2)));
if (!environ)
return -1;
}
else
{ /* get new space */
alloced = 1; /* copy old entries into it */
P = (char **) malloc ((size_t) (sizeof (char *) * (cnt + 2)));
if (!P)
return (-1);
bcopy ((char *) environ, (char *) P, cnt * sizeof (char *));
environ = P;
}
environ[cnt + 1] = NULL;
offset = cnt;
}
for (C = (char *) name; *C && *C != '='; ++C); /* no `=' in name */
if (!(environ[offset] = /* name + `=' + value */
malloc ((size_t) ((int) (C - name) + l_value + 2))))
return -1;
for (C = environ[offset]; (*C = *name++) && *C != '='; ++C);
for (*C++ = '='; *C++ = *value++;);
return 0;
}
/*
* unsetenv(name) --
* Delete environmental variable "name".
*/
void
_DEFUN (unsetenv, (name),
_CONST char *name)
{
extern char **environ;
register char **P;
int offset;
while (_findenv (name, &offset)) /* if set multiple times */
for (P = &environ[offset];; ++P)
if (!(*P = *(P + 1)))
break;
}

33
agbcc/libc/stdlib/std.h Normal file
View File

@ -0,0 +1,33 @@
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <limits.h>
#include <math.h>
#ifndef CYGNUS_NEC
#include <ctype.h>
#endif
#define Ise(c) ((c == 'e') || (c == 'E') || (c == 'd') || (c == 'D'))
#define Isdigit(c) ((c <= '9') && (c >= '0'))
#define Isspace(c) ((c == ' ') || (c == '\t') || (c=='\n') || (c=='\v') \
|| (c == '\r') || (c == '\f'))
#define Issign(c) ((c == '-') || (c == '+'))
#define Val(c) ((c - '0'))
#define MAXE 308
#define MINE (-308)
/* flags */
#define SIGN 0x01
#define ESIGN 0x02
#define DECP 0x04
#ifdef _HAVE_STDC
int __ten_mul(double *acc, int digit);
double __adjust(struct _reent *ptr, double *acc, int dexp, int sign);
const double __exp10(unsigned x);
#else
int __ten_mul();
double __adjust();
double __exp10();
#endif

View File

@ -0,0 +1,14 @@
#include <stdlib.h>
#include <string.h>
char *
_DEFUN (strdup, (str), _CONST char *str)
{
size_t len = strlen (str) + 1;
char *copy = malloc (len);
if (copy)
{
memcpy (copy, str, len);
}
return copy;
}

731
agbcc/libc/stdlib/strtod.c Normal file
View File

@ -0,0 +1,731 @@
/*
FUNCTION
<<strtod>>, <<strtodf>>---string to double or float
INDEX
strtod
INDEX
_strtod_r
INDEX
strtodf
ANSI_SYNOPSIS
#include <stdlib.h>
double strtod(const char *<[str]>, char **<[tail]>);
float strtodf(const char *<[str]>, char **<[tail]>);
double _strtod_r(void *<[reent]>,
const char *<[str]>, char **<[tail]>);
TRAD_SYNOPSIS
#include <stdlib.h>
double strtod(<[str]>,<[tail]>)
char *<[str]>;
char **<[tail]>;
float strtodf(<[str]>,<[tail]>)
char *<[str]>;
char **<[tail]>;
double _strtod_r(<[reent]>,<[str]>,<[tail]>)
char *<[reent]>;
char *<[str]>;
char **<[tail]>;
DESCRIPTION
The function <<strtod>> parses the character string <[str]>,
producing a substring which can be converted to a double
value. The substring converted is the longest initial
subsequence of <[str]>, beginning with the first
non-whitespace character, that has the format:
.[+|-]<[digits]>[.][<[digits]>][(e|E)[+|-]<[digits]>]
The substring contains no characters if <[str]> is empty, consists
entirely of whitespace, or if the first non-whitespace
character is something other than <<+>>, <<->>, <<.>>, or a
digit. If the substring is empty, no conversion is done, and
the value of <[str]> is stored in <<*<[tail]>>>. Otherwise,
the substring is converted, and a pointer to the final string
(which will contain at least the terminating null character of
<[str]>) is stored in <<*<[tail]>>>. If you want no
assignment to <<*<[tail]>>>, pass a null pointer as <[tail]>.
<<strtodf>> is identical to <<strtod>> except for its return type.
This implementation returns the nearest machine number to the
input decimal string. Ties are broken by using the IEEE
round-even rule.
The alternate function <<_strtod_r>> is a reentrant version.
The extra argument <[reent]> is a pointer to a reentrancy structure.
RETURNS
<<strtod>> returns the converted substring value, if any. If
no conversion could be performed, 0 is returned. If the
correct value is out of the range of representable values,
plus or minus <<HUGE_VAL>> is returned, and <<ERANGE>> is
stored in errno. If the correct value would cause underflow, 0
is returned and <<ERANGE>> is stored in errno.
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
*/
/****************************************************************
*
* The author of this software is David M. Gay.
*
* Copyright (c) 1991 by AT&T.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose without fee is hereby granted, provided that this entire notice
* is included in all copies of any software which is or includes a copy
* or modification of this software and in all copies of the supporting
* documentation for such software.
*
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
* OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
*
***************************************************************/
/* Please send bug reports to
David M. Gay
AT&T Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-2070
U.S.A.
dmg@research.att.com or research!dmg
*/
#include <_ansi.h>
#include <reent.h>
#include <string.h>
#include "mprec.h"
double
_DEFUN (_strtod_r, (ptr, s00, se),
struct _reent *ptr _AND
_CONST char *s00 _AND
char **se)
{
int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign, e1, esign, i, j,
k, nd, nd0, nf, nz, nz0, sign;
long e;
_CONST char *s, *s0, *s1;
double aadj, aadj1, adj;
long L;
unsigned long z;
ULong y;
union double_union rv, rv0;
_Bigint *bb, *bb1, *bd, *bd0, *bs, *delta;
sign = nz0 = nz = 0;
rv.d = 0.;
for (s = s00;; s++)
switch (*s)
{
case '-':
sign = 1;
/* no break */
case '+':
if (*++s)
goto break2;
/* no break */
case 0:
s = s00;
goto ret;
case '\t':
case '\n':
case '\v':
case '\f':
case '\r':
case ' ':
continue;
default:
goto break2;
}
break2:
if (*s == '0')
{
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;
if (c == '.')
{
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)
{
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')
{
e = c - '0';
s1 = s;
while ((c = *++s) >= '0' && c <= '9')
e = 10 * e + c - '0';
if (s - s1 > 8)
/* Avoid confusion from exponents
* so large that e might overflow.
*/
e = 9999999L;
if (esign)
e = -e;
}
else
e = 0;
}
else
s = s00;
}
if (!nd)
{
if (!nz && !nz0)
s = s00;
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;
rv.d = y;
if (k > 9)
rv.d = tens[k - 9] * rv.d + z;
bd0 = 0;
if (nd <= DBL_DIG
#ifndef RND_PRODQUOT
&& FLT_ROUNDS == 1
#endif
)
{
if (!e)
goto ret;
if (e > 0)
{
if (e <= Ten_pmax)
{
#ifdef VAX
goto vax_ovfl_check;
#else
/* rv.d = */ rounded_product (rv.d, 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.
*/
e -= i;
rv.d *= 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.d = */ rounded_product (rv.d, tens[e]);
if ((word0 (rv) & Exp_mask)
> Exp_msk1 * (DBL_MAX_EXP + Bias - 1 - P))
goto ovfl;
word0 (rv) += P * Exp_msk1;
#else
/* rv.d = */ rounded_product (rv.d, tens[e]);
#endif
goto ret;
}
}
#ifndef Inaccurate_Divide
else if (e >= -Ten_pmax)
{
/* rv.d = */ rounded_quotient (rv.d, tens[-e]);
goto ret;
}
#endif
}
e1 += nd - k;
/* Get starting approximation = rv.d * 10**e1 */
if (e1 > 0)
{
if (i = e1 & 15)
rv.d *= tens[i];
if (e1 &= ~15)
{
if (e1 > DBL_MAX_10_EXP)
{
ovfl:
ptr->_errno = ERANGE;
#ifdef _HAVE_STDC
rv.d = HUGE_VAL;
#else
/* Can't trust HUGE_VAL */
#ifdef IEEE_Arith
word0 (rv) = Exp_mask;
#ifndef _DOUBLE_IS_32BITS
word1 (rv) = 0;
#endif
#else
word0 (rv) = Big0;
#ifndef _DOUBLE_IS_32BITS
word1 (rv) = Big1;
#endif
#endif
#endif
if (bd0)
goto retfree;
goto ret;
}
if (e1 >>= 4)
{
for (j = 0; e1 > 1; j++, e1 >>= 1)
if (e1 & 1)
rv.d *= bigtens[j];
/* The last multiplication could overflow. */
word0 (rv) -= P * Exp_msk1;
rv.d *= 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;
#ifndef _DOUBLE_IS_32BITS
word1 (rv) = Big1;
#endif
}
else
word0 (rv) += P * Exp_msk1;
}
}
}
else if (e1 < 0)
{
e1 = -e1;
if (i = e1 & 15)
rv.d /= tens[i];
if (e1 &= ~15)
{
e1 >>= 4;
if (e1 >= 1 << n_bigtens)
goto undfl;
for (j = 0; e1 > 1; j++, e1 >>= 1)
if (e1 & 1)
rv.d *= tinytens[j];
/* The last multiplication could underflow. */
rv0.d = rv.d;
rv.d *= tinytens[j];
if (!rv.d)
{
rv.d = 2. * rv0.d;
rv.d *= tinytens[j];
if (!rv.d)
{
undfl:
rv.d = 0.;
ptr->_errno = ERANGE;
if (bd0)
goto retfree;
goto ret;
}
#ifndef _DOUBLE_IS_32BITS
word0 (rv) = Tiny0;
word1 (rv) = Tiny1;
#else
word0 (rv) = Tiny1;
#endif
/* The refinement below will clean
* this approximation up.
*/
}
}
}
/* Now the hard part -- adjusting rv to the correct value.*/
/* Put digits into bd: true value = bd * 10^e */
bd0 = s2b (ptr, s0, nd0, nd, y);
for (;;)
{
bd = Balloc (ptr, bd0->_k);
Bcopy (bd, bd0);
bb = d2b (ptr, rv.d, &bbe, &bbbits); /* rv.d = bb * 2^bbe */
bs = i2b (ptr, 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 Sudden_Underflow
#ifdef IBM
j = 1 + 4 * P - 3 - bbbits + ((bbe + bbbits - 1) & 3);
#else
j = P + 1 - bbbits;
#endif
#else
i = bbe + bbbits - 1; /* logb(rv.d) */
if (i < Emin) /* denormal */
j = bbe + (P - Emin);
else
j = P + 1 - bbbits;
#endif
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 (ptr, bs, bb5);
bb1 = mult (ptr, bs, bb);
Bfree (ptr, bb);
bb = bb1;
}
if (bb2 > 0)
bb = lshift (ptr, bb, bb2);
if (bd5 > 0)
bd = pow5mult (ptr, bd, bd5);
if (bd2 > 0)
bd = lshift (ptr, bd, bd2);
if (bs2 > 0)
bs = lshift (ptr, bs, bs2);
delta = diff (ptr, bb, bd);
dsign = delta->_sign;
delta->_sign = 0;
i = cmp (delta, bs);
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)
break;
delta = lshift (ptr, 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) == 0xffffffff)
{
/*boundary case -- increment exponent*/
word0 (rv) = (word0 (rv) & Exp_mask)
+ Exp_msk1
#ifdef IBM
| Exp_msk1 >> 4
#endif
;
#ifndef _DOUBLE_IS_32BITS
word1 (rv) = 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
if (L <= Exp_msk1)
#endif
goto undfl;
L -= Exp_msk1;
#else
L = (word0 (rv) & Exp_mask) - Exp_msk1;
#endif
word0 (rv) = L | Bndry_mask1;
#ifndef _DOUBLE_IS_32BITS
word1 (rv) = 0xffffffff;
#endif
#ifdef IBM
goto cont;
#else
break;
#endif
}
#ifndef ROUND_BIASED
if (!(word1 (rv) & LSB))
break;
#endif
if (dsign)
rv.d += ulp (rv.d);
#ifndef ROUND_BIASED
else
{
rv.d -= ulp (rv.d);
#ifndef Sudden_Underflow
if (!rv.d)
goto undfl;
#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 (FLT_ROUNDS)
{
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
}
y = word0 (rv) & Exp_mask;
/* Check for overflow */
if (y == Exp_msk1 * (DBL_MAX_EXP + Bias - 1))
{
rv0.d = rv.d;
word0 (rv) -= P * Exp_msk1;
adj = aadj1 * ulp (rv.d);
rv.d += adj;
if ((word0 (rv) & Exp_mask) >=
Exp_msk1 * (DBL_MAX_EXP + Bias - P))
{
if (word0 (rv0) == Big0 && word1 (rv0) == Big1)
goto ovfl;
#ifdef _DOUBLE_IS_32BITS
word0 (rv) = Big1;
#else
word0 (rv) = Big0;
word1 (rv) = Big1;
#endif
goto cont;
}
else
word0 (rv) += P * Exp_msk1;
}
else
{
#ifdef Sudden_Underflow
if ((word0 (rv) & Exp_mask) <= P * Exp_msk1)
{
rv0.d = rv.d;
word0 (rv) += P * Exp_msk1;
adj = aadj1 * ulp (rv.d);
rv.d += 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 (rv.d);
rv.d += adj;
}
#else
/* Compute adj so that the IEEE rounding rules will
* correctly round rv.d + adj in some half-way cases.
* If rv.d * ulp(rv.d) 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 (rv.d);
rv.d += adj;
#endif
}
z = word0 (rv) & Exp_mask;
if (y == z)
{
/* Can we stop now? */
L = 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;
}
cont:
Bfree (ptr, bb);
Bfree (ptr, bd);
Bfree (ptr, bs);
Bfree (ptr, delta);
}
retfree:
Bfree (ptr, bb);
Bfree (ptr, bd);
Bfree (ptr, bs);
Bfree (ptr, bd0);
Bfree (ptr, delta);
ret:
if (se)
*se = (char *) s;
return sign ? -rv.d : rv.d;
}
#ifndef NO_REENT
double
_DEFUN (strtod, (s00, se),
_CONST char *s00 _AND char **se)
{
return _strtod_r (_REENT, s00, se);
}
float
_DEFUN (strtodf, (s00, se),
_CONST char *s00 _AND
char **se)
{
return strtod (s00, se);
}
#endif

226
agbcc/libc/stdlib/strtol.c Normal file
View File

@ -0,0 +1,226 @@
/*
FUNCTION
<<strtol>>---string to long
INDEX
strtol
INDEX
_strtol_r
ANSI_SYNOPSIS
#include <stdlib.h>
long strtol(const char *<[s]>, char **<[ptr]>,int <[base]>);
long _strtol_r(void *<[reent]>,
const char *<[s]>, char **<[ptr]>,int <[base]>);
TRAD_SYNOPSIS
#include <stdlib.h>
long strtol (<[s]>, <[ptr]>, <[base]>)
char *<[s]>;
char **<[ptr]>;
int <[base]>;
long _strtol_r (<[reent]>, <[s]>, <[ptr]>, <[base]>)
char *<[reent]>;
char *<[s]>;
char **<[ptr]>;
int <[base]>;
DESCRIPTION
The function <<strtol>> converts the string <<*<[s]>>> to
a <<long>>. First, it breaks down the string into three parts:
leading whitespace, which is ignored; a subject string consisting
of characters resembling an integer in the radix specified by <[base]>;
and a trailing portion consisting of zero or more unparseable characters,
and always including the terminating null character. Then, it attempts
to convert the subject string into a <<long>> and returns the
result.
If the value of <[base]> is 0, the subject string is expected to look
like a normal C integer constant: an optional sign, a possible `<<0x>>'
indicating a hexadecimal base, and a number. If <[base]> is between
2 and 36, the expected form of the subject is a sequence of letters
and digits representing an integer in the radix specified by <[base]>,
with an optional plus or minus sign. The letters <<a>>--<<z>> (or,
equivalently, <<A>>--<<Z>>) are used to signify values from 10 to 35;
only letters whose ascribed values are less than <[base]> are
permitted. If <[base]> is 16, a leading <<0x>> is permitted.
The subject sequence is the longest initial sequence of the input
string that has the expected form, starting with the first
non-whitespace character. If the string is empty or consists entirely
of whitespace, or if the first non-whitespace character is not a
permissible letter or digit, the subject string is empty.
If the subject string is acceptable, and the value of <[base]> is zero,
<<strtol>> attempts to determine the radix from the input string. A
string with a leading <<0x>> is treated as a hexadecimal value; a string with
a leading 0 and no <<x>> is treated as octal; all other strings are
treated as decimal. If <[base]> is between 2 and 36, it is used as the
conversion radix, as described above. If the subject string begins with
a minus sign, the value is negated. Finally, a pointer to the first
character past the converted subject string is stored in <[ptr]>, if
<[ptr]> is not <<NULL>>.
If the subject string is empty (or not in acceptable form), no conversion
is performed and the value of <[s]> is stored in <[ptr]> (if <[ptr]> is
not <<NULL>>).
The alternate function <<_strtol_r>> is a reentrant version. The
extra argument <[reent]> is a pointer to a reentrancy structure.
RETURNS
<<strtol>> returns the converted value, if any. If no conversion was
made, 0 is returned.
<<strtol>> returns <<LONG_MAX>> or <<LONG_MIN>> if the magnitude of
the converted value is too large, and sets <<errno>> to <<ERANGE>>.
PORTABILITY
<<strtol>> is ANSI.
No supporting OS subroutines are required.
*/
/*-
* Copyright (c) 1990 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.
*/
#include <_ansi.h>
#include <limits.h>
#include <ctype.h>
#include <errno.h>
#include <stdlib.h>
#include <reent.h>
/*
* Convert a string to a long integer.
*
* Ignores `locale' stuff. Assumes that the upper and lower case
* alphabets and digits are each contiguous.
*/
long
_DEFUN (_strtol_r, (rptr, nptr, endptr, base),
struct _reent *rptr _AND
_CONST char *nptr _AND
char **endptr _AND
int base)
{
register const char *s = nptr;
register unsigned long acc;
register int c;
register unsigned long cutoff;
register int neg = 0, any, cutlim;
/*
* Skip white space and pick up leading +/- sign if any.
* If base is 0, allow 0x for hex and 0 for octal, else
* assume decimal; if base is already 16, allow 0x.
*/
do {
c = *s++;
} while (isspace(c));
if (c == '-') {
neg = 1;
c = *s++;
} else if (c == '+')
c = *s++;
if ((base == 0 || base == 16) &&
c == '0' && (*s == 'x' || *s == 'X')) {
c = s[1];
s += 2;
base = 16;
}
if (base == 0)
base = c == '0' ? 8 : 10;
/*
* Compute the cutoff value between legal numbers and illegal
* numbers. That is the largest legal value, divided by the
* base. An input number that is greater than this value, if
* followed by a legal input character, is too big. One that
* is equal to this value may be valid or not; the limit
* between valid and invalid numbers is then based on the last
* digit. For instance, if the range for longs is
* [-2147483648..2147483647] and the input base is 10,
* cutoff will be set to 214748364 and cutlim to either
* 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
* a value > 214748364, or equal but the next digit is > 7 (or 8),
* the number is too big, and we will return a range error.
*
* Set any if any `digits' consumed; make it negative to indicate
* overflow.
*/
cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX;
cutlim = cutoff % (unsigned long)base;
cutoff /= (unsigned long)base;
for (acc = 0, any = 0;; c = *s++) {
if (isdigit(c))
c -= '0';
else if (isalpha(c))
c -= isupper(c) ? 'A' - 10 : 'a' - 10;
else
break;
if (c >= base)
break;
if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim)
any = -1;
else {
any = 1;
acc *= base;
acc += c;
}
}
if (any < 0) {
acc = neg ? LONG_MIN : LONG_MAX;
rptr->_errno = ERANGE;
} else if (neg)
acc = -acc;
if (endptr != 0)
*endptr = (char *) (any ? s - 1 : nptr);
return (acc);
}
#ifndef _REENT_ONLY
long
_DEFUN (strtol, (s, ptr, base),
_CONST char *s _AND
char **ptr _AND
int base)
{
return _strtol_r (_REENT, s, ptr, base);
}
#endif

206
agbcc/libc/stdlib/strtoul.c Normal file
View File

@ -0,0 +1,206 @@
/*
FUNCTION
<<strtoul>>---string to unsigned long
INDEX
strtoul
INDEX
_strtoul_r
ANSI_SYNOPSIS
#include <stdlib.h>
unsigned long strtoul(const char *<[s]>, char **<[ptr]>,
int <[base]>);
unsigned long _strtoul_r(void *<[reent]>, const char *<[s]>,
char **<[ptr]>, int <[base]>);
TRAD_SYNOPSIS
#include <stdlib.h>
unsigned long strtoul(<[s]>, <[ptr]>, <[base]>)
char *<[s]>;
char **<[ptr]>;
int <[base]>;
unsigned long _strtoul_r(<[reent]>, <[s]>, <[ptr]>, <[base]>)
char *<[reent]>;
char *<[s]>;
char **<[ptr]>;
int <[base]>;
DESCRIPTION
The function <<strtoul>> converts the string <<*<[s]>>> to
an <<unsigned long>>. First, it breaks down the string into three parts:
leading whitespace, which is ignored; a subject string consisting
of the digits meaningful in the radix specified by <[base]>
(for example, <<0>> through <<7>> if the value of <[base]> is 8);
and a trailing portion consisting of one or more unparseable characters,
which always includes the terminating null character. Then, it attempts
to convert the subject string into an unsigned long integer, and returns the
result.
If the value of <[base]> is zero, the subject string is expected to look
like a normal C integer constant (save that no optional sign is permitted):
a possible <<0x>> indicating hexadecimal radix, and a number.
If <[base]> is between 2 and 36, the expected form of the subject is a
sequence of digits (which may include letters, depending on the
base) representing an integer in the radix specified by <[base]>.
The letters <<a>>--<<z>> (or <<A>>--<<Z>>) are used as digits valued from
10 to 35. If <[base]> is 16, a leading <<0x>> is permitted.
The subject sequence is the longest initial sequence of the input
string that has the expected form, starting with the first
non-whitespace character. If the string is empty or consists entirely
of whitespace, or if the first non-whitespace character is not a
permissible digit, the subject string is empty.
If the subject string is acceptable, and the value of <[base]> is zero,
<<strtoul>> attempts to determine the radix from the input string. A
string with a leading <<0x>> is treated as a hexadecimal value; a string with
a leading <<0>> and no <<x>> is treated as octal; all other strings are
treated as decimal. If <[base]> is between 2 and 36, it is used as the
conversion radix, as described above. Finally, a pointer to the first
character past the converted subject string is stored in <[ptr]>, if
<[ptr]> is not <<NULL>>.
If the subject string is empty (that is, if <<*>><[s]> does not start
with a substring in acceptable form), no conversion
is performed and the value of <[s]> is stored in <[ptr]> (if <[ptr]> is
not <<NULL>>).
The alternate function <<_strtoul_r>> is a reentrant version. The
extra argument <[reent]> is a pointer to a reentrancy structure.
RETURNS
<<strtoul>> returns the converted value, if any. If no conversion was
made, <<0>> is returned.
<<strtoul>> returns <<ULONG_MAX>> if the magnitude of the converted
value is too large, and sets <<errno>> to <<ERANGE>>.
PORTABILITY
<<strtoul>> is ANSI.
<<strtoul>> requires no supporting OS subroutines.
*/
/*
* Copyright (c) 1990 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.
*/
#include <_ansi.h>
#include <limits.h>
#include <ctype.h>
#include <errno.h>
#include <stdlib.h>
#include <reent.h>
/*
* Convert a string to an unsigned long integer.
*
* Ignores `locale' stuff. Assumes that the upper and lower case
* alphabets and digits are each contiguous.
*/
unsigned long
_DEFUN (_strtoul_r, (rptr, nptr, endptr, base),
struct _reent *rptr _AND
_CONST char *nptr _AND
char **endptr _AND
int base)
{
register const char *s = nptr;
register unsigned long acc;
register int c;
register unsigned long cutoff;
register int neg = 0, any, cutlim;
/*
* See strtol for comments as to the logic used.
*/
do {
c = *s++;
} while (isspace(c));
if (c == '-') {
neg = 1;
c = *s++;
} else if (c == '+')
c = *s++;
if ((base == 0 || base == 16) &&
c == '0' && (*s == 'x' || *s == 'X')) {
c = s[1];
s += 2;
base = 16;
}
if (base == 0)
base = c == '0' ? 8 : 10;
cutoff = (unsigned long)ULONG_MAX / (unsigned long)base;
cutlim = (unsigned long)ULONG_MAX % (unsigned long)base;
for (acc = 0, any = 0;; c = *s++) {
if (isdigit(c))
c -= '0';
else if (isalpha(c))
c -= isupper(c) ? 'A' - 10 : 'a' - 10;
else
break;
if (c >= base)
break;
if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim)
any = -1;
else {
any = 1;
acc *= base;
acc += c;
}
}
if (any < 0) {
acc = ULONG_MAX;
rptr->_errno = ERANGE;
} else if (neg)
acc = -acc;
if (endptr != 0)
*endptr = (char *) (any ? s - 1 : nptr);
return (acc);
}
#ifndef _REENT_ONLY
unsigned long
_DEFUN (strtoul, (s, ptr, base),
_CONST char *s _AND
char **ptr _AND
int base)
{
return _strtoul_r (_REENT, s, ptr, base);
}
#endif

179
agbcc/libc/stdlib/system.c Normal file
View File

@ -0,0 +1,179 @@
/*
FUNCTION
<<system>>---execute command string
INDEX
system
INDEX
_system_r
ANSI_SYNOPSIS
#include <stdlib.h>
int system(char *<[s]>);
int _system_r(void *<[reent]>, char *<[s]>);
TRAD_SYNOPSIS
#include <stdlib.h>
int system(<[s]>)
char *<[s]>;
int _system_r(<[reent]>, <[s]>)
char *<[reent]>;
char *<[s]>;
DESCRIPTION
Use <<system>> to pass a command string <<*<[s]>>> to <</bin/sh>> on
your system, and wait for it to finish executing.
Use `<<system(NULL)>>' to test whether your system has <</bin/sh>>
available.
The alternate function <<_system_r>> is a reentrant version. The
extra argument <[reent]> is a pointer to a reentrancy structure.
RETURNS
<<system(NULL)>> returns a non-zero value if <</bin/sh>> is available, and
<<0>> if it is not.
With a command argument, the result of <<system>> is the exit status
returned by <</bin/sh>>.
PORTABILITY
ANSI C requires <<system>>, but leaves the nature and effects of a
command processor undefined. ANSI C does, however, specify that
<<system(NULL)>> return zero or nonzero to report on the existence of
a command processor.
POSIX.2 requires <<system>>, and requires that it invoke a <<sh>>.
Where <<sh>> is found is left unspecified.
Supporting OS subroutines required: <<_exit>>, <<_execve>>, <<_fork_r>>,
<<_wait_r>>.
*/
#include <errno.h>
#include <stddef.h>
#include <stdlib.h>
#include <_syslist.h>
#if defined (unix) || defined (__CYGWIN32__)
static int do_system ();
#endif
int
_system_r (ptr, s)
struct _reent *ptr;
_CONST char *s;
{
#ifdef NO_EXEC
if (s == NULL)
return 0;
errno = ENOSYS;
return -1;
#else
/* ??? How to handle (s == NULL) here is not exactly clear.
If _fork_r fails, that's not really a justification for returning 0.
For now we always return 0 and leave it to each target to explicitly
handle otherwise (this can always be relaxed in the future). */
#if defined (unix) || defined (__CYGWIN32__)
if (s == NULL)
return 1;
return do_system (ptr, s);
#else
if (s == NULL)
return 0;
errno = ENOSYS;
return -1;
#endif
#endif
}
#ifndef _REENT_ONLY
int
system (s)
_CONST char *s;
{
return _system_r (_REENT, s);
}
#endif
#if defined (unix) && !defined (__CYGWIN32__)
static int
do_system (ptr, s)
struct _reent *ptr;
_CONST char *s;
{
char *argv[4];
int pid, status;
extern char *environ[];
argv[0] = "sh";
argv[1] = "-c";
argv[2] = (char *) s;
argv[3] = NULL;
if ((pid = _fork_r (ptr)) == 0)
{
_execve ("/bin/sh", argv, environ);
exit (100);
}
else if (pid == -1)
return -1;
else
{
int rc = _wait_r (ptr, &status);
if (rc == -1)
return -1;
status = (status >> 8) & 0xff;
return status;
}
}
#endif
#if defined (__CYGWIN32__)
static int
do_system (ptr, s)
struct _reent *ptr;
_CONST char *s;
{
char *argv[4];
int pid, status;
extern char *environ[];
argv[0] = "sh";
argv[1] = "-c";
argv[2] = (char *) s;
argv[3] = NULL;
if ((pid = vfork ()) == 0)
{
/* ??? It's not clear what's the right path to take (pun intended :-).
There won't be an "sh" in any fixed location so we need each user
to be able to say where to find "sh". That suggests using an
environment variable, but after a few more such situations we may
have too many of them. */
char *sh = getenv ("SH_PATH");
if (sh == NULL)
sh = "/bin/sh";
_execve (sh, argv, environ);
exit (100);
}
else if (pid == -1)
return -1;
else
{
int rc = _wait (&status);
if (rc == -1)
return -1;
status = (status >> 8) & 0xff;
return status;
}
}
#endif

View File

@ -0,0 +1,24 @@
/* valloc.c -- a wrapper for valloc_r and pvalloc_r. */
#include <_ansi.h>
#include <reent.h>
#include <stdlib.h>
#include <malloc.h>
#ifndef _REENT_ONLY
_PTR
_DEFUN (valloc, (nbytes),
size_t nbytes)
{
return _valloc_r (_REENT, nbytes);
}
_PTR
_DEFUN (pvalloc, (nbytes),
size_t nbytes)
{
return _pvalloc_r (_REENT, nbytes);
}
#endif

View File

@ -0,0 +1,79 @@
/*
FUNCTION
<<wcstombs>>---minimal wide char string to multibyte string converter
INDEX
wcstombs
ANSI_SYNOPSIS
#include <stdlib.h>
int wcstombs(const char *<[s]>, wchar_t *<[pwc]>, size_t <[n]>);
TRAD_SYNOPSIS
#include <stdlib.h>
int wcstombs(<[s]>, <[pwc]>, <[n]>)
const char *<[s]>;
wchar_t *<[pwc]>;
size_t <[n]>;
DESCRIPTION
When MB_CAPABLE is not defined, this is a minimal ANSI-conforming
implementation of <<wcstombs>>. In this case,
all wide-characters are expected to represent single bytes and so
are converted simply by casting to char.
When MB_CAPABLE is defined, this routine calls <<_wcstombs_r>> to perform
the conversion, passing a state variable to allow state dependent
decoding. The result is based on the locale setting which may
be restricted to a defined set of locales.
RETURNS
This implementation of <<wcstombs>> returns <<0>> if
<[s]> is <<NULL>> or is the empty string;
it returns <<-1>> if MB_CAPABLE and one of the
wide-char characters does not represent a valid multi-byte character;
otherwise it returns the minimum of: <<n>> or the
number of bytes that are transferred to <<s>>, not including the
nul terminator.
If the return value is -1, the state of the <<pwc>> string is
indeterminate. If the input has a length of 0, the output
string will be modified to contain a wchar_t nul terminator if
<<n>> > 0.
PORTABILITY
<<wcstombs>> is required in the ANSI C standard. However, the precise
effects vary with the locale.
<<wcstombs>> requires no supporting OS subroutines.
*/
#include <stdlib.h>
size_t
_DEFUN (wcstombs, (s, pwcs, n),
char *s _AND
const wchar_t *pwcs _AND
size_t n)
{
#ifdef MB_CAPABLE
int state = 0;
return _wcstombs_r (_REENT, s, pwcs, n, &state);
#else /* not MB_CAPABLE */
int count = 0;
if (n != 0) {
do {
if ((*s++ = (char) *pwcs++) == 0)
break;
count++;
} while (--n != 0);
}
return count;
#endif /* not MB_CAPABLE */
}

View File

@ -0,0 +1,32 @@
#include <stdlib.h>
size_t
_DEFUN (_wcstombs_r, (reent, s, pwcs, n, state),
struct _reent *r _AND
char *s _AND
const wchar_t *pwcs _AND
size_t n _AND
int *state)
{
char *ptr = s;
size_t max = n;
char buff[8];
int i, num_to_copy;
while (n > 0)
{
int bytes = _wctomb_r (r, buff, *pwcs, state);
if (bytes == -1)
return -1;
num_to_copy = (n > bytes ? bytes : (int)n);
for (i = 0; i < num_to_copy; ++i)
*ptr++ = buff[i];
if (*pwcs == 0x00)
return ptr - s - (n >= bytes);
++pwcs;
n -= num_to_copy;
}
return max;
}

View File

@ -0,0 +1,64 @@
/*
FUNCTION
<<wctomb>>---minimal wide char to multibyte converter
INDEX
wctomb
ANSI_SYNOPSIS
#include <stdlib.h>
int wctomb(char *<[s]>, wchar_t <[wchar]>);
TRAD_SYNOPSIS
#include <stdlib.h>
int wctomb(<[s]>, <[wchar]>)
char *<[s]>;
wchar_t <[wchar]>;
DESCRIPTION
When MB_CAPABLE is not defined, this is a minimal ANSI-conforming
implementation of <<wctomb>>. The
only ``wide characters'' recognized are single bytes,
and they are ``converted'' to themselves.
When MB_CAPABLE is defined, this routine calls <<_wctomb_r>> to perform
the conversion, passing a state variable to allow state dependent
decoding. The result is based on the locale setting which may
be restricted to a defined set of locales.
Each call to <<wctomb>> modifies <<*<[s]>>> unless <[s]> is a null
pointer or MB_CAPABLE is defined and <[wchar]> is invalid.
RETURNS
This implementation of <<wctomb>> returns <<0>> if
<[s]> is <<NULL>>; it returns <<-1>> if MB_CAPABLE is enabled
and the wchar is not a valid multi-byte character, it returns <<1>>
if MB_CAPABLE is not defined or the wchar is in reality a single
byte character, otherwise it returns the number of bytes in the
multi-byte character.
PORTABILITY
<<wctomb>> is required in the ANSI C standard. However, the precise
effects vary with the locale.
<<wctomb>> requires no supporting OS subroutines.
*/
#include <stdlib.h>
int
_DEFUN (wctomb, (s, wchar),
char *s _AND
wchar_t wchar)
{
#ifdef MB_CAPABLE
static int state;
return _wctomb_r (_REENT, s, wchar, &state);
#else /* not MB_CAPABLE */
if (s == NULL)
return 0;
*s = (char) wchar;
return 1;
#endif /* not MB_CAPABLE */
}

View File

@ -0,0 +1,110 @@
#include <stdlib.h>
#include <locale.h>
#include "mbctype.h"
int
_DEFUN (_wctomb_r, (r, s, wchar, state),
struct _reent *r _AND
char *s _AND
wchar_t wchar _AND
int *state)
{
if (strlen (r->_current_locale) <= 1)
{ /* fall-through */ }
else if (!strcmp (r->_current_locale, "C-SJIS"))
{
unsigned char char2 = (unsigned char)wchar;
unsigned char char1 = (unsigned char)(wchar >> 8);
if (s == NULL)
return 0; /* not state-dependent */
if (char1 != 0x00)
{
/* first byte is non-zero..validate multi-byte char */
if (_issjis1(char1) && _issjis2(char2))
{
*s++ = (char)char1;
*s = (char)char2;
return 2;
}
else
return -1;
}
}
else if (!strcmp (r->_current_locale, "C-EUCJP"))
{
unsigned char char2 = (unsigned char)wchar;
unsigned char char1 = (unsigned char)(wchar >> 8);
if (s == NULL)
return 0; /* not state-dependent */
if (char1 != 0x00)
{
/* first byte is non-zero..validate multi-byte char */
if (_iseucjp (char1) && _iseucjp (char2))
{
*s++ = (char)char1;
*s = (char)char2;
return 2;
}
else
return -1;
}
}
else if (!strcmp (r->_current_locale, "C-JIS"))
{
int cnt = 0;
unsigned char char2 = (unsigned char)wchar;
unsigned char char1 = (unsigned char)(wchar >> 8);
if (s == NULL)
return 1; /* state-dependent */
if (char1 != 0x00)
{
/* first byte is non-zero..validate multi-byte char */
if (_isjis (char1) && _isjis (char2))
{
if (*state == 0)
{
/* must switch from ASCII to JIS state */
*state = 1;
*s++ = ESC_CHAR;
*s++ = '$';
*s++ = 'B';
cnt = 3;
}
*s++ = (char)char1;
*s = (char)char2;
return cnt + 2;
}
else
return -1;
}
else
{
if (*state != 0)
{
/* must switch from JIS to ASCII state */
*state = 0;
*s++ = ESC_CHAR;
*s++ = '(';
*s++ = 'B';
cnt = 3;
}
*s = (char)char2;
return cnt + 1;
}
}
if (s == NULL)
return 0;
/* otherwise we are dealing with a single byte character */
*s = (char) wchar;
return 1;
}

50
agbcc/libc/string/bcmp.c Normal file
View File

@ -0,0 +1,50 @@
/*
FUNCTION
<<bcmp>>---compare two memory areas
INDEX
bcmp
ANSI_SYNOPSIS
#include <string.h>
int bcmp(const char *<[s1]>, const char *<[s2]>, size_t <[n]>);
TRAD_SYNOPSIS
#include <string.h>
int bcmp(<[s1]>, <[s2]>, <[n]>)
char *<[s1]>;
char *<[s2]>;
size_t <[n]>;
DESCRIPTION
This function compares not more than <[n]> characters of the
object pointed to by <[s1]> with the object pointed to by <[s2]>.
This function is identical to <<memcmp>>.
RETURNS
The function returns an integer greater than, equal to or
less than zero according to whether the object pointed to by
<[s1]> is greater than, equal to or less than the object
pointed to by <[s2]>.
PORTABILITY
<<bcmp>> requires no supporting OS subroutines.
QUICKREF
bcmp ansi pure
*/
#include <string.h>
int
_DEFUN (bcmp, (m1, m2, n),
_CONST char *m1 _AND
_CONST char *m2 _AND
size_t n)
{
return memcmp (m1, m2, n);
}

38
agbcc/libc/string/bcopy.c Normal file
View File

@ -0,0 +1,38 @@
/*
FUNCTION
<<bcopy>>---copy memory regions
ANSI_SYNOPSIS
#include <string.h>
void bcopy(const char *<[in]>, char *<[out]>, size_t <[n]>);
TRAD_SYNOPSIS
void bcopy(<[in]>, <[out]>, <[n]>
char *<[in]>;
char *<[out]>;
size_t <[n]>;
DESCRIPTION
This function copies <[n]> bytes from the memory region
pointed to by <[in]> to the memory region pointed to by
<[out]>.
This function is implemented in term of <<memmove>>.
PORTABILITY
<<bcopy>> requires no supporting OS subroutines.
QUICKREF
bcopy - pure
*/
#include <string.h>
void
_DEFUN (bcopy, (b1, b2, length),
_CONST char *b1 _AND
char *b2 _AND
size_t length)
{
memmove ((_PTR) b2, (_PTR) b1, length);
}

42
agbcc/libc/string/bzero.c Normal file
View File

@ -0,0 +1,42 @@
/*
FUNCTION
<<bzero>>---initialize memory to zero
INDEX
bzero
ANSI_SYNOPSIS
#include <string.h>
void bzero(char *<[b]>, size_t <[length]>);
TRAD_SYNOPSIS
#include <string.h>
void bzero(<[b]>, <[length]>)
char *<[b]>;
size_t <[length]>;
DESCRIPTION
<<bzero>> initializes <[length]> bytes of memory, starting at address
<[b]>, to zero.
RETURNS
<<bzero>> does not return a result.
PORTABILITY
<<bzero>> is in the Berkeley Software Distribution.
Neither ANSI C nor the System V Interface Definition (Issue 2) require
<<bzero>>.
<<bzero>> requires no supporting OS subroutines.
*/
#include <string.h>
_VOID
_DEFUN (bzero, (b, length),
char *b _AND
size_t length)
{
while (length--)
*b++ = 0;
}

44
agbcc/libc/string/index.c Normal file
View File

@ -0,0 +1,44 @@
/*
FUNCTION
<<index>>---search for character in string
INDEX
index
ANSI_SYNOPSIS
#include <string.h>
char * index(const char *<[string]>, int <[c]>);
TRAD_SYNOPSIS
#include <string.h>
char * index(<[string]>, <[c]>);
char *<[string]>;
int *<[c]>;
DESCRIPTION
This function finds the first occurence of <[c]> (converted to
a char) in the string pointed to by <[string]> (including the
terminating null character).
This function is identical to <<strchr>>.
RETURNS
Returns a pointer to the located character, or a null pointer
if <[c]> does not occur in <[string]>.
PORTABILITY
<<index>> requires no supporting OS subroutines.
QUICKREF
index - pure
*/
#include <string.h>
char *
_DEFUN (index, (s, c),
_CONST char *s _AND
int c)
{
return strchr (s, c);
}

143
agbcc/libc/string/memchr.c Normal file
View File

@ -0,0 +1,143 @@
/*
FUNCTION
<<memchr>>---find character in memory
INDEX
memchr
ANSI_SYNOPSIS
#include <string.h>
void *memchr(const void *<[src]>, int <[c]>, size_t <[length]>);
TRAD_SYNOPSIS
#include <string.h>
void *memchr(<[src]>, <[c]>, <[length]>)
void *<[src]>;
void *<[c]>;
size_t <[length]>;
DESCRIPTION
This function searches memory starting at <<*<[src]>>> for the
character <[c]>. The search only ends with the first
occurrence of <[c]>, or after <[length]> characters; in
particular, <<NULL>> does not terminate the search.
RETURNS
If the character <[c]> is found within <[length]> characters
of <<*<[src]>>>, a pointer to the character is returned. If
<[c]> is not found, then <<NULL>> is returned.
PORTABILITY
<<memchr>>> is ANSI C.
<<memchr>> requires no supporting OS subroutines.
QUICKREF
memchr ansi pure
*/
#include <_ansi.h>
#include <string.h>
#include <limits.h>
/* Nonzero if either X or Y is not aligned on a "long" boundary. */
#define UNALIGNED(X) ((long)X & (sizeof (long) - 1))
/* How many bytes are loaded each iteration of the word copy loop. */
#define LBLOCKSIZE (sizeof (long))
/* Threshhold for punting to the bytewise iterator. */
#define TOO_SMALL(LEN) ((LEN) < LBLOCKSIZE)
#if LONG_MAX == 2147483647L
#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
#else
#if LONG_MAX == 9223372036854775807L
/* Nonzero if X (a long int) contains a NULL byte. */
#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
#else
#error long int is not a 32bit or 64bit type.
#endif
#endif
#ifndef DETECTNULL
#error long int is not a 32bit or 64bit byte
#endif
_PTR
_DEFUN (memchr, (src_void, c, length),
_CONST _PTR src_void _AND
int c _AND
size_t length)
{
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
_CONST unsigned char *src = (_CONST unsigned char *) src_void;
c &= 0xff;
while (length--)
{
if (*src == c)
return (char *) src;
src++;
}
return NULL;
#else
_CONST unsigned char *src = (_CONST unsigned char *) src_void;
unsigned long *asrc;
unsigned long buffer;
unsigned long mask;
int i, j;
c &= 0xff;
/* If the size is small, or src is unaligned, then
use the bytewise loop. We can hope this is rare. */
if (!TOO_SMALL (length) && !UNALIGNED (src))
{
/* The fast code reads the ASCII one word at a time and only
performs the bytewise search on word-sized segments if they
contain the search character, which is detected by XORing
the word-sized segment with a word-sized block of the search
character and then detecting for the presence of NULL in the
result. */
asrc = (unsigned long*) src;
mask = 0;
for (i = 0; i < LBLOCKSIZE; i++)
mask = (mask << 8) + c;
while (length >= LBLOCKSIZE)
{
buffer = *asrc;
buffer ^= mask;
if (DETECTNULL (buffer))
{
src = (unsigned char*) asrc;
for ( j = 0; j < LBLOCKSIZE; j++ )
{
if (*src == c)
return (char*) src;
src++;
}
}
length -= LBLOCKSIZE;
asrc++;
}
/* If there are fewer than LBLOCKSIZE characters left,
then we resort to the bytewise loop. */
src = (unsigned char*) asrc;
}
while (length--)
{
if (*src == c)
return (char*) src;
src++;
}
return NULL;
#endif /* not PREFER_SIZE_OVER_SPEED */
}

113
agbcc/libc/string/memcmp.c Normal file
View File

@ -0,0 +1,113 @@
/*
FUNCTION
<<memcmp>>---compare two memory areas
INDEX
memcmp
ANSI_SYNOPSIS
#include <string.h>
int memcmp(const void *<[s1]>, const void *<[s2]>, size_t <[n]>);
TRAD_SYNOPSIS
#include <string.h>
int memcmp(<[s1]>, <[s2]>, <[n]>)
void *<[s1]>;
void *<[s2]>;
size_t <[n]>;
DESCRIPTION
This function compares not more than <[n]> characters of the
object pointed to by <[s1]> with the object pointed to by <[s2]>.
RETURNS
The function returns an integer greater than, equal to or
less than zero according to whether the object pointed to by
<[s1]> is greater than, equal to or less than the object
pointed to by <[s2]>.
PORTABILITY
<<memcmp>> is ANSI C.
<<memcmp>> requires no supporting OS subroutines.
QUICKREF
memcmp ansi pure
*/
#include <string.h>
/* Nonzero if either X or Y is not aligned on a "long" boundary. */
#define UNALIGNED(X, Y) \
(((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
/* How many bytes are copied each iteration of the word copy loop. */
#define LBLOCKSIZE (sizeof (long))
/* Threshhold for punting to the byte copier. */
#define TOO_SMALL(LEN) ((LEN) < LBLOCKSIZE)
int
_DEFUN (memcmp, (m1, m2, n),
_CONST _PTR m1 _AND
_CONST _PTR m2 _AND
size_t n)
{
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
unsigned char *s1 = (unsigned char *) m1;
unsigned char *s2 = (unsigned char *) m2;
while (n--)
{
if (*s1 != *s2)
{
return *s1 - *s2;
}
s1++;
s2++;
}
return 0;
#else
unsigned char *s1 = (unsigned char *) m1;
unsigned char *s2 = (unsigned char *) m2;
unsigned long *a1;
unsigned long *a2;
/* If the size is too small, or either pointer is unaligned,
then we punt to the byte compare loop. Hopefully this will
not turn up in inner loops. */
if (!TOO_SMALL(n) && !UNALIGNED(s1,s2))
{
/* Otherwise, load and compare the blocks of memory one
word at a time. */
a1 = (unsigned long*) s1;
a2 = (unsigned long*) s2;
while (n >= LBLOCKSIZE)
{
if (*a1 != *a2)
break;
a1++;
a2++;
n -= LBLOCKSIZE;
}
/* check m mod LBLOCKSIZE remaining characters */
s1 = (char*)a1;
s2 = (char*)a2;
}
while (n--)
{
if (*s1 != *s2)
return *s1 - *s2;
s1++;
s2++;
}
return 0;
#endif /* not PREFER_SIZE_OVER_SPEED */
}

111
agbcc/libc/string/memcpy.c Normal file
View File

@ -0,0 +1,111 @@
/*
FUNCTION
<<memcpy>>---copy memory regions
ANSI_SYNOPSIS
#include <string.h>
void* memcpy(void *<[out]>, const void *<[in]>, size_t <[n]>);
TRAD_SYNOPSIS
void *memcpy(<[out]>, <[in]>, <[n]>
void *<[out]>;
void *<[in]>;
size_t <[n]>;
DESCRIPTION
This function copies <[n]> bytes from the memory region
pointed to by <[in]> to the memory region pointed to by
<[out]>.
If the regions overlap, the behavior is undefined.
RETURNS
<<memcpy>> returns a pointer to the first byte of the <[out]>
region.
PORTABILITY
<<memcpy>> is ANSI C.
<<memcpy>> requires no supporting OS subroutines.
QUICKREF
memcpy ansi pure
*/
#include <_ansi.h>
#include <stddef.h>
#include <limits.h>
/* Nonzero if either X or Y is not aligned on a "long" boundary. */
#define UNALIGNED(X, Y) \
(((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
/* How many bytes are copied each iteration of the 4X unrolled loop. */
#define BIGBLOCKSIZE (sizeof (long) << 2)
/* How many bytes are copied each iteration of the word copy loop. */
#define LITTLEBLOCKSIZE (sizeof (long))
/* Threshhold for punting to the byte copier. */
#define TOO_SMALL(LEN) ((LEN) < BIGBLOCKSIZE)
_PTR
_DEFUN (memcpy, (dst0, src0, len0),
_PTR dst0 _AND
_CONST _PTR src0 _AND
size_t len0)
{
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
char *dst = (char *) dst0;
char *src = (char *) src0;
_PTR save = dst0;
while (len0--)
{
*dst++ = *src++;
}
return save;
#else
char *dst = dst0;
_CONST char *src = src0;
long *aligned_dst;
_CONST long *aligned_src;
int len = len0;
/* If the size is small, or either SRC or DST is unaligned,
then punt into the byte copy loop. This should be rare. */
if (!TOO_SMALL(len) && !UNALIGNED (src, dst))
{
aligned_dst = (long*)dst;
aligned_src = (long*)src;
/* Copy 4X long words at a time if possible. */
while (len >= BIGBLOCKSIZE)
{
*aligned_dst++ = *aligned_src++;
*aligned_dst++ = *aligned_src++;
*aligned_dst++ = *aligned_src++;
*aligned_dst++ = *aligned_src++;
len -= BIGBLOCKSIZE;
}
/* Copy one long word at a time if possible. */
while (len >= LITTLEBLOCKSIZE)
{
*aligned_dst++ = *aligned_src++;
len -= LITTLEBLOCKSIZE;
}
/* Pick up any residual with a byte copier. */
dst = (char*)aligned_dst;
src = (char*)aligned_src;
}
while (len--)
*dst++ = *src++;
return dst0;
#endif /* not PREFER_SIZE_OVER_SPEED */
}

143
agbcc/libc/string/memmove.c Normal file
View File

@ -0,0 +1,143 @@
/*
FUNCTION
<<memmove>>---move possibly overlapping memory
INDEX
memmove
ANSI_SYNOPSIS
#include <string.h>
void *memmove(void *<[dst]>, const void *<[src]>, size_t <[length]>);
TRAD_SYNOPSIS
#include <string.h>
void *memmove(<[dst]>, <[src]>, <[length]>)
void *<[dst]>;
void *<[src]>;
size_t <[length]>;
DESCRIPTION
This function moves <[length]> characters from the block of
memory starting at <<*<[src]>>> to the memory starting at
<<*<[dst]>>>. <<memmove>> reproduces the characters correctly
at <<*<[dst]>>> even if the two areas overlap.
RETURNS
The function returns <[dst]> as passed.
PORTABILITY
<<memmove>> is ANSI C.
<<memmove>> requires no supporting OS subroutines.
QUICKREF
memmove ansi pure
*/
#include <string.h>
#include <_ansi.h>
#include <stddef.h>
#include <limits.h>
/* Nonzero if either X or Y is not aligned on a "long" boundary. */
#define UNALIGNED(X, Y) \
(((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
/* How many bytes are copied each iteration of the 4X unrolled loop. */
#define BIGBLOCKSIZE (sizeof (long) << 2)
/* How many bytes are copied each iteration of the word copy loop. */
#define LITTLEBLOCKSIZE (sizeof (long))
/* Threshhold for punting to the byte copier. */
#define TOO_SMALL(LEN) ((LEN) < BIGBLOCKSIZE)
/*SUPPRESS 20*/
_PTR
_DEFUN (memmove, (dst_void, src_void, length),
_PTR dst_void _AND
_CONST _PTR src_void _AND
size_t length)
{
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
char *dst = dst_void;
_CONST char *src = src_void;
if (src < dst && dst < src + length)
{
/* Have to copy backwards */
src += length;
dst += length;
while (length--)
{
*--dst = *--src;
}
}
else
{
while (length--)
{
*dst++ = *src++;
}
}
return dst_void;
#else
char *dst = dst_void;
_CONST char *src = src_void;
long *aligned_dst;
_CONST long *aligned_src;
int len = length;
if (src < dst && dst < src + len)
{
/* Destructive overlap...have to copy backwards */
src += len;
dst += len;
while (len--)
{
*--dst = *--src;
}
}
else
{
/* Use optimizing algorithm for a non-destructive copy to closely
match memcpy. If the size is small or either SRC or DST is unaligned,
then punt into the byte copy loop. This should be rare. */
if (!TOO_SMALL(len) && !UNALIGNED (src, dst))
{
aligned_dst = (long*)dst;
aligned_src = (long*)src;
/* Copy 4X long words at a time if possible. */
while (len >= BIGBLOCKSIZE)
{
*aligned_dst++ = *aligned_src++;
*aligned_dst++ = *aligned_src++;
*aligned_dst++ = *aligned_src++;
*aligned_dst++ = *aligned_src++;
len -= BIGBLOCKSIZE;
}
/* Copy one long word at a time if possible. */
while (len >= LITTLEBLOCKSIZE)
{
*aligned_dst++ = *aligned_src++;
len -= LITTLEBLOCKSIZE;
}
/* Pick up any residual with a byte copier. */
dst = (char*)aligned_dst;
src = (char*)aligned_src;
}
while (len--)
{
*dst++ = *src++;
}
}
return dst_void;
#endif /* not PREFER_SIZE_OVER_SPEED */
}

110
agbcc/libc/string/memset.c Normal file
View File

@ -0,0 +1,110 @@
/*
FUNCTION
<<memset>>---set an area of memory
INDEX
memset
ANSI_SYNOPSIS
#include <string.h>
void *memset(const void *<[dst]>, int <[c]>, size_t <[length]>);
TRAD_SYNOPSIS
#include <string.h>
void *memset(<[dst]>, <[c]>, <[length]>)
void *<[dst]>;
int <[c]>;
size_t <[length]>;
DESCRIPTION
This function converts the argument <[c]> into an unsigned
char and fills the first <[length]> characters of the array
pointed to by <[dst]> to the value.
RETURNS
<<memset>> returns the value of <[m]>.
PORTABILITY
<<memset>> is ANSI C.
<<memset>> requires no supporting OS subroutines.
QUICKREF
memset ansi pure
*/
#include <string.h>
#define LBLOCKSIZE (sizeof(long))
#define UNALIGNED(X) ((long)X & (LBLOCKSIZE - 1))
#define TOO_SMALL(LEN) ((LEN) < LBLOCKSIZE)
_PTR
_DEFUN (memset, (m, c, n),
_PTR m _AND
int c _AND
size_t n)
{
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
char *s = (char *) m;
while (n-- != 0)
{
*s++ = (char) c;
}
return m;
#else
char *s = (char *) m;
int count, i;
unsigned long buffer;
unsigned long *aligned_addr;
unsigned char *unaligned_addr;
if (!TOO_SMALL (n) && !UNALIGNED (m))
{
/* If we get this far, we know that n is large and m is word-aligned. */
aligned_addr = (unsigned long*)m;
/* Store C into each char sized location in BUFFER so that
we can set large blocks quickly. */
c &= 0xff;
if (LBLOCKSIZE == 4)
{
buffer = (c << 8) | c;
buffer |= (buffer << 16);
}
else
{
buffer = 0;
for (i = 0; i < LBLOCKSIZE; i++)
buffer = (buffer << 8) | c;
}
while (n >= LBLOCKSIZE*4)
{
*aligned_addr++ = buffer;
*aligned_addr++ = buffer;
*aligned_addr++ = buffer;
*aligned_addr++ = buffer;
n -= 4*LBLOCKSIZE;
}
while (n >= LBLOCKSIZE)
{
*aligned_addr++ = buffer;
n -= LBLOCKSIZE;
}
/* Pick up the remainder with a bytewise loop. */
s = (char*)aligned_addr;
}
while (n--)
{
*s++ = (char)c;
}
return m;
#endif /* not PREFER_SIZE_OVER_SPEED */
}

View File

@ -0,0 +1,44 @@
/*
FUNCTION
<<rindex>>---reverse search for character in string
INDEX
rindex
ANSI_SYNOPSIS
#include <string.h>
char * rindex(const char *<[string]>, int <[c]>);
TRAD_SYNOPSIS
#include <string.h>
char * rindex(<[string]>, <[c]>);
char *<[string]>;
int *<[c]>;
DESCRIPTION
This function finds the last occurence of <[c]> (converted to
a char) in the string pointed to by <[string]> (including the
terminating null character).
This function is identical to <<strrchr>>.
RETURNS
Returns a pointer to the located character, or a null pointer
if <[c]> does not occur in <[string]>.
PORTABILITY
<<rindex>> requires no supporting OS subroutines.
QUICKREF
rindex - pure
*/
#include <string.h>
char *
_DEFUN (rindex, (s, c),
_CONST char *s _AND
int c)
{
return strrchr (s, c);
}

View File

@ -0,0 +1,56 @@
/*
FUNCTION
<<strcasecmp>>---case insensitive character string compare
INDEX
strcasecmp
ANSI_SYNOPSIS
#include <string.h>
int strcasecmp(const char *<[a]>, const char *<[b]>);
TRAD_SYNOPSIS
#include <string.h>
int strcasecmp(<[a]>, <[b]>)
char *<[a]>;
char *<[b]>;
DESCRIPTION
<<strcasecmp>> compares the string at <[a]> to
the string at <[b]> in a case-insensitive manner.
RETURNS
If <<*<[a]>>> sorts lexicographically after <<*<[b]>>> (after
both are converted to upper case), <<strcasecmp>> returns a
number greater than zero. If the two strings match,
<<strcasecmp>> returns zero. If <<*<[a]>>> sorts
lexicographically before <<*<[b]>>>, <<strcasecmp>> returns a
number less than zero.
PORTABILITY
<<strcasecmp>> is in the Berkeley Software Distribution.
<<strcasecmp>> requires no supporting OS subroutines. It uses
tolower() from elsewhere in this library.
QUICKREF
strcasecmp
*/
#include <string.h>
#include <ctype.h>
int
_DEFUN (strcasecmp, (s1, s2),
_CONST char *s1 _AND
_CONST char *s2)
{
while (*s1 != '\0' && tolower(*s1) == tolower(*s2))
{
s1++;
s2++;
}
return tolower(*(unsigned char *) s1) - tolower(*(unsigned char *) s2);
}

104
agbcc/libc/string/strcat.c Normal file
View File

@ -0,0 +1,104 @@
/*
FUNCTION
<<strcat>>---concatenate strings
INDEX
strcat
ANSI_SYNOPSIS
#include <string.h>
char *strcat(char *<[dst]>, const char *<[src]>);
TRAD_SYNOPSIS
#include <string.h>
char *strcat(<[dst]>, <[src]>)
char *<[dst]>;
char *<[src]>;
DESCRIPTION
<<strcat>> appends a copy of the string pointed to by <[src]>
(including the terminating null character) to the end of the
string pointed to by <[dst]>. The initial character of
<[src]> overwrites the null character at the end of <[dst]>.
RETURNS
This function returns the initial value of <[dst]>
PORTABILITY
<<strcat>> is ANSI C.
<<strcat>> requires no supporting OS subroutines.
QUICKREF
strcat ansi pure
*/
#include <string.h>
#include <limits.h>
/* Nonzero if X is aligned on a "long" boundary. */
#define ALIGNED(X) \
(((long)X & (sizeof (long) - 1)) == 0)
#if LONG_MAX == 2147483647L
#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
#else
#if LONG_MAX == 9223372036854775807L
/* Nonzero if X (a long int) contains a NULL byte. */
#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
#else
#error long int is not a 32bit or 64bit type.
#endif
#endif
#ifndef DETECTNULL
#error long int is not a 32bit or 64bit byte
#endif
/*SUPPRESS 560*/
/*SUPPRESS 530*/
char *
_DEFUN (strcat, (s1, s2),
char *s1 _AND
_CONST char *s2)
{
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
char *s = s1;
while (*s1)
s1++;
while (*s1++ = *s2++)
;
return s;
#else
char *s = s1;
/* Skip over the data in s1 as quickly as possible. */
if (ALIGNED (s1))
{
unsigned long *aligned_s1 = (unsigned long *)s1;
while (!DETECTNULL (*aligned_s1))
aligned_s1++;
s1 = (char *)aligned_s1;
}
while (*s1)
s1++;
/* s1 now points to the its trailing null character, we can
just use strcpy to do the work for us now.
?!? We might want to just include strcpy here.
Also, this will cause many more unaligned string copies because
s1 is much less likely to be aligned. I don't know if its worth
tweaking strcpy to handle this better. */
strcpy (s1, s2);
return s;
#endif /* not PREFER_SIZE_OVER_SPEED */
}

108
agbcc/libc/string/strchr.c Normal file
View File

@ -0,0 +1,108 @@
/*
FUNCTION
<<strchr>>---search for character in string
INDEX
strchr
ANSI_SYNOPSIS
#include <string.h>
char * strchr(const char *<[string]>, int <[c]>);
TRAD_SYNOPSIS
#include <string.h>
char * strchr(<[string]>, <[c]>);
char *<[string]>;
int *<[c]>;
DESCRIPTION
This function finds the first occurence of <[c]> (converted to
a char) in the string pointed to by <[string]> (including the
terminating null character).
RETURNS
Returns a pointer to the located character, or a null pointer
if <[c]> does not occur in <[string]>.
PORTABILITY
<<strchr>> is ANSI C.
<<strchr>> requires no supporting OS subroutines.
QUICKREF
strchr ansi pure
*/
#include <string.h>
#include <limits.h>
/* Nonzero if X is not aligned on a "long" boundary. */
#define UNALIGNED(X) ((long)X & (sizeof (long) - 1))
/* How many bytes are loaded each iteration of the word copy loop. */
#define LBLOCKSIZE (sizeof (long))
#if LONG_MAX == 2147483647L
#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
#else
#if LONG_MAX == 9223372036854775807L
/* Nonzero if X (a long int) contains a NULL byte. */
#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
#else
#error long int is not a 32bit or 64bit type.
#endif
#endif
/* DETECTCHAR returns nonzero if (long)X contains the byte used
to fill (long)MASK. */
#define DETECTCHAR(X,MASK) (DETECTNULL(X ^ MASK))
char *
_DEFUN (strchr, (s1, i),
_CONST char *s1 _AND
int i)
{
_CONST unsigned char *s = (_CONST unsigned char *)s1;
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
unsigned char c = (unsigned int)i;
while (*s && *s != c)
{
s++;
}
if (*s != c)
{
s = NULL;
}
return (char *) s;
#else
unsigned char c = (unsigned char)i;
unsigned long mask,j;
unsigned long *aligned_addr;
if (!UNALIGNED (s))
{
mask = 0;
for (j = 0; j < LBLOCKSIZE; j++)
mask = (mask << 8) | c;
aligned_addr = (unsigned long*)s;
while (!DETECTNULL (*aligned_addr) && !DETECTCHAR (*aligned_addr, mask))
aligned_addr++;
/* The block of bytes currently pointed to by aligned_addr
contains either a null or the target char, or both. We
catch it using the bytewise search. */
s = (unsigned char*)aligned_addr;
}
while (*s && *s != c)
s++;
if (*s == c)
return (char *)s;
return NULL;
#endif /* not PREFER_SIZE_OVER_SPEED */
}

106
agbcc/libc/string/strcmp.c Normal file
View File

@ -0,0 +1,106 @@
/*
FUNCTION
<<strcmp>>---character string compare
INDEX
strcmp
ANSI_SYNOPSIS
#include <string.h>
int strcmp(const char *<[a]>, const char *<[b]>);
TRAD_SYNOPSIS
#include <string.h>
int strcmp(<[a]>, <[b]>)
char *<[a]>;
char *<[b]>;
DESCRIPTION
<<strcmp>> compares the string at <[a]> to
the string at <[b]>.
RETURNS
If <<*<[a]>>> sorts lexicographically after <<*<[b]>>>,
<<strcmp>> returns a number greater than zero. If the two
strings match, <<strcmp>> returns zero. If <<*<[a]>>>
sorts lexicographically before <<*<[b]>>>, <<strcmp>> returns a
number less than zero.
PORTABILITY
<<strcmp>> is ANSI C.
<<strcmp>> requires no supporting OS subroutines.
QUICKREF
strcmp ansi pure
*/
#include <string.h>
#include <limits.h>
/* Nonzero if either X or Y is not aligned on a "long" boundary. */
#define UNALIGNED(X, Y) \
(((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
/* DETECTNULL returns nonzero if (long)X contains a NULL byte. */
#if LONG_MAX == 2147483647L
#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
#else
#if LONG_MAX == 9223372036854775807L
#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
#else
#error long int is not a 32bit or 64bit type.
#endif
#endif
#ifndef DETECTNULL
#error long int is not a 32bit or 64bit byte
#endif
int
_DEFUN (strcmp, (s1, s2),
_CONST char *s1 _AND
_CONST char *s2)
{
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
while (*s1 != '\0' && *s1 == *s2)
{
s1++;
s2++;
}
return (*(unsigned char *) s1) - (*(unsigned char *) s2);
#else
unsigned long *a1;
unsigned long *a2;
/* If s1 or s2 are unaligned, then compare bytes. */
if (!UNALIGNED (s1, s2))
{
/* If s1 and s2 are word-aligned, compare them a word at a time. */
a1 = (unsigned long*)s1;
a2 = (unsigned long*)s2;
while (*a1 == *a2)
{
/* To get here, *a1 == *a2, thus if we find a null in *a1,
then the strings must be equal, so return zero. */
if (DETECTNULL (*a1))
return 0;
a1++;
a2++;
}
/* A difference was detected in last few bytes of s1, so search bytewise */
s1 = (char*)a1;
s2 = (char*)a2;
}
while (*s1 != '\0' && *s1 == *s2)
{
s1++;
s2++;
}
return (*(unsigned char *) s1) - (*(unsigned char *) s2);
#endif /* not PREFER_SIZE_OVER_SPEED */
}

View File

@ -0,0 +1,48 @@
/*
FUNCTION
<<strcoll>>---locale specific character string compare
INDEX
strcoll
ANSI_SYNOPSIS
#include <string.h>
int strcoll(const char *<[stra]>, const char * <[strb]>);
TRAD_SYNOPSIS
#include <string.h>
int strcoll(<[stra]>, <[strb]>)
char *<[stra]>;
char *<[strb]>;
DESCRIPTION
<<strcoll>> compares the string pointed to by <[stra]> to
the string pointed to by <[strb]>, using an interpretation
appropriate to the current <<LC_COLLATE>> state.
RETURNS
If the first string is greater than the second string,
<<strcoll>> returns a number greater than zero. If the two
strings are equivalent, <<strcoll>> returns zero. If the first
string is less than the second string, <<strcoll>> returns a
number less than zero.
PORTABILITY
<<strcoll>> is ANSI C.
<<strcoll>> requires no supporting OS subroutines.
QUICKREF
strcoll ansi pure
*/
#include <string.h>
int
_DEFUN (strcoll, (a, b),
_CONST char *a _AND
_CONST char *b)
{
return strcmp (a, b);
}

View File

@ -0,0 +1,99 @@
/*
FUNCTION
<<strcpy>>---copy string
INDEX
strcpy
ANSI_SYNOPSIS
#include <string.h>
char *strcpy(char *<[dst]>, const char *<[src]>);
TRAD_SYNOPSIS
#include <string.h>
char *strcpy(<[dst]>, <[src]>)
char *<[dst]>;
char *<[src]>;
DESCRIPTION
<<strcpy>> copies the string pointed to by <[src]>
(including the terminating null character) to the array
pointed to by <[dst]>.
RETURNS
This function returns the initial value of <[dst]>.
PORTABILITY
<<strcpy>> is ANSI C.
<<strcpy>> requires no supporting OS subroutines.
QUICKREF
strcpy ansi pure
*/
#include <string.h>
#include <limits.h>
/*SUPPRESS 560*/
/*SUPPRESS 530*/
/* Nonzero if either X or Y is not aligned on a "long" boundary. */
#define UNALIGNED(X, Y) \
(((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
#if LONG_MAX == 2147483647L
#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
#else
#if LONG_MAX == 9223372036854775807L
/* Nonzero if X (a long int) contains a NULL byte. */
#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
#else
#error long int is not a 32bit or 64bit type.
#endif
#endif
#ifndef DETECTNULL
#error long int is not a 32bit or 64bit byte
#endif
char*
_DEFUN (strcpy, (dst0, src0),
char *dst0 _AND
_CONST char *src0)
{
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
char *s = dst0;
while (*dst0++ = *src0++)
;
return s;
#else
char *dst = dst0;
_CONST char *src = src0;
long *aligned_dst;
_CONST long *aligned_src;
/* If SRC or DEST is unaligned, then copy bytes. */
if (!UNALIGNED (src, dst))
{
aligned_dst = (long*)dst;
aligned_src = (long*)src;
/* SRC and DEST are both "long int" aligned, try to do "long int"
sized copies. */
while (!DETECTNULL(*aligned_src))
{
*aligned_dst++ = *aligned_src++;
}
dst = (char*)aligned_dst;
src = (char*)aligned_src;
}
while (*dst++ = *src++)
;
return dst0;
#endif /* not PREFER_SIZE_OVER_SPEED */
}

View File

@ -0,0 +1,54 @@
/*
FUNCTION
<<strcspn>>---count chars not in string
INDEX
strcspn
ANSI_SYNOPSIS
size_t strcspn(const char *<[s1]>, const char *<[s2]>);
TRAD_SYNOPSIS
size_t strcspn(<[s1]>, <[s2]>)
char *<[s1]>;
char *<[s2]>;
DESCRIPTION
This function computes the length of the initial part of
the string pointed to by <[s1]> which consists entirely of
characters <[NOT]> from the string pointed to by <[s2]>
(excluding the terminating null character).
RETURNS
<<strcspn>> returns the length of the substring found.
PORTABILITY
<<strcspn>> is ANSI C.
<<strcspn>> requires no supporting OS subroutines.
*/
#include <string.h>
size_t
_DEFUN (strcspn, (s1, s2),
_CONST char *s1 _AND
_CONST char *s2)
{
_CONST char *s = s1;
_CONST char *c;
while (*s1)
{
for (c = s2; *c; c++)
{
if (*s1 == *c)
break;
}
if (*c)
break;
s1++;
}
return s1 - s;
}

View File

@ -0,0 +1,615 @@
/***
**** CAUTION!!! KEEP DOC CONSISTENT---if you change text of a message
**** here, change two places:
**** 1) the leading doc section (alphabetized by macro)
**** 2) the real text inside switch(errnum)
***/
/*
FUNCTION
<<strerror>>---convert error number to string
INDEX
strerror
ANSI_SYNOPSIS
#include <string.h>
char *strerror(int <[errnum]>);
TRAD_SYNOPSIS
#include <string.h>
char *strerror(<[errnum]>)
int <[errnum]>;
DESCRIPTION
<<strerror>> converts the error number <[errnum]> into a
string. The value of <[errnum]> is usually a copy of <<errno>>.
If <<errnum>> is not a known error number, the result points to an
empty string.
This implementation of <<strerror>> prints out the following strings
for each of the values defined in `<<errno.h>>':
o+
o E2BIG
Arg list too long
o EACCES
Permission denied
o EADV
Advertise error
o EAGAIN
No more processes
o EBADF
Bad file number
o EBADMSG
Bad message
o EBUSY
Device or resource busy
o ECHILD
No children
o ECOMM
Communication error
o EDEADLK
Deadlock
o EEXIST
File exists
o EDOM
Math argument
o EFAULT
Bad address
o EFBIG
File too large
o EIDRM
Identifier removed
o EINTR
Interrupted system call
o EINVAL
Invalid argument
o EIO
I/O error
o EISDIR
Is a directory
o ELIBACC
Cannot access a needed shared library
o ELIBBAD
Accessing a corrupted shared library
o ELIBEXEC
Cannot exec a shared library directly
o ELIBMAX
Attempting to link in more shared libraries than system limit
o ELIBSCN
<<.lib>> section in a.out corrupted
o EMFILE
Too many open files
o EMLINK
Too many links
o EMULTIHOP
Multihop attempted
o ENAMETOOLONG
File or path name too long
o ENFILE
Too many open files in system
o ENODEV
No such device
o ENOENT
No such file or directory
o ENOEXEC
Exec format error
o ENOLCK
No lock
o ENOLINK
Virtual circuit is gone
o ENOMEM
Not enough space
o ENOMSG
No message of desired type
o ENONET
Machine is not on the network
o ENOPKG
No package
o ENOSPC
No space left on device
o ENOSR
No stream resources
o ENOSTR
Not a stream
o ENOSYS
Function not implemented
o ENOTBLK
Block device required
o ENOTDIR
Not a directory
o ENOTEMPTY
Directory not empty
o ENOTTY
Not a character device
o ENXIO
No such device or address
o EPERM
Not owner
o EPIPE
Broken pipe
o EPROTO
Protocol error
o ERANGE
Result too large
o EREMOTE
Resource is remote
o EROFS
Read-only file system
o ESPIPE
Illegal seek
o ESRCH
No such process
o ESRMNT
Srmount error
o ETIME
Stream ioctl timeout
o ETXTBSY
Text file busy
o EXDEV
Cross-device link
o-
RETURNS
This function returns a pointer to a string. Your application must
not modify that string.
PORTABILITY
ANSI C requires <<strerror>>, but does not specify the strings used
for each error number.
Although this implementation of <<strerror>> is reentrant, ANSI C
declares that subsequent calls to <<strerror>> may overwrite the
result string; therefore portable code cannot depend on the reentrancy
of this subroutine.
This implementation of <<strerror>> provides for user-defined
extensibility. <<errno.h>> defines <[__ELASTERROR]>, which can be
used as a base for user-defined error values. If the user supplies a
routine named <<_user_strerror>>, and <[errnum]> passed to
<<strerror>> does not match any of the supported values,
<<_user_strerror>> is called with <[errnum]> as its argument.
<<_user_strerror>> takes one argument of type <[int]>, and returns a
character pointer. If <[errnum]> is unknown to <<_user_strerror>>,
<<_user_strerror>> returns <[NULL]>. The default <<_user_strerror>>
returns <[NULL]> for all input values.
<<strerror>> requires no supporting OS subroutines.
QUICKREF
strerror ansi pure
*/
#include <errno.h>
#include <string.h>
char *
_DEFUN (strerror, (errnum),
int errnum)
{
char *error;
extern char *_user_strerror _PARAMS ((int));
switch (errnum)
{
/* go32 defines EPERM as EACCES */
#if defined (EPERM) && (!defined (EACCES) || (EPERM != EACCES))
case EPERM:
error = "Not owner";
break;
#endif
#ifdef ENOENT
case ENOENT:
error = "No such file or directory";
break;
#endif
#ifdef ESRCH
case ESRCH:
error = "No such process";
break;
#endif
#ifdef EINTR
case EINTR:
error = "Interrupted system call";
break;
#endif
#ifdef EIO
case EIO:
error = "I/O error";
break;
#endif
/* go32 defines ENXIO as ENODEV */
#if defined (ENXIO) && (!defined (ENODEV) || (ENXIO != ENODEV))
case ENXIO:
error = "No such device or address";
break;
#endif
#ifdef E2BIG
case E2BIG:
error = "Arg list too long";
break;
#endif
#ifdef ENOEXEC
case ENOEXEC:
error = "Exec format error";
break;
#endif
#ifdef EBADF
case EBADF:
error = "Bad file number";
break;
#endif
#ifdef ECHILD
case ECHILD:
error = "No children";
break;
#endif
#ifdef EAGAIN
case EAGAIN:
error = "No more processes";
break;
#endif
#ifdef ENOMEM
case ENOMEM:
error = "Not enough space";
break;
#endif
#ifdef EACCES
case EACCES:
error = "Permission denied";
break;
#endif
#ifdef EFAULT
case EFAULT:
error = "Bad address";
break;
#endif
#ifdef ENOTBLK
case ENOTBLK:
error = "Block device required";
break;
#endif
#ifdef EBUSY
case EBUSY:
error = "Device or resource busy";
break;
#endif
#ifdef EEXIST
case EEXIST:
error = "File exists";
break;
#endif
#ifdef EXDEV
case EXDEV:
error = "Cross-device link";
break;
#endif
#ifdef ENODEV
case ENODEV:
error = "No such device";
break;
#endif
#ifdef ENOTDIR
case ENOTDIR:
error = "Not a directory";
break;
#endif
#ifdef EISDIR
case EISDIR:
error = "Is a directory";
break;
#endif
#ifdef EINVAL
case EINVAL:
error = "Invalid argument";
break;
#endif
#ifdef ENFILE
case ENFILE:
error = "Too many open files in system";
break;
#endif
#ifdef EMFILE
case EMFILE:
error = "Too many open files";
break;
#endif
#ifdef ENOTTY
case ENOTTY:
error = "Not a character device";
break;
#endif
#ifdef ETXTBSY
case ETXTBSY:
error = "Text file busy";
break;
#endif
#ifdef EFBIG
case EFBIG:
error = "File too large";
break;
#endif
#ifdef ENOSPC
case ENOSPC:
error = "No space left on device";
break;
#endif
#ifdef ESPIPE
case ESPIPE:
error = "Illegal seek";
break;
#endif
#ifdef EROFS
case EROFS:
error = "Read-only file system";
break;
#endif
#ifdef EMLINK
case EMLINK:
error = "Too many links";
break;
#endif
#ifdef EPIPE
case EPIPE:
error = "Broken pipe";
break;
#endif
#ifdef EDOM
case EDOM:
error = "Math argument";
break;
#endif
#ifdef ERANGE
case ERANGE:
error = "Result too large";
break;
#endif
#ifdef ENOMSG
case ENOMSG:
error = "No message of desired type";
break;
#endif
#ifdef EIDRM
case EIDRM:
error = "Identifier removed";
break;
#endif
#ifdef EDEADLK
case EDEADLK:
error = "Deadlock";
break;
#endif
#ifdef ENOLCK
case ENOLCK:
error = "No lock";
break;
#endif
#ifdef ENOSTR
case ENOSTR:
error = "Not a stream";
break;
#endif
#ifdef ETIME
case ETIME:
error = "Stream ioctl timeout";
break;
#endif
#ifdef ENOSR
case ENOSR:
error = "No stream resources";
break;
#endif
#ifdef ENONET
case ENONET:
error = "Machine is not on the network";
break;
#endif
#ifdef ENOPKG
case ENOPKG:
error = "No package";
break;
#endif
#ifdef EREMOTE
case EREMOTE:
error = "Resource is remote";
break;
#endif
#ifdef ENOLINK
case ENOLINK:
error = "Virtual circuit is gone";
break;
#endif
#ifdef EADV
case EADV:
error = "Advertise error";
break;
#endif
#ifdef ESRMNT
case ESRMNT:
error = "Srmount error";
break;
#endif
#ifdef ECOMM
case ECOMM:
error = "Communication error";
break;
#endif
#ifdef EPROTO
case EPROTO:
error = "Protocol error";
break;
#endif
#ifdef EMULTIHOP
case EMULTIHOP:
error = "Multihop attempted";
break;
#endif
#ifdef EBADMSG
case EBADMSG:
error = "Bad message";
break;
#endif
#ifdef ELIBACC
case ELIBACC:
error = "Cannot access a needed shared library";
break;
#endif
#ifdef ELIBBAD
case ELIBBAD:
error = "Accessing a corrupted shared library";
break;
#endif
#ifdef ELIBSCN
case ELIBSCN:
error = ".lib section in a.out corrupted";
break;
#endif
#ifdef ELIBMAX
case ELIBMAX:
error = "Attempting to link in more shared libraries than system limit";
break;
#endif
#ifdef ELIBEXEC
case ELIBEXEC:
error = "Cannot exec a shared library directly";
break;
#endif
#ifdef ENOSYS
case ENOSYS:
error = "Function not implemented";
break;
#endif
#ifdef ENMFILE
case ENMFILE:
error = "No more files";
break;
#endif
#ifdef ENOTEMPTY
case ENOTEMPTY:
error = "Directory not empty";
break;
#endif
#ifdef ENAMETOOLONG
case ENAMETOOLONG:
error = "File or path name too long";
break;
#endif
#ifdef ELOOP
case ELOOP:
error = "Too many symbolic links";
break;
#endif
#ifdef ENOBUFS
case ENOBUFS:
error = "No buffer space available";
break;
#endif
#ifdef EAFNOSUPPORT
case EAFNOSUPPORT:
error = "Address family not supported by protocol family";
break;
#endif
#ifdef EPROTOTYPE
case EPROTOTYPE:
error = "Protocol wrong type for socket";
break;
#endif
#ifdef ENOTSOCK
case ENOTSOCK:
error = "Socket operation on non-socket";
break;
#endif
#ifdef ENOPROTOOPT
case ENOPROTOOPT:
error = "Protocol not available";
break;
#endif
#ifdef ESHUTDOWN
case ESHUTDOWN:
error = "Can't send after socket shutdown";
break;
#endif
#ifdef ECONNREFUSED
case ECONNREFUSED:
error = "Connection refused";
break;
#endif
#ifdef EADDRINUSE
case EADDRINUSE:
error = "Address already in use";
break;
#endif
#ifdef ECONNABORTED
case ECONNABORTED:
error = "Software caused connection abort";
break;
#endif
default:
if ((error = _user_strerror (errnum)) == 0)
error = "";
break;
}
return error;
}

View File

@ -0,0 +1,88 @@
/*
FUNCTION
<<strlen>>---character string length
INDEX
strlen
ANSI_SYNOPSIS
#include <string.h>
size_t strlen(const char *<[str]>);
TRAD_SYNOPSIS
#include <string.h>
size_t strlen(<[str]>)
char *<[src]>;
DESCRIPTION
The <<strlen>> function works out the length of the string
starting at <<*<[str]>>> by counting chararacters until it
reaches a <<NULL>> character.
RETURNS
<<strlen>> returns the character count.
PORTABILITY
<<strlen>> is ANSI C.
<<strlen>> requires no supporting OS subroutines.
QUICKREF
strlen ansi pure
*/
#include <_ansi.h>
#include <string.h>
#include <limits.h>
#define LBLOCKSIZE (sizeof (long))
#define UNALIGNED(X) ((long)X & (LBLOCKSIZE - 1))
#if LONG_MAX == 2147483647L
#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
#else
#if LONG_MAX == 9223372036854775807L
/* Nonzero if X (a long int) contains a NULL byte. */
#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
#else
#error long int is not a 32bit or 64bit type.
#endif
#endif
#ifndef DETECTNULL
#error long int is not a 32bit or 64bit byte
#endif
size_t
_DEFUN (strlen, (str),
_CONST char *str)
{
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
_CONST char *start = str;
while (*str)
str++;
return str - start;
#else
_CONST char *start = str;
unsigned long *aligned_addr;
if (!UNALIGNED (str))
{
/* If the string is word-aligned, we can check for the presence of
a null in each word-sized block. */
aligned_addr = (unsigned long*)str;
while (!DETECTNULL (*aligned_addr))
aligned_addr++;
/* Once a null is detected, we check each byte in that block for a
precise position of the null. */
str = (char*)aligned_addr;
}
while (*str)
str++;
return str - start;
#endif /* not PREFER_SIZE_OVER_SPEED */
}

View File

@ -0,0 +1,50 @@
/*
FUNCTION
<<strlwr>>---force string to lower case
INDEX
strlwr
ANSI_SYNOPSIS
#include <string.h>
char *strlwr(char *<[a]>);
TRAD_SYNOPSIS
#include <string.h>
char *strlwr(<[a]>)
char *<[a]>;
DESCRIPTION
<<strlwr>> converts each characters in the string at <[a]> to
lower case.
RETURNS
<<strlwr>> returns its argument, <[a]>.
PORTABILITY
<<strlwr>> is not widely portable.
<<strlwr>> requires no supporting OS subroutines.
QUICKREF
strlwr
*/
#include <string.h>
#include <ctype.h>
char *
strlwr (a)
char *a;
{
char *ret = a;
while (*a != '\0')
{
if (isupper (*a))
*a = tolower (*a);
++a;
}
return ret;
}

View File

@ -0,0 +1,64 @@
/*
FUNCTION
<<strncasecmp>>---case insensitive character string compare
INDEX
strncasecmp
ANSI_SYNOPSIS
#include <string.h>
int strncasecmp(const char *<[a]>, const char * <[b]>, size_t <[length]>);
TRAD_SYNOPSIS
#include <string.h>
int strncasecmp(<[a]>, <[b]>, <[length]>)
char *<[a]>;
char *<[b]>;
size_t <[length]>
DESCRIPTION
<<strncasecmp>> compares up to <[length]> characters
from the string at <[a]> to the string at <[b]> in a
case-insensitive manner.
RETURNS
If <<*<[a]>>> sorts lexicographically after <<*<[b]>>> (after
both are converted to upper case), <<strncasecmp>> returns a
number greater than zero. If the two strings are equivalent,
<<strncasecmp>> returns zero. If <<*<[a]>>> sorts
lexicographically before <<*<[b]>>>, <<strncasecmp>> returns a
number less than zero.
PORTABILITY
<<strncasecmp>> is in the Berkeley Software Distribution.
<<strncasecmp>> requires no supporting OS subroutines. It uses
tolower() from elsewhere in this library.
QUICKREF
strncasecmp
*/
#include <string.h>
#include <ctype.h>
int
_DEFUN (strncasecmp, (s1, s2, n),
_CONST char *s1 _AND
_CONST char *s2 _AND
size_t n)
{
if (n == 0)
return 0;
while (n-- != 0 && tolower(*s1) == tolower(*s2))
{
if (n == 0 || *s1 == '\0' || *s2 == '\0')
break;
s1++;
s2++;
}
return tolower(*(unsigned char *) s1) - tolower(*(unsigned char *) s2);
}

115
agbcc/libc/string/strncat.c Normal file
View File

@ -0,0 +1,115 @@
/*
FUNCTION
<<strncat>>---concatenate strings
INDEX
strncat
ANSI_SYNOPSIS
#include <string.h>
char *strncat(char *<[dst]>, const char *<[src]>, size_t <[length]>);
TRAD_SYNOPSIS
#include <string.h>
char *strncat(<[dst]>, <[src]>, <[length]>)
char *<[dst]>;
char *<[src]>;
size_t <[length]>;
DESCRIPTION
<<strncat>> appends not more than <[length]> characters from
the string pointed to by <[src]> (including the terminating
null character) to the end of the string pointed to by
<[dst]>. The initial character of <[src]> overwrites the null
character at the end of <[dst]>. A terminating null character
is always appended to the result
WARNINGS
Note that a null is always appended, so that if the copy is
limited by the <[length]> argument, the number of characters
appended to <[dst]> is <<n + 1>>.
RETURNS
This function returns the initial value of <[dst]>
PORTABILITY
<<strncat>> is ANSI C.
<<strncat>> requires no supporting OS subroutines.
QUICKREF
strncat ansi pure
*/
#include <string.h>
#include <limits.h>
/* Nonzero if X is aligned on a "long" boundary. */
#define ALIGNED(X) \
(((long)X & (sizeof (long) - 1)) == 0)
#if LONG_MAX == 2147483647L
#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
#else
#if LONG_MAX == 9223372036854775807L
/* Nonzero if X (a long int) contains a NULL byte. */
#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
#else
#error long int is not a 32bit or 64bit type.
#endif
#endif
#ifndef DETECTNULL
#error long int is not a 32bit or 64bit byte
#endif
char *
_DEFUN (strncat, (s1, s2, n),
char *s1 _AND
_CONST char *s2 _AND
size_t n)
{
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
char *s = s1;
while (*s1)
s1++;
while (n-- != 0 && (*s1++ = *s2++))
{
if (n == 0)
*s1 = '\0';
}
return s;
#else
char *s = s1;
/* Skip over the data in s1 as quickly as possible. */
if (ALIGNED (s1))
{
unsigned long *aligned_s1 = (unsigned long *)s1;
while (!DETECTNULL (*aligned_s1))
aligned_s1++;
s1 = (char *)aligned_s1;
}
while (*s1)
s1++;
/* s1 now points to the its trailing null character, now copy
up to N bytes from S2 into S1 stopping if a NULL is encountered
in S2.
It is not safe to use strncpy here since it copies EXACTLY N
characters, NULL padding if necessary. */
while (n-- != 0 && (*s1++ = *s2++))
{
if (n == 0)
*s1 = '\0';
}
return s;
#endif /* not PREFER_SIZE_OVER_SPEED */
}

122
agbcc/libc/string/strncmp.c Normal file
View File

@ -0,0 +1,122 @@
/*
FUNCTION
<<strncmp>>---character string compare
INDEX
strncmp
ANSI_SYNOPSIS
#include <string.h>
int strncmp(const char *<[a]>, const char * <[b]>, size_t <[length]>);
TRAD_SYNOPSIS
#include <string.h>
int strncmp(<[a]>, <[b]>, <[length]>)
char *<[a]>;
char *<[b]>;
size_t <[length]>
DESCRIPTION
<<strncmp>> compares up to <[length]> characters
from the string at <[a]> to the string at <[b]>.
RETURNS
If <<*<[a]>>> sorts lexicographically after <<*<[b]>>>,
<<strncmp>> returns a number greater than zero. If the two
strings are equivalent, <<strncmp>> returns zero. If <<*<[a]>>>
sorts lexicographically before <<*<[b]>>>, <<strncmp>> returns a
number less than zero.
PORTABILITY
<<strncmp>> is ANSI C.
<<strncmp>> requires no supporting OS subroutines.
QUICKREF
strncmp ansi pure
*/
#include <string.h>
#include <limits.h>
/* Nonzero if either X or Y is not aligned on a "long" boundary. */
#define UNALIGNED(X, Y) \
(((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
/* DETECTNULL returns nonzero if (long)X contains a NULL byte. */
#if LONG_MAX == 2147483647L
#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
#else
#if LONG_MAX == 9223372036854775807L
#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
#else
#error long int is not a 32bit or 64bit type.
#endif
#endif
#ifndef DETECTNULL
#error long int is not a 32bit or 64bit byte
#endif
int
_DEFUN (strncmp, (s1, s2, n),
_CONST char *s1 _AND
_CONST char *s2 _AND
size_t n)
{
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
if (n == 0)
return 0;
while (n-- != 0 && *s1 == *s2)
{
if (n == 0 || *s1 == '\0')
break;
s1++;
s2++;
}
return (*(unsigned char *) s1) - (*(unsigned char *) s2);
#else
unsigned long *a1;
unsigned long *a2;
if (n == 0)
return 0;
/* If s1 or s2 are unaligned, then compare bytes. */
if (!UNALIGNED (s1, s2))
{
/* If s1 and s2 are word-aligned, compare them a word at a time. */
a1 = (unsigned long*)s1;
a2 = (unsigned long*)s2;
while (n >= sizeof (long) && *a1 == *a2)
{
n -= sizeof (long);
/* If we've run out of bytes or hit a null, return zero
since we already know *a1 == *a2. */
if (n == 0 || DETECTNULL (*a1))
return 0;
a1++;
a2++;
}
/* A difference was detected in last few bytes of s1, so search bytewise */
s1 = (char*)a1;
s2 = (char*)a2;
}
while (n-- > 0 && *s1 == *s2)
{
/* If we've run out of bytes or hit a null, return zero
since we already know *s1 == *s2. */
if (n == 0 || *s1 == '\0')
return 0;
s1++;
s2++;
}
return (*(unsigned char *) s1) - (*(unsigned char *) s2);
#endif /* not PREFER_SIZE_OVER_SPEED */
}

125
agbcc/libc/string/strncpy.c Normal file
View File

@ -0,0 +1,125 @@
/*
FUNCTION
<<strncpy>>---counted copy string
INDEX
strncpy
ANSI_SYNOPSIS
#include <string.h>
char *strncpy(char *<[dst]>, const char *<[src]>, size_t <[length]>);
TRAD_SYNOPSIS
#include <string.h>
char *strncpy(<[dst]>, <[src]>, <[length]>)
char *<[dst]>;
char *<[src]>;
size_t <[length]>;
DESCRIPTION
<<strncpy>> copies not more than <[length]> characters from the
the string pointed to by <[src]> (including the terminating
null character) to the array pointed to by <[dst]>. If the
string pointed to by <[src]> is shorter than <[length]>
characters, null characters are appended to the destination
array until a total of <[length]> characters have been
written.
RETURNS
This function returns the initial value of <[dst]>.
PORTABILITY
<<strncpy>> is ANSI C.
<<strncpy>> requires no supporting OS subroutines.
QUICKREF
strncpy ansi pure
*/
#include <string.h>
#include <limits.h>
/*SUPPRESS 560*/
/*SUPPRESS 530*/
/* Nonzero if either X or Y is not aligned on a "long" boundary. */
#define UNALIGNED(X, Y) \
(((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
#if LONG_MAX == 2147483647L
#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
#else
#if LONG_MAX == 9223372036854775807L
/* Nonzero if X (a long int) contains a NULL byte. */
#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
#else
#error long int is not a 32bit or 64bit type.
#endif
#endif
#ifndef DETECTNULL
#error long int is not a 32bit or 64bit byte
#endif
#define TOO_SMALL(LEN) ((LEN) < sizeof (long))
char *
_DEFUN (strncpy, (dst0, src0),
char *dst0 _AND
_CONST char *src0 _AND
size_t count)
{
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
char *dscan;
_CONST char *sscan;
dscan = dst0;
sscan = src0;
while (count > 0)
{
--count;
if ((*dscan++ = *sscan++) == '\0')
break;
}
while (count-- > 0)
*dscan++ = '\0';
return dst0;
#else
char *dst = dst0;
_CONST char *src = src0;
long *aligned_dst;
_CONST long *aligned_src;
/* If SRC and DEST is aligned and count large enough, then copy words. */
if (!UNALIGNED (src, dst) && !TOO_SMALL (count))
{
aligned_dst = (long*)dst;
aligned_src = (long*)src;
/* SRC and DEST are both "long int" aligned, try to do "long int"
sized copies. */
while (count >= sizeof (long int) && !DETECTNULL(*aligned_src))
{
count -= sizeof (long int);
*aligned_dst++ = *aligned_src++;
}
dst = (char*)aligned_dst;
src = (char*)aligned_src;
}
while (count > 0)
{
--count;
if ((*dst++ = *src++) == '\0')
break;
}
while (count-- > 0)
*dst++ = '\0';
return dst0;
#endif /* not PREFER_SIZE_OVER_SPEED */
}

View File

@ -0,0 +1,58 @@
/*
FUNCTION
<<strpbrk>>---find chars in string
INDEX
strpbrk
ANSI_SYNOPSIS
#include <string.h>
char *strpbrk(const char *<[s1]>, const char *<[s2]>);
TRAD_SYNOPSIS
#include <string.h>
char *strpbrk(<[s1]>, <[s2]>)
char *<[s1]>;
char *<[s2]>;
DESCRIPTION
This function locates the first occurence in the string
pointed to by <[s1]> of any character in string pointed to by
<[s2]> (excluding the terminating null character).
RETURNS
<<strpbrk>> returns a pointer to the character found in <[s1]>, or a
null pointer if no character from <[s2]> occurs in <[s1]>.
PORTABILITY
<<strpbrk>> requires no supporting OS subroutines.
*/
#include <string.h>
char *
_DEFUN (strpbrk, (s1, s2),
_CONST char *s1 _AND
_CONST char *s2)
{
_CONST char *c = s2;
if (!*s1)
return (char *) NULL;
while (*s1)
{
for (c = s2; *c; c++)
{
if (*s1 == *c)
break;
}
if (*c)
break;
s1++;
}
if (*c == '\0')
s1 = NULL;
return (char *) s1;
}

View File

@ -0,0 +1,61 @@
/*
FUNCTION
<<strrchr>>---reverse search for character in string
INDEX
strrchr
ANSI_SYNOPSIS
#include <string.h>
char * strrchr(const char *<[string]>, int <[c]>);
TRAD_SYNOPSIS
#include <string.h>
char * strrchr(<[string]>, <[c]>);
char *<[string]>;
int *<[c]>;
DESCRIPTION
This function finds the last occurence of <[c]> (converted to
a char) in the string pointed to by <[string]> (including the
terminating null character).
RETURNS
Returns a pointer to the located character, or a null pointer
if <[c]> does not occur in <[string]>.
PORTABILITY
<<strrchr>> is ANSI C.
<<strrchr>> requires no supporting OS subroutines.
QUICKREF
strrchr ansi pure
*/
#include <string.h>
char *
_DEFUN (strrchr, (s, i),
_CONST char *s _AND
int i)
{
_CONST char *last = NULL;
char c = i;
while (*s)
{
if (*s == c)
{
last = s;
}
s++;
}
if (*s == c)
{
last = s;
}
return (char *) last;
}

View File

@ -0,0 +1,59 @@
/*
FUNCTION
<<strspn>>---find initial match
INDEX
strspn
ANSI_SYNOPSIS
#include <string.h>
size_t strspn(const char *<[s1]>, const char *<[s2]>);
TRAD_SYNOPSIS
#include <string.h>
size_t strspn(<[s1]>, <[s2]>)
char *<[s1]>;
char *<[s2]>;
DESCRIPTION
This function computes the length of the initial segment of
the string pointed to by <[s1]> which consists entirely of
characters from the string pointed to by <[s2]> (excluding the
terminating null character).
RETURNS
<<strspn>> returns the length of the segment found.
PORTABILITY
<<strspn>> is ANSI C.
<<strspn>> requires no supporting OS subroutines.
QUICKREF
strspn ansi pure
*/
#include <string.h>
size_t
_DEFUN (strspn, (s1, s2),
_CONST char *s1 _AND
_CONST char *s2)
{
_CONST char *s = s1;
_CONST char *c;
while (*s1)
{
for (c = s2; *c; c++)
{
if (*s1 == *c)
break;
}
if (*c == '\0')
break;
s1++;
}
return s1 - s;
}

View File

@ -0,0 +1,73 @@
/*
FUNCTION
<<strstr>>---find string segment
INDEX
strstr
ANSI_SYNOPSIS
#include <string.h>
char *strstr(const char *<[s1]>, const char *<[s2]>);
TRAD_SYNOPSIS
#include <string.h>
char *strstr(<[s1]>, <[s2]>)
char *<[s1]>;
char *<[s2]>;
DESCRIPTION
Locates the first occurence in the string pointed to by <[s1]> of
the sequence of characters in the string pointed to by <[s2]>
(excluding the terminating null character).
RETURNS
Returns a pointer to the located string segment, or a null
pointer if the string <[s2]> is not found. If <[s2]> points to
a string with zero length, the <[s1]> is returned.
PORTABILITY
<<strstr>> is ANSI C.
<<strstr>> requires no supporting OS subroutines.
QUICKREF
strstr ansi pure
*/
#include <string.h>
char *
_DEFUN (strstr, (searchee, lookfor),
_CONST char *searchee _AND
_CONST char *lookfor)
{
if (*searchee == 0)
{
if (*lookfor)
return (char *) NULL;
return (char *) searchee;
}
while (*searchee)
{
size_t i;
i = 0;
while (1)
{
if (lookfor[i] == 0)
{
return (char *) searchee;
}
if (lookfor[i] != searchee[i])
{
break;
}
i++;
}
searchee++;
}
return (char *) NULL;
}

View File

@ -0,0 +1,76 @@
/*
FUNCTION
<<strtok>>---get next token from a string
INDEX
strtok
INDEX
strtok_r
ANSI_SYNOPSIS
#include <string.h>
char *strtok(char *<[source]>, const char *<[delimiters]>)
char *strtok_r(char *<[source]>, const char *<[delimiters]>,
char **<[lasts]>)
TRAD_SYNOPSIS
#include <string.h>
char *strtok(<[source]>, <[delimiters]>)
char *<[source]>;
char *<[delimiters]>;
char *strtok_r(<[source]>, <[delimiters]>, <[lasts]>)
char *<[source]>;
char *<[delimiters]>;
char **<[lasts]>;
DESCRIPTION
The <<strtok>> function is used to isolate sequential tokens in a
null-terminated string, <<*<[source]>>>. These tokens are delimited
in the string by at least one of the characters in <<*<[delimiters]>>>.
The first time that <<strtok>> is called, <<*<[source]>>> should be
specified; subsequent calls, wishing to obtain further tokens from
the same string, should pass a null pointer instead. The separator
string, <<*<[delimiters]>>>, must be supplied each time, and may
change between calls.
The <<strtok>> function returns a pointer to the beginning of each
subsequent token in the string, after replacing the separator
character itself with a NUL character. When no more tokens remain,
a null pointer is returned.
The <<strtok_r>> function has the same behavior as <<strtok>>, except
a pointer to placeholder <<*[lasts]>> must be supplied by the caller.
RETURNS
<<strtok>> returns a pointer to the next token, or <<NULL>> if
no more tokens can be found.
NOTES
<<strtok>> is unsafe for multi-thread applications. <<strtok_r>>
is MT-Safe and should be used instead.
PORTABILITY
<<strtok>> is ANSI C.
<<strtok>> requires no supporting OS subroutines.
QUICKREF
strtok ansi impure
*/
#include <string.h>
#include <_ansi.h>
#include <reent.h>
#ifndef _REENT_ONLY
char *
_DEFUN (strtok, (s, delim),
register char *s _AND
register const char *delim)
{
return strtok_r (s, delim, &(_REENT->_new._reent._strtok_last));
}
#endif

View File

@ -0,0 +1,85 @@
/*
* Copyright (c) 1988 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.
*/
#include <string.h>
char *
_DEFUN (strtok_r, (s, delim, lasts),
register char *s _AND
register const char *delim _AND
char **lasts)
{
register char *spanp;
register int c, sc;
char *tok;
if (s == NULL && (s = *lasts) == NULL)
return (NULL);
/*
* Skip (span) leading delimiters (s += strspn(s, delim), sort of).
*/
cont:
c = *s++;
for (spanp = (char *)delim; (sc = *spanp++) != 0;) {
if (c == sc)
goto cont;
}
if (c == 0) { /* no non-delimiter characters */
*lasts = NULL;
return (NULL);
}
tok = s - 1;
/*
* Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
* Note that delim must have one NUL; we stop if we see that, too.
*/
for (;;) {
c = *s++;
spanp = (char *)delim;
do {
if ((sc = *spanp++) == c) {
if (c == 0)
s = NULL;
else
s[-1] = 0;
*lasts = s;
return (tok);
}
} while (sc != 0);
}
/* NOTREACHED */
}

View File

@ -0,0 +1,49 @@
/*
FUNCTION
<<strupr>>---force string to uppercase
INDEX
strupr
ANSI_SYNOPSIS
#include <string.h>
char *strupr(char *<[a]>);
TRAD_SYNOPSIS
#include <string.h>
char *strupr(<[a]>)
char *<[a]>;
DESCRIPTION
<<strupr>> converts each characters in the string at <[a]> to
upper case.
RETURNS
<<strupr>> returns its argument, <[a]>.
PORTABILITY
<<strupr>> is not widely portable.
<<strupr>> requires no supporting OS subroutines.
QUICKREF
strupr */
#include <string.h>
#include <ctype.h>
char *
strupr (a)
char *a;
{
char *ret = a;
while (*a != '\0')
{
if (islower (*a))
*a = toupper (*a);
++a;
}
return ret;
}

View File

@ -0,0 +1,75 @@
/*
FUNCTION
<<strxfrm>>---transform string
INDEX
strxfrm
ANSI_SYNOPSIS
#include <string.h>
size_t strxfrm(char *<[s1]>, const char *<[s2]>, size_t <[n]>);
TRAD_SYNOPSIS
#include <string.h>
size_t strxfrm(<[s1]>, <[s2]>, <[n]>);
char *<[s1]>;
char *<[s2]>;
size_t <[n]>;
DESCRIPTION
This function transforms the string pointed to by <[s2]> and
places the resulting string into the array pointed to by
<[s1]>. The transformation is such that if the <<strcmp>>
function is applied to the two transformed strings, it returns
a value greater than, equal to, or less than zero,
correspoinding to the result of a <<strcoll>> function applied
to the same two original strings.
No more than <[n]> characters are placed into the resulting
array pointed to by <[s1]>, including the terminating null
character. If <[n]> is zero, <[s1]> may be a null pointer. If
copying takes place between objects that overlap, the behavior
is undefined.
With a C locale, this function just copies.
RETURNS
The <<strxfrm>> function returns the length of the transformed string
(not including the terminating null character). If the value returned
is <[n]> or more, the contents of the array pointed to by
<[s1]> are indeterminate.
PORTABILITY
<<strxfrm>> is ANSI C.
<<strxfrm>> requires no supporting OS subroutines.
QUICKREF
strxfrm ansi pure
*/
#include <string.h>
size_t
_DEFUN (strxfrm, (s1, s2, n),
char *s1 _AND
_CONST char *s2 _AND
size_t n)
{
size_t res;
res = 0;
while (n-- > 0)
{
if ((*s1++ = *s2++) != '\0')
++res;
else
return res;
}
while (*s2)
{
++s2;
++res;
}
return res;
}

View File

@ -0,0 +1,8 @@
#include <_ansi.h>
char *
_DEFUN(_user_strerror, (errnum),
int errnum)
{
return 0;
}

View File

@ -0,0 +1,14 @@
/* connector for close */
#include <reent.h>
int
close (fd)
int fd;
{
#ifdef REENTRANT_SYSCALLS_PROVIDED
return _close_r (_REENT, fd);
#else
return _close (fd);
#endif
}

View File

@ -0,0 +1,16 @@
/* connector for execve */
#include <reent.h>
int
execve (name, argv, env)
char *name;
char **argv;
char **env;
{
#ifdef REENTRANT_SYSCALLS_PROVIDED
return _execve_r (_REENT, name, argv, env);
#else
return _execve (name, argv, env);
#endif
}

View File

@ -0,0 +1,17 @@
/* connector for fcntl */
/* only called from stdio/fdopen.c, so arg can be int. */
#include <reent.h>
int
fcntl (fd, flag, arg)
int fd;
int flag;
int arg;
{
#ifdef REENTRANT_SYSCALLS_PROVIDED
return _fcntl_r (_REENT, fd, flag, arg);
#else
return _fcntl (fd, flag, arg);
#endif
}

View File

@ -0,0 +1,19 @@
/* connector for fork */
/* Don't define this if NO_FORK. See for example libc/sys/win32/spawn.c. */
#ifndef NO_FORK
#include <reent.h>
int
fork ()
{
#ifdef REENTRANT_SYSCALLS_PROVIDED
return _fork_r (_REENT);
#else
return _fork ();
#endif
}
#endif

View File

@ -0,0 +1,16 @@
/* connector for fstat */
#include <reent.h>
#include <unistd.h>
int
fstat (fd, pstat)
int fd;
struct stat *pstat;
{
#ifdef REENTRANT_SYSCALLS_PROVIDED
return _fstat_r (_REENT, fd, pstat);
#else
return _fstat (fd, pstat);
#endif
}

View File

@ -0,0 +1,13 @@
/* connector for getpid */
#include <reent.h>
int
getpid ()
{
#ifdef REENTRANT_SYSCALLS_PROVIDED
return _getpid_r (_REENT);
#else
return _getpid ();
#endif
}

View File

@ -0,0 +1,20 @@
/* connector for gettimeofday */
#include <reent.h>
#include <sys/types.h>
#include <sys/times.h>
struct timeval;
struct timezone;
int
gettimeofday (ptimeval, ptimezone)
struct timeval *ptimeval;
struct timezone *ptimezone;
{
#ifdef REENTRANT_SYSCALLS_PROVIDED
return _gettimeofday_r (_REENT, ptimeval, ptimezone);
#else
return _gettimeofday (ptimeval, ptimezone);
#endif
}

View File

@ -0,0 +1,15 @@
/* connector for kill */
#include <reent.h>
int
kill (pid, sig)
int pid;
int sig;
{
#ifdef REENTRANT_SYSCALLS_PROVIDED
return _kill_r (_REENT, pid, sig);
#else
return _kill (pid, sig);
#endif
}

View File

@ -0,0 +1,15 @@
/* connector for link */
#include <reent.h>
int
link (old, new)
char *old;
char *new;
{
#ifdef REENTRANT_SYSCALLS_PROVIDED
return _link_r (_REENT, old, new);
#else
return _link (old, new);
#endif
}

View File

@ -0,0 +1,17 @@
/* connector for lseek */
#include <reent.h>
#include <unistd.h>
off_t
lseek (fd, pos, whence)
int fd;
off_t pos;
int whence;
{
#ifdef REENTRANT_SYSCALLS_PROVIDED
return _lseek_r (_REENT, fd, pos, whence);
#else
return _lseek (fd, pos, whence);
#endif
}

View File

@ -0,0 +1,43 @@
/* connector for open */
#include <reent.h>
#include <fcntl.h>
#ifdef _HAVE_STDC
/* The prototype in <fcntl.h> uses ..., so we must correspond. */
#include <stdarg.h>
int
open (const char *file, int flags, ...)
{
va_list ap;
int ret;
va_start (ap, flags);
#ifdef REENTRANT_SYSCALLS_PROVIDED
ret = _open_r (_REENT, file, flags, va_arg (ap, int));
#else
ret = _open (file, flags, va_arg (ap, int));
#endif
va_end (ap);
return ret;
}
#else /* ! _HAVE_STDC */
int
open (file, flags, mode)
const char *file;
int flags;
int mode;
{
#ifdef REENTRANT_SYSCALLS_PROVIDED
return _open_r (_REENT, file, flags, mode);
#else
return _open (file, flags, mode);
#endif
}
#endif /* ! _HAVE_STDC */

View File

@ -0,0 +1,17 @@
/* connector for read */
#include <reent.h>
#include <unistd.h>
int
read (fd, buf, cnt)
int fd;
void *buf;
size_t cnt;
{
#ifdef REENTRANT_SYSCALLS_PROVIDED
return _read_r (_REENT, fd, buf, cnt);
#else
return _read (fd, buf, cnt);
#endif
}

View File

@ -0,0 +1,18 @@
/* connector for sbrk */
#include <reent.h>
#include <unistd.h>
extern void *_sbrk_r (struct _reent *, size_t);
extern void *_sbrk (size_t);
void *
sbrk (incr)
size_t incr;
{
#ifdef REENTRANT_SYSCALLS_PROVIDED
return _sbrk_r (_REENT, incr);
#else
return _sbrk (incr);
#endif
}

View File

@ -0,0 +1,16 @@
/* connector for stat */
#include <reent.h>
#include <unistd.h>
int
stat (file, pstat)
char *file;
struct stat *pstat;
{
#ifdef REENTRANT_SYSCALLS_PROVIDED
return _stat_r (_REENT, file, pstat);
#else
return _stat (file, pstat);
#endif
}

View File

@ -0,0 +1,15 @@
/* connector for times */
#include <reent.h>
#include <sys/times.h>
clock_t
times (buf)
struct tms *buf;
{
#ifdef REENTRANT_SYSCALLS_PROVIDED
return _times_r (_REENT, buf);
#else
return _times (buf);
#endif
}

View File

@ -0,0 +1,14 @@
/* connector for unlink */
#include <reent.h>
int
unlink (file)
char *file;
{
#ifdef REENTRANT_SYSCALLS_PROVIDED
return _unlink_r (_REENT, file);
#else
return _unlink (file);
#endif
}

View File

@ -0,0 +1,14 @@
/* connector for wait */
#include <reent.h>
int
wait (status)
int *status;
{
#ifdef REENTRANT_SYSCALLS_PROVIDED
return _wait_r (_REENT, status);
#else
return _wait (status);
#endif
}

View File

@ -0,0 +1,17 @@
/* connector for write */
#include <reent.h>
#include <unistd.h>
int
write (fd, buf, cnt)
int fd;
const void *buf;
size_t cnt;
{
#ifdef REENTRANT_SYSCALLS_PROVIDED
return _write_r (_REENT, fd, buf, cnt);
#else
return _write (fd, buf, cnt);
#endif
}

64
agbcc/libc/time/asctime.c Normal file
View File

@ -0,0 +1,64 @@
/*
* asctime.c
* Original Author: G. Haley
*
* Converts the broken down time in the structure pointed to by tim_p into a
* string of the form
*
* Wed Jun 15 11:38:07 1988\n\0
*
* Returns a pointer to the string.
*/
/*
FUNCTION
<<asctime>>---format time as string
INDEX
asctime
INDEX
_asctime_r
ANSI_SYNOPSIS
#include <time.h>
char *asctime(const struct tm *<[clock]>);
char *asctime_r(const struct tm *<[clock]>, char *<[buf]>);
TRAD_SYNOPSIS
#include <time.h>
char *asctime(<[clock]>)
struct tm *<[clock]>;
char *asctime_r(<[clock]>)
struct tm *<[clock]>;
char *<[buf]>;
DESCRIPTION
Format the time value at <[clock]> into a string of the form
. Wed Jun 15 11:38:07 1988\n\0
The string is generated in a static buffer; each call to <<asctime>>
overwrites the string generated by previous calls.
RETURNS
A pointer to the string containing a formatted timestamp.
PORTABILITY
ANSI C requires <<asctime>>.
<<asctime>> requires no supporting OS subroutines.
*/
#include <time.h>
#include <_ansi.h>
#include <reent.h>
#ifndef _REENT_ONLY
char *
_DEFUN (asctime, (tim_p),
_CONST struct tm *tim_p)
{
char *buf = _REENT->_new._reent._asctime_buf;
return asctime_r (tim_p, buf);
}
#endif

View File

@ -0,0 +1,27 @@
/*
* asctime_r.c
*/
#include <stdio.h>
#include <time.h>
char *
_DEFUN (asctime_r, (tim_p, result),
_CONST struct tm *tim_p _AND
char *result)
{
static _CONST char day_name[7][3] = {
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
};
static _CONST char mon_name[12][3] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
sprintf (result, "%.3s %.3s %.2d %.2d:%.2d:%.2d %d\n",
day_name[tim_p->tm_wday],
mon_name[tim_p->tm_mon],
tim_p->tm_mday, tim_p->tm_hour, tim_p->tm_min,
tim_p->tm_sec, 1900 + tim_p->tm_year);
return result;
}

69
agbcc/libc/time/clock.c Normal file
View File

@ -0,0 +1,69 @@
/* NetWare can not use this implementation of clock, since it does not
have times or any similar function. It provides its own version of
clock in clib.nlm. If we can not use clib.nlm, then we must write
clock in sys/netware. */
#ifdef CLOCK_PROVIDED
int _dummy_clock = 1;
#else
/*
* clock.c
* Original Author: G. Haley
*
* Determines the processor time used by the program since invocation. The time
* in seconds is the value returned divided by the value of the macro CLK_TCK.
* If the processor time used is not available, (clock_t) -1 is returned.
*/
/*
FUNCTION
<<clock>>---cumulative processor time
INDEX
clock
ANSI_SYNOPSIS
#include <time.h>
clock_t clock(void);
TRAD_SYNOPSIS
#include <time.h>
clock_t clock();
DESCRIPTION
Calculates the best available approximation of the cumulative amount
of time used by your program since it started. To convert the result
into seconds, divide by the macro <<CLOCKS_PER_SEC>>.
RETURNS
The amount of processor time used so far by your program, in units
defined by the machine-dependent macro <<CLOCKS_PER_SEC>>. If no
measurement is available, the result is <<-1>>.
PORTABILITY
ANSI C requires <<clock>> and <<CLOCKS_PER_SEC>>.
Supporting OS subroutine required: <<times>>.
*/
#include <time.h>
#include <sys/times.h>
#include <reent.h>
clock_t
clock ()
{
struct tms tim_s;
clock_t res;
if ((res = (clock_t) _times_r (_REENT, &tim_s)) != -1)
res = (clock_t) (tim_s.tms_utime + tim_s.tms_stime +
tim_s.tms_cutime + tim_s.tms_cstime);
return res;
}
#endif /* CLOCK_PROVIDED */

52
agbcc/libc/time/ctime.c Normal file
View File

@ -0,0 +1,52 @@
/*
* ctime.c
* Original Author: G. Haley
*/
/*
FUNCTION
<<ctime>>---convert time to local and format as string
INDEX
ctime
ANSI_SYNOPSIS
#include <time.h>
char *ctime(time_t <[clock]>);
char *ctime_r(time_t <[clock]>, char *<[buf]>);
TRAD_SYNOPSIS
#include <time.h>
char *ctime(<[clock]>)
time_t <[clock]>;
char *ctime_r(<[clock]>, <[buf]>)
time_t <[clock]>;
char *<[buf]>;
DESCRIPTION
Convert the time value at <[clock]> to local time (like <<localtime>>)
and format it into a string of the form
. Wed Jun 15 11:38:07 1988\n\0
(like <<asctime>>).
RETURNS
A pointer to the string containing a formatted timestamp.
PORTABILITY
ANSI C requires <<ctime>>.
<<ctime>> requires no supporting OS subroutines.
*/
#include <time.h>
#ifndef _REENT_ONLY
char *
_DEFUN (ctime, (tim_p),
_CONST time_t * tim_p)
{
return asctime (localtime (tim_p));
}
#endif

15
agbcc/libc/time/ctime_r.c Normal file
View File

@ -0,0 +1,15 @@
/*
* ctime_r.c
*/
#include <time.h>
char *
_DEFUN (ctime_r, (tim_p, result),
_CONST time_t * tim_p _AND
char * result)
{
struct tm tm;
return asctime_r (localtime_r (tim_p, &tm), result);
}

View File

@ -0,0 +1,44 @@
/*
* difftime.c
* Original Author: G. Haley
*/
/*
FUNCTION
<<difftime>>---subtract two times
INDEX
difftime
ANSI_SYNOPSIS
#include <time.h>
double difftime(time_t <[tim1]>, time_t <[tim2]>);
TRAD_SYNOPSIS
#include <time.h>
double difftime(<[tim1]>, <[tim2]>)
time_t <[tim1]>;
time_t <[tim2]>;
DESCRIPTION
Subtracts the two times in the arguments: `<<<[tim1]> - <[tim2]>>>'.
RETURNS
The difference (in seconds) between <[tim2]> and <[tim1]>, as a <<double>>.
PORTABILITY
ANSI C requires <<difftime>>, and defines its result to be in seconds
in all implementations.
<<difftime>> requires no supporting OS subroutines.
*/
#include <time.h>
double
_DEFUN (difftime, (tim1, tim2),
time_t tim1 _AND
time_t tim2)
{
return ((double) tim1 - tim2);
}

67
agbcc/libc/time/gmtime.c Normal file
View File

@ -0,0 +1,67 @@
/*
* gmtime.c
* Original Author: G. Haley
*
* Converts the calendar time pointed to by tim_p into a broken-down time
* expressed as Greenwich Mean Time (GMT). Returns a pointer to a structure
* containing the broken-down time, or a null pointer if GMT is not
* available.
*/
/*
FUNCTION
<<gmtime>>---convert time to UTC traditional form
INDEX
gmtime
ANSI_SYNOPSIS
#include <time.h>
struct tm *gmtime(const time_t *<[clock]>);
struct tm *gmtime_r(const time_t *<[clock]>, struct tm *<[res]>);
TRAD_SYNOPSIS
#include <time.h>
struct tm *gmtime(<[clock]>)
const time_t *<[clock]>;
struct tm *gmtime_r(<[clock]>, <[res]>)
const time_t *<[clock]>;
struct tm *<[res]>;
DESCRIPTION
<<gmtime>> assumes the time at <[clock]> represents a local time.
<<gmtime>> converts it to UTC (Universal Coordinated Time, also known in some
countries as GMT, Greenwich Mean time), then converts the
representation from the arithmetic representation to
the traditional representation defined by <<struct tm>>.
<<gmtime>> constructs the traditional time representation in static
storage; each call to <<gmtime>> or <<localtime>> will overwrite the
information generated by previous calls to either function.
RETURNS
A pointer to the traditional time representation (<<struct tm>>).
PORTABILITY
ANSI C requires <<gmtime>>.
<<gmtime>> requires no supporting OS subroutines.
*/
#include <stdlib.h>
#include <time.h>
#define _GMT_OFFSET 0
#ifndef _REENT_ONLY
struct tm *
_DEFUN (gmtime, (tim_p),
_CONST time_t * tim_p)
{
time_t tim = *tim_p + _GMT_OFFSET;
return (localtime (&tim));
}
#endif

View File

@ -0,0 +1,17 @@
/*
* gmtime_r.c
*/
#include <time.h>
#define _GMT_OFFSET 0
struct tm *
_DEFUN (gmtime_r, (tim_p, res),
_CONST time_t * tim_p _AND
struct tm *res)
{
time_t tim = *tim_p + _GMT_OFFSET;
return (localtime_r (&tim, res));
}

57
agbcc/libc/time/lcltime.c Normal file
View File

@ -0,0 +1,57 @@
/*
* localtime.c
*/
/*
FUNCTION
<<localtime>>---convert time to local representation
INDEX
localtime
ANSI_SYNOPSIS
#include <time.h>
struct tm *localtime(time_t *<[clock]>);
struct tm *localtime_r(time_t *<[clock]>, struct tm *<[res]>);
TRAD_SYNOPSIS
#include <time.h>
struct tm *localtime(<[clock]>)
time_t *<[clock]>;
struct tm *localtime(<[clock]>, <[res]>)
time_t *<[clock]>;
struct tm *<[res]>;
DESCRIPTION
<<localtime>> converts the time at <[clock]> into local time, then
converts its representation from the arithmetic representation to the
traditional representation defined by <<struct tm>>.
<<localtime>> constructs the traditional time representation in static
storage; each call to <<gmtime>> or <<localtime>> will overwrite the
information generated by previous calls to either function.
<<mktime>> is the inverse of <<localtime>>.
RETURNS
A pointer to the traditional time representation (<<struct tm>>).
PORTABILITY
ANSI C requires <<localtime>>.
<<localtime>> requires no supporting OS subroutines.
*/
#include <time.h>
#include <reent.h>
#ifndef _REENT_ONLY
struct tm *
_DEFUN (localtime, (tim_p),
_CONST time_t * tim_p)
{
return localtime_r (tim_p, &(_REENT->_new._reent._localtime_buf));
}
#endif

104
agbcc/libc/time/lcltime_r.c Normal file
View File

@ -0,0 +1,104 @@
/*
* localtime_r.c
* Original Author: Adapted from tzcode maintained by Arthur David Olson.
*
* Converts the calendar time pointed to by tim_p into a broken-down time
* expressed as local time. Returns a pointer to a structure containing the
* broken-down time.
*/
#include <stdlib.h>
#include <time.h>
#define SECSPERMIN 60L
#define MINSPERHOUR 60L
#define HOURSPERDAY 24L
#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
#define SECSPERDAY (SECSPERHOUR * HOURSPERDAY)
#define DAYSPERWEEK 7
#define MONSPERYEAR 12
#define YEAR_BASE 1900
#define EPOCH_YEAR 1970
#define EPOCH_WDAY 4
#define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
static _CONST int mon_lengths[2][MONSPERYEAR] = {
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
} ;
static _CONST int year_lengths[2] = {
365,
366
} ;
struct tm *
_DEFUN (localtime_r, (tim_p, res),
_CONST time_t * tim_p _AND
struct tm *res)
{
long days, rem;
int y;
int yleap;
_CONST int *ip;
days = ((long) *tim_p) / SECSPERDAY;
rem = ((long) *tim_p) % SECSPERDAY;
while (rem < 0)
{
rem += SECSPERDAY;
--days;
}
while (rem >= SECSPERDAY)
{
rem -= SECSPERDAY;
++days;
}
/* compute hour, min, and sec */
res->tm_hour = (int) (rem / SECSPERHOUR);
rem %= SECSPERHOUR;
res->tm_min = (int) (rem / SECSPERMIN);
res->tm_sec = (int) (rem % SECSPERMIN);
/* compute day of week */
if ((res->tm_wday = ((EPOCH_WDAY + days) % DAYSPERWEEK)) < 0)
res->tm_wday += DAYSPERWEEK;
/* compute year & day of year */
y = EPOCH_YEAR;
if (days >= 0)
{
for (;;)
{
yleap = isleap(y);
if (days < year_lengths[yleap])
break;
y++;
days -= year_lengths[yleap];
}
}
else
{
do
{
--y;
yleap = isleap(y);
days += year_lengths[yleap];
} while (days < 0);
}
res->tm_year = y - YEAR_BASE;
res->tm_yday = days;
ip = mon_lengths[yleap];
for (res->tm_mon = 0; days >= ip[res->tm_mon]; ++res->tm_mon)
days -= ip[res->tm_mon];
res->tm_mday = days + 1;
/* set daylight saving time flag */
res->tm_isdst = -1;
return (res);
}

204
agbcc/libc/time/mktime.c Normal file
View File

@ -0,0 +1,204 @@
/*
* mktime.c
* Original Author: G. Haley
*
* Converts the broken-down time, expressed as local time, in the structure
* pointed to by tim_p into a calendar time value. The original values of the
* tm_wday and tm_yday fields of the structure are ignored, and the original
* values of the other fields have no restrictions. On successful completion
* the fields of the structure are set to represent the specified calendar
* time. Returns the specified calendar time. If the calendar time can not be
* represented, returns the value (time_t) -1.
*/
/*
FUNCTION
<<mktime>>---convert time to arithmetic representation
INDEX
mktime
ANSI_SYNOPSIS
#include <time.h>
time_t mktime(struct tm *<[timp]>);
TRAD_SYNOPSIS
#include <time.h>
time_t mktime(<[timp]>)
struct tm *<[timp]>;
DESCRIPTION
<<mktime>> assumes the time at <[timp]> is a local time, and converts
its representation from the traditional representation defined by
<<struct tm>> into a representation suitable for arithmetic.
<<localtime>> is the inverse of <<mktime>>.
RETURNS
If the contents of the structure at <[timp]> do not form a valid
calendar time representation, the result is <<-1>>. Otherwise, the
result is the time, converted to a <<time_t>> value.
PORTABILITY
ANSI C requires <<mktime>>.
<<mktime>> requires no supporting OS subroutines.
*/
#include <stdlib.h>
#include <time.h>
#define _SEC_IN_MINUTE 60
#define _SEC_IN_HOUR 3600
#define _SEC_IN_DAY 86400
static _CONST int DAYS_IN_MONTH[12] =
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
#define _DAYS_IN_MONTH(x) ((x == 1) ? days_in_feb : DAYS_IN_MONTH[x])
static _CONST int _DAYS_BEFORE_MONTH[12] =
{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
#define _ISLEAP(y) (((y) % 4) == 0 && (((y) % 100) != 0 || (((y)+1900) % 400) == 0))
#define _DAYS_IN_YEAR(year) (_ISLEAP(year) ? 366 : 365)
static void
validate_structure (tim_p)
struct tm *tim_p;
{
div_t res;
int days_in_feb = 28;
/* calculate time & date to account for out of range values */
if (tim_p->tm_sec < 0 || tim_p->tm_sec > 59)
{
res = div (tim_p->tm_sec, 60);
tim_p->tm_min += res.quot;
if ((tim_p->tm_sec = res.rem) < 0)
{
tim_p->tm_sec += 60;
--tim_p->tm_min;
}
}
if (tim_p->tm_min < 0 || tim_p->tm_min > 59)
{
res = div (tim_p->tm_min, 60);
tim_p->tm_hour += res.quot;
if ((tim_p->tm_min = res.rem) < 0)
{
tim_p->tm_min += 60;
--tim_p->tm_hour;
}
}
if (tim_p->tm_hour < 0 || tim_p->tm_hour > 23)
{
res = div (tim_p->tm_hour, 24);
tim_p->tm_mday += res.quot;
if ((tim_p->tm_hour = res.rem) < 0)
{
tim_p->tm_hour += 24;
--tim_p->tm_mday;
}
}
if (tim_p->tm_mon > 11)
{
res = div (tim_p->tm_mon, 12);
tim_p->tm_year += res.quot;
if ((tim_p->tm_mon = res.rem) < 0)
{
tim_p->tm_mon += 12;
--tim_p->tm_year;
}
}
if (_DAYS_IN_YEAR (tim_p->tm_year) == 366)
days_in_feb = 29;
if (tim_p->tm_mday <= 0)
{
while (tim_p->tm_mday <= 0)
{
if (--tim_p->tm_mon == -1)
{
tim_p->tm_year--;
tim_p->tm_mon = 11;
days_in_feb =
((_DAYS_IN_YEAR (tim_p->tm_year) == 366) ?
29 : 28);
}
tim_p->tm_mday += _DAYS_IN_MONTH (tim_p->tm_mon);
}
}
else
{
while (tim_p->tm_mday > _DAYS_IN_MONTH (tim_p->tm_mon))
{
tim_p->tm_mday -= _DAYS_IN_MONTH (tim_p->tm_mon);
if (++tim_p->tm_mon == 12)
{
tim_p->tm_year++;
tim_p->tm_mon = 0;
days_in_feb =
((_DAYS_IN_YEAR (tim_p->tm_year) == 366) ?
29 : 28);
}
}
}
}
time_t
mktime (tim_p)
struct tm *tim_p;
{
time_t tim = 0;
long days = 0;
int year;
/* validate structure */
validate_structure (tim_p);
/* compute hours, minutes, seconds */
tim += tim_p->tm_sec + (tim_p->tm_min * _SEC_IN_MINUTE) +
(tim_p->tm_hour * _SEC_IN_HOUR);
/* compute days in year */
days += tim_p->tm_mday - 1;
days += _DAYS_BEFORE_MONTH[tim_p->tm_mon];
if (tim_p->tm_mon > 1 && _DAYS_IN_YEAR (tim_p->tm_year) == 366)
days++;
/* compute day of the year */
tim_p->tm_yday = days;
if (tim_p->tm_year > 10000
|| tim_p->tm_year < -10000)
{
return (time_t) -1;
}
/* compute days in other years */
if (tim_p->tm_year > 70)
{
for (year = 70; year < tim_p->tm_year; year++)
days += _DAYS_IN_YEAR (year);
}
else if (tim_p->tm_year < 70)
{
for (year = 69; year > tim_p->tm_year; year--)
days -= _DAYS_IN_YEAR (year);
days -= _DAYS_IN_YEAR (year);
}
/* compute day of the week */
if ((tim_p->tm_wday = (days + 4) % 7) < 0)
tim_p->tm_wday += 7;
/* compute total seconds */
tim += (days * _SEC_IN_DAY);
return tim;
}

444
agbcc/libc/time/strftime.c Normal file
View File

@ -0,0 +1,444 @@
/*
* strftime.c
* Original Author: G. Haley
*
* Places characters into the array pointed to by s as controlled by the string
* pointed to by format. If the total number of resulting characters including
* the terminating null character is not more than maxsize, returns the number
* of characters placed into the array pointed to by s (not including the
* terminating null character); otherwise zero is returned and the contents of
* the array indeterminate.
*/
/*
FUNCTION
<<strftime>>---flexible calendar time formatter
INDEX
strftime
ANSI_SYNOPSIS
#include <time.h>
size_t strftime(char *<[s]>, size_t <[maxsize]>,
const char *<[format]>, const struct tm *<[timp]>);
TRAD_SYNOPSIS
#include <time.h>
size_t strftime(<[s]>, <[maxsize]>, <[format]>, <[timp]>)
char *<[s]>;
size_t <[maxsize]>;
char *<[format]>;
struct tm *<[timp]>;
DESCRIPTION
<<strftime>> converts a <<struct tm>> representation of the time (at
<[timp]>) into a string, starting at <[s]> and occupying no more than
<[maxsize]> characters.
You control the format of the output using the string at <[format]>.
<<*<[format]>>> can contain two kinds of specifications: text to be
copied literally into the formatted string, and time conversion
specifications. Time conversion specifications are two-character
sequences beginning with `<<%>>' (use `<<%%>>' to include a percent
sign in the output). Each defined conversion specification selects a
field of calendar time data from <<*<[timp]>>>, and converts it to a
string in one of the following ways:
o+
o %a
An abbreviation for the day of the week.
o %A
The full name for the day of the week.
o %b
An abbreviation for the month name.
o %B
The full name of the month.
o %c
A string representing the complete date and time, in the form
. Mon Apr 01 13:13:13 1992
o %d
The day of the month, formatted with two digits.
o %H
The hour (on a 24-hour clock), formatted with two digits.
o %I
The hour (on a 12-hour clock), formatted with two digits.
o %j
The count of days in the year, formatted with three digits
(from `<<001>>' to `<<366>>').
o %m
The month number, formatted with two digits.
o %M
The minute, formatted with two digits.
o %p
Either `<<AM>>' or `<<PM>>' as appropriate.
o %S
The second, formatted with two digits.
o %U
The week number, formatted with two digits (from `<<00>>' to `<<53>>';
week number 1 is taken as beginning with the first Sunday in a year).
See also <<%W>>.
o %w
A single digit representing the day of the week: Sunday is day <<0>>.
o %W
Another version of the week number: like `<<%U>>', but counting week 1
as beginning with the first Monday in a year.
o
o %x
A string representing the complete date, in a format like
. Mon Apr 01 1992
o %X
A string representing the full time of day (hours, minutes, and
seconds), in a format like
. 13:13:13
o %y
The last two digits of the year.
o %Y
The full year, formatted with four digits to include the century.
o %Z
Defined by ANSI C as eliciting the time zone if available; it is not
available in this implementation (which accepts `<<%Z>>' but generates
no output for it).
o %%
A single character, `<<%>>'.
o-
RETURNS
When the formatted time takes up no more than <[maxsize]> characters,
the result is the length of the formatted string. Otherwise, if the
formatting operation was abandoned due to lack of room, the result is
<<0>>, and the string starting at <[s]> corresponds to just those
parts of <<*<[format]>>> that could be completely filled in within the
<[maxsize]> limit.
PORTABILITY
ANSI C requires <<strftime>>, but does not specify the contents of
<<*<[s]>>> when the formatted string would require more than
<[maxsize]> characters.
<<strftime>> requires no supporting OS subroutines.
*/
#include <stddef.h>
#include <stdio.h>
#include <time.h>
static _CONST int dname_len[7] =
{6, 6, 7, 9, 8, 6, 8};
static _CONST char *_CONST dname[7] =
{"Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday"};
static _CONST int mname_len[12] =
{7, 8, 5, 5, 3, 4, 4, 6, 9, 7, 8, 8};
static _CONST char *_CONST mname[12] =
{"January", "February", "March", "April",
"May", "June", "July", "August", "September", "October", "November",
"December"};
size_t
_DEFUN (strftime, (s, maxsize, format, tim_p),
char *s _AND
size_t maxsize _AND
_CONST char *format _AND
_CONST struct tm *tim_p)
{
size_t count = 0;
int i;
for (;;)
{
while (*format && *format != '%')
{
if (count < maxsize - 1)
s[count++] = *format++;
else
return 0;
}
if (*format == '\0')
break;
format++;
switch (*format)
{
case 'a':
for (i = 0; i < 3; i++)
{
if (count < maxsize - 1)
s[count++] =
dname[tim_p->tm_wday][i];
else
return 0;
}
break;
case 'A':
for (i = 0; i < dname_len[tim_p->tm_wday]; i++)
{
if (count < maxsize - 1)
s[count++] =
dname[tim_p->tm_wday][i];
else
return 0;
}
break;
case 'b':
for (i = 0; i < 3; i++)
{
if (count < maxsize - 1)
s[count++] =
mname[tim_p->tm_mon][i];
else
return 0;
}
break;
case 'B':
for (i = 0; i < mname_len[tim_p->tm_mon]; i++)
{
if (count < maxsize - 1)
s[count++] =
mname[tim_p->tm_mon][i];
else
return 0;
}
break;
case 'c':
if (count < maxsize - 24)
{
for (i = 0; i < 3; i++)
s[count++] =
dname[tim_p->tm_wday][i];
s[count++] = ' ';
for (i = 0; i < 3; i++)
s[count++] =
mname[tim_p->tm_mon][i];
sprintf (&s[count],
" %.2d %2.2d:%2.2d:%2.2d %.4d",
tim_p->tm_mday, tim_p->tm_hour,
tim_p->tm_min,
tim_p->tm_sec, 1900 +
tim_p->tm_year);
count += 17;
}
else
return 0;
break;
case 'd':
if (count < maxsize - 2)
{
sprintf (&s[count], "%.2d",
tim_p->tm_mday);
count += 2;
}
else
return 0;
break;
case 'H':
if (count < maxsize - 2)
{
sprintf (&s[count], "%2.2d",
tim_p->tm_hour);
count += 2;
}
else
return 0;
break;
case 'I':
if (count < maxsize - 2)
{
if (tim_p->tm_hour == 0 ||
tim_p->tm_hour == 12)
{
s[count++] = '1';
s[count++] = '2';
}
else
{
sprintf (&s[count], "%.2d",
tim_p->tm_hour % 12);
count += 2;
}
}
else
return 0;
break;
case 'j':
if (count < maxsize - 3)
{
sprintf (&s[count], "%.3d",
tim_p->tm_yday + 1);
count += 3;
}
else
return 0;
break;
case 'm':
if (count < maxsize - 2)
{
sprintf (&s[count], "%.2d",
tim_p->tm_mon + 1);
count += 2;
}
else
return 0;
break;
case 'M':
if (count < maxsize - 2)
{
sprintf (&s[count], "%2.2d",
tim_p->tm_min);
count += 2;
}
else
return 0;
break;
case 'p':
if (count < maxsize - 2)
{
if (tim_p->tm_hour < 12)
s[count++] = 'A';
else
s[count++] = 'P';
s[count++] = 'M';
}
else
return 0;
break;
case 'S':
if (count < maxsize - 2)
{
sprintf (&s[count], "%2.2d",
tim_p->tm_sec);
count += 2;
}
else
return 0;
break;
case 'U':
if (count < maxsize - 2)
{
sprintf (&s[count], "%2.2d",
(tim_p->tm_yday + 7 -
tim_p->tm_wday) / 7);
count += 2;
}
else
return 0;
break;
case 'w':
if (count < maxsize - 1)
{
sprintf (&s[count], "%1.1d",
tim_p->tm_wday);
count++;
}
else
return 0;
break;
case 'W':
if (count < maxsize - 2)
{
sprintf (&s[count], "%2.2d",
(tim_p->tm_yday + ((8 -
tim_p->tm_wday) % 7)) / 7);
count += 2;
}
else
return 0;
break;
case 'x':
if (count < maxsize - 15)
{
for (i = 0; i < 3; i++)
s[count++] =
dname[tim_p->tm_wday][i];
s[count++] = ' ';
for (i = 0; i < 3; i++)
s[count++] =
mname[tim_p->tm_mon][i];
sprintf (&s[count],
" %.2d %.4d", tim_p->tm_mday,
1900 + tim_p->tm_year);
count += 8;
}
else
return 0;
break;
case 'X':
if (count < maxsize - 8)
{
sprintf (&s[count],
"%2.2d:%2.2d:%2.2d",
tim_p->tm_hour, tim_p->tm_min,
tim_p->tm_sec);
count += 8;
}
else
return 0;
break;
case 'y':
if (count < maxsize - 2)
{
/* The year could be greater than 100, so we need the value
modulo 100. The year could be negative, so we need to
correct for a possible negative remainder. */
sprintf (&s[count], "%2.2d",
(tim_p->tm_year % 100 + 100) % 100);
count += 2;
}
else
return 0;
break;
case 'Y':
if (count < maxsize - 4)
{
sprintf (&s[count], "%.4d",
1900 + tim_p->tm_year);
count += 4;
}
else
return 0;
break;
case 'Z':
break;
case '%':
if (count < maxsize - 1)
s[count++] = '%';
else
return 0;
break;
}
if (*format)
format++;
else
break;
}
s[count] = '\0';
return count;
}

59
agbcc/libc/time/time.c Normal file
View File

@ -0,0 +1,59 @@
/* FIXME: doc says "not avail" due to #if 0.
DELETE that line if inappropriate! */
/*
FUNCTION
<<time>>---get current calendar time (as single number)
INDEX
time
ANSI_SYNOPSIS
#include <time.h>
time_t time(time_t *<[t]>);
TRAD_SYNOPSIS
#include <time.h>
time_t time(<[t]>)
time_t *<[t]>;
DESCRIPTION
<<time>> looks up the best available representation of the current
time and returns it, encoded as a <<time_t>>. It stores the same
value at <[t]> unless the argument is <<NULL>>.
RETURNS
A <<-1>> result means the current time is not available; otherwise the
result represents the current time.
PORTABILITY
ANSI C requires <<time>>.
Supporting OS subroutine required: Some implementations require
<<gettimeofday>>.
*/
#ifdef HAVE_GETTIMEOFDAY
/* Most times we have a system call in newlib/libc/sys/.. to do this job */
#include <_ansi.h>
#include <reent.h>
#include <sys/types.h>
#include <sys/time.h>
time_t
_DEFUN (time, (t),
time_t * t)
{
struct timeval now;
if (_gettimeofday_r (_REENT, &now, (struct timezone *) 0) >= 0)
{
if (t)
*t = now.tv_sec;
return now.tv_sec;
}
return -1;
}
#endif