add directory gnu

This commit is contained in:
gohigh
2024-02-19 00:24:47 -05:00
parent 32616db5a4
commit a40f4cadb0
5086 changed files with 1860970 additions and 0 deletions

View File

@@ -0,0 +1,42 @@
# Copyright (C) 1991, 1992 Free Software Foundation, Inc.
# This file is part of the GNU C Library.
# The GNU C Library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public License as
# published by the Free Software Foundation; either version 2 of the
# License, or (at your option) any later version.
# The GNU C Library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Library General Public License for more details.
# You should have received a copy of the GNU Library General Public
# License along with the GNU C Library; see the file COPYING.LIB. If
# not, write to the Free Software Foundation, Inc., 675 Mass Ave,
# Cambridge, MA 02139, USA.
#
# Makefile for stdlib routines
#
subdir := stdlib
headers := stdlib.h alloca.h
routines := \
atof atoi atol \
abort \
bsearch qsort \
getenv putenv \
exit on_exit atexit \
abs labs \
div ldiv \
mblen mbstowcs mbtowc wcstombs wctomb \
__random random rand srand \
strtod strtol strtoul \
system
distribute := exit.h
tests := tst-strtol tst-strtod
include ../Rules

View File

@@ -0,0 +1,349 @@
/*
* Copyright (c) 1983 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.
*/
/*
* This is derived from the Berkeley source:
* @(#)random.c 5.5 (Berkeley) 7/6/88
* It was reworked for the GNU C Library by Roland McGrath.
*/
#include <ansidecl.h>
#include <errno.h>
#include <limits.h>
#include <stddef.h>
#include <stdlib.h>
/* An improved random number generation package. In addition to the standard
rand()/srand() like interface, this package also has a special state info
interface. The initstate() routine is called with a seed, an array of
bytes, and a count of how many bytes are being passed in; this array is
then initialized to contain information for random number generation with
that much state information. Good sizes for the amount of state
information are 32, 64, 128, and 256 bytes. The state can be switched by
calling the setstate() function with the same array as was initiallized
with initstate(). By default, the package runs with 128 bytes of state
information and generates far better random numbers than a linear
congruential generator. If the amount of state information is less than
32 bytes, a simple linear congruential R.N.G. is used. Internally, the
state information is treated as an array of longs; the zeroeth element of
the array is the type of R.N.G. being used (small integer); the remainder
of the array is the state information for the R.N.G. Thus, 32 bytes of
state information will give 7 longs worth of state information, which will
allow a degree seven polynomial. (Note: The zeroeth word of state
information also has some other information stored in it; see setstate
for details). The random number generation technique is a linear feedback
shift register approach, employing trinomials (since there are fewer terms
to sum up that way). In this approach, the least significant bit of all
the numbers in the state table will act as a linear feedback shift register,
and will have period 2^deg - 1 (where deg is the degree of the polynomial
being used, assuming that the polynomial is irreducible and primitive).
The higher order bits will have longer periods, since their values are
also influenced by pseudo-random carries out of the lower bits. The
total period of the generator is approximately deg*(2**deg - 1); thus
doubling the amount of state information has a vast influence on the
period of the generator. Note: The deg*(2**deg - 1) is an approximation
only good for large deg, when the period of the shift register is the
dominant factor. With deg equal to seven, the period is actually much
longer than the 7*(2**7 - 1) predicted by this formula. */
/* For each of the currently supported random number generators, we have a
break value on the amount of state information (you need at least thi
bytes of state info to support this random number generator), a degree for
the polynomial (actually a trinomial) that the R.N.G. is based on, and
separation between the two lower order coefficients of the trinomial. */
/* Linear congruential. */
#define TYPE_0 0
#define BREAK_0 8
#define DEG_0 0
#define SEP_0 0
/* x**7 + x**3 + 1. */
#define TYPE_1 1
#define BREAK_1 32
#define DEG_1 7
#define SEP_1 3
/* x**15 + x + 1. */
#define TYPE_2 2
#define BREAK_2 64
#define DEG_2 15
#define SEP_2 1
/* x**31 + x**3 + 1. */
#define TYPE_3 3
#define BREAK_3 128
#define DEG_3 31
#define SEP_3 3
/* x**63 + x + 1. */
#define TYPE_4 4
#define BREAK_4 256
#define DEG_4 63
#define SEP_4 1
/* Array versions of the above information to make code run faster.
Relies on fact that TYPE_i == i. */
#define MAX_TYPES 5 /* Max number of types above. */
static int degrees[MAX_TYPES] = { DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 };
static int seps[MAX_TYPES] = { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 };
/* Initially, everything is set up as if from:
initstate(1, randtbl, 128);
Note that this initialization takes advantage of the fact that srandom
advances the front and rear pointers 10*rand_deg times, and hence the
rear pointer which starts at 0 will also end up at zero; thus the zeroeth
element of the state information, which contains info about the current
position of the rear pointer is just
(MAX_TYPES * (rptr - state)) + TYPE_3 == TYPE_3. */
static long int randtbl[DEG_3 + 1] =
{ TYPE_3,
0x9a319039, 0x32d9c024, 0x9b663182, 0x5da1f342,
0xde3b81e0, 0xdf0a6fb5, 0xf103bc02, 0x48f340fb,
0x7449e56b, 0xbeb1dbb0, 0xab5c5918, 0x946554fd,
0x8c2e680f, 0xeb3d799f, 0xb11ee0b7, 0x2d436b86,
0xda672e2a, 0x1588ca88, 0xe369735d, 0x904f35f7,
0xd7158fd6, 0x6fa6f051, 0x616e6b96, 0xac94efdc,
0x36413f93, 0xc622c298, 0xf5a42ab8, 0x8a88d77b,
0xf5ad9d0e, 0x8999220b, 0x27fb47b9
};
/* FPTR and RPTR are two pointers into the state info, a front and a rear
pointer. These two pointers are always rand_sep places aparts, as they
cycle through the state information. (Yes, this does mean we could get
away with just one pointer, but the code for random is more efficient
this way). The pointers are left positioned as they would be from the call:
initstate(1, randtbl, 128);
(The position of the rear pointer, rptr, is really 0 (as explained above
in the initialization of randtbl) because the state table pointer is set
to point to randtbl[1] (as explained below).) */
static long int *fptr = &randtbl[SEP_3 + 1];
static long int *rptr = &randtbl[1];
/* The following things are the pointer to the state information table,
the type of the current generator, the degree of the current polynomial
being used, and the separation between the two pointers.
Note that for efficiency of random, we remember the first location of
the state information, not the zeroeth. Hence it is valid to access
state[-1], which is used to store the type of the R.N.G.
Also, we remember the last location, since this is more efficient than
indexing every time to find the address of the last element to see if
the front and rear pointers have wrapped. */
static long int *state = &randtbl[1];
static int rand_type = TYPE_3;
static int rand_deg = DEG_3;
static int rand_sep = SEP_3;
static long int *end_ptr = &randtbl[sizeof(randtbl) / sizeof(randtbl[0])];
/* Initialize the random number generator based on the given seed. If the
type is the trivial no-state-information type, just remember the seed.
Otherwise, initializes state[] based on the given "seed" via a linear
congruential generator. Then, the pointers are set to known locations
that are exactly rand_sep places apart. Lastly, it cycles the state
information a given number of times to get rid of any initial dependencies
introduced by the L.C.R.N.G. Note that the initialization of randtbl[]
for default usage relies on values produced by this routine. */
void
DEFUN(__srandom, (x), unsigned int x)
{
state[0] = x;
if (rand_type != TYPE_0)
{
register long int i;
for (i = 1; i < rand_deg; ++i)
state[i] = (1103515145 * state[i - 1]) + 12345;
fptr = &state[rand_sep];
rptr = &state[0];
for (i = 0; i < 10 * rand_deg; ++i)
(void) __random();
}
}
/* Initialize the state information in the given array of N bytes for
future random number generation. Based on the number of bytes we
are given, and the break values for the different R.N.G.'s, we choose
the best (largest) one we can and set things up for it. srandom is
then called to initialize the state information. Note that on return
from srandom, we set state[-1] to be the type multiplexed with the current
value of the rear pointer; this is so successive calls to initstate won't
lose this information and will be able to restart with setstate.
Note: The first thing we do is save the current state, if any, just like
setstate so that it doesn't matter when initstate is called.
Returns a pointer to the old state. */
PTR
DEFUN(__initstate, (seed, arg_state, n),
unsigned int seed AND PTR arg_state AND size_t n)
{
PTR ostate = (PTR) &state[-1];
if (rand_type == TYPE_0)
state[-1] = rand_type;
else
state[-1] = (MAX_TYPES * (rptr - state)) + rand_type;
if (n < BREAK_1)
{
if (n < BREAK_0)
{
errno = EINVAL;
return NULL;
}
rand_type = TYPE_0;
rand_deg = DEG_0;
rand_sep = SEP_0;
}
else if (n < BREAK_2)
{
rand_type = TYPE_1;
rand_deg = DEG_1;
rand_sep = SEP_1;
}
else if (n < BREAK_3)
{
rand_type = TYPE_2;
rand_deg = DEG_2;
rand_sep = SEP_2;
}
else if (n < BREAK_4)
{
rand_type = TYPE_3;
rand_deg = DEG_3;
rand_sep = SEP_3;
}
else
{
rand_type = TYPE_4;
rand_deg = DEG_4;
rand_sep = SEP_4;
}
state = &((long int *) arg_state)[1]; /* First location. */
/* Must set END_PTR before srandom. */
end_ptr = &state[rand_deg];
__srandom(seed);
if (rand_type == TYPE_0)
state[-1] = rand_type;
else
state[-1] = (MAX_TYPES * (rptr - state)) + rand_type;
return ostate;
}
/* Restore the state from the given state array.
Note: It is important that we also remember the locations of the pointers
in the current state information, and restore the locations of the pointers
from the old state information. This is done by multiplexing the pointer
location into the zeroeth word of the state information. Note that due
to the order in which things are done, it is OK to call setstate with the
same state as the current state
Returns a pointer to the old state information. */
PTR
DEFUN(__setstate, (arg_state), PTR arg_state)
{
register long int *new_state = (long int *) arg_state;
register int type = new_state[0] % MAX_TYPES;
register int rear = new_state[0] / MAX_TYPES;
PTR ostate = (PTR) &state[-1];
if (rand_type == TYPE_0)
state[-1] = rand_type;
else
state[-1] = (MAX_TYPES * (rptr - state)) + rand_type;
switch (type)
{
case TYPE_0:
case TYPE_1:
case TYPE_2:
case TYPE_3:
case TYPE_4:
rand_type = type;
rand_deg = degrees[type];
rand_sep = seps[type];
break;
default:
/* State info munged. */
errno = EINVAL;
return NULL;
}
state = &new_state[1];
if (rand_type != TYPE_0)
{
rptr = &state[rear];
fptr = &state[(rear + rand_sep) % rand_deg];
}
/* Set end_ptr too. */
end_ptr = &state[rand_deg];
return ostate;
}
/* If we are using the trivial TYPE_0 R.N.G., just do the old linear
congruential bit. Otherwise, we do our fancy trinomial stuff, which is the
same in all ther other cases due to all the global variables that have been
set up. The basic operation is to add the number at the rear pointer into
the one at the front pointer. Then both pointers are advanced to the next
location cyclically in the table. The value returned is the sum generated,
reduced to 31 bits by throwing away the "least random" low bit.
Note: The code takes advantage of the fact that both the front and
rear pointers can't wrap on the same call by not testing the rear
pointer if the front one has wrapped. Returns a 31-bit random number. */
long int
DEFUN_VOID(__random)
{
if (rand_type == TYPE_0)
{
state[0] = ((state[0] * 1103515245) + 12345) & LONG_MAX;
return state[0];
}
else
{
long int i;
*fptr += *rptr;
/* Chucking least random bit. */
i = (*fptr >> 1) & LONG_MAX;
++fptr;
if (fptr >= end_ptr)
{
fptr = state;
++rptr;
}
else
{
++rptr;
if (rptr >= end_ptr)
rptr = state;
}
return i;
}
}

View File

@@ -0,0 +1,62 @@
/* Copyright (C) 1991 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
/* Cause an abnormal program termination with core-dump. */
__NORETURN
void
DEFUN_VOID(abort)
{
sig_atomic_t aborting = 0;
sigset_t sigs;
if (__sigemptyset(&sigs) == 0 &&
__sigaddset(&sigs, SIGABRT) == 0)
(void) __sigprocmask(SIG_UNBLOCK, &sigs, (sigset_t *) NULL);
if (!aborting)
{
aborting = 1;
#ifdef HAVE_GNU_LD
{
extern unsigned long int __libc_atexit[];
register unsigned long int i;
for (i = 1; i <= __libc_atexit[0]; ++i)
(*(void EXFUN((*), (NOARGS))) __libc_atexit[i])();
}
#else
{
extern void EXFUN(_cleanup, (NOARGS));
_cleanup();
}
#endif
}
while (1)
if (raise(SIGABRT))
/* If we can't signal ourselves, exit. */
_exit(127);
/* If we signal ourselves and are still alive,
or can't exit, loop forever. */
}

View File

@@ -0,0 +1,30 @@
/* Copyright (C) 1991 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stdlib.h>
#undef abs
/* Return the absolute value of I. */
__CONSTVALUE
int
DEFUN(abs, (i), int i)
{
return(i < 0 ? -i : i);
}

View File

@@ -0,0 +1,40 @@
/* Copyright (C) 1992 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#ifndef _ALLOCA_H
#define _ALLOCA_H 1
#include <features.h>
#define __need_size_t
#include <stddef.h>
/* Remove any previous definitions. */
#undef __alloca
#undef alloca
/* Allocate a block that will be freed when the calling function exits. */
extern PTR EXFUN(__alloca, (size_t __size));
extern PTR EXFUN(alloca, (size_t __size));
#ifdef __GNUC__
#define __alloca(size) __builtin_alloca(size)
#endif /* GCC. */
#define alloca(size) __alloca(size)
#endif /* alloca.h */

View File

@@ -0,0 +1,65 @@
/* Copyright (C) 1991 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stdlib.h>
#include "exit.h"
/* Register FUNC to be executed by `exit'. */
int
DEFUN(atexit, (func), void EXFUN((*func), (NOARGS)))
{
struct exit_function *new = __new_exitfn();
if (new == NULL)
return -1;
new->flavor = ef_at;
new->func.at = func;
return 0;
}
static struct exit_function_list fnlist = { NULL, 0, };
struct exit_function_list *__exit_funcs = &fnlist;
struct exit_function *
DEFUN_VOID(__new_exitfn)
{
register struct exit_function_list *l;
for (l = __exit_funcs; l != NULL; l = l->next)
{
register size_t i;
for (i = 0; i < l->idx; ++i)
if (l->fns[i].flavor == ef_free)
return &l->fns[i];
if (l->idx < sizeof(l->fns) / sizeof(l->fns[0]))
return &l->fns[l->idx++];
}
l = (struct exit_function_list *) malloc(sizeof(struct exit_function_list));
if (l == NULL)
return NULL;
l->next = __exit_funcs;
__exit_funcs = l;
l->idx = 1;
return &l->fns[0];
}

View File

@@ -0,0 +1,30 @@
/* Copyright (C) 1991 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stdlib.h>
#undef atof
/* Convert a string to a double. */
double
DEFUN(atof, (nptr), CONST char *nptr)
{
return(strtod(nptr, (char **) NULL));
}

View File

@@ -0,0 +1,30 @@
/* Copyright (C) 1991 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stdlib.h>
#undef atoi
/* Convert a string to an int. */
int
DEFUN(atoi, (nptr), CONST char *nptr)
{
return((int) strtol(nptr, (char **) NULL, 10));
}

View File

@@ -0,0 +1,30 @@
/* Copyright (C) 1991 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stdlib.h>
#undef atol
/* Convert a string to a long int. */
long int
DEFUN(atol, (nptr), CONST char *nptr)
{
return(strtol(nptr, (char **) NULL, 10));
}

View File

@@ -0,0 +1,56 @@
/* Copyright (C) 1991 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stdlib.h>
/* Perform a binary search for KEY in BASE which has NMEMB elements
of SIZE bytes each. The comparisons are done by (*COMPAR)(). */
PTR
DEFUN(bsearch, (key, base, nmemb, size, compar),
register CONST PTR key AND register CONST PTR base AND
size_t nmemb AND register size_t size AND
register int EXFUN((*compar), (CONST PTR, CONST PTR)))
{
register size_t l, u, idx;
register CONST PTR p;
register int comparison;
l = 0;
u = nmemb - 1;
while (l <= u)
{
idx = (l + u) / 2;
p = (PTR) (((CONST char *) base) + (idx * size));
comparison = (*compar)(key, p);
/* Don't make U negative because it will wrap around. */
if (comparison < 0)
{
if (idx == 0)
break;
u = idx - 1;
}
else if (comparison > 0)
l = idx + 1;
else
return (PTR) p;
}
return NULL;
}

View File

@@ -0,0 +1,39 @@
/* Copyright (C) 1991 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stdlib.h>
/* Return the `div_t' representation of NUMER over DENOM. */
__CONSTVALUE
div_t
DEFUN(div, (numer, denom), int numer AND int denom)
{
div_t result;
/* Behavior for negative numbers is guaranteed. */
register int sign = (numer < 0) == (denom < 0) ? 1 : -1;
numer = numer < 0 ? -numer : numer;
denom = denom < 0 ? -denom : denom;
result.quot = (numer / denom) * sign;
result.rem = (numer % denom) * sign;
return(result);
}

View File

@@ -0,0 +1,77 @@
/* Copyright (C) 1991 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "exit.h"
#ifdef HAVE_GNU_LD
CONST struct
{
size_t n;
void EXFUN((*fn[1]), (NOARGS));
} __libc_atexit;
#endif
/* Call all functions registered with `atexit' and `on_exit',
in the reverse of the order in which they were registered
perform stdio cleanup, and terminate program execution with STATUS. */
__NORETURN
void
DEFUN(exit, (status), int status)
{
register CONST struct exit_function_list *l;
for (l = __exit_funcs; l != NULL; l = l->next)
{
register size_t i = l->idx;
while (i-- > 0)
{
CONST struct exit_function *CONST f = &l->fns[i];
switch (f->flavor)
{
case ef_free:
break;
case ef_on:
(*f->func.on.fn)(status, f->func.on.arg);
break;
case ef_at:
(*f->func.at)();
break;
}
}
}
#ifdef HAVE_GNU_LD
{
void EXFUN((*CONST *fn), (NOARGS));
for (fn = __libc_atexit.fn; *fn != NULL; ++fn)
(**fn) ();
}
#else
{
extern void EXFUN(_cleanup, (NOARGS));
_cleanup();
}
#endif
_exit(status);
}

View File

@@ -0,0 +1,44 @@
/* Copyright (C) 1991 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#ifndef _EXIT_H
struct exit_function
{
enum { ef_free, ef_on, ef_at } flavor; /* `ef_free' MUST be zero! */
union
{
void EXFUN((*at), (NOARGS));
struct
{
void EXFUN((*fn), (int status, PTR arg));
PTR arg;
} on;
} func;
};
struct exit_function_list
{
struct exit_function_list *next;
size_t idx;
struct exit_function fns[32];
};
extern struct exit_function_list *__exit_funcs;
extern struct exit_function *EXFUN(__new_exitfn, (NOARGS));
#endif /* exit.h */

View File

@@ -0,0 +1,31 @@
/* Copyright (C) 1991 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stdlib.h>
#undef labs
/* Return the absolute value of I. */
__CONSTVALUE
long int
DEFUN(labs, (i), long int i)
{
return(i < 0 ? -i : i);
}

View File

@@ -0,0 +1,39 @@
/* Copyright (C) 1991 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stdlib.h>
/* Return the `ldiv_t' representation of NUMER over DENOM. */
__CONSTVALUE
ldiv_t
DEFUN(ldiv, (numer, denom), long int numer AND long int denom)
{
ldiv_t result;
/* Behavior for negative numbers is guaranteed. */
register long int sign = (numer < 0L) == (denom < 0L) ? 1L : -1L;
numer = numer < 0L ? -numer : numer;
denom = denom < 0L ? -denom : denom;
result.quot = (numer / denom) * sign;
result.rem = (numer % denom) * sign;
return result;
}

View File

@@ -0,0 +1,31 @@
/* Copyright (C) 1991 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stdlib.h>
#undef mblen
/* Return the length of the multibyte character (if there is one)
at S which is no longer than N characters. */
int
DEFUN(mblen, (s, n), CONST char *s AND size_t n)
{
return(mbtowc((wchar_t *) NULL, s, n));
}

View File

@@ -0,0 +1,70 @@
/* Copyright (C) 1991 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <ctype.h>
#include <stddef.h>
#include <stdlib.h>
extern int _mb_shift; /* Defined in mbtowc.c. */
/* Convert the string of multibyte characters in S to `wchar_t's in
PWCS, writing no more than N. Return the number written,
or (size_t) -1 if an invalid multibyte character is encountered. */
size_t
DEFUN(mbstowcs, (pwcs, s, n),
register wchar_t *pwcs AND register CONST char *s AND register size_t n)
{
int save_shift;
register size_t written = 0;
/* Save the shift state. */
save_shift = _mb_shift;
/* Reset the shift state. */
_mb_shift = 0;
while (*s != '\0')
{
int len;
if (isascii(*s) || (len = mbtowc(pwcs, s, n)) < 1)
{
/* Return an error. */
written = (size_t) -1;
break;
}
else
{
/* Multibyte character converted. */
++pwcs;
++written;
s += len;
n -= len;
}
}
/* Terminate the string if it has space. */
if (n > 0)
*pwcs = (wchar_t) 0;
/* Restore the old shift state. */
_mb_shift = save_shift;
/* Return how many we wrote (or maybe an error). */
return written;
}

View File

@@ -0,0 +1,74 @@
/* Copyright (C) 1991 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <localeinfo.h>
#include <ctype.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
long int _mb_shift = 0;
/* Convert the multibyte character at S, which is no longer
than N characters, to its `wchar_t' representation, placing
this n *PWC and returning its length. */
int
DEFUN(mbtowc, (pwc, s, n), wchar_t *pwc AND CONST char *s AND size_t n)
{
register CONST mb_char *mb;
register wchar_t i;
if (s == NULL)
return _mb_shift != 0;
if (_ctype_info->mbchar == NULL ||
_ctype_info->mbchar->mb_chars == NULL)
return -1;
if (*s == '\0')
return 0;
if (n > MB_CUR_MAX)
n = MB_CUR_MAX;
for (i = 0; i < WCHAR_MAX; ++i)
{
mb = &_ctype_info->mbchar->mb_chars[i];
/* EOF and NUL aren't MB chars. */
if (i == (wchar_t) EOF || i == (wchar_t) '\0')
continue;
/* Normal ASCII values can't start MB chars. */
else if (isascii(i))
continue;
else if (mb->string == NULL || mb->len == 0)
continue;
else if (mb->len > n)
continue;
else if (!strncmp(mb->string, s, mb->len))
{
_mb_shift += mb->shift;
if (pwc != NULL)
*pwc = i;
return mb->len;
}
}
return -1;
}

View File

@@ -0,0 +1,37 @@
/* Copyright (C) 1991 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stdlib.h>
#include "exit.h"
/* Register a function to be called by exit. */
int
DEFUN(on_exit, (func, arg),
void EXFUN((*func), (int status, PTR arg)) AND PTR arg)
{
struct exit_function *new = __new_exitfn();
if (new == NULL)
return -1;
new->flavor = ef_on;
new->func.on.fn = func;
new->func.on.arg = arg;
return 0;
}

View File

@@ -0,0 +1,239 @@
/* Copyright (C) 1991 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Douglas C. Schmidt (schmidt@ics.uci.edu).
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stdlib.h>
#include <string.h>
/* Byte-wise swap two items of size SIZE. */
#define SWAP(a, b, size) \
do \
{ \
register size_t __size = (size); \
register char *__a = (a), *__b = (b); \
do \
{ \
char __tmp = *__a; \
*__a++ = *__b; \
*__b++ = __tmp; \
} while (--__size > 0); \
} while (0)
/* Discontinue quicksort algorithm when partition gets below this size.
This particular magic number was chosen to work best on a Sun 4/260. */
#define MAX_THRESH 4
/* Stack node declarations used to store unfulfilled partition obligations. */
typedef struct
{
char *lo;
char *hi;
} stack_node;
/* The next 4 #defines implement a very fast in-line stack abstraction. */
#define STACK_SIZE (8 * sizeof(unsigned long int))
#define PUSH(low, high) ((void) ((top->lo = (low)), (top->hi = (high)), ++top))
#define POP(low, high) ((void) (--top, (low = top->lo), (high = top->hi)))
#define STACK_NOT_EMPTY (stack < top)
/* Order size using quicksort. This implementation incorporates
four optimizations discussed in Sedgewick:
1. Non-recursive, using an explicit stack of pointer that store the
next array partition to sort. To save time, this maximum amount
of space required to store an array of MAX_INT is allocated on the
stack. Assuming a 32-bit integer, this needs only 32 *
sizeof(stack_node) == 136 bits. Pretty cheap, actually.
2. Chose the pivot element using a median-of-three decision tree.
This reduces the probability of selecting a bad pivot value and
eliminates certain extraneous comparisons.
3. Only quicksorts TOTAL_ELEMS / MAX_THRESH partitions, leaving
insertion sort to order the MAX_THRESH items within each partition.
This is a big win, since insertion sort is faster for small, mostly
sorted array segements.
4. The larger of the two sub-partitions is always pushed onto the
stack first, with the algorithm then concentrating on the
smaller partition. This *guarantees* no more than log (n)
stack size is needed (actually O(1) in this case)! */
void
DEFUN(qsort, (pbase, total_elems, size, cmp),
PTR CONST pbase AND size_t total_elems AND size_t size AND
int EXFUN((*cmp), (CONST PTR, CONST PTR)))
{
register char *base_ptr = (char *) pbase;
/* Allocating SIZE bytes for a pivot buffer facilitates a better
algorithm below since we can do comparisons directly on the pivot. */
char *pivot_buffer = (char *) __alloca (size);
CONST size_t max_thresh = MAX_THRESH * size;
if (total_elems > MAX_THRESH)
{
char *lo = base_ptr;
char *hi = &lo[size * (total_elems - 1)];
/* Largest size needed for 32-bit int!!! */
stack_node stack[STACK_SIZE];
stack_node *top = stack + 1;
while (STACK_NOT_EMPTY)
{
char *left_ptr;
char *right_ptr;
char *pivot = pivot_buffer;
/* Select median value from among LO, MID, and HI. Rearrange
LO and HI so the three values are sorted. This lowers the
probability of picking a pathological pivot value and
skips a comparison for both the LEFT_PTR and RIGHT_PTR. */
char *mid = lo + size * ((hi - lo) / size >> 1);
if ((*cmp)((PTR) mid, (PTR) lo) < 0)
SWAP(mid, lo, size);
if ((*cmp)((PTR) hi, (PTR) mid) < 0)
SWAP(mid, hi, size);
else
goto jump_over;
if ((*cmp)((PTR) mid, (PTR) lo) < 0)
SWAP(mid, lo, size);
jump_over:;
memcpy(pivot, mid, size);
pivot = pivot_buffer;
left_ptr = lo + size;
right_ptr = hi - size;
/* Here's the famous ``collapse the walls'' section of quicksort.
Gotta like those tight inner loops! They are the main reason
that this algorithm runs much faster than others. */
do
{
while ((*cmp)((PTR) left_ptr, (PTR) pivot) < 0)
left_ptr += size;
while ((*cmp)((PTR) pivot, (PTR) right_ptr) < 0)
right_ptr -= size;
if (left_ptr < right_ptr)
{
SWAP(left_ptr, right_ptr, size);
left_ptr += size;
right_ptr -= size;
}
else if (left_ptr == right_ptr)
{
left_ptr += size;
right_ptr -= size;
break;
}
}
while (left_ptr <= right_ptr);
/* Set up pointers for next iteration. First determine whether
left and right partitions are below the threshold size. If so,
ignore one or both. Otherwise, push the larger partition's
bounds on the stack and continue sorting the smaller one. */
if ((size_t) (right_ptr - lo) <= max_thresh)
{
if ((size_t) (hi - left_ptr) <= max_thresh)
/* Ignore both small partitions. */
POP(lo, hi);
else
/* Ignore small left partition. */
lo = left_ptr;
}
else if ((size_t) (hi - left_ptr) <= max_thresh)
/* Ignore small right partition. */
hi = right_ptr;
else if ((right_ptr - lo) > (hi - left_ptr))
{
/* Push larger left partition indices. */
PUSH(lo, right_ptr);
lo = left_ptr;
}
else
{
/* Push larger right partition indices. */
PUSH(left_ptr, hi);
hi = right_ptr;
}
}
}
/* Once the BASE_PTR array is partially sorted by quicksort the rest
is completely sorted using insertion sort, since this is efficient
for partitions below MAX_THRESH size. BASE_PTR points to the beginning
of the array to sort, and END_PTR points at the very last element in
the array (*not* one beyond it!). */
#define min(x, y) ((x) < (y) ? (x) : (y))
{
char *CONST end_ptr = &base_ptr[size * (total_elems - 1)];
char *tmp_ptr = base_ptr;
char *thresh = min(end_ptr, base_ptr + max_thresh);
register char *run_ptr;
/* Find smallest element in first threshold and place it at the
array's beginning. This is the smallest array element,
and the operation speeds up insertion sort's inner loop. */
for (run_ptr = tmp_ptr + size; run_ptr <= thresh; run_ptr += size)
if ((*cmp)((PTR) run_ptr, (PTR) tmp_ptr) < 0)
tmp_ptr = run_ptr;
if (tmp_ptr != base_ptr)
SWAP(tmp_ptr, base_ptr, size);
/* Insertion sort, running from left-hand-side up to right-hand-side. */
run_ptr = base_ptr + size;
while ((run_ptr += size) <= end_ptr)
{
tmp_ptr = run_ptr - size;
while ((*cmp)((PTR) run_ptr, (PTR) tmp_ptr) < 0)
tmp_ptr -= size;
tmp_ptr += size;
if (tmp_ptr != run_ptr)
{
char *trav;
trav = run_ptr + size;
while (--trav >= run_ptr)
{
char c = *trav;
char *hi, *lo;
for (hi = lo = trav; (lo -= size) >= tmp_ptr; hi = lo)
*hi = *lo;
*hi = c;
}
}
}
}
}

View File

@@ -0,0 +1,30 @@
/* Copyright (C) 1991 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stdlib.h>
#undef rand
/* Return a random integer between 0 and RAND_MAX. */
int
DEFUN_VOID(rand)
{
return (int) __random();
}

View File

@@ -0,0 +1,38 @@
/* Copyright (C) 1991 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stdlib.h>
#undef random
#undef srandom
#undef initstate
#undef setstate
#include <gnu-stabs.h>
function_alias(random, __random, long int, (),
DEFUN_VOID(random))
function_alias(srandom, __srandom, void, (seed),
DEFUN(srandom, (seed), unsigned int seed))
function_alias(initstate, __initstate, PTR, (seed, buf, size),
DEFUN(initstate, (seed, buf, size),
unsigned int seed AND PTR buf AND size_t size))
function_alias(setstate, __setstate, PTR, (buf),
DEFUN(setstate, (buf), PTR buf))

View File

@@ -0,0 +1,27 @@
/* Copyright (C) 1991 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stdlib.h>
#undef srand
#include <gnu-stabs.h>
function_alias(srand, __srandom, void, (seed),
DEFUN(srand, (seed), unsigned int seed))

View File

@@ -0,0 +1,279 @@
/* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
/*
* ANSI Standard: 4.10 GENERAL UTILITIES <stdlib.h>
*/
#ifndef _STDLIB_H
#define _STDLIB_H 1
#include <features.h>
/* Get size_t, wchar_t and NULL from <stddef.h>. */
#define __need_size_t
#define __need_wchar_t
#define __need_NULL
#include <stddef.h>
#define __need_Emath
#include <errno.h>
/* Get HUGE_VAL (returned by strtod on overflow) from <float.h>. */
#define __need_HUGE_VAL
#include <float.h>
/* Returned by `div'. */
typedef struct
{
int quot; /* Quotient. */
int rem; /* Remainder. */
} div_t;
/* Returned by `ldiv'. */
typedef struct
{
long int quot; /* Quotient. */
long int rem; /* Remainder. */
} ldiv_t;
/* The largest number rand will return (same as INT_MAX). */
#define RAND_MAX 2147483647
/* We define these the same for all machines.
Changes from this to the outside world should be done in `_exit'. */
#define EXIT_FAILURE 1 /* Failing exit status. */
#define EXIT_SUCCESS 0 /* Successful exit status. */
/* Maximum length of a multibyte character in the current locale.
This is just one until the fancy locale support is finished. */
#define MB_CUR_MAX 1
/* Convert a string to a floating-point number. */
extern double EXFUN(atof, (CONST char *__nptr));
/* Convert a string to an integer. */
extern int EXFUN(atoi, (CONST char *__nptr));
/* Convert a string to a long integer. */
extern long int EXFUN(atol, (CONST char *__nptr));
/* Convert a string to a floating-point number. */
extern double EXFUN(strtod, (CONST char *__nptr, char **__endptr));
/* Convert a string to a long integer. */
extern long int EXFUN(strtol, (CONST char *__nptr, char **__endptr,
int __base));
/* Convert a string to an unsigned long integer. */
extern unsigned long int EXFUN(strtoul, (CONST char *__nptr,
char **__endptr, int __base));
#ifdef __OPTIMIZE__
#define atof(nptr) strtod((nptr), (char **) NULL)
#define atoi(nptr) ((int) atol(nptr))
#define atol(nptr) strtol((nptr), (char **) NULL, 10)
#endif /* Optimizing. */
/* Return a random integer between 0 and RAND_MAX inclusive. */
extern int EXFUN(rand, (NOARGS));
/* Seed the random number generator with the given number. */
extern void EXFUN(srand, (unsigned int __seed));
/* These are the functions that actually do things. The `random', `srandom',
`initstate' and `setstate' functions are those from BSD Unices.
The `rand' and `srand' functions are required by the ANSI standard.
We provide both interfaces to the same random number generator. */
/* Return a random long integer between 0 and RAND_MAX inclusive. */
extern long int EXFUN(__random, (NOARGS));
/* Seed the random number generator with the given number. */
extern void EXFUN(__srandom, (unsigned int __seed));
/* Initialize the random number generator to use state buffer STATEBUF,
of length STATELEN, and seed it with SEED. Optimal lengths are 8, 16,
32, 64, 128 and 256, the bigger the better; values less than 8 will
cause an error and values greater than 256 will be rounded down. */
extern PTR EXFUN(__initstate, (unsigned int __seed, PTR __statebuf,
size_t __statelen));
/* Switch the random number generator to state buffer STATEBUF,
which should have been previously initialized by `initstate'. */
extern PTR EXFUN(__setstate, (PTR __statebuf));
#ifdef __USE_BSD
extern long int EXFUN(random, (NOARGS));
extern void EXFUN(srandom, (unsigned int __seed));
extern PTR EXFUN(initstate, (unsigned int __seed, PTR __statebuf,
size_t __statelen));
extern PTR EXFUN(setstate, (PTR __statebuf));
#ifdef __OPTIMIZE__
#define random() __random()
#define srandom(seed) __srandom(seed)
#define initstate(s, b, n) __initstate((s), (b), (n))
#define setstate(state) __setstate(state)
#endif /* Optimizing. */
#endif /* Use BSD. */
#ifdef __OPTIMIZE__
#define rand() ((int) __random())
#define srand(seed) __srandom(seed)
#endif /* Optimizing. */
/* Allocate SIZE bytes of memory. */
extern PTR EXFUN(malloc, (size_t __size));
/* Re-allocate the previously allocated block
in PTR, making the new block SIZE bytes long. */
extern PTR EXFUN(realloc, (PTR __ptr, size_t __size));
/* Allocate NMEMB elements of SIZE bytes each, all initialized to 0. */
extern PTR EXFUN(calloc, (size_t __nmemb, size_t __size));
/* Free a block allocated by `malloc', `realloc' or `calloc'. */
extern void EXFUN(free, (PTR __ptr));
#ifdef __USE_MISC
/* Free a block. An alias for `free'. (Sun Unices). */
extern void EXFUN(cfree, (PTR __ptr));
#ifdef __OPTIMIZE__
#define cfree(ptr) free(ptr)
#endif /* Optimizing. */
#endif /* Use misc. */
#if defined(__USE_GNU) || defined(__USE_BSD) || defined(__USE_MISC)
#include <alloca.h>
#endif /* Use GNU, BSD, or misc. */
#ifdef __USE_BSD
/* Allocate SIZE bytes on a page boundary. The storage cannot be freed. */
extern PTR EXFUN(valloc, (size_t __size));
#endif
#ifndef __NORETURN
#ifdef __GNUC__
/* The `volatile' keyword tells GCC that a function never returns. */
#define __NORETURN __volatile
#else /* Not GCC. */
#define __NORETURN
#endif /* GCC. */
#endif /* __NORETURN not defined. */
/* Abort execution and generate a core-dump. */
extern __NORETURN void EXFUN(abort, (NOARGS));
/* Register a function to be called when `exit' is called. */
extern int EXFUN(atexit, (void (*__func)(NOARGS)));
#ifdef __USE_MISC
/* Register a function to be called with the status
given to `exit' and the given argument. */
extern int EXFUN(on_exit, (void (*__func)(int __status, PTR __arg),
PTR __arg));
#endif
/* Call all functions registered with `atexit' and `on_exit',
in the reverse of the order in which they were registered
perform stdio cleanup, and terminate program execution with STATUS. */
extern __NORETURN void EXFUN(exit, (int __status));
/* Return the value of envariable NAME, or NULL if it doesn't exist. */
extern char *EXFUN(getenv, (CONST char *__name));
#ifdef __USE_SVID
/* The SVID says this is in <stdio.h>, but this seems a better place. */
/* Put STRING, which is of the form "NAME=VALUE", in the environment.
If there is no `=', remove NAME from the environment. */
extern int EXFUN(putenv, (CONST char *__string));
#endif
/* Execute the given line as a shell command. */
extern int EXFUN(system, (CONST char *__command));
/* Shorthand for type of comparison functions. */
typedef int (*__compar_fn_t) (CONST PTR, CONST PTR);
#ifdef __GNUC__
#define comparison_fn_t __compar_fn_t
#endif
/* Do a binary search for KEY in BASE, which consists of NMEMB elements
of SIZE bytes each, using COMPAR to perform the comparisons. */
extern PTR EXFUN(bsearch, (CONST PTR __key, CONST PTR __base,
size_t __nmemb, size_t __size,
__compar_fn_t __compar));
/* Sort NMEMB elements of BASE, of SIZE bytes each,
using COMPAR to perform the comparisons. */
extern void EXFUN(qsort, (PTR __base, size_t __nmemb, size_t __size,
__compar_fn_t __compar));
#ifndef __CONSTVALUE
#ifdef __GNUC__
/* The `const' keyword tells GCC that a function's return value is
based solely on its arguments, and there are no side-effects. */
#define __CONSTVALUE __const
#else
#define __CONSTVALUE
#endif /* GCC. */
#endif /* __CONSTVALUE not defined. */
/* Return the absolute value of X. */
extern __CONSTVALUE int EXFUN(abs, (int __x));
extern __CONSTVALUE long int EXFUN(labs, (long int __x));
#if defined(__GNUC__) && defined(__OPTIMIZE__)
#define abs(x) __builtin_abs(x)
#define labs(x) __builtin_labs(x)
#endif /* GCC and optimizing. */
/* Return the `div_t' or `ldiv_t' representation
of the value of NUMER over DENOM. */
/* GCC may have built-ins for these someday. */
extern __CONSTVALUE div_t EXFUN(div, (int __numer, int __denom));
extern __CONSTVALUE ldiv_t EXFUN(ldiv, (long int __numer, long int __denom));
/* Return the length of the multibyte character
in S, which is no longer than N. */
extern int EXFUN(mblen, (CONST char *__s, size_t __n));
/* Return the length of the given multibyte character,
putting its `wchar_t' representation in *PWC. */
extern int EXFUN(mbtowc, (wchar_t *__pwc, CONST char *__s, size_t __n));
/* Put the multibyte character represented
by WCHAR in S, returning its length. */
extern int EXFUN(wctomb, (char *__s, wchar_t __wchar));
#ifdef __OPTIMIZE__
#define mblen(s, n) mbtowc((wchar_t *) NULL, (s), (n))
#endif /* Optimizing. */
/* Convert a multibyte string to a wide char string. */
extern size_t EXFUN(mbstowcs, (wchar_t *__pwcs, CONST char *__s, size_t __n));
/* Convert a wide char string to multibyte string. */
extern size_t EXFUN(wcstombs, (char *__s, CONST wchar_t *__pwcs, size_t __n));
#endif /* stdlib.h */

View File

@@ -0,0 +1,179 @@
/* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <localeinfo.h>
#include <errno.h>
#include <float.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
/* Convert NPTR to a double. If ENDPTR is not NULL, a pointer to the
character after the last one used in the number is put in *ENDPTR. */
double
DEFUN(strtod, (nptr, endptr), CONST char *nptr AND char **endptr)
{
register CONST char *s;
short int sign;
wchar_t decimal; /* Decimal point character. */
/* The number so far. */
double num;
int got_dot; /* Found a decimal point. */
int got_digit; /* Seen any digits. */
/* The exponent of the number. */
long int exponent;
if (nptr == NULL)
{
errno = EINVAL;
goto noconv;
}
/* Figure out the decimal point character. */
if (mbtowc(&decimal, _numeric_info->decimal_point, 1) <= 0)
decimal = (wchar_t) *_numeric_info->decimal_point;
s = nptr;
/* Eat whitespace. */
while (isspace(*s))
++s;
/* Get the sign. */
sign = *s == '-' ? -1 : 1;
if (*s == '-' || *s == '+')
++s;
num = 0.0;
got_dot = 0;
got_digit = 0;
exponent = 0;
for (;; ++s)
{
if (isdigit (*s))
{
got_digit = 1;
/* Make sure that multiplication by 10 will not overflow. */
if (num > DBL_MAX * 0.1)
/* The value of the digit doesn't matter, since we have already
gotten as many digits as can be represented in a `double'.
This doesn't necessarily mean the result will overflow.
The exponent may reduce it to within range.
We just need to record that there was another
digit so that we can multiply by 10 later. */
++exponent;
else
num = (num * 10.0) + (*s - '0');
/* Keep track of the number of digits after the decimal point.
If we just divided by 10 here, we would lose precision. */
if (got_dot)
--exponent;
}
else if (!got_dot && (wchar_t) *s == decimal)
/* Record that we have found the decimal point. */
got_dot = 1;
else
/* Any other character terminates the number. */
break;
}
if (!got_digit)
goto noconv;
if (tolower(*s) == 'e')
{
/* Get the exponent specified after the `e' or `E'. */
int save = errno;
char *end;
long int exp;
errno = 0;
++s;
exp = strtol(s, &end, 10);
if (errno == ERANGE)
{
/* The exponent overflowed a `long int'. It is probably a safe
assumption that an exponent that cannot be represented by
a `long int' exceeds the limits of a `double'. */
if (endptr != NULL)
*endptr = end;
if (exp < 0)
goto underflow;
else
goto overflow;
}
else if (end == s)
/* There was no exponent. Reset END to point to
the 'e' or 'E', so *ENDPTR will be set there. */
end = (char *) s - 1;
errno = save;
s = end;
exponent += exp;
}
if (endptr != NULL)
*endptr = (char *) s;
if (num == 0.0)
return 0.0;
/* Multiply NUM by 10 to the EXPONENT power,
checking for overflow and underflow. */
if (exponent < 0)
{
if (num < DBL_MIN * pow(10.0, (double) -exponent))
goto underflow;
}
else if (exponent > 0)
{
if (num > DBL_MAX * pow(10.0, (double) -exponent))
goto overflow;
}
num *= pow(10.0, (double) exponent);
return num * sign;
overflow:
/* Return an overflow error. */
errno = ERANGE;
return HUGE_VAL * sign;
underflow:
/* Return an underflow error. */
if (endptr != NULL)
*endptr = (char *) nptr;
errno = ERANGE;
return 0.0;
noconv:
/* There was no number. */
if (endptr != NULL)
*endptr = (char *) nptr;
return 0.0;
}

View File

@@ -0,0 +1,159 @@
/* Copyright (C) 1991 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <ctype.h>
#include <limits.h>
#include <stddef.h>
#include <stdlib.h>
#ifndef UNSIGNED
#define UNSIGNED 0
#endif
/* Convert NPTR to an `unsigned long int' or `long int' in base BASE.
If BASE is 0 the base is determined by the presence of a leading
zero, indicating octal or a leading "0x" or "0X", indicating hexadecimal.
If BASE is < 2 or > 36, it is reset to 10.
If ENDPTR is not NULL, a pointer to the character after the last
one converted is stored in *ENDPTR. */
#if UNSIGNED
unsigned long int
#define strtol strtoul
#else
long int
#endif
DEFUN(strtol, (nptr, endptr, base),
CONST char *nptr AND char **endptr AND int base)
{
char sign;
register unsigned long int cutoff;
register unsigned int cutlim;
register unsigned long int i;
register CONST char *s;
register unsigned char c;
CONST char *save;
int overflow;
if (base < 0 || base == 1 || base > 36)
base = 10;
s = nptr;
/* Skip white space. */
while (isspace(*s))
++s;
if (*s == '\0')
goto noconv;
/* Check for a sign. */
if (*s == '-')
{
sign = -1;
++s;
}
else if (*s == '+')
{
sign = 1;
++s;
}
else
sign = 1;
if (base == 16 && s[0] == '0' && toupper(s[1]) == 'X')
s += 2;
/* If BASE is zero, figure it out ourselves. */
if (base == 0)
if (*s == '0')
{
if (toupper(s[1]) == 'X')
{
s += 2;
base = 16;
}
else
base = 8;
}
else
base = 10;
/* Save the pointer so we can check later if anything happened. */
save = s;
cutoff = ULONG_MAX / (unsigned long int) base;
cutlim = ULONG_MAX % (unsigned long int) base;
overflow = 0;
i = 0;
for (c = *s; c != '\0'; c = *++s)
{
if (isdigit(c))
c -= '0';
else if (isalpha(c))
c = toupper(c) - 'A' + 10;
else
break;
if (c >= base)
break;
/* Check for overflow. */
if (i > cutoff || (i == cutoff && c > cutlim))
overflow = 1;
else
{
i *= (unsigned long int) base;
i += c;
}
}
/* Check if anything actually happened. */
if (s == save)
goto noconv;
/* Store in ENDPTR the address of one character
past the last character we converted. */
if (endptr != NULL)
*endptr = (char *) s;
#if !UNSIGNED
/* Check for a value that is within the range of
`unsigned long int', but outside the range of `long int'. */
if (i > (unsigned long int) (sign > 0 ? LONG_MAX : - LONG_MAX))
overflow = 1;
#endif
if (overflow)
{
errno = ERANGE;
#if UNSIGNED
return ULONG_MAX;
#else
return sign > 0 ? LONG_MAX : LONG_MIN;
#endif
}
/* Return the result of the appropriate sign. */
return i * sign;
noconv:;
/* There was no number to convert. */
if (endptr != NULL)
*endptr = (char *) nptr;
return 0L;
}

View File

@@ -0,0 +1,21 @@
/* Copyright (C) 1991 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#define UNSIGNED 1
#include <strtol.c>

View File

@@ -0,0 +1,94 @@
/* Copyright (C) 1991 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
struct ltest
{
CONST char *str; /* Convert this. */
double expect; /* To get this. */
char left; /* With this left over. */
int err; /* And this in errno. */
};
static CONST struct ltest tests[] =
{
{ "12.345", 12.345, '\0', 0 },
{ "12.345e19", 12.345e19, '\0', 0 },
{ "-.1e+9", -.1e+9, '\0', 0 },
{ ".125", .125, '\0', 0 },
{ "1e20", 1e20, '\0', 0 },
{ NULL, 0, '\0', 0 }
};
static void EXFUN(expand, (char *dst, int c));
int
DEFUN_VOID(main)
{
register CONST struct ltest *lt;
char *ep;
int status = 0;
for (lt = tests; lt->str != NULL; ++lt)
{
double d;
errno = 0;
d = strtod(lt->str, &ep);
printf("strtod(\"%s\") test %u",
lt->str, (unsigned int) (lt - tests));
if (d == lt->expect && *ep == lt->left && errno == lt->err)
puts("\tOK");
else
{
puts("\tBAD");
if (d != lt->expect)
printf(" returns %.60g, expected %.60g\n", d, lt->expect);
if (lt->left != *ep)
{
char exp1[5], exp2[5];
expand(exp1, *ep);
expand(exp2, lt->left);
printf(" leaves '%s', expected '%s'\n", exp1, exp2);
}
if (errno != lt->err)
printf(" errno %d (%s) instead of %d (%s)\n",
errno, strerror(errno), lt->err, strerror(lt->err));
status = 1;
}
}
exit(status ? EXIT_FAILURE : EXIT_SUCCESS);
}
static void
DEFUN(expand, (dst, c), register char *dst AND register int c)
{
if (isprint(c))
{
dst[0] = c;
dst[1] = '\0';
}
else
(void) sprintf(dst, "%#.3o", (unsigned int) c);
}

View File

@@ -0,0 +1,127 @@
/* My bet is this was written by Chris Torek.
I reformatted and ansidecl-ized it, and tweaked it a little. */
#include <ansidecl.h>
#include <ctype.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <strings.h>
struct ltest
{
CONST char *str; /* Convert this. */
unsigned long int expect; /* To get this. */
int base; /* Use this base. */
char left; /* With this left over. */
int err; /* And this in errno. */
};
static CONST struct ltest tests[] =
{
/* First, signed numbers. */
" -17", -17, 0, 0, 0,
" +0x123fg", 0x123f, 0, 'g', 0,
"2147483647", 2147483647, 0, 0, 0,
"2147483648", 2147483647, 0, 0, ERANGE,
"214748364888", 2147483647, 0, 0, ERANGE,
"2147483650", 2147483647, 0, 0, ERANGE,
"-2147486349", -2147483648, 0, 0, ERANGE,
"-2147483648", -2147483648, 0, 0, 0,
"0123", 0123, 0, 0, 0,
"0x1122334455z", 2147483647, 16, 'z', ERANGE,
"0x0xc", 0, 0, 'x', 0,
"yz!", 34*36+35, 36, '!', 0,
NULL, 0, 0, 0, 0,
/* Then unsigned. */
" 0", 0, 0, 0, 0,
"0xffffffffg", 0xffffffff, 0, 'g', 0,
"0xf1f2f3f4f5", 0xffffffff, 0, 0, ERANGE,
"-0x123456789", 0xffffffff, 0, 0, ERANGE,
"-0xfedcba98", -0xfedcba98, 0, 0, 0,
NULL, 0, 0, 0, 0,
};
static void EXFUN(expand, (char *dst, int c));
int
DEFUN_VOID(main)
{
register CONST struct ltest *lt;
char *ep;
int status = 0;
for (lt = tests; lt->str != NULL; ++lt)
{
register long int l;
errno = 0;
l = strtol(lt->str, &ep, lt->base);
printf("strtol(\"%s\", , %d) test %u",
lt->str, lt->base, (unsigned int) (lt - tests));
if (l == (long int) lt->expect && *ep == lt->left && errno == lt->err)
puts("\tOK");
else
{
puts("\tBAD");
if (l != (long int) lt->expect)
printf(" returns %ld, expected %ld\n",
l, (long int) lt->expect);
if (lt->left != *ep)
{
char exp1[5], exp2[5];
expand(exp1, *ep);
expand(exp2, lt->left);
printf(" leaves '%s', expected '%s'\n", exp1, exp2);
}
if (errno != lt->err)
printf(" errno %d (%s) instead of %d (%s)\n",
errno, strerror(errno), lt->err, strerror(lt->err));
status = 1;
}
}
for (++lt; lt->str != NULL; lt++)
{
register unsigned long int ul;
errno = 0;
ul = strtoul(lt->str, &ep, lt->base);
printf("strtoul(\"%s\", , %d) test %u",
lt->str, lt->base, (unsigned int) (lt - tests));
if (ul == lt->expect && *ep == lt->left && errno == lt->err)
puts("\tOK");
else
{
puts("\tBAD");
if (ul != lt->expect)
printf(" returns %lu, expected %lu\n",
ul, lt->expect);
if (lt->left != *ep)
{
char exp1[5], exp2[5];
expand(exp1, *ep);
expand(exp2, lt->left);
printf(" leaves '%s', expected '%s'\n", exp1, exp2);
}
if (errno != lt->err)
printf(" errno %d (%s) instead of %d (%s)\n",
errno, strerror(errno), lt->err, strerror(lt->err));
status = 1;
}
}
exit(status ? EXIT_FAILURE : EXIT_SUCCESS);
}
static void
DEFUN(expand, (dst, c), register char *dst AND register int c)
{
if (isprint(c))
{
dst[0] = c;
dst[1] = '\0';
}
else
(void) sprintf(dst, "%#.3o", (unsigned int) c);
}

View File

@@ -0,0 +1,74 @@
/* Copyright (C) 1991 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <localeinfo.h>
#include <ctype.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* Convert the `wchar_t' string in PWCS to a multibyte character string
in S, writing no more than N characters. Return the number of bytes
written, or (size_t) -1 if an invalid `wchar_t' was found. */
size_t
DEFUN(wcstombs, (s, pwcs, n),
register char *s AND register CONST wchar_t *pwcs AND register size_t n)
{
register CONST mb_char *mb;
register int shift = 0;
register size_t written = 0;
register wchar_t w;
while ((w = *pwcs++) != (wchar_t) '\0')
{
if (w == ((wchar_t) EOF) || isascii(w))
{
written = (size_t) -1;
break;
}
else
{
mb = &_ctype_info->mbchar->mb_chars[w + shift];
if (mb->string == NULL || mb->len == 0)
{
written = (size_t) -1;
break;
}
else if (mb->len > n)
break;
else
{
memcpy((PTR) s, (CONST PTR) mb->string, mb->len);
n -= mb->len;
written += mb->len;
shift += mb->shift;
}
}
}
/* Terminate the string if it has space. */
if (n > 0)
*s = '\0';
/* Return the number of characters written (or maybe an error). */
return written;
}

View File

@@ -0,0 +1,59 @@
/* Copyright (C) 1991 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <localeinfo.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
extern int _mb_shift; /* Defined in mbtowc.c. */
/* Convert WCHAR into its multibyte character representation,
putting this in S and returning its length. */
int
DEFUN(wctomb, (s, wchar), register char *s AND wchar_t wchar)
{
register CONST mb_char *mb;
if (_ctype_info->mbchar == NULL)
mb = NULL;
else
mb = _ctype_info->mbchar->mb_chars;
/* If S is NULL, just say if we're shifted or not. */
if (s == NULL)
return _mb_shift != 0;
if (wchar == (wchar_t) '\0')
{
_mb_shift = 0;
return 0;
}
else if (mb == NULL)
return -1;
mb += wchar + _mb_shift;
if (mb->string == NULL || mb->len == 0)
return -1;
memcpy((PTR) s, (CONST PTR) mb->string, mb->len + 1);
_mb_shift += mb->shift;
return mb->len;
}