1
0
mirror of https://github.com/adtools/clib2.git synced 2025-12-08 14:59:05 +00:00

71 Commits

Author SHA1 Message Date
c02665938f Merge pull request #13 from sodero/topic/additional_error_codes
Add ENOTSUP error code
2021-05-14 00:38:42 +02:00
1e2863c5b8 fixed README.md 2021-05-14 00:32:09 +02:00
e1da3dadfb moved from travis-ci to github actions and retired codeclimate. 2021-05-14 00:31:17 +02:00
b51c79577e Add ENOTSUP error code. 2021-01-20 15:34:37 +01:00
975f949aa1 Rewritten to handle date ranges better which lie outside the expected time of day, day of month and month.
The 'struct tm' is now properly updated to reflect the time and date information which comes out of the number of seconds calculated.

A bug reported by Andreas Falkenhahn is resolved which had the effect of distorting the number of seconds calculated.
2020-07-06 12:09:51 +02:00
5f14118d73 Fix for translation bug, which would make "a/../b" into "a./b". Contributed by Thomas Frieden - thank you very much! 2018-12-05 13:31:43 +01:00
b874ff71de Add wcscoll() dummy. 2018-04-22 11:21:24 +02:00
397013922c Use IsMinListEmpty() for MinList rather than IsListEmpty().
This removes the warnings about breaking the strict-aliasing rules.
2018-04-10 23:20:20 +02:00
85c36839d5 Create the proper directoy for MAKELIB. 2018-04-10 23:19:13 +02:00
196d37b28a Compile with -nostdlib, rather than -mcrt=clib2.
We are actually building the clib2 here.
2018-04-10 23:18:30 +02:00
e8086be768 Disable -Wunused-label.
There are a lot of unused lables, depending on the actual
compiling mode.
2018-04-10 23:17:08 +02:00
82dd474e3b Disable -Wbad-function-cast. It produces a lot of useless warnings. 2018-04-09 23:24:56 +02:00
58f36203b1 Fix cast to function pointer. 2018-04-09 23:24:07 +02:00
425f899302 Merge pull request #7 from sba1/wchar-fixes
Wchar fixes
2018-03-31 09:37:50 +02:00
febe89c61b Update changelog. 2018-03-30 22:17:41 +02:00
3e50be491b Include stdint.h for WCHAR_MAX to avoid redundant definitions. 2018-03-30 21:42:12 +02:00
dfc7f310d6 Don't define wchar_t in C++ as it is a bultin-type there. 2018-03-30 21:35:06 +02:00
a6a9352a00 Compile wchar_wscoll.c. 2018-03-30 21:21:31 +02:00
eb1d784c0d Provide stub for mbrtowc(). 2018-03-30 21:21:11 +02:00
d1092099d0 Provide some more wide char functions. 2018-03-29 20:59:02 +02:00
bc621bed9c Disable the LOG_COMMAND.
Piping will have the consequence that the exit status of the first command
will not be considered. As this is the compiling command in our case, make
will not exit with an error code even if the compiling failed.

While there are shell-specific solutions, disabling LOG_COMMAND seems to
be the most general solution.
2018-03-29 20:57:32 +02:00
60eebbe732 Implement wcscat(). 2018-03-28 21:23:13 +02:00
345995000a Implement some more of the iswXXX() functions. 2018-03-28 21:16:14 +02:00
ef18bf5f3e Fix vswprintf() prototype. 2018-03-28 18:47:24 +02:00
6f3b3b6d28 Implement few wide char functions. 2018-03-28 17:09:18 +02:00
846eebc66c Fix mbtowc() to and compile it. 2018-03-28 17:08:42 +02:00
75d47ccdad Build all existing wchar and wctype functions. 2018-03-27 20:03:45 +02:00
456123fe7f Add dummy wctob(). 2018-03-27 20:02:54 +02:00
5733c99ba1 Fix wcspbrk() definition to match the prototype. 2018-03-27 20:00:28 +02:00
391e7e39ad Add wcscoll() prototype. 2018-03-27 19:59:54 +02:00
f5f0e17e78 Define ISO 99 multibyte functions also in C++ context. 2018-03-27 19:59:23 +02:00
f6f0082a0e Include sys/clib2_stdc.h for restrict. 2018-03-27 19:56:45 +02:00
c84b1fc1ff Tiny fixes 2018-02-18 13:58:25 +01:00
e35307a7e3 Ignore linker map files, too. 2018-02-17 13:45:21 +01:00
911114c286 add an unimplemented tzset().
ctime_r() and localtime_r() are already using the localtime, so no need to do anything.
http://pubs.opengroup.org/onlinepubs/9699919799/functions/tzset.html

Signed-off-by: Henning Nielsen Lund <hnl_dk@amigaos.dk>
2017-08-27 13:30:12 +02:00
9e998ca108 should have been sys/clib2_stdc.h 2017-08-15 21:53:49 +02:00
99695dec0b we use restrict
Signed-off-by: Henning Nielsen Lund <hnl_dk@amigaos.dk>
2017-08-15 21:45:33 +02:00
0ec7094877 Code depending on statfs or fstatfs do both depend on sys/mount.h and sys/param.h where we only had sys/mount.h
Signed-off-by: Henning Nielsen Lund <hnl_dk@amigaos.dk>
2017-08-15 21:26:45 +02:00
a471e73adf add timespec declaration 2017-08-05 17:28:39 +02:00
c76bf8e20b add strnlen() 2017-08-01 21:28:07 +02:00
309bbd8c8c Add a few extra wide-character prototypes and the missing typedef locale_t 2017-08-01 21:26:59 +02:00
d6e5769bc5 using restrict, so restrict to c99 2017-08-01 14:52:45 +02:00
976b6ae7e1 Change the mbrlen declaration to equal ISO C.
http://pubs.opengroup.org/onlinepubs/9699919799/functions/mbrlen.html

Signed-off-by: Henning Nielsen Lund <hnl_dk@amigaos.dk>
2017-08-01 13:55:11 +02:00
8af96cb6cb Merge branch 'master' of https://github.com/adtools/clib2 2017-07-08 18:10:45 +02:00
febe690623 This got lost last year
The missing calloc() overflow test never made it to the CVS or git repositories :-(
2017-07-08 18:10:28 +02:00
e36ebff16e Merge pull request #3 from adtools/gcc5-fixes
Fixes for compiling with GCC 5.4.0 on AmigaOS 4.1
2017-06-28 08:55:21 +02:00
6a1fd36b3a Revision bump. 2017-06-28 06:35:31 +02:00
feebeb6751 GCC 5 changes 2017-06-28 06:34:57 +02:00
1b2c798467 Fixed calloc() and getopt_long()
Added integer overflow test to calloc().

Tiny change in getopt_long() so that the value pointed to by the "longindex" parameter is always initialized to an invalid index position (that being -1), instead of 0. The value of 0 can break some shell commands, most notably GNU wget.
2017-05-01 18:06:23 +02:00
053a61fc4b Create LICENSE 2016-12-05 14:41:06 +01:00
4c54ee3f2d Version bump 2016-12-04 11:14:17 +01:00
f491e38b38 Added code to temporarily disable profiling 2016-12-04 11:14:00 +01:00
734ce4c1a9 Added code to temporarily disable profiling 2016-12-04 11:13:37 +01:00
ce345df9da Hide warnings for deprecated functions 2016-12-04 11:13:00 +01:00
5e0fa78d61 Only builds with GCC now 2016-12-04 11:12:42 +01:00
bc3e19abe5 Only uses MEMF_PRIVATE on OS4 now 2016-12-04 11:12:32 +01:00
29e02775fb Cleaned up the build rules, added missing files 2016-12-04 11:11:53 +01:00
5cb27db203 Slab allocator is exercised much more 2016-12-04 11:11:28 +01:00
4fc1b13945 Added a rogue malloc/free pair 2016-12-04 11:11:05 +01:00
8beaabac4f Removed unused local variable 2016-12-04 11:10:46 +01:00
271572ed56 Fixed so that it builds correctly with SAS/C again 2016-12-04 11:10:33 +01:00
e0feef8932 Moved __CXV54 into sas_cxv.asm
sas_cxv54.asm is no longer needed.
2016-12-04 11:10:13 +01:00
07259ed7eb This is needed when building with math=ieee option 2016-12-04 11:09:24 +01:00
3203fcf96a Removed unused result variable 2016-12-04 11:08:54 +01:00
bfba44bf83 Rewritten to use setjmp()/longjmp()
Also contains new code which prints the number of times a slab was reused.
2016-12-04 11:08:41 +01:00
35434bdedc Updated to build correctly with SAS/C again 2016-12-04 11:07:40 +01:00
17ba18c731 Added code which temporarily disables profiling 2016-12-04 11:06:50 +01:00
78a8c7655e Added __decay_unused_slabs() 2016-12-04 11:05:50 +01:00
184a127860 Added stdlib_decay_unused_slabs() 2016-12-04 11:05:30 +01:00
5617c0eacf Slab allocator update
Unused slabs which get recycled are no longer reinitialized from scratch if their chunk size matches what the allocator needed. If the chunk size matches, the list of available chunks is left unchanged, and just the various counters are reset.

Added __get_slab_stats() function.

Added support for global __slab_purge_threshold tuning variable.

Added a short test program for the slab allocator.

The malloc-test program was linked against the wrong object file in GNUmakefile.68k. Fixed.
2016-11-27 15:53:40 +01:00
ac710b333e Accidentally omitted from version 1.211 2016-11-24 09:45:35 +01:00
108 changed files with 2947 additions and 1328 deletions

View File

@ -1,14 +0,0 @@
---
engines:
duplication:
enabled: false
fixme:
enabled: true
markdownlint:
enabled: true
ratings:
paths:
- "**.c"
- "**.h"
- "**.l"
- "**.md"

54
.github/workflows/ci.yml vendored Normal file
View File

@ -0,0 +1,54 @@
name: CI
on:
push:
pull_request:
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-20.04
timeout-minutes: 480
strategy:
fail-fast: false
matrix:
platform: [os4, os3]
steps:
- uses: actions/checkout@v2
- name: setup dependencies
run: |
sudo dpkg --add-architecture i386
sudo apt-get update -y -qq || true
sudo apt-get -qq install libc6:i386
sudo ln -s /usr/lib/x86_64-linux-gnu/libmpfr.so.6 /usr/lib/x86_64-linux-gnu/libmpfr.so.4
- name: setup env
run : |
echo "GITHUB_SHA7=$(echo ${GITHUB_SHA::7})" >>$GITHUB_ENV
- name: install adtools build env
run: |
DOWNLOAD_PATH=https://github.com/adtools/adtools/releases/download/20170213
curl -L ${DOWNLOAD_PATH}/adtools-utils.tar.bz2 | sudo tar xj -C /
if [[ ${{ matrix.platform }} =~ os3 ]]; then curl -L ${DOWNLOAD_PATH}/adtools-m68k-amigaos.tar.bz2 | sudo tar xj -C / ; fi
if [[ ${{ matrix.platform }} =~ os4 ]]; then curl -L ${DOWNLOAD_PATH}/adtools-ppc-amigaos.tar.bz2 | sudo tar xj -C / ; fi
if [[ ${{ matrix.platform }} =~ mos ]]; then curl -L ${DOWNLOAD_PATH}/adtools-ppc-morphos.tar.bz2 | sudo tar xj -C / ; fi
if [[ ${{ matrix.platform }} =~ aros-ppc ]]; then curl -L ${DOWNLOAD_PATH}/adtools-ppc-aros.tar.bz2 | sudo tar xj -C / ; fi
if [[ ${{ matrix.platform }} =~ aros-i386 ]]; then curl -L ${DOWNLOAD_PATH}/adtools-i386-aros.tar.bz2 | sudo tar xj -C / ; fi
if [[ ${{ matrix.platform }} =~ aros-x86_64 ]]; then curl -L ${DOWNLOAD_PATH}/adtools-x86_64-aros.tar.bz2 | sudo tar xj -C / ; fi
- name: cleanup old action artifacts
run: .github/workflows/purge_artifacts.sh ${{ secrets.GITHUB_TOKEN }}
#- name: remote debug tmate session
# uses: mxschmitt/action-tmate@v1
# if: matrix.platform == 'os4'
- name: build [${{ matrix.platform }}]
timeout-minutes: 480
run: |
export PATH=/usr/local/amiga/bin:/opt/m68k-amigaos/bin:/opt/ppc-amigaos/bin:/opt/ppc-morphos/bin:${PATH}
if [[ ${{ matrix.platform }} =~ os4 ]]; then make -C library -j1 -f GNUmakefile.os4 OS=os4 ; fi
if [[ ${{ matrix.platform }} =~ os3 ]]; then make -C library -j1 -f GNUmakefile.68k OS=os3 ; fi

55
.github/workflows/purge_artifacts.sh vendored Executable file
View File

@ -0,0 +1,55 @@
#!/usr/bin/env bash
# Customize those three lines with your repository and credentials:
REPO=https://api.github.com/repos/${GITHUB_REPOSITORY}
GITHUB_USER=${GITHUB_REPOSITORY%%/*}
GITHUB_TOKEN=${1}
# Number of most recent versions to keep for each artifact:
KEEP=4
# A shortcut to call GitHub API.
ghapi() { curl --silent --location --user $GITHUB_USER:$GITHUB_TOKEN "$@"; }
# A temporary file which receives HTTP response headers.
TMPFILE=/tmp/tmp.$$
# An associative array, key: artifact name, value: number of artifacts of that name.
declare -A ARTCOUNT
# Process all artifacts on this repository, loop on returned "pages".
URL=$REPO/actions/artifacts
while [[ -n "$URL" ]]; do
# Get current page, get response headers in a temporary file.
JSON=$(ghapi --dump-header $TMPFILE "$URL")
# Get URL of next page. Will be empty if we are at the last page.
URL=$(grep '^Link:' "$TMPFILE" | tr ',' '\n' | grep 'rel="next"' | head -1 | sed -e 's/.*<//' -e 's/>.*//')
rm -f ${TMPFILE}
# Number of artifacts on this page:
COUNT=$(( $(jq <<<$JSON -r '.artifacts | length') ))
# Loop on all artifacts on this page.
for ((i=0; $i < $COUNT; i++)); do
# Get name of artifact and count instances of this name.
STR=$(jq <<<$JSON -r ".artifacts[$i].name?")
name=${STR%%-*}-${STR##*-}
ARTCOUNT[$name]=$(( $(( ${ARTCOUNT[$name]} )) + 1))
printf "Found '%s' #%d, " $STR ${ARTCOUNT[$name]}
# Check if we must delete this one.
if [[ ${ARTCOUNT[$name]} -gt $KEEP ]]; then
id=$(jq <<<$JSON -r ".artifacts[$i].id?")
size=$(( $(jq <<<$JSON -r ".artifacts[$i].size_in_bytes?") ))
printf "deleting %d bytes\n" $size
ghapi -X DELETE $REPO/actions/artifacts/$id
else
printf "OK\n"
fi
done
done
exit 0

1
.gitignore vendored
View File

@ -2,3 +2,4 @@
*.a *.a
/library/compiler.log /library/compiler.log
/library/netinclude /library/netinclude
*.map

View File

@ -1,36 +0,0 @@
sudo: required
dist: trusty
language: c
# download and install our required cross compilers
install:
# Make sure we can install i386 packages as some adtools binaries
# requires i386 libraries being installed to work in the 64bit env
# of Travis
- sudo dpkg --add-architecture i386
- sudo apt-get -qq update || true
- sudo apt-get -qq install libc6:i386
# Install all adtools related stuff we need
- curl -L https://dl.bintray.com/jens-maus/adtools/adtools-utils.tar.bz2 | sudo tar xj -C /
- if [[ ${BUILD} =~ os3|release ]]; then curl -L https://dl.bintray.com/jens-maus/adtools/adtools-m68k-amigaos.tar.bz2 | sudo tar xj -C / ; fi
- if [[ ${BUILD} =~ os4|release ]]; then curl -L https://dl.bintray.com/jens-maus/adtools/adtools-ppc-amigaos.tar.bz2 | sudo tar xj -C / ; fi
- if [[ ${BUILD} =~ mos|release ]]; then curl -L https://dl.bintray.com/jens-maus/adtools/adtools-ppc-morphos.tar.bz2 | sudo tar xj -C / ; fi
- if [[ ${BUILD} =~ aros-ppc|release ]]; then curl -L https://dl.bintray.com/jens-maus/adtools/adtools-ppc-aros.tar.bz2 | sudo tar xj -C / ; fi
- if [[ ${BUILD} =~ aros-i386|release ]]; then curl -L https://dl.bintray.com/jens-maus/adtools/adtools-i386-aros.tar.bz2 | sudo tar xj -C / ; fi
- if [[ ${BUILD} =~ aros-x86_64|release ]]; then curl -L https://dl.bintray.com/jens-maus/adtools/adtools-x86_64-aros.tar.bz2 | sudo tar xj -C / ; fi
- if [[ ${BUILD} =~ mingw32|release ]]; then sudo apt-get -qq install binutils-mingw-w64-i686 gcc-mingw-w64-i686 ; fi
# set the PATH variable to the directories the cross compilers are installed.
before_script:
- export PATH=/usr/local/amiga/bin:/opt/m68k-amigaos/bin:/opt/ppc-amigaos/bin:/opt/ppc-morphos/bin:${PATH}
# specify a list of variables to test (here we test the build for our supported
# list of operating systems).
env:
- BUILD="-f GNUmakefile.68k OS=os3"
- BUILD="-f GNUmakefile.os4 OS=os4"
# the build command to execute for each test
script:
- make -C library -j1 ${BUILD}

29
LICENSE Normal file
View File

@ -0,0 +1,29 @@
BSD 3-Clause License
Copyright (c) 2016, Olaf Barthel
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.

View File

@ -1,9 +1,7 @@
# clib2 An ISO 'C' (1994) compliant runtime library for AmigaOS # clib2 An ISO 'C' (1994) compliant runtime library for AmigaOS
[![Build Status](https://travis-ci.org/adtools/clib2.svg?branch=master)](https://travis-ci.org/adtools/clib2) [![Build](https://github.com/adtools/clib2/workflows/CI/badge.svg)](https://github.com/adtools/clib2/actions)
[![Code Climate](https://codeclimate.com/github/adtools/clib2/badges/gpa.svg)](https://codeclimate.com/github/adtools/clib2)
[![License](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause) [![License](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)
[![Github Issues](http://githubbadges.herokuapp.com/adtools/clib2/issues.svg)](https://github.com/adtools/clib2/issues)
## What is this? ## What is this?

View File

@ -327,6 +327,7 @@ C_LIB = \
stdlib_exit.o \ stdlib_exit.o \
stdlib_free.o \ stdlib_free.o \
stdlib_free_unused_slabs.o \ stdlib_free_unused_slabs.o \
stdlib_decay_unused_slabs.o \
stdlib_getdefstacksize.o \ stdlib_getdefstacksize.o \
stdlib_getenv.o \ stdlib_getenv.o \
stdlib_getmemstats.o \ stdlib_getmemstats.o \
@ -334,6 +335,7 @@ C_LIB = \
stdlib_get_errno.o \ stdlib_get_errno.o \
stdlib_get_slab_usage.o \ stdlib_get_slab_usage.o \
stdlib_get_slab_allocations.o \ stdlib_get_slab_allocations.o \
stdlib_get_slab_stats.o \
stdlib_isresident.o \ stdlib_isresident.o \
stdlib_labs.o \ stdlib_labs.o \
stdlib_llabs.o \ stdlib_llabs.o \
@ -373,6 +375,7 @@ C_LIB = \
stdlib_showerror.o \ stdlib_showerror.o \
stdlib_slab.o \ stdlib_slab.o \
stdlib_slab_max_size.o \ stdlib_slab_max_size.o \
stdlib_slab_purge_threshold.o \
stdlib_srand.o \ stdlib_srand.o \
stdlib_stacksize.o \ stdlib_stacksize.o \
stdlib_stack_usage.o \ stdlib_stack_usage.o \
@ -446,6 +449,7 @@ C_LIB = \
time_numbertostring.o \ time_numbertostring.o \
time_strftime.o \ time_strftime.o \
time_time.o \ time_time.o \
time_tzset.o \
time_weekday.o \ time_weekday.o \
uio_readv.o \ uio_readv.o \
uio_writev.o \ uio_writev.o \
@ -1124,25 +1128,31 @@ $(LIBC_OBJS)/stdlib_getdefstacksize.o : stdlib_getdefstacksize.c stdlib_gcc_help
$(LIBC_OBJS)/stdlib_shell_escape.o : stdlib_shell_escape.c stdlib_gcc_help.h $(LIBC_OBJS)/stdlib_shell_escape.o : stdlib_shell_escape.c stdlib_gcc_help.h
$(LIBC_OBJS)/stdlib_alloca.o : stdlib_alloca.c stdlib_memory.h $(LIBC_OBJS)/stdlib_alloca.o : stdlib_alloca.c stdlib_memory.h include/stdlib.h
$(LIBC_OBJS)/stdlib_calloc.o : stdlib_calloc.c stdlib_memory.h $(LIBC_OBJS)/stdlib_calloc.o : stdlib_calloc.c stdlib_memory.h include/stdlib.h
$(LIBC_OBJS)/stdlib_free.o : stdlib_free.c stdlib_memory.h $(LIBC_OBJS)/stdlib_free.o : stdlib_free.c stdlib_memory.h include/stdlib.h
$(LIBC_OBJS)/stdlib_malloc.o : stdlib_malloc.c stdlib_memory.h $(LIBC_OBJS)/stdlib_malloc.o : stdlib_malloc.c stdlib_memory.h include/stdlib.h
$(LIBC_OBJS)/stdlib_slab.o : stdlib_slab.c stdlib_memory.h $(LIBC_OBJS)/stdlib_slab.o : stdlib_slab.c stdlib_memory.h include/stdlib.h
$(LIBC_OBJS)/stdlib_free_unused_slabs.o : stdlib_free_unused_slabs.c stdlib_memory.h $(LIBC_OBJS)/stdlib_slab_purge_threshold.o : stdlib_slab_purge_threshold.c stdlib_memory.h include/stdlib.h
$(LIBC_OBJS)/stdlib_get_slab_usage.o : stdlib_get_slab_usage.c stdlib_memory.h $(LIBC_OBJS)/stdlib_get_slab_stats.o : stdlib_get_slab_stats.c stdlib_memory.h include/stdlib.h
$(LIBC_OBJS)/stdlib_get_slab_allocations.o : stdlib_get_slab_allocations.c stdlib_memory.h $(LIBC_OBJS)/stdlib_free_unused_slabs.o : stdlib_free_unused_slabs.c stdlib_memory.h include/stdlib.h
$(LIBC_OBJS)/stdlib_realloc.o : stdlib_realloc.c stdlib_memory.h $(LIBC_OBJS)/stdlib_decay_unused_slabs.o : stdlib_decay_unused_slabs.c stdlib_memory.h include/stdlib.h
$(LIBC_OBJS)/stdlib_red_black.o : stdlib_red_black.c stdlib_memory.h $(LIBC_OBJS)/stdlib_get_slab_usage.o : stdlib_get_slab_usage.c stdlib_memory.h include/stdlib.h
$(LIBC_OBJS)/stdlib_get_slab_allocations.o : stdlib_get_slab_allocations.c stdlib_memory.h include/stdlib.h
$(LIBC_OBJS)/stdlib_realloc.o : stdlib_realloc.c stdlib_memory.h include/stdlib.h
$(LIBC_OBJS)/stdlib_red_black.o : stdlib_red_black.c stdlib_memory.h include/stdlib.h
############################################################################## ##############################################################################

View File

@ -29,7 +29,11 @@ RANLIB := ppc-amigaos-ranlib
COPY := cp -p COPY := cp -p
DELETE := rm -rf DELETE := rm -rf
MAKEDIR := mkdir -p MAKEDIR := mkdir -p
LOG_COMMAND := 2>&1 | tee -a compiler.log # Enabling the LOG_COMMAND has the consequence that a rule will not
# fail on an error because only the exit status from the tee command
# will be considered
#LOG_COMMAND := 2>&1 | tee -a compiler.log
LOG_COMMAND :=
# You may need to request a specific compiler version in order to # You may need to request a specific compiler version in order to
# build the baserel versions of the library. At this time of # build the baserel versions of the library. At this time of
# writing (2008-11-06) GCC 4.0.4 and below support the -mbaserel # writing (2008-11-06) GCC 4.0.4 and below support the -mbaserel
@ -54,12 +58,13 @@ LOG_COMMAND := 2>&1 | tee -a compiler.log
WARNINGS := \ WARNINGS := \
-Wall -W -Wpointer-arith -Wsign-compare -Wmissing-prototypes \ -Wall -W -Wpointer-arith -Wsign-compare -Wmissing-prototypes \
-Wundef -Wbad-function-cast -Wmissing-declarations -Wunused -Wwrite-strings -Wundef -Wmissing-declarations -Wunused -Wwrite-strings \
-Wno-deprecated-declarations -Wno-unused-label \
# -Wconversion -Wshadow # -Wconversion -Wshadow -Wbad-function-cast
INCLUDES := -Iinclude -I. -I$(SDK_INCLUDE) INCLUDES := -Iinclude -I. -I$(SDK_INCLUDE)
OPTIONS := -DUSE_64_BIT_INTS -D__USE_INLINE__ -Wa,-mregnames -fno-common -std=gnu99 -mcrt=clib2 OPTIONS := -DUSE_64_BIT_INTS -D__USE_INLINE__ -Wa,-mregnames -fno-builtin -fno-common -std=c99 -nostdlib
OPTIMIZE := -DNDEBUG -O3 OPTIMIZE := -DNDEBUG -O3
#DEBUG := -ggdb #DEBUG := -ggdb
@ -159,6 +164,10 @@ cvs-tag:
# General build rules for all object files and the individual libraries # General build rules for all object files and the individual libraries
lib/crtbegin.o : CFLAGS += -fno-aggressive-loop-optimizations
lib/crtbegin.o : crtbegin.c
@$(COMPILE)
lib/%.o : AFLAGS += $(LARGEDATA) lib/%.o : AFLAGS += $(LARGEDATA)
lib/%.o : %.S lib/%.o : %.S
@$(ASSEMBLE) @$(ASSEMBLE)
@ -170,6 +179,11 @@ lib/small-data/%.o : AFLAGS += $(SMALLDATA)
lib/small-data/%.o : %.S lib/small-data/%.o : %.S
@$(ASSEMBLE) @$(ASSEMBLE)
lib/small-data/crtbegin.o : CFLAGS += $(SMALLDATA) -fno-aggressive-loop-optimizations
lib/small-data/crtbegin.o : crtbegin.c
@$(COMPILE)
lib/small-data/%.o : CFLAGS += $(SMALLDATA)
lib/small-data/%.o : %.c lib/small-data/%.o : %.c
@$(COMPILE) @$(COMPILE)
@ -177,6 +191,11 @@ lib/soft-float/%.o : AFLAGS += $(SOFTFLOAT)
lib/soft-float/%.o : %.S lib/soft-float/%.o : %.S
@$(ASSEMBLE) @$(ASSEMBLE)
lib/soft-float/crtbegin.o : CFLAGS += $(SOFTFLOAT) -fno-aggressive-loop-optimizations
lib/soft-float/crtbegin.o : crtbegin.c
@$(COMPILE)
lib/soft-float/%.o : CFLAGS += $(SOFTFLOAT)
lib/soft-float/%.o : %.c lib/soft-float/%.o : %.c
@$(COMPILE) @$(COMPILE)
@ -184,6 +203,11 @@ lib/baserel/%.o : AFLAGS += $(BASEREL)
lib/baserel/%.o : %.S lib/baserel/%.o : %.S
@$(ASSEMBLE) @$(ASSEMBLE)
lib/baserel/crtbegin.o : CFLAGS += $(BASEREL) -fno-aggressive-loop-optimizations
lib/baserel/crtbegin.o : crtbegin.c
@$(COMPILE)
lib/baserel/%.o : CFLAGS += $(BASEREL)
lib/baserel/%.o : %.c lib/baserel/%.o : %.c
@$(COMPILE) @$(COMPILE)
@ -191,6 +215,11 @@ lib.threadsafe/%.o : AFLAGS += $(LARGEDATA) $(THREADSAFE)
lib.threadsafe/%.o : %.S lib.threadsafe/%.o : %.S
@$(ASSEMBLE) @$(ASSEMBLE)
lib.threadsafe/crtbegin.o : CFLAGS += $(THREADSAFE) $(LARGEDATA) -fno-aggressive-loop-optimizations
lib.threadsafe/crtbegin.o : crtbegin.c
@$(COMPILE)
lib.threadsafe/%.o : CFLAGS += $(THREADSAFE) $(LARGEDATA)
lib.threadsafe/%.o : %.c lib.threadsafe/%.o : %.c
@$(COMPILE) @$(COMPILE)
@ -198,6 +227,11 @@ lib.threadsafe/small-data/%.o : AFLAGS += $(SMALLDATA) $(THREADSAFE)
lib.threadsafe/small-data/%.o : %.S lib.threadsafe/small-data/%.o : %.S
@$(ASSEMBLE) @$(ASSEMBLE)
lib.threadsafe/small-data/crtbegin.o : CFLAGS += $(THREADSAFE) $(SMALLDATA) -fno-aggressive-loop-optimizations
lib.threadsafe/small-data/crtbegin.o : crtbegin.c
@$(COMPILE)
lib.threadsafe/small-data/%.o : CFLAGS += $(THREADSAFE) $(SMALLDATA)
lib.threadsafe/small-data/%.o : %.c lib.threadsafe/small-data/%.o : %.c
@$(COMPILE) @$(COMPILE)
@ -205,6 +239,11 @@ lib.threadsafe/soft-float/%.o : AFLAGS += $(SOFTFLOAT) $(THREADSAFE)
lib.threadsafe/soft-float/%.o : %.S lib.threadsafe/soft-float/%.o : %.S
@$(ASSEMBLE) @$(ASSEMBLE)
lib.threadsafe/soft-float/crtbegin.o : CFLAGS += $(THREADSAFE) $(SOFTFLOAT) -fno-aggressive-loop-optimizations
lib.threadsafe/soft-float/crtbegin.o : crtbegin.c
@$(COMPILE)
lib.threadsafe/soft-float/%.o : CFLAGS += $(THREADSAFE) $(SOFTFLOAT)
lib.threadsafe/soft-float/%.o : %.c lib.threadsafe/soft-float/%.o : %.c
@$(COMPILE) @$(COMPILE)
@ -212,6 +251,11 @@ lib.threadsafe/baserel/%.o : AFLAGS += $(BASEREL) $(THREADSAFE)
lib.threadsafe/baserel/%.o : %.S lib.threadsafe/baserel/%.o : %.S
@$(ASSEMBLE) @$(ASSEMBLE)
lib.threadsafe/baserel/crtbegin.o : CFLAGS += $(THREADSAFE) $(BASEREL) -fno-aggressive-loop-optimizations
lib.threadsafe/baserel/crtbegin.o : crtbegin.c
@$(COMPILE)
lib.threadsafe/baserel/%.o : CFLAGS += $(THREADSAFE) $(BASEREL)
lib.threadsafe/baserel/%.o : %.c lib.threadsafe/baserel/%.o : %.c
@$(COMPILE) @$(COMPILE)
@ -230,7 +274,7 @@ $(CC) $(AFLAGS) -o $@ -c $< $(LOG_COMMAND)
endef endef
define MAKELIB define MAKELIB
-$(MAKEDIR) $@ -$(MAKEDIR) $(@D)
$(DELETE) $@ $(DELETE) $@
echo "Making $@" echo "Making $@"
$(AR) $@ $^ $(LOG_COMMAND) $(AR) $@ $^ $(LOG_COMMAND)

View File

@ -1,6 +1,6 @@
#define VERSION 1 #define VERSION 1
#define REVISION 211 #define REVISION 215
#define DATE "23.11.2016" #define DATE "26.6.2017"
#define VERS "amiga.lib 1.211" #define VERS "amiga.lib 1.215"
#define VSTRING "amiga.lib 1.211 (23.11.2016)\r\n" #define VSTRING "amiga.lib 1.215 (26.6.2017)\r\n"
#define VERSTAG "\0$VER: amiga.lib 1.211 (23.11.2016)" #define VERSTAG "\0$VER: amiga.lib 1.215 (26.6.2017)"

View File

@ -1 +1 @@
211 215

View File

@ -79,6 +79,8 @@ DoTimer(struct timeval *tv,LONG unit,LONG command)
struct MsgPort * mp; struct MsgPort * mp;
LONG error; LONG error;
PROFILE_OFF();
assert( tv != NULL ); assert( tv != NULL );
#if defined(__amigaos4__) #if defined(__amigaos4__)
@ -129,14 +131,10 @@ DoTimer(struct timeval *tv,LONG unit,LONG command)
tr->tr_time.tv_secs = tv->tv_secs; tr->tr_time.tv_secs = tv->tv_secs;
tr->tr_time.tv_micro = tv->tv_micro; tr->tr_time.tv_micro = tv->tv_micro;
PROFILE_OFF();
SetSignal(0,(1UL << mp->mp_SigBit)); SetSignal(0,(1UL << mp->mp_SigBit));
error = DoIO((struct IORequest *)tr); error = DoIO((struct IORequest *)tr);
PROFILE_ON();
tv->tv_secs = tr->tr_time.tv_secs; tv->tv_secs = tr->tr_time.tv_secs;
tv->tv_micro = tr->tr_time.tv_micro; tv->tv_micro = tr->tr_time.tv_micro;
@ -161,5 +159,7 @@ DoTimer(struct timeval *tv,LONG unit,LONG command)
} }
#endif /* __amigaos4__ */ #endif /* __amigaos4__ */
PROFILE_ON();
return(error); return(error);
} }

View File

@ -262,9 +262,8 @@ STATIC VOID
_SetValue(struct Environment * env,struct NexxStr * value,struct Node * symbol_table_node) _SetValue(struct Environment * env,struct NexxStr * value,struct Node * symbol_table_node)
{ {
STATIC CONST UWORD code[] = { 0x4EAE,0xFFAC,0x4E75 }; /* jsr -84(a6) ; rts */ STATIC CONST UWORD code[] = { 0x4EAE,0xFFAC,0x4E75 }; /* jsr -84(a6) ; rts */
struct Node * result;
result = (struct Node *)EmulateTags(code, EmulateTags(code,
ET_RegisterA0,env, ET_RegisterA0,env,
ET_RegisterA1,value, ET_RegisterA1,value,
ET_RegisterD0,symbol_table_node, ET_RegisterD0,symbol_table_node,

View File

@ -1,6 +1,6 @@
#define VERSION 1 #define VERSION 1
#define REVISION 211 #define REVISION 215
#define DATE "23.11.2016" #define DATE "26.6.2017"
#define VERS "c.lib 1.211" #define VERS "c.lib 1.215"
#define VSTRING "c.lib 1.211 (23.11.2016)\r\n" #define VSTRING "c.lib 1.215 (26.6.2017)\r\n"
#define VERSTAG "\0$VER: c.lib 1.211 (23.11.2016)" #define VERSTAG "\0$VER: c.lib 1.215 (26.6.2017)"

View File

@ -1 +1 @@
211 215

View File

@ -1,3 +1,76 @@
c.lib 1.216 (xxx)
- Add some wchar and multbyte-string related functions to allow gcc
building a libstdc++ library with wide char support. For now, the
functions are mostly stub ones only. They can be implemented on
demand.
c.lib 1.215 (26.6.2017)
- Added -fno-aggressive-loop-optimizations option when building crtbegin.c
to work around constructor/destructor hack with GCC 5.4.0 on AmigaOS 4.
- Added -fno-builtin option to fix conflicts with builtin memset()
with GCC 5.4.0 on AmigaOS 4.
c.lib 1.214 (27.4.2017)
- Added integer overflow test to calloc().
- Tiny change in getopt_long() so that the value pointed to by longindex
is always initialized to an invalid index position (that being -1),
instead of 0. The value of 0 can break some shell commands, most notably
GNU wget.
c.lib 1.213 (4.12.2016)
- Added the __decay_unused_slabs() function which brings all currently
empty slabs which are still protected from reuse closer to getting
reused or released.
- The slab-test program now exercises the memory allocation functions
to a greater degree. Memory is allocated in random chunk sizes,
the allocations are resized (to other random chunk sizes),
33% of all allocations are randomly freed, empty slabs readied for
reuse then discarded. The output in JSON format now shows a bit
more information as to what is being done.
- Rewrote __get_slab_stats() to use setjmp() and longjmp() in the
print() callback invocation.
- __get_slab_stats() now reports how many times a slab was reused
after having stuck around in the "empty slab" list.
- Changing the slab size through an environment variable is now
a feature of the debug build.
- Small changes to allow the library to be built with SAS/C again.
This includes adding code to disable/re-enable profiling,
fixing "stdlib_profile.h" and updating the smakefiles.
- Still not sure what it does, but _CXV45 now sits along with _CX25
and _CX35 in "sas_cxv.asm". "sas_cxv54.asm" is not needed any
more.
- Found the last use of MEMF_PRIVATE which should have been compiled
only for the OS4 version.
c.lib 1.212 (27.11.2016)
- Unused slabs which get recycled are no longer reinitialized from
scratch if their chunk size matches what the allocator needed.
If the chunk size matches, the list of available chunks is
left unchanged, and just the various counters are reset.
- Added __get_slab_stats() function.
- Added support for global __slab_purge_threshold tuning variable.
c.lib 1.211 (23.11.2016) c.lib 1.211 (23.11.2016)
- Added more consistency checking to the slab allocator, which is - Added more consistency checking to the slab allocator, which is

View File

@ -1,5 +1,5 @@
/* /*
* $Id: crtbegin.c,v 1.13 2010-08-21 11:37:03 obarthel Exp $ * crtbegin.c
* *
* :ts=4 * :ts=4
* *
@ -48,7 +48,12 @@
* Dummy constructor and destructor array. The linker script will put these at the * Dummy constructor and destructor array. The linker script will put these at the
* very beginning of section ".ctors" and ".dtors". crtend.o contains a similar entry * very beginning of section ".ctors" and ".dtors". crtend.o contains a similar entry
* with a NULL pointer entry and is put at the end of the sections. This way, the init * with a NULL pointer entry and is put at the end of the sections. This way, the init
* code can find the global constructor/destructor pointers * code can find the global constructor/destructor pointers.
*
* WARNING:
* This hack does not work correctly with GCC 5 and higher. The optimizer
* will see a one element array and act appropriately. The current workaround
* is to use -fno-aggressive-loop-optimizations when compiling this file.
*/ */
static void (*__CTOR_LIST__[1]) (void) __attribute__(( used, section(".ctors"), aligned(sizeof(void (*)(void))) )); static void (*__CTOR_LIST__[1]) (void) __attribute__(( used, section(".ctors"), aligned(sizeof(void (*)(void))) ));
static void (*__DTOR_LIST__[1]) (void) __attribute__(( used, section(".dtors"), aligned(sizeof(void (*)(void))) )); static void (*__DTOR_LIST__[1]) (void) __attribute__(( used, section(".dtors"), aligned(sizeof(void (*)(void))) ));

View File

@ -1,6 +1,6 @@
#define VERSION 1 #define VERSION 1
#define REVISION 211 #define REVISION 215
#define DATE "23.11.2016" #define DATE "26.6.2017"
#define VERS "debug.lib 1.211" #define VERS "debug.lib 1.215"
#define VSTRING "debug.lib 1.211 (23.11.2016)\r\n" #define VSTRING "debug.lib 1.215 (26.6.2017)\r\n"
#define VERSTAG "\0$VER: debug.lib 1.211 (23.11.2016)" #define VERSTAG "\0$VER: debug.lib 1.215 (26.6.2017)"

View File

@ -1 +1 @@
211 215

View File

@ -125,7 +125,7 @@ CLIB_DESTRUCTOR(dirent_exit)
if(__directory_list.mlh_Head != NULL) if(__directory_list.mlh_Head != NULL)
{ {
while(NOT IsListEmpty((struct List *)&__directory_list)) while(NOT IsMinListEmpty(&__directory_list))
closedir((DIR *)__directory_list.mlh_Head); closedir((DIR *)__directory_list.mlh_Head);
} }

View File

@ -196,7 +196,7 @@ opendir(const char * path_name)
UnLockDosList(LDF_VOLUMES|LDF_READ); UnLockDosList(LDF_VOLUMES|LDF_READ);
/* Bail out if we cannot present anything. */ /* Bail out if we cannot present anything. */
if(IsListEmpty((struct List *)&dh->dh_VolumeList)) if(IsMinListEmpty(&dh->dh_VolumeList))
{ {
__set_errno(ENOMEM); __set_errno(ENOMEM);
goto out; goto out;

View File

@ -93,7 +93,7 @@ readdir(DIR * directory_pointer)
assert( (((ULONG)name) & 3) == 0 ); assert( (((ULONG)name) & 3) == 0 );
if(dh->dh_VolumeNode == NULL && NOT IsListEmpty((struct List *)&dh->dh_VolumeList)) if(dh->dh_VolumeNode == NULL && NOT IsMinListEmpty(&dh->dh_VolumeList))
dh->dh_VolumeNode = (struct Node *)dh->dh_VolumeList.mlh_Head; dh->dh_VolumeNode = (struct Node *)dh->dh_VolumeList.mlh_Head;
strcpy(name,"\1:"); /* BSTR for ":" */ strcpy(name,"\1:"); /* BSTR for ":" */

View File

@ -296,7 +296,7 @@ static int getopt_long_internal(int argc, const char **argv, const char *optstri
optp = strchr(optstring, c); optp = strchr(optstring, c);
/* We never find a long option in a compound option */ /* We never find a long option in a compound option */
*longindex = 0; *longindex = -1;
/* Check if it's legal */ /* Check if it's legal */
if (c == ':' || (optp == NULL)) if (c == ':' || (optp == NULL))

View File

@ -359,7 +359,7 @@ extern unsigned int (* __get_default_stack_size)(void);
/* /*
* This library falls back onto locale.library to perform string collation * This library falls back onto locale.library to perform string collation
* in strcoll(), character conversion in toupper() and various other * in strcoll(), character conversion in toupper() and various other
* functions. This may not your intention. To restrict the library to use * functions. This may not be your intention. To restrict the library to use
* only the "C" language locale, declare the following variable in your * only the "C" language locale, declare the following variable in your
* code and set it to FALSE, so that it overrides the default settings. * code and set it to FALSE, so that it overrides the default settings.
* The variable value is checked during program startup and, if set to * The variable value is checked during program startup and, if set to

View File

@ -166,6 +166,8 @@ extern int errno;
#define EILSEQ 85 /* Encoding error detected */ #define EILSEQ 85 /* Encoding error detected */
#define ENOTSUP 86 /* Not supported */
/****************************************************************************/ /****************************************************************************/
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -59,6 +59,10 @@ extern "C" {
/****************************************************************************/ /****************************************************************************/
typedef void *locale_t;
/****************************************************************************/
struct lconv struct lconv
{ {
char * decimal_point; /* Decimal point character (non-monetary). */ char * decimal_point; /* Decimal point character (non-monetary). */

View File

@ -61,7 +61,11 @@ extern "C" {
typedef int ptrdiff_t; typedef int ptrdiff_t;
typedef unsigned int size_t; typedef unsigned int size_t;
/* wchar_t is a built-in type in C++ */
#ifndef __cplusplus
typedef unsigned short wchar_t; typedef unsigned short wchar_t;
#endif
/****************************************************************************/ /****************************************************************************/

View File

@ -47,6 +47,10 @@
#include <stddef.h> #include <stddef.h>
#endif /* _STDDEF_H */ #endif /* _STDDEF_H */
#ifndef _SYS_CLIB2_STDC_H
#include <sys/clib2_stdc.h>
#endif /* _SYS_CLIB2_STDC_H */
/****************************************************************************/ /****************************************************************************/
#ifdef __cplusplus #ifdef __cplusplus
@ -173,6 +177,19 @@ extern int rand_r(unsigned int * seed);
extern unsigned long __slab_max_size; extern unsigned long __slab_max_size;
/*
* The slab allocator will periodically free all currently unused memory.
* You can control how much memory should be released, instead of
* releasing everything.
*
* This would make the slab allocator release only up to 512 KBytes of
* unused memory at a time:
*
* unsigned long __slab_purge_threshold = 512 * 1024;
*/
extern unsigned long __slab_purge_threshold;
/****************************************************************************/ /****************************************************************************/
/* /*
@ -188,6 +205,21 @@ extern void __free_unused_slabs(void);
/****************************************************************************/ /****************************************************************************/
/*
* You can accelerate the reuse of currently unused slabs by calling
* the __decay_unused_slabs() function. Each call decrements the decay
* counter until it reaches 0, at which point an unused slab can be
* reused instead of allocating a new slab. Also, at 0 unused slabs
* will be freed by the allocator.
*
* Please note that this function works within the context of the memory
* allocation system and is not safe to call from interrupt code. It may
* break a Forbid() or Disable() condition.
*/
extern void __decay_unused_slabs(void);
/****************************************************************************/
/* /*
* You can obtain runtime statistics about the slab allocator by * You can obtain runtime statistics about the slab allocator by
* invoking the __get_slab_usage() function which in turn invokes * invoking the __get_slab_usage() function which in turn invokes
@ -250,6 +282,11 @@ struct __slab_usage_information
/* How many memory chunks in this slab are being used? */ /* How many memory chunks in this slab are being used? */
size_t sui_num_chunks_used; size_t sui_num_chunks_used;
/* How many time was this slab reused without reinitializing
* it all over again from scratch?
*/
size_t sui_num_reused;
}; };
/****************************************************************************/ /****************************************************************************/
@ -324,6 +361,31 @@ void __get_slab_allocations(__slab_allocation_callback callback);
/****************************************************************************/ /****************************************************************************/
/*
* You can obtain information about the memory managed by the slab allocator,
* as well as additional information about the slab allocator's performance
* in JSON format. This format can be used for more detailed analysis.
*
* You supply a function which will be called for each line of the JSON
* data produced. You can store this data in a file, or in the clipboard,
* for later use. Your function must return 0 if it wants to be called
* again, or return -1 if it wants to stop (e.g. if an error occured
* when writing the JSON data to disk). The same "user_data" pointer which
* you pass to __get_slab_stats() will be passed to your callback function.
*
* Please note that this function works within the context of the memory
* allocation system and is not safe to call from interrupt code. It may
* break a Forbid() or Disable() condition.
*/
typedef int (* __slab_status_callback)(void * user_data, const char * line, size_t line_length);
/****************************************************************************/
extern void __get_slab_stats(void * user_data, __slab_status_callback callback);
/****************************************************************************/
/* /*
* You can request to use the alloca() variant that actually does allocate * You can request to use the alloca() variant that actually does allocate
* memory from the system rather than the current stack frame, which will * memory from the system rather than the current stack frame, which will
@ -389,6 +451,11 @@ extern lldiv_t lldiv(long long n,long long d);
/****************************************************************************/ /****************************************************************************/
extern int mbtowc(wchar_t *restrict pwc, const char *restrict s, size_t n);
extern int wctomb(char *s, wchar_t wchar);
/****************************************************************************/
#endif /* __GNUC__ || (__STDC_VERSION__ && __STDC_VERSION__ >= 199901L) */ #endif /* __GNUC__ || (__STDC_VERSION__ && __STDC_VERSION__ >= 199901L) */
/****************************************************************************/ /****************************************************************************/

View File

@ -62,6 +62,7 @@ extern int strcmp(const char *s1, const char * s2);
extern int strncmp(const char *s1, const char *s2, size_t n); extern int strncmp(const char *s1, const char *s2, size_t n);
extern char *strcpy(char *dest, const char *src); extern char *strcpy(char *dest, const char *src);
extern char *strncpy(char *dest, const char *src, size_t n); extern char *strncpy(char *dest, const char *src, size_t n);
extern size_t strnlen(const char *s, size_t maxlen);
extern size_t strlen(const char *s); extern size_t strlen(const char *s);
extern char *strchr(const char *s, int c); extern char *strchr(const char *s, int c);
extern char *strrchr(const char *s, int c); extern char *strrchr(const char *s, int c);

View File

@ -0,0 +1,73 @@
/*
* $Id: $
*
* :ts=4
*
* Portable ISO 'C' (1994) runtime library for the Amiga computer
* Copyright (c) 2002-2017 by Olaf Barthel <obarthel (at) gmx.net>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Neither the name of Olaf Barthel nor the names of contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************
*
* Documentation and source code for this library, and the most recent library
* build are available from <https://github.com/adtools/clib2>.
*
*****************************************************************************
*/
#ifndef _SYS_PARAM_H
#define _SYS_PARAM_H
/****************************************************************************/
/* The following is not part of the ISO 'C' (1994) standard. */
/****************************************************************************/
#ifndef _UNISTD_H
#include <unistd.h>
#endif /* _UNISTD_H */
/****************************************************************************/
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/****************************************************************************/
#define MIN(a,b) (((a)<(b))?(a):(b))
#define MAX(a,b) (((a)>(b))?(a):(b))
/****************************************************************************/
#ifdef __cplusplus
}
#endif /* __cplusplus */
/****************************************************************************/
#endif /* _SYS_MOUNT_H */

View File

@ -106,10 +106,24 @@ extern size_t strftime(char *s, size_t maxsize, const char *format,
/****************************************************************************/ /****************************************************************************/
/* Timespec declaration */
struct timespec
{
time_t tv_secs;
long tv_nsec;
};
#ifndef tv_sec
#define tv_sec tv_secs
#endif /* tv_sec */
/****************************************************************************/
extern char * asctime_r(const struct tm *tm,char * buffer); extern char * asctime_r(const struct tm *tm,char * buffer);
extern char * ctime_r(const time_t *tptr,char * buffer); extern char * ctime_r(const time_t *tptr,char * buffer);
extern struct tm * gmtime_r(const time_t *t,struct tm * tm_ptr); extern struct tm * gmtime_r(const time_t *t,struct tm * tm_ptr);
extern struct tm * localtime_r(const time_t *t,struct tm * tm_ptr); extern struct tm * localtime_r(const time_t *t,struct tm * tm_ptr);
extern void tzset(void);
/****************************************************************************/ /****************************************************************************/

View File

@ -43,6 +43,10 @@
/****************************************************************************/ /****************************************************************************/
#ifndef _SYS_CLIB2_STDC_H
#include <sys/clib2_stdc.h>
#endif /* _SYS_CLIB2_STDC_H */
#ifndef _STDDEF_H #ifndef _STDDEF_H
#include <stddef.h> #include <stddef.h>
#endif /* _STDDEF_H */ #endif /* _STDDEF_H */
@ -59,6 +63,14 @@
#include <time.h> #include <time.h>
#endif /* _TIME_H */ #endif /* _TIME_H */
#ifndef _LOCALE_H
#include <locale.h>
#endif /* _LOCALE_H */
#ifndef _STDINT_H
#include <stdint.h>
#endif
/****************************************************************************/ /****************************************************************************/
#ifdef __cplusplus #ifdef __cplusplus
@ -68,8 +80,6 @@ extern "C" {
/****************************************************************************/ /****************************************************************************/
#define WEOF (-1) #define WEOF (-1)
#define WCHAR_MAX 65535
#define WCHAR_MIN 0
/****************************************************************************/ /****************************************************************************/
@ -81,7 +91,6 @@ typedef long mbstate_t;
extern wint_t btowc(int c); extern wint_t btowc(int c);
extern int wctob(wint_t c); extern int wctob(wint_t c);
extern int mbsinit(const mbstate_t *ps); extern int mbsinit(const mbstate_t *ps);
extern size_t mbrlen(wchar_t *pwc, const char * s, size_t n, mbstate_t *ps);
extern size_t wcrtomb(char *s, wchar_t wc, mbstate_t *ps); extern size_t wcrtomb(char *s, wchar_t wc, mbstate_t *ps);
extern size_t mbsrtowcs(wchar_t *pwcs, const char **src, size_t n, mbstate_t *ps); extern size_t mbsrtowcs(wchar_t *pwcs, const char **src, size_t n, mbstate_t *ps);
extern size_t wcsrtombs(char *s, const wchar_t **src, size_t n, mbstate_t *ps); extern size_t wcsrtombs(char *s, const wchar_t **src, size_t n, mbstate_t *ps);
@ -161,7 +170,7 @@ extern int swprintf(wchar_t *s, const wchar_t *format, ...);
extern int vfwprintf(FILE *stream,const wchar_t *format,va_list arg); extern int vfwprintf(FILE *stream,const wchar_t *format,va_list arg);
extern int vwprintf(const wchar_t *format,va_list arg); extern int vwprintf(const wchar_t *format,va_list arg);
extern int vswprintf(char *s, const wchar_t *format,va_list arg); extern int vswprintf(wchar_t *s, size_t maxlen, const wchar_t *format, va_list arg);
/****************************************************************************/ /****************************************************************************/
@ -174,16 +183,24 @@ extern size_t wcsftime(wchar_t *s, size_t maxsize, const wchar_t *format, const
/****************************************************************************/ /****************************************************************************/
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) #if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || defined(__cplusplus)
extern size_t mbrlen(const char *restrict s, size_t n, mbstate_t *restrict ps);
extern size_t mbrtowc(wchar_t *restrict pwc, const char *restrict s, size_t n, mbstate_t *restrict ps);
extern int mbsinit(const mbstate_t *ps);
extern size_t mbsnrtowcs(wchar_t *restrict dst, const char **restrict src, size_t nmc, size_t len, mbstate_t *restrict ps);
extern size_t mbsrtowcs(wchar_t *restrict dst, const char **restrict src, size_t len, mbstate_t *restrict ps);
extern size_t wcrtomb(char *restrict s, wchar_t wc, mbstate_t *restrict ps);
extern int wcscoll(const wchar_t *ws1, const wchar_t *ws2);
extern int wcscoll_l(const wchar_t *ws1, const wchar_t *ws2, locale_t loc);
extern size_t wcscspn(const wchar_t *s, const wchar_t *c);
extern size_t wcsnrtombs(char *restrict dst, const wchar_t **restrict src, size_t nwc, size_t len, mbstate_t *restrict ps);
extern wchar_t * wcsrchr(const wchar_t *ws, wchar_t wc);
extern size_t wcsrtombs(char *restrict dst, const wchar_t **restrict src, size_t len, mbstate_t *restrict ps);
extern long long wcstoll(const wchar_t *str, wchar_t **ptr, int base); extern long long wcstoll(const wchar_t *str, wchar_t **ptr, int base);
extern unsigned long long wcstoull(const wchar_t *str, wchar_t **ptr, int base); extern unsigned long long wcstoull(const wchar_t *str, wchar_t **ptr, int base);
extern size_t mbrtowc_l(wchar_t *restrict pwc, const char *restrict s, size_t n, mbstate_t *restrict ps, locale_t loc);
extern int wcscoll_l(const wchar_t *ws1, const wchar_t *ws2, locale_t loc);
extern size_t wcscspn(const wchar_t *ws1, const wchar_t *ws2);
extern wchar_t * wcsrchr(const wchar_t *ws, wchar_t wc);
#endif /* __STDC_VERSION__ && __STDC_VERSION__ >= 199901L */ #endif /* __STDC_VERSION__ && __STDC_VERSION__ >= 199901L */
/****************************************************************************/ /****************************************************************************/

View File

@ -212,6 +212,7 @@ C_LIB := \
stdlib_dosbase.o \ stdlib_dosbase.o \
stdlib_exit.o \ stdlib_exit.o \
stdlib_free.o \ stdlib_free.o \
stdlib_decay_unused_slabs.o \
stdlib_free_unused_slabs.o \ stdlib_free_unused_slabs.o \
stdlib_getdefstacksize.o \ stdlib_getdefstacksize.o \
stdlib_getenv.o \ stdlib_getenv.o \
@ -220,6 +221,7 @@ C_LIB := \
stdlib_get_errno.o \ stdlib_get_errno.o \
stdlib_get_slab_usage.o \ stdlib_get_slab_usage.o \
stdlib_get_slab_allocations.o \ stdlib_get_slab_allocations.o \
stdlib_get_slab_stats.o \
stdlib_isresident.o \ stdlib_isresident.o \
stdlib_labs.o \ stdlib_labs.o \
stdlib_llabs.o \ stdlib_llabs.o \
@ -232,6 +234,7 @@ C_LIB := \
stdlib_main_stub.o \ stdlib_main_stub.o \
stdlib_malloc.o \ stdlib_malloc.o \
stdlib_math.o \ stdlib_math.o \
stdlib_mbtowc.o \
stdlib_mkdtemp.o \ stdlib_mkdtemp.o \
stdlib_mkstemp.o \ stdlib_mkstemp.o \
stdlib_mktemp.o \ stdlib_mktemp.o \
@ -260,6 +263,7 @@ C_LIB := \
stdlib_showerror.o \ stdlib_showerror.o \
stdlib_slab.o \ stdlib_slab.o \
stdlib_slab_max_size.o \ stdlib_slab_max_size.o \
stdlib_slab_purge_threshold.o \
stdlib_srand.o \ stdlib_srand.o \
stdlib_stacksize.o \ stdlib_stacksize.o \
stdlib_stack_usage.o \ stdlib_stack_usage.o \
@ -307,6 +311,7 @@ C_LIB := \
string_strncat.o \ string_strncat.o \
string_strncmp.o \ string_strncmp.o \
string_strncpy.o \ string_strncpy.o \
string_strnlen.o \
string_strpbrk.o \ string_strpbrk.o \
string_strrchr.o \ string_strrchr.o \
string_strspn.o \ string_strspn.o \
@ -333,6 +338,7 @@ C_LIB := \
time_numbertostring.o \ time_numbertostring.o \
time_strftime.o \ time_strftime.o \
time_time.o \ time_time.o \
time_tzset.o \
time_weekday.o \ time_weekday.o \
uio_readv.o \ uio_readv.o \
uio_writev.o \ uio_writev.o \
@ -369,7 +375,79 @@ C_LIB := \
unistd_unlink.o \ unistd_unlink.o \
unistd_usleep.o \ unistd_usleep.o \
utime_utime.o \ utime_utime.o \
utsname_uname.o utsname_uname.o \
wchar_btowc.o \
wchar_fgetwc.o \
wchar_fgetws.o \
wchar_fputwc.o \
wchar_fputws.o \
wchar_fwide.o \
wchar_fwprintf.o \
wchar_fwscanf.o \
wchar_getwc.o \
wchar_getwchar.o \
wchar_mbrlen.o \
wchar_mbrtowc.o \
wchar_mbsinit.o \
wchar_mbsrtowcs.o \
wchar_putwc.o \
wchar_putwchar.o \
wchar_swprintf.o \
wchar_swscanf.o \
wchar_ungetwc.o \
wchar_vfwprintf.o \
wchar_vswprintf.o \
wchar_vwprintf.o \
wchar_wcrtomb.o \
wchar_wcscat.o \
wchar_wcschr.o \
wchar_wcscmp.o \
wchar_wcscoll.o \
wchar_wcscpy.o \
wchar_wcscspn.o \
wchar_wcsftime.o \
wchar_wcslen.o \
wchar_wcsncat.o \
wchar_wcsncmp.o \
wchar_wcsncpy.o \
wchar_wscoll.o \
wchar_wcspbrk.o \
wchar_wcsrtombs.o \
wchar_wcsspn.o \
wchar_wcstod.o \
wchar_wcstok.o \
wchar_wcstol.o \
wchar_wcstoll.o \
wchar_wcstoul.o \
wchar_wcstoull.o \
wchar_wcsxfrm.o \
wchar_wctob.o \
wchar_wmemchr.o \
wchar_wmemcmp.o \
wchar_wmemcpy.o \
wchar_wmemmove.o \
wchar_wmemset.o \
wchar_wprintf.o \
wchar_wscanf.o \
wchar_wscoll.o \
wctype_iswalnum.o \
wctype_iswalpha.o \
wctype_iswblank.o \
wctype_iswcntrl.o \
wctype_iswctype.o \
wctype_iswdigit.o \
wctype_iswgraph.o \
wctype_iswlower.o \
wctype_iswprint.o \
wctype_iswpunc.o \
wctype_iswspace.o \
wctype_iswupper.o \
wctype_iswxdigit.o \
wctype_towctrans.o \
wctype_towlower.o \
wctype_towupper.o \
wctype_wctrans.o \
wctype_wctype.o
############################################################################## ##############################################################################

View File

@ -1,6 +1,6 @@
#define VERSION 1 #define VERSION 1
#define REVISION 211 #define REVISION 215
#define DATE "23.11.2016" #define DATE "26.6.2017"
#define VERS "m.lib 1.211" #define VERS "m.lib 1.215"
#define VSTRING "m.lib 1.211 (23.11.2016)\r\n" #define VSTRING "m.lib 1.215 (26.6.2017)\r\n"
#define VERSTAG "\0$VER: m.lib 1.211 (23.11.2016)" #define VERSTAG "\0$VER: m.lib 1.215 (26.6.2017)"

View File

@ -1 +1 @@
211 215

View File

@ -1,6 +1,6 @@
#define VERSION 1 #define VERSION 1
#define REVISION 211 #define REVISION 214
#define DATE "23.11.2016" #define DATE "27.4.2017"
#define VERS "m881.lib 1.211" #define VERS "m881.lib 1.214"
#define VSTRING "m881.lib 1.211 (23.11.2016)\r\n" #define VSTRING "m881.lib 1.214 (27.4.2017)\r\n"
#define VERSTAG "\0$VER: m881.lib 1.211 (23.11.2016)" #define VERSTAG "\0$VER: m881.lib 1.214 (27.4.2017)"

View File

@ -1 +1 @@
211 214

View File

@ -93,6 +93,13 @@
/****************************************************************************/ /****************************************************************************/
#ifndef IsMinListEmpty
#define IsMinListEmpty(ml) \
((struct MinList *)((ml)->mlh_TailPred) == (struct MinList *)(ml))
#endif
/****************************************************************************/
#ifndef AMIGA_COMPILER_H #ifndef AMIGA_COMPILER_H
#ifdef __SASC #ifdef __SASC

View File

@ -1,6 +1,6 @@
#define VERSION 1 #define VERSION 1
#define REVISION 211 #define REVISION 215
#define DATE "23.11.2016" #define DATE "26.6.2017"
#define VERS "net.lib 1.211" #define VERS "net.lib 1.215"
#define VSTRING "net.lib 1.211 (23.11.2016)\r\n" #define VSTRING "net.lib 1.215 (26.6.2017)\r\n"
#define VERSTAG "\0$VER: net.lib 1.211 (23.11.2016)" #define VERSTAG "\0$VER: net.lib 1.215 (26.6.2017)"

View File

@ -1 +1 @@
211 215

View File

@ -136,7 +136,7 @@ profil(unsigned short *buffer, size_t bufSize, size_t offset, unsigned int scale
ProfileData.CounterStart = GetCounterStart(); ProfileData.CounterStart = GetCounterStart();
/* Set interrupt vector */ /* Set interrupt vector */
CounterInt.is_Code = (void (*)())CounterIntFn; CounterInt.is_Code = (void (*)(void))CounterIntFn;
CounterInt.is_Data = &ProfileData; CounterInt.is_Data = &ProfileData;
IPM->SetInterruptVector(1, &CounterInt); IPM->SetInterruptVector(1, &CounterInt);

View File

@ -37,6 +37,7 @@
xdef __CXV25 xdef __CXV25
xdef __CXV35 xdef __CXV35
xdef __CXV45
xdef __CXNRM5 xdef __CXNRM5
xdef __CXTAB5 xdef __CXTAB5
@ -74,6 +75,43 @@ L44: MOVE.W D0,D1
MOVEM.L (SP)+,D2-D5/A1 MOVEM.L (SP)+,D2-D5/A1
RTS RTS
__CXV45:
MOVE.L D0,D1
SWAP D1
AND.W #$7FFF,D1
CMP.W #$80,D1
BLT .1
CMP.W #$7F80,D1
BGE .3
ASR.L #3,D0
AND.L #$8FFFFFFF,D0
ADD.L #$38000000,D0
SWAP D1
AND.L #7,D1
ROR.L #3,D1
.2 RTS
.1 TST.L D1
BEQ.S .2
MOVEM.L D2-D5,-(SP)
SWAP D0
MOVE.W D0,D4
AND.W #$8000,D4
MOVE.W #$39D0,D5
MOVEQ #0,D0
SWAP D1
JSR __CXNRM5(PC)
MOVEM.L (SP)+,D2-D5
RTS
.3 ASR.L #3,D0
OR.L #$7FF00000,D0
SWAP D1
AND.L #7,D1
ROR.L #3,D1
RTS
__CXNRM5: __CXNRM5:
CMP.L #$20,D0 CMP.L #$20,D0

106
library/sas_cxv52.asm Normal file
View File

@ -0,0 +1,106 @@
*
* :ts=8
*
* Adapted from reassembled SAS/C runtime library code.
*
* Portable ISO 'C' (1994) runtime library for the Amiga computer
* Copyright (c) 2002-2015 by Olaf Barthel <obarthel (at) gmx.net>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Neither the name of Olaf Barthel nor the names of contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
xdef __CXV52
xdef __CXV53
xref __CXFERR
section text,code
__CXV52:
MOVEM.L D2/D3,-(SP)
MOVEQ #-1,D3
MOVE.L D0,D2
BPL.W lab04A
CMPI.L #$BFF00000,D0
BCS.W lab07A
MOVEM.L D0/D1/A0/A1,-(SP)
PEA (2).L
JSR __CXFERR
ADDQ.W #4,SP
MOVEM.L (SP)+,D0/D1/A0/A1
BRA.W lab07A
__CXV53:
MOVEM.L D2/D3,-(SP)
MOVE.L #$7FFFFFFF,D3
MOVE.L D0,D2
BPL.W lab04A
ADDQ.L #1,D3
EOR.L D3,D0
lab04A: SWAP D0
MOVE.W D0,D2
ANDI.W #$7FF0,D2
EOR.W D2,D0
SUBI.W #$3FF0,D2
BLT.W lab07A
EORI.W #$10,D0
SWAP D0
ASR.W #4,D2
SUBI.W #$14,D2
BGT.W lab09A
NEG.W D2
LSR.L D2,D0
TST.L D2
BMI.W lab0B2
BRA.W lab0B4
lab07A: MOVEQ #0,D0
BRA.W lab0B4
lab080: MOVEM.L D0/D1/A0/A1,-(SP)
PEA (2).L
JSR __CXFERR
ADDQ.W #4,SP
MOVEM.L (SP)+,D0/D1/A0/A1
MOVE.L D3,D0
BRA.W lab0B4
lab09A: CMPI.W #11,D2
BGT.B lab080
EOR.L D1,D0
ROL.L D2,D0
LSL.L D2,D1
EOR.L D1,D0
CMP.L D3,D0
BHI.B lab080
TST.L D2
BPL.W lab0B4
lab0B2: NEG.L D0
lab0B4: MOVEM.L (SP)+,D2/D3
RTS
end

View File

@ -1,6 +1,4 @@
* *
* $Id: sas_cxv54.asm,v 1.1.1.1 2004-07-26 16:31:04 obarthel Exp $
*
* :ts=8 * :ts=8
* *
* Adapted from reassembled SAS/C runtime library code. * Adapted from reassembled SAS/C runtime library code.
@ -38,7 +36,8 @@
xdef __CXV54 xdef __CXV54
xref __CXFERR xref __CXFERR
__CXV54 __CXV54:
MOVEM.L A0/A1,-(SP) MOVEM.L A0/A1,-(SP)
MOVE.L D4,A0 MOVE.L D4,A0
SWAP D0 SWAP D0
@ -47,11 +46,11 @@ __CXV54
EOR.W D4,D0 EOR.W D4,D0
SUB.W #$3800,D0 SUB.W #$3800,D0
CMP.W #$10,D0 CMP.W #$10,D0
BLT lbC000098 BLT lab098
CMP.W #$FEF,D0 CMP.W #$FEF,D0
BLT lbC000102 BLT lab102
CMP.W #$47F0,D0 CMP.W #$47F0,D0
BLT lbC000058 BLT lab058
SWAP D0 SWAP D0
LSL.L #3,D0 LSL.L #3,D0
ROL.L #3,D1 ROL.L #3,D1
@ -59,17 +58,16 @@ __CXV54
EOR.L D1,D0 EOR.L D1,D0
SWAP D0 SWAP D0
OR.W #$7F80,D0 OR.W #$7F80,D0
BRA lbC000112 BRA lab112
lbC000058 lab058: CMP.W #$FF0,D0
CMP.W #$FF0,D0 BGE lab074
BGE lbC000074
CMP.L #$FFFF0FEF,D0 CMP.L #$FFFF0FEF,D0
BNE lbC000102 BNE lab102
CMP.L #$F0000000,D1 CMP.L #$F0000000,D1
BCS lbC000102 BCS lab102
lbC000074
MOVEM.L D0/D1/A0/A1,-(SP) lab074: MOVEM.L D0/D1/A0/A1,-(SP)
PEA 2.L PEA 2.L
JSR __CXFERR JSR __CXFERR
ADDQ.W #4,SP ADDQ.W #4,SP
@ -78,63 +76,56 @@ lbC000074
EOR.W D4,D0 EOR.W D4,D0
SWAP D0 SWAP D0
MOVEQ #0,D1 MOVEQ #0,D1
BRA lbC000116 BRA lab116
lbC000098 lab098: CMP.W #$FE90,D0
CMP.W #$FE90,D0 BGE lab0C4
BGE lbC0000C4
ADD.W #$3800,D0 ADD.W #$3800,D0
OR.L D1,D0 OR.L D1,D0
BEQ lbC000112 BEQ lab112
MOVEM.L D0/D1/A0/A1,-(SP) MOVEM.L D0/D1/A0/A1,-(SP)
PEA 1.L PEA 1.L
JSR __CXFERR JSR __CXFERR
ADDQ.W #4,SP ADDQ.W #4,SP
MOVEM.L (SP)+,D0/D1/A0/A1 MOVEM.L (SP)+,D0/D1/A0/A1
MOVEQ #0,D0 MOVEQ #0,D0
BRA lbC000112 BRA lab112
lbC0000C4 lab0C4: MOVE.L D5,A1
MOVE.L D5,A1
MOVE.W D0,D5 MOVE.W D0,D5
AND.W #15,D0 AND.W #15,D0
EOR.W #$10,D0 EOR.W #$10,D0
SWAP D0 SWAP D0
ASR.W #4,D5 ASR.W #4,D5
ADDQ.W #2,D5 ADDQ.W #2,D5
BGE lbC0000E6 BGE lab0E6
NEG.W D5 NEG.W D5
LSR.L D5,D0 LSR.L D5,D0
MOVEQ #0,D5 MOVEQ #0,D5
ADDX.L D5,D0 ADDX.L D5,D0
BRA lbC0000F6 BRA lab0F6
lbC0000E6 lab0E6: CLR.W D1
CLR.W D1
LSL.L D5,D0 LSL.L D5,D0
ADDQ.W #1,D5 ADDQ.W #1,D5
ROXL.L D5,D1 ROXL.L D5,D1
AND.L #15,D1 AND.L #15,D1
ADDX.L D1,D0 ADDX.L D1,D0
lbC0000F6 lab0F6: MOVE.L A1,D5
MOVE.L A1,D5
SWAP D0 SWAP D0
EOR.W D4,D0 EOR.W D4,D0
SWAP D0 SWAP D0
BRA lbC000116 BRA lab116
lbC000102 lab102: SWAP D0
SWAP D0
LSL.L #3,D0 LSL.L #3,D0
ROXL.L #4,D1 ROXL.L #4,D1
AND.L #7,D1 AND.L #7,D1
ADDX.L D1,D0 ADDX.L D1,D0
SWAP D0 SWAP D0
lbC000112 lab112: EOR.W D4,D0
EOR.W D4,D0
SWAP D0 SWAP D0
lbC000116 lab116: MOVE.L A0,D4
MOVE.L A0,D4
MOVEM.L (SP)+,A0/A1 MOVEM.L (SP)+,A0/A1
RTS RTS

File diff suppressed because it is too large Load Diff

View File

@ -327,7 +327,7 @@ remove_locked_region_node(struct FileLockSemaphore * fls,struct fd * fd,LONG sta
/* Check if there are any locked regions left. /* Check if there are any locked regions left.
* If not, mark the entire file as unlocked. * If not, mark the entire file as unlocked.
*/ */
if(IsListEmpty((struct List *)&which_lock->fln_LockedRegionList)) if(IsMinListEmpty(&which_lock->fln_LockedRegionList))
{ {
SHOWMSG("no more regions are locked; removing the file lock node"); SHOWMSG("no more regions are locked; removing the file lock node");
@ -705,7 +705,7 @@ cleanup_locked_records(struct fd * fd)
} }
} }
if(IsListEmpty((struct List *)&which_lock->fln_LockedRegionList)) if(IsMinListEmpty(&which_lock->fln_LockedRegionList))
{ {
SHOWMSG("no more regions are locked; removing the file lock node"); SHOWMSG("no more regions are locked; removing the file lock node");

View File

@ -94,7 +94,7 @@ alloca_cleanup(const char * file,int line)
NewList((struct List *)&alloca_memory_list); NewList((struct List *)&alloca_memory_list);
/* Is this worth cleaning up? */ /* Is this worth cleaning up? */
if(NOT IsListEmpty((struct List *)&alloca_memory_list)) if(NOT IsMinListEmpty(&alloca_memory_list))
{ {
struct MemoryContextNode * mcn_prev; struct MemoryContextNode * mcn_prev;
struct MemoryContextNode * mcn; struct MemoryContextNode * mcn;
@ -120,7 +120,7 @@ alloca_cleanup(const char * file,int line)
/* Drop the cleanup callback if there's nothing to be cleaned /* Drop the cleanup callback if there's nothing to be cleaned
up any more. */ up any more. */
if(IsListEmpty((struct List *)&alloca_memory_list)) if(IsMinListEmpty(&alloca_memory_list))
__alloca_cleanup = NULL; __alloca_cleanup = NULL;
} }

View File

@ -59,13 +59,25 @@ __calloc(size_t num_elements,size_t element_size,const char * file,int line)
} }
#endif /* __MEM_DEBUG */ #endif /* __MEM_DEBUG */
/* This might overflow. */
total_size = num_elements * element_size; total_size = num_elements * element_size;
result = __malloc(total_size,file,line); /* No arithmetic overflow? */
if(result != NULL) if(total_size >= num_elements)
memset(result,0,total_size); {
result = __malloc(total_size,file,line);
if(result != NULL)
memset(result,0,total_size);
else
SHOWMSG("memory allocation failure");
}
/* Multiplying the number and size of elements overflows
* the size_t range.
*/
else else
SHOWMSG("memory allocation failure"); {
D(("calloc(num_elements=%ld, element_size=%ld) overflow"));
}
return(result); return(result);
} }

View File

@ -0,0 +1,75 @@
/*
* :ts=4
*
* Portable ISO 'C' (1994) runtime library for the Amiga computer
* Copyright (c) 2002-2015 by Olaf Barthel <obarthel (at) gmx.net>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Neither the name of Olaf Barthel nor the names of contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _STDLIB_HEADERS_H
#include "stdlib_headers.h"
#endif /* _STDLIB_HEADERS_H */
/****************************************************************************/
#ifndef _STDLIB_MEMORY_H
#include "stdlib_memory.h"
#endif /* _STDLIB_MEMORY_H */
/****************************************************************************/
/* Look at all currently unused slabs, decrementing the decay
* counter which prevents them from being reused.
*/
void
__decay_unused_slabs(void)
{
if(__slab_data.sd_InUse)
{
struct MinNode * free_node;
struct MinNode * free_node_next;
struct SlabNode * sn;
__memory_lock();
for(free_node = (struct MinNode *)__slab_data.sd_EmptySlabs.mlh_Head ;
free_node->mln_Succ != NULL ;
free_node = free_node_next)
{
free_node_next = (struct MinNode *)free_node->mln_Succ;
/* free_node points to SlabNode.sn_EmptyLink, which
* directly follows the SlabNode.sn_MinNode.
*/
sn = (struct SlabNode *)&free_node[-1];
if(sn->sn_EmptyDecay > 0)
sn->sn_EmptyDecay--;
}
__memory_unlock();
}
}

View File

@ -374,44 +374,57 @@ remove_and_free_memory_node(struct MemoryNode * mn)
#if defined(__USE_SLAB_ALLOCATOR) #if defined(__USE_SLAB_ALLOCATOR)
{ {
/* Are we using the slab allocator? */ /* Are we using the slab allocator? */
if (__slab_data.sd_InUse) if(__slab_data.sd_InUse)
{ {
__slab_free(mn,allocation_size); __slab_free(mn,allocation_size);
} }
else if (__memory_pool != NULL)
{
FreePooled(__memory_pool,mn,allocation_size);
}
else else
{ {
#if defined(__MEM_DEBUG) if(__memory_pool != NULL)
{ {
FreeMem(mn,allocation_size); PROFILE_OFF();
FreePooled(__memory_pool,mn,allocation_size);
PROFILE_ON();
} }
#else else
{ {
struct MinNode * mln = (struct MinNode *)mn; #if defined(__MEM_DEBUG)
{
PROFILE_OFF();
FreeMem(mn,allocation_size);
PROFILE_ON();
}
#else
{
struct MinNode * mln = (struct MinNode *)mn;
mln--; mln--;
Remove((struct Node *)mln); Remove((struct Node *)mln);
FreeMem(mln,sizeof(*mln) + allocation_size); PROFILE_OFF();
FreeMem(mln,sizeof(*mln) + allocation_size);
PROFILE_ON();
}
#endif /* __MEM_DEBUG */
} }
#endif /* __MEM_DEBUG */
} }
} }
#else #else
{ {
if (__memory_pool != NULL) if(__memory_pool != NULL)
{ {
PROFILE_OFF();
FreePooled(__memory_pool,mn,allocation_size); FreePooled(__memory_pool,mn,allocation_size);
PROFILE_ON();
} }
else else
{ {
#if defined(__MEM_DEBUG) #if defined(__MEM_DEBUG)
{ {
PROFILE_OFF();
FreeMem(mn,allocation_size); FreeMem(mn,allocation_size);
PROFILE_ON();
} }
#else #else
{ {
@ -421,7 +434,9 @@ remove_and_free_memory_node(struct MemoryNode * mn)
Remove((struct Node *)mln); Remove((struct Node *)mln);
PROFILE_OFF();
FreeMem(mln,sizeof(*mln) + allocation_size); FreeMem(mln,sizeof(*mln) + allocation_size);
PROFILE_ON();
} }
#endif /* __MEM_DEBUG */ #endif /* __MEM_DEBUG */
} }

View File

@ -72,7 +72,9 @@ __free_unused_slabs(void)
/* Unlink from list of slabs of the same size. */ /* Unlink from list of slabs of the same size. */
Remove((struct Node *)sn); Remove((struct Node *)sn);
PROFILE_OFF();
FreeVec(sn); FreeVec(sn);
PROFILE_ON();
} }
__memory_unlock(); __memory_unlock();

View File

@ -0,0 +1,206 @@
/*
* :ts=4
*
* Portable ISO 'C' (1994) runtime library for the Amiga computer
* Copyright (c) 2002-2015 by Olaf Barthel <obarthel (at) gmx.net>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Neither the name of Olaf Barthel nor the names of contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _STDLIB_HEADERS_H
#include "stdlib_headers.h"
#endif /* _STDLIB_HEADERS_H */
/****************************************************************************/
#ifndef _STDLIB_MEMORY_H
#include "stdlib_memory.h"
#endif /* _STDLIB_MEMORY_H */
/****************************************************************************/
#include <setjmp.h>
/****************************************************************************/
struct context
{
jmp_buf abort_buf;
void * user_data;
__slab_status_callback callback;
char * buffer;
size_t buffer_size;
};
/****************************************************************************/
static void print(struct context * ct, const char * format, ...)
{
va_list args;
int len;
va_start(args,format);
len = vsnprintf(ct->buffer, ct->buffer_size, format, args);
va_end(args);
/* This shouldn't happen: the buffer ought to be large enough
* to hold every single line.
*/
if(len >= (int)ct->buffer_size)
len = strlen(ct->buffer);
if((*ct->callback)(ct->user_data, ct->buffer, len) != 0)
longjmp(ct->abort_buf,-1);
}
/****************************************************************************/
void
__get_slab_stats(void * user_data, __slab_status_callback callback)
{
if(__slab_data.sd_InUse)
{
static int times_checked = 1;
const struct SlabNode * sn;
volatile size_t num_empty_slabs = 0;
volatile size_t num_full_slabs = 0;
volatile size_t num_slabs = 0;
volatile size_t slab_allocation_size = 0;
volatile size_t total_slab_allocation_size = 0;
struct context ct;
char line[1024];
char time_buffer[40];
time_t now;
struct tm when;
int i;
memset(&ct, 0, sizeof(ct));
ct.user_data = user_data;
ct.callback = callback;
ct.buffer = line;
ct.buffer_size = sizeof(line);
__memory_lock();
if(setjmp(ct.abort_buf) == 0)
{
now = time(NULL);
localtime_r(&now, &when);
strftime(time_buffer, sizeof(time_buffer), "%Y-%m-%dT%H:%M:%S", &when);
print(&ct,"{\n");
print(&ct,"\t\"when\": \"%s\",\n", time_buffer);
print(&ct,"\t\"times_checked\": %d,\n", times_checked++);
print(&ct,"\t\"slab_size\": %zu,\n", __slab_data.sd_StandardSlabSize);
print(&ct,"\t\"num_single_allocations\": %zu,\n", __slab_data.sd_NumSingleAllocations);
print(&ct,"\t\"total_single_allocation_size\": %zu,\n", __slab_data.sd_TotalSingleAllocationSize);
if(__slab_data.sd_SingleAllocations.mlh_Head->mln_Succ != NULL)
{
const struct SlabSingleAllocation * ssa;
print(&ct,"\t\"single_allocations\": [\n");
for(ssa = (struct SlabSingleAllocation *)__slab_data.sd_SingleAllocations.mlh_Head ;
ssa->ssa_MinNode.mln_Succ != NULL ;
ssa = (struct SlabSingleAllocation *)ssa->ssa_MinNode.mln_Succ)
{
print(&ct,"\t\t{ \"size\": %lu, \"total_size\": %lu }%s\n",
ssa->ssa_Size - sizeof(*ssa), ssa->ssa_Size,
ssa->ssa_MinNode.mln_Succ->mln_Succ != NULL ? "," : "");
}
print(&ct,"\t],\n");
}
else
{
print(&ct,"\t\"single_allocations\": [],\n");
}
for(i = 0 ; i < (int)NUM_ENTRIES(__slab_data.sd_Slabs) ; i++)
{
for(sn = (struct SlabNode *)__slab_data.sd_Slabs[i].mlh_Head ;
sn->sn_MinNode.mln_Succ != NULL ;
sn = (struct SlabNode *)sn->sn_MinNode.mln_Succ)
{
if (sn->sn_UseCount == 0)
num_empty_slabs++;
else if (sn->sn_UseCount == sn->sn_Count)
num_full_slabs++;
num_slabs++;
slab_allocation_size += sn->sn_ChunkSize * sn->sn_UseCount;
total_slab_allocation_size += sizeof(*sn) + __slab_data.sd_StandardSlabSize;
}
}
print(&ct,"\t\"num_slabs\": %zu,\n", num_slabs);
print(&ct,"\t\"num_empty_slabs\": %zu,\n", num_empty_slabs);
print(&ct,"\t\"num_full_slabs\": %zu,\n", num_full_slabs);
print(&ct,"\t\"slab_allocation_size\": %zu,\n", slab_allocation_size);
print(&ct,"\t\"total_slab_allocation_size\": %zu,\n", total_slab_allocation_size);
if(num_slabs > 0)
{
const char * eol = "";
print(&ct,"\t\"slabs\": [\n");
for(i = 0 ; i < (int)NUM_ENTRIES(__slab_data.sd_Slabs) ; i++)
{
for(sn = (struct SlabNode *)__slab_data.sd_Slabs[i].mlh_Head ;
sn->sn_MinNode.mln_Succ != NULL ;
sn = (struct SlabNode *)sn->sn_MinNode.mln_Succ)
{
print(&ct,"%s\t\t{ \"size\": %lu, \"chunks\": %lu, \"chunks_in_use\": %lu, \"times_reused\": %lu, \"empty_decay\": %lu }",
eol,
sn->sn_ChunkSize,
sn->sn_Count,
sn->sn_UseCount,
sn->sn_NumReused,
sn->sn_EmptyDecay);
eol = ",\n";
}
}
print(&ct,"\n\t]\n");
}
else
{
print(&ct,"\t\"slabs\": []\n");
}
print(&ct,"}\n");
}
__memory_unlock();
}
}

View File

@ -87,6 +87,7 @@ __get_slab_usage(__slab_usage_callback callback)
sui.sui_chunk_size = sn->sn_ChunkSize; sui.sui_chunk_size = sn->sn_ChunkSize;
sui.sui_num_chunks = sn->sn_Count; sui.sui_num_chunks = sn->sn_Count;
sui.sui_num_chunks_used = sn->sn_UseCount; sui.sui_num_chunks_used = sn->sn_UseCount;
sui.sui_num_reused = sn->sn_NumReused;
sui.sui_slab_index++; sui.sui_slab_index++;

View File

@ -37,6 +37,10 @@
/****************************************************************************/ /****************************************************************************/
#if defined(__GNUC__) || (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L))
/****************************************************************************/
lldiv_t lldiv_t
lldiv(long long n,long long d) lldiv(long long n,long long d)
{ {
@ -49,3 +53,7 @@ lldiv(long long n,long long d)
return(result); return(result);
} }
/****************************************************************************/
#endif

View File

@ -117,9 +117,20 @@ call_main(void)
struct Process * this_process = (struct Process *)FindTask(NULL); struct Process * this_process = (struct Process *)FindTask(NULL);
UBYTE * arg_str = GetArgStr(); UBYTE * arg_str = GetArgStr();
size_t arg_str_len = strlen(arg_str); size_t arg_str_len = strlen(arg_str);
UBYTE * arg_str_copy = AllocVec(arg_str_len+1,MEMF_PRIVATE); UBYTE * arg_str_copy;
UBYTE current_dir_name[256]; UBYTE current_dir_name[256];
#if defined(__amigaos4__)
{
arg_str_copy = AllocVec(arg_str_len+1,MEMF_PRIVATE);
}
#else
{
arg_str_copy = AllocVec(arg_str_len+1,MEMF_ANY);
}
#endif /* __amigaos4__ */
if(arg_str_copy != NULL && NameFromLock(this_process->pr_CurrentDir,current_dir_name,sizeof(current_dir_name))) if(arg_str_copy != NULL && NameFromLock(this_process->pr_CurrentDir,current_dir_name,sizeof(current_dir_name)))
{ {
strcpy(arg_str_copy,arg_str); strcpy(arg_str_copy,arg_str);

View File

@ -75,14 +75,15 @@ struct MinList NOCOMMON __memory_list;
/****************************************************************************/ /****************************************************************************/
void * void *
__allocate_memory(size_t size,BOOL never_free,const char * UNUSED debug_file_name,int UNUSED debug_line_number) __allocate_memory(size_t size,BOOL never_free,const char *debug_file_name UNUSED,int debug_line_number UNUSED)
{ {
struct MemoryNode * mn; struct MemoryNode * mn;
size_t allocation_size; size_t allocation_size;
void * result = NULL; void * result = NULL;
size_t original_size;
#if defined(UNIX_PATH_SEMANTICS) #if defined(UNIX_PATH_SEMANTICS)
size_t original_size;
{ {
original_size = size; original_size = size;
@ -147,56 +148,73 @@ __allocate_memory(size_t size,BOOL never_free,const char * UNUSED debug_file_nam
#if defined(__USE_SLAB_ALLOCATOR) #if defined(__USE_SLAB_ALLOCATOR)
{ {
/* Are we using the slab allocator? */ /* Are we using the slab allocator? */
if (__slab_data.sd_InUse) if(__slab_data.sd_InUse)
{ {
mn = __slab_allocate(allocation_size); mn = __slab_allocate(allocation_size);
} }
else if (__memory_pool != NULL)
{
mn = AllocPooled(__memory_pool,allocation_size);
}
else else
{ {
#ifdef __MEM_DEBUG if (__memory_pool != NULL)
{ {
mn = AllocMem(allocation_size,MEMF_ANY); PROFILE_OFF();
mn = AllocPooled(__memory_pool,allocation_size);
PROFILE_ON();
} }
#else else
{ {
struct MinNode * mln; #ifdef __MEM_DEBUG
mln = AllocMem(sizeof(*mln) + allocation_size,MEMF_ANY);
if(mln != NULL)
{ {
AddTail((struct List *)&__memory_list,(struct Node *)mln); PROFILE_OFF();
mn = AllocMem(allocation_size,MEMF_ANY);
mn = (struct MemoryNode *)&mln[1]; PROFILE_ON();
} }
else #else
{ {
mn = NULL; struct MinNode * mln;
PROFILE_OFF();
mln = AllocMem(sizeof(*mln) + allocation_size,MEMF_ANY);
PROFILE_ON();
if(mln != NULL)
{
AddTail((struct List *)&__memory_list,(struct Node *)mln);
mn = (struct MemoryNode *)&mln[1];
}
else
{
mn = NULL;
}
} }
#endif /* __MEM_DEBUG */
} }
#endif /* __MEM_DEBUG */
} }
} }
#else #else
{ {
if(__memory_pool != NULL) if(__memory_pool != NULL)
{ {
PROFILE_OFF();
mn = AllocPooled(__memory_pool,allocation_size); mn = AllocPooled(__memory_pool,allocation_size);
PROFILE_ON();
} }
else else
{ {
#ifdef __MEM_DEBUG #ifdef __MEM_DEBUG
{ {
PROFILE_OFF();
mn = AllocMem(allocation_size,MEMF_ANY); mn = AllocMem(allocation_size,MEMF_ANY);
PROFILE_ON();
} }
#else #else
{ {
struct MinNode * mln; struct MinNode * mln;
PROFILE_OFF();
mln = AllocMem(sizeof(*mln) + allocation_size,MEMF_ANY); mln = AllocMem(sizeof(*mln) + allocation_size,MEMF_ANY);
PROFILE_ON();
if(mln != NULL) if(mln != NULL)
{ {
AddTail((struct List *)&__memory_list,(struct Node *)mln); AddTail((struct List *)&__memory_list,(struct Node *)mln);
@ -355,8 +373,12 @@ static struct SignalSemaphore * memory_semaphore;
void void
__memory_lock(void) __memory_lock(void)
{ {
PROFILE_OFF();
if(memory_semaphore != NULL) if(memory_semaphore != NULL)
ObtainSemaphore(memory_semaphore); ObtainSemaphore(memory_semaphore);
PROFILE_ON();
} }
/****************************************************************************/ /****************************************************************************/
@ -364,8 +386,12 @@ __memory_lock(void)
void void
__memory_unlock(void) __memory_unlock(void)
{ {
PROFILE_OFF();
if(memory_semaphore != NULL) if(memory_semaphore != NULL)
ReleaseSemaphore(memory_semaphore); ReleaseSemaphore(memory_semaphore);
PROFILE_ON();
} }
/****************************************************************************/ /****************************************************************************/
@ -392,7 +418,7 @@ STDLIB_DESTRUCTOR(stdlib_memory_exit)
if(__memory_list.mlh_Head != NULL) if(__memory_list.mlh_Head != NULL)
{ {
while(NOT IsListEmpty((struct List *)&__memory_list)) while(NOT IsMinListEmpty(&__memory_list))
{ {
((struct MemoryNode *)__memory_list.mlh_Head)->mn_AlreadyFree = FALSE; ((struct MemoryNode *)__memory_list.mlh_Head)->mn_AlreadyFree = FALSE;
@ -428,12 +454,12 @@ STDLIB_DESTRUCTOR(stdlib_memory_exit)
{ {
#ifdef __MEM_DEBUG #ifdef __MEM_DEBUG
{ {
while(NOT IsListEmpty((struct List *)&__memory_list)) while(NOT IsMinListEmpty(&__memory_list))
__free_memory_node((struct MemoryNode *)__memory_list.mlh_Head,__FILE__,__LINE__); __free_memory_node((struct MemoryNode *)__memory_list.mlh_Head,__FILE__,__LINE__);
} }
#else #else
{ {
while(NOT IsListEmpty((struct List *)&__memory_list)) while(NOT IsMinListEmpty(&__memory_list))
__free_memory_node((struct MemoryNode *)__memory_list.mlh_Head,NULL,0); __free_memory_node((struct MemoryNode *)__memory_list.mlh_Head,NULL,0);
} }
#endif /* __MEM_DEBUG */ #endif /* __MEM_DEBUG */
@ -453,12 +479,12 @@ STDLIB_DESTRUCTOR(stdlib_memory_exit)
{ {
#ifdef __MEM_DEBUG #ifdef __MEM_DEBUG
{ {
while(NOT IsListEmpty((struct List *)&__memory_list)) while(NOT IsMinListEmpty(&__memory_list))
__free_memory_node((struct MemoryNode *)__memory_list.mlh_Head,__FILE__,__LINE__); __free_memory_node((struct MemoryNode *)__memory_list.mlh_Head,__FILE__,__LINE__);
} }
#else #else
{ {
while(NOT IsListEmpty((struct List *)&__memory_list)) while(NOT IsMinListEmpty(&__memory_list))
__free_memory_node((struct MemoryNode *)__memory_list.mlh_Head,NULL,0); __free_memory_node((struct MemoryNode *)__memory_list.mlh_Head,NULL,0);
} }
#endif /* __MEM_DEBUG */ #endif /* __MEM_DEBUG */
@ -503,7 +529,7 @@ STDLIB_CONSTRUCTOR(stdlib_memory_init)
#if defined(__USE_SLAB_ALLOCATOR) #if defined(__USE_SLAB_ALLOCATOR)
{ {
/* ZZZ this is just for the purpose of testing */ /* ZZZ this is just for the purpose of testing */
#if 0 #if DEBUG
{ {
TEXT slab_size_var[20]; TEXT slab_size_var[20];

View File

@ -37,9 +37,13 @@
/****************************************************************************/ /****************************************************************************/
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
int int
mbtowc(wchar_t *pwc, const char *s, size_t n) mbtowc(wchar_t *restrict pwc, const char *restrict s, size_t n)
{ {
/* ZZZ unimplemented */ errno = EILSEQ;
return(-1); return -1;
} }
#endif

View File

@ -235,6 +235,11 @@ struct SlabNode
/* How many chunks of this slab are currently in use? */ /* How many chunks of this slab are currently in use? */
ULONG sn_UseCount; ULONG sn_UseCount;
/* How many times was this slab reused instead of allocating
* it from system memory?
*/
ULONG sn_NumReused;
/* This contains all the chunks of memory which are available /* This contains all the chunks of memory which are available
* for allocation. * for allocation.
*/ */
@ -286,7 +291,7 @@ struct SlabData
*/ */
size_t sd_StandardSlabSize; size_t sd_StandardSlabSize;
/* These fields kees track of how many entries there are in /* These fields keep track of how many entries there are in
* the sd_SingleAllocations list, and how much memory these * the sd_SingleAllocations list, and how much memory these
* allocations occupy. * allocations occupy.
*/ */
@ -303,6 +308,7 @@ struct SlabData
extern struct SlabData NOCOMMON __slab_data; extern struct SlabData NOCOMMON __slab_data;
extern unsigned long NOCOMMON __slab_max_size; extern unsigned long NOCOMMON __slab_max_size;
extern unsigned long NOCOMMON __slab_purge_threshold;
/****************************************************************************/ /****************************************************************************/

View File

@ -45,8 +45,8 @@
/****************************************************************************/ /****************************************************************************/
extern void ASM _PROLOG(REG(a0,char *)); extern void __asm _PROLOG(register __a0 char *);
extern void ASM _EPILOG(REG(a0,char *)); extern void __asm _EPILOG(register __a0 char *);
#if _PROFILE #if _PROFILE
#define PROFILE_OFF() _PROLOG(0L) #define PROFILE_OFF() _PROLOG(0L)

View File

@ -31,6 +31,8 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
*/ */
/*#define DEBUG*/
#ifndef _STDLIB_HEADERS_H #ifndef _STDLIB_HEADERS_H
#include "stdlib_headers.h" #include "stdlib_headers.h"
#endif /* _STDLIB_HEADERS_H */ #endif /* _STDLIB_HEADERS_H */
@ -76,6 +78,7 @@ __realloc(void *ptr,size_t size,const char * file,int line)
#endif /* UNIX_PATH_SEMANTICS */ #endif /* UNIX_PATH_SEMANTICS */
else else
{ {
size_t old_size;
struct MemoryNode * mn; struct MemoryNode * mn;
BOOL reallocate; BOOL reallocate;
@ -108,29 +111,23 @@ __realloc(void *ptr,size_t size,const char * file,int line)
} }
#endif /* __MEM_DEBUG */ #endif /* __MEM_DEBUG */
if(mn == NULL || mn->mn_NeverFree) if(mn == NULL || FLAG_IS_SET(mn->mn_Size, MN_SIZE_NEVERFREE))
{ {
SHOWMSG("cannot free this chunk"); SHOWMSG("cannot free this chunk");
goto out; goto out;
} }
old_size = GET_MN_SIZE(mn);
/* Don't do anything unless the size of the allocation /* Don't do anything unless the size of the allocation
has really changed. */ has really changed. */
#if defined(__MEM_DEBUG) #if defined(__MEM_DEBUG)
{ {
reallocate = (mn->mn_Size != size); reallocate = (old_size != size);
} }
#else #else
{ {
size_t rounded_allocation_size; if(size > old_size)
/* Round the total allocation size to the operating system
granularity. */
rounded_allocation_size = __get_allocation_size(size);
assert( rounded_allocation_size >= size );
if(rounded_allocation_size > mn->mn_Size)
{ {
/* Allocation size should grow. */ /* Allocation size should grow. */
reallocate = TRUE; reallocate = TRUE;
@ -143,7 +140,7 @@ __realloc(void *ptr,size_t size,const char * file,int line)
allocation. We also take into account that the allocation. We also take into account that the
actual size of the allocation is affected by a actual size of the allocation is affected by a
certain operating system imposed granularity. */ certain operating system imposed granularity. */
reallocate = (rounded_allocation_size < mn->mn_Size && rounded_allocation_size <= mn->mn_Size / 2); reallocate = (size < old_size && size <= old_size / 2);
} }
} }
#endif /* __MEM_DEBUG */ #endif /* __MEM_DEBUG */
@ -152,7 +149,7 @@ __realloc(void *ptr,size_t size,const char * file,int line)
{ {
void * new_ptr; void * new_ptr;
D(("realloc() size has changed; old=%ld, new=%ld",mn->mn_Size,size)); D(("realloc() size has changed; old=%ld, new=%ld",old_size,size));
/* We allocate the new memory chunk before we /* We allocate the new memory chunk before we
attempt to replace the old. */ attempt to replace the old. */
@ -164,8 +161,8 @@ __realloc(void *ptr,size_t size,const char * file,int line)
} }
/* Copy the contents of the old allocation to the new buffer. */ /* Copy the contents of the old allocation to the new buffer. */
if(size > mn->mn_Size) if(size > old_size)
size = mn->mn_Size; size = old_size;
memmove(new_ptr,ptr,size); memmove(new_ptr,ptr,size);
@ -177,7 +174,7 @@ __realloc(void *ptr,size_t size,const char * file,int line)
} }
else else
{ {
D(("size didn't actually change that much (%ld -> %ld); returning memory block as is.",mn->mn_Size,size)); D(("size didn't actually change that much (%ld -> %ld); returning memory block as is.",old_size,size));
/* No change in size. */ /* No change in size. */
result = ptr; result = ptr;

View File

@ -85,6 +85,8 @@ __slab_allocate(size_t allocation_size)
/* No integer overflow? */ /* No integer overflow? */
if(allocation_size < total_single_allocation_size) if(allocation_size < total_single_allocation_size)
{ {
PROFILE_OFF();
#if defined(__amigaos4__) #if defined(__amigaos4__)
{ {
ssa = AllocMem(total_single_allocation_size,MEMF_PRIVATE); ssa = AllocMem(total_single_allocation_size,MEMF_PRIVATE);
@ -94,6 +96,8 @@ __slab_allocate(size_t allocation_size)
ssa = AllocMem(total_single_allocation_size,MEMF_ANY); ssa = AllocMem(total_single_allocation_size,MEMF_ANY);
} }
#endif /* __amigaos4__ */ #endif /* __amigaos4__ */
PROFILE_ON();
} }
/* Integer overflow has occured. */ /* Integer overflow has occured. */
else else
@ -125,6 +129,7 @@ __slab_allocate(size_t allocation_size)
else else
{ {
struct MinList * slab_list = NULL; struct MinList * slab_list = NULL;
BOOL slab_reused = FALSE;
ULONG entry_size; ULONG entry_size;
ULONG chunk_size; ULONG chunk_size;
int slab_index; int slab_index;
@ -202,6 +207,9 @@ __slab_allocate(size_t allocation_size)
/* Pull it out of the list of slabs available for reuse. */ /* Pull it out of the list of slabs available for reuse. */
Remove((struct Node *)&sn->sn_EmptyLink); Remove((struct Node *)&sn->sn_EmptyLink);
sn->sn_EmptyDecay = 0;
sn->sn_NumReused++;
} }
sn->sn_UseCount++; sn->sn_UseCount++;
@ -252,14 +260,27 @@ __slab_allocate(size_t allocation_size)
/* Unlink from list of empty slabs. */ /* Unlink from list of empty slabs. */
Remove((struct Node *)free_node); Remove((struct Node *)free_node);
/* Unlink from list of slabs which keep chunks /* If the chunk size of the reused slab matches
* of the same size. It will be added there * exactly what we need then we won't have to
* again, at a different position. * completely reinitialize it again.
*/ */
Remove((struct Node *)sn); if(sn->sn_ChunkSize == chunk_size)
{
slab_reused = TRUE;
}
else
{
/* Unlink from list of slabs which keep chunks
* of the same size. It will be added there
* again, at a different position.
*/
Remove((struct Node *)sn);
}
D(("reusing a slab")); D(("reusing a slab"));
sn->sn_NumReused++;
new_sn = sn; new_sn = sn;
break; break;
} }
@ -272,6 +293,8 @@ __slab_allocate(size_t allocation_size)
{ {
D(("no slab is available for reuse; allocating a new slab (%lu bytes)",sizeof(*new_sn) + __slab_data.sd_StandardSlabSize)); D(("no slab is available for reuse; allocating a new slab (%lu bytes)",sizeof(*new_sn) + __slab_data.sd_StandardSlabSize));
PROFILE_OFF();
#if defined(__amigaos4__) #if defined(__amigaos4__)
{ {
new_sn = (struct SlabNode *)AllocVec(sizeof(*new_sn) + __slab_data.sd_StandardSlabSize,MEMF_PRIVATE); new_sn = (struct SlabNode *)AllocVec(sizeof(*new_sn) + __slab_data.sd_StandardSlabSize,MEMF_PRIVATE);
@ -282,6 +305,8 @@ __slab_allocate(size_t allocation_size)
} }
#endif /* __amigaos4__ */ #endif /* __amigaos4__ */
PROFILE_ON();
if(new_sn == NULL) if(new_sn == NULL)
D(("slab allocation failed")); D(("slab allocation failed"));
@ -295,59 +320,73 @@ __slab_allocate(size_t allocation_size)
if(new_sn != NULL) if(new_sn != NULL)
{ {
struct MinNode * free_chunk;
ULONG num_free_chunks = 0;
BYTE * first_byte;
BYTE * last_byte;
D(("setting up slab 0x%08lx", new_sn)); D(("setting up slab 0x%08lx", new_sn));
assert( chunk_size <= __slab_data.sd_StandardSlabSize ); assert( chunk_size <= __slab_data.sd_StandardSlabSize );
memset(new_sn,0,sizeof(*new_sn)); /* Do we have to completely initialize this slab from scratch? */
if(NOT slab_reused)
NewList((struct List *)&new_sn->sn_FreeList);
/* Split up the slab memory into individual chunks
* of the same size and keep track of them
* in the free list. The memory managed by
* this slab immediately follows the
* SlabNode header.
*/
first_byte = (BYTE *)&new_sn[1];
last_byte = &first_byte[__slab_data.sd_StandardSlabSize - chunk_size];
for(free_chunk = (struct MinNode *)first_byte ;
free_chunk <= (struct MinNode *)last_byte;
free_chunk = (struct MinNode *)(((BYTE *)free_chunk) + chunk_size))
{ {
AddTail((struct List *)&new_sn->sn_FreeList, (struct Node *)free_chunk); struct SlabChunk * free_chunk;
num_free_chunks++; ULONG num_free_chunks = 0;
} BYTE * first_byte;
BYTE * last_byte;
D(("slab contains %lu chunks, %lu bytes each",num_free_chunks,chunk_size)); memset(new_sn,0,sizeof(*new_sn));
NewList((struct List *)&new_sn->sn_FreeList);
/* This slab has room for new allocations, so make sure that
* it goes to the front of the slab list. It will be used
* by the next allocation request of this size.
*/
AddHead((struct List *)slab_list,(struct Node *)new_sn);
/* Split up the slab memory into individual chunks
* of the same size and keep track of them
* in the free list. The memory managed by
* this slab immediately follows the
* SlabNode header.
*/
first_byte = (BYTE *)&new_sn[1];
last_byte = &first_byte[__slab_data.sd_StandardSlabSize - chunk_size];
for(free_chunk = (struct SlabChunk *)first_byte ;
free_chunk <= (struct SlabChunk *)last_byte;
free_chunk = (struct SlabChunk *)(((BYTE *)free_chunk) + chunk_size))
{
AddTail((struct List *)&new_sn->sn_FreeList, (struct Node *)free_chunk);
num_free_chunks++;
}
new_sn->sn_Count = num_free_chunks;
new_sn->sn_ChunkSize = chunk_size;
D(("new slab contains %lu chunks, %lu bytes each",num_free_chunks,chunk_size));
}
/* This slab was reused and need not be reinitialized from scratch. */
else
{
assert( new_sn->sn_FreeList.mlh_Head != NULL );
assert( new_sn->sn_ChunkSize == chunk_size );
assert( new_sn->sn_Count == 0 );
}
/* Grab the first free chunk (there has to be one). */ /* Grab the first free chunk (there has to be one). */
chunk = (struct SlabChunk *)RemHead((struct List *)&new_sn->sn_FreeList); chunk = (struct SlabChunk *)RemHead((struct List *)&new_sn->sn_FreeList);
assert( chunk != NULL );
/* Keep track of this chunk's parent slab. */ /* Keep track of this chunk's parent slab. */
chunk->sc_Parent = new_sn; chunk->sc_Parent = new_sn;
assert( chunk != NULL );
assert( chunk->sc_Parent == new_sn );
allocation = &chunk[1]; allocation = &chunk[1];
D(("allocation succeeded at 0x%08lx in slab 0x%08lx (slab use count = %lu)",allocation,new_sn,new_sn->sn_UseCount+1)); /* This slab is now in use. */
new_sn->sn_UseCount = 1;
/* Set up the new slab and put it where it belongs. */ D(("allocation succeeded at 0x%08lx in slab 0x%08lx (slab use count = %lu)",allocation,new_sn,new_sn->sn_UseCount));
new_sn->sn_EmptyDecay = 0;
new_sn->sn_UseCount = 1;
new_sn->sn_Count = num_free_chunks;
new_sn->sn_ChunkSize = chunk_size;
SHOWVALUE(new_sn->sn_ChunkSize);
AddHead((struct List *)slab_list,(struct Node *)new_sn);
} }
/* Mark unused slabs for purging, and purge those which /* Mark unused slabs for purging, and purge those which
@ -355,6 +394,8 @@ __slab_allocate(size_t allocation_size)
*/ */
if(purge) if(purge)
{ {
size_t total_purged = 0;
D(("purging empty slabs")); D(("purging empty slabs"));
for(free_node = (struct MinNode *)__slab_data.sd_EmptySlabs.mlh_Head ; for(free_node = (struct MinNode *)__slab_data.sd_EmptySlabs.mlh_Head ;
@ -379,7 +420,18 @@ __slab_allocate(size_t allocation_size)
/* Unlink from list of slabs of the same size. */ /* Unlink from list of slabs of the same size. */
Remove((struct Node *)sn); Remove((struct Node *)sn);
PROFILE_OFF();
FreeVec(sn); FreeVec(sn);
PROFILE_ON();
total_purged += sizeof(*sn) + __slab_data.sd_StandardSlabSize;
/* Stop releasing memory if we reach the threshold. If no
* threshold has been set, we will free as much memory
* as possible.
*/
if(__slab_purge_threshold > 0 && total_purged >= __slab_purge_threshold)
break;
} }
/* Give it another chance. */ /* Give it another chance. */
else else
@ -470,7 +522,10 @@ __slab_free(void * address,size_t allocation_size)
assert( size <= __slab_data.sd_TotalSingleAllocationSize ); assert( size <= __slab_data.sd_TotalSingleAllocationSize );
Remove((struct Node *)ssa); Remove((struct Node *)ssa);
PROFILE_OFF();
FreeMem(ssa, size); FreeMem(ssa, size);
PROFILE_ON();
__slab_data.sd_NumSingleAllocations--; __slab_data.sd_NumSingleAllocations--;
__slab_data.sd_TotalSingleAllocationSize -= size; __slab_data.sd_TotalSingleAllocationSize -= size;
@ -700,6 +755,21 @@ __slab_init(size_t slab_size)
/****************************************************************************/ /****************************************************************************/
#if DEBUG
static int print_json(void * ignore,const char * buffer,size_t len)
{
extern void kputs(const char * str);
kputs(buffer);
return(0);
}
#endif /* DEBUG */
/****************************************************************************/
void void
__slab_exit(void) __slab_exit(void)
{ {
@ -712,7 +782,19 @@ __slab_exit(void)
struct SlabNode * sn_next; struct SlabNode * sn_next;
struct MinNode * mn; struct MinNode * mn;
struct MinNode * mn_next; struct MinNode * mn_next;
int i; size_t slab_count = 0, total_slab_size = 0;
size_t single_allocation_count = 0, total_single_allocation_size = 0;
int i, j;
#if DEBUG
{
kprintf("---BEGIN JSON DATA ---\n");
__get_slab_stats(NULL, print_json);
kprintf("---END JSON DATA ---\n\n");
}
#endif /* DEBUG */
D(("freeing slabs")); D(("freeing slabs"));
@ -720,25 +802,40 @@ __slab_exit(void)
for(i = 0 ; i < (int)NUM_ENTRIES(__slab_data.sd_Slabs) ; i++) for(i = 0 ; i < (int)NUM_ENTRIES(__slab_data.sd_Slabs) ; i++)
{ {
if(__slab_data.sd_Slabs[i].mlh_Head->mln_Succ != NULL) if(__slab_data.sd_Slabs[i].mlh_Head->mln_Succ != NULL)
D(("freeing slab #%ld (%lu bytes per chunk)", i, (1UL << i))); D(("freeing slab slot #%ld (%lu bytes per chunk)", i, (1UL << i)));
for(sn = (struct SlabNode *)__slab_data.sd_Slabs[i].mlh_Head ; for(sn = (struct SlabNode *)__slab_data.sd_Slabs[i].mlh_Head, j = 0 ;
sn->sn_MinNode.mln_Succ != NULL ; sn->sn_MinNode.mln_Succ != NULL ;
sn = sn_next) sn = sn_next)
{ {
sn_next = (struct SlabNode *)sn->sn_MinNode.mln_Succ; sn_next = (struct SlabNode *)sn->sn_MinNode.mln_Succ;
D((" slab #%ld.%ld at 0x%08lx",i, ++j, sn));
D((" fragmentation = %ld%%",100 * (__slab_data.sd_StandardSlabSize - sn->sn_Count * sn->sn_ChunkSize) / __slab_data.sd_StandardSlabSize));
D((" total space used = %ld (%ld%%)",sn->sn_UseCount * sn->sn_ChunkSize, 100 * sn->sn_UseCount / sn->sn_Count));
D((" number of chunks total = %ld",sn->sn_Count));
D((" number of chunks used = %ld%s",sn->sn_UseCount,sn->sn_UseCount == 0 ? " (empty)" : (sn->sn_UseCount == sn->sn_Count) ? " (full)" : ""));
D((" how often reused = %ld",sn->sn_NumReused));
total_slab_size += sizeof(*sn) + __slab_data.sd_StandardSlabSize;
slab_count++;
PROFILE_OFF();
FreeVec(sn); FreeVec(sn);
PROFILE_ON();
} }
} }
if(slab_count > 0)
D(("number of slabs = %ld, total slab size = %ld bytes",slab_count, total_slab_size));
if(__slab_data.sd_SingleAllocations.mlh_Head->mln_Succ != NULL) if(__slab_data.sd_SingleAllocations.mlh_Head->mln_Succ != NULL)
D(("freeing single allocations")); D(("freeing single allocations"));
/* Free the memory allocated for each allocation which did not /* Free the memory allocated for each allocation which did not
* go into a slab. * go into a slab.
*/ */
for(mn = __slab_data.sd_SingleAllocations.mlh_Head ; for(mn = __slab_data.sd_SingleAllocations.mlh_Head, j = 0 ;
mn->mln_Succ != NULL ; mn->mln_Succ != NULL ;
mn = mn_next) mn = mn_next)
{ {
@ -746,9 +843,19 @@ __slab_exit(void)
ssa = (struct SlabSingleAllocation *)mn; ssa = (struct SlabSingleAllocation *)mn;
D((" allocation #%ld at 0x%08lx, %lu bytes", ++j, ssa, ssa->ssa_Size));
total_single_allocation_size += ssa->ssa_Size;
single_allocation_count++;
PROFILE_OFF();
FreeMem(ssa, ssa->ssa_Size); FreeMem(ssa, ssa->ssa_Size);
PROFILE_ON();
} }
if(single_allocation_count > 0)
D(("number of single allocations = %ld, total single allocation size = %ld", single_allocation_count, total_single_allocation_size));
__slab_data.sd_InUse = FALSE; __slab_data.sd_InUse = FALSE;
} }

View File

@ -0,0 +1,38 @@
/*
* :ts=4
*
* Portable ISO 'C' (1994) runtime library for the Amiga computer
* Copyright (c) 2002-2015 by Olaf Barthel <obarthel (at) gmx.net>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Neither the name of Olaf Barthel nor the names of contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _STDLIB_HEADERS_H
#include "stdlib_headers.h"
#endif /* _STDLIB_HEADERS_H */
/****************************************************************************/
unsigned long __slab_purge_threshold;

View File

@ -41,7 +41,7 @@
/****************************************************************************/ /****************************************************************************/
static const char * error_table[EILSEQ - EPERM + 1] = static const char * error_table[ENOTSUP - EPERM + 1] =
{ {
"Operation not permitted", "Operation not permitted",
"No such file or directory", "No such file or directory",
@ -127,7 +127,8 @@ static const char * error_table[EILSEQ - EPERM + 1] =
"Identifier removed", "Identifier removed",
"No message of the desired type.", "No message of the desired type.",
"Value too large to be stored in data type.", "Value too large to be stored in data type.",
"Encoding error detected" "Encoding error detected",
"Not supported"
}; };
/****************************************************************************/ /****************************************************************************/
@ -139,7 +140,7 @@ strerror_r(int number,char * buffer,size_t buffer_size)
const char * str; const char * str;
size_t len; size_t len;
if(number < EPERM || number > EILSEQ) if(number < EPERM || number > ENOTSUP)
{ {
__set_errno(EINVAL); __set_errno(EINVAL);
goto out; goto out;

75
library/string_strnlen.c Normal file
View File

@ -0,0 +1,75 @@
/*
* $Id: string_strlen.c,v 1.4 2006-01-08 12:04:27 obarthel Exp $
*
* :ts=4
*
* Portable ISO 'C' (1994) runtime library for the Amiga computer
* Copyright (c) 2002-2015 by Olaf Barthel <obarthel (at) gmx.net>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Neither the name of Olaf Barthel nor the names of contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _STDLIB_NULL_POINTER_CHECK_H
#include "stdlib_null_pointer_check.h"
#endif /* _STDLIB_NULL_POINTER_CHECK_H */
/****************************************************************************/
#ifndef _STRING_HEADERS_H
#include "string_headers.h"
#endif /* _STRING_HEADERS_H */
/****************************************************************************/
size_t
strnlen(const char *s, size_t maxlen)
{
const char * start = s;
size_t result = 0;
assert( s != NULL );
#if defined(CHECK_FOR_NULL_POINTERS)
{
if(s == NULL)
{
__set_errno(EFAULT);
goto out;
}
}
#endif /* CHECK_FOR_NULL_POINTERS */
while((maxlen != 0) && ((*s) != '\0'))
{
s++;
maxlen--;
}
result = (size_t)(s - start);
out:
return(result);
}

View File

@ -1,5 +1,5 @@
/* /*
* $Id: time_mktime.c,v 1.10 2006-01-08 12:04:27 obarthel Exp $ * $Id: time_mktime.c,v 1.11 2015-06-26 11:22:00 obarthel Exp $
* *
* :ts=4 * :ts=4
* *
@ -52,9 +52,10 @@ mktime(struct tm *tm)
{ {
DECLARE_UTILITYBASE(); DECLARE_UTILITYBASE();
struct ClockData clock_data; struct ClockData clock_data;
ULONG seconds, delta; ULONG seconds;
time_t result = (time_t)-1; time_t result = (time_t)-1;
int max_month_days; LONG combined_seconds;
int month, year;
ENTER(); ENTER();
@ -73,116 +74,63 @@ mktime(struct tm *tm)
} }
#endif /* CHECK_FOR_NULL_POINTERS */ #endif /* CHECK_FOR_NULL_POINTERS */
/* The month must be valid. */ /* Normalize the year and month. */
if(tm->tm_mon < 0 || tm->tm_mon > 11) year = tm->tm_year + 1900;
month = tm->tm_mon + 1;
if(month < 0 || month > 12)
{ {
SHOWVALUE(tm->tm_mon); int y;
SHOWMSG("invalid month");
goto out; y = month / 12;
month -= y * 12;
year += y;
} }
/* The day of the month must be valid. */ if(month < 1)
if(tm->tm_mday < 1 || tm->tm_mday > 31)
{ {
SHOWVALUE(tm->tm_mday); month += 12;
SHOWMSG("invalid day of month"); year -= 1;
goto out;
} }
/* The year must be valid. */ /* The year must be valid. Amiga time begins with January 1st, 1978. */
if(tm->tm_year < 78) if(year < 1978)
{ {
SHOWVALUE(tm->tm_year); SHOWVALUE(year);
SHOWMSG("invalid year"); SHOWMSG("invalid year");
goto out; goto out;
} }
/* Is this the month of February? */ /* Convert the first day of the month in the given year
if(tm->tm_mon == 1) into the corresponding number of seconds. */
{ memset(&clock_data, 0, sizeof(clock_data));
int year;
/* We need to have the full year number for the
leap year calculation below. */
year = tm->tm_year + 1900;
/* Now for the famous leap year calculation rules... In
the given year, how many days are there in the month
of February? */
if((year % 4) != 0)
max_month_days = 28;
else if ((year % 400) == 0)
max_month_days = 29;
else if ((year % 100) == 0)
max_month_days = 28;
else
max_month_days = 29;
}
else
{
static const char days_per_month[12] =
{
31, 0,31,
30,31,30,
31,31,30,
31,30,31
};
max_month_days = days_per_month[tm->tm_mon];
}
/* The day of the month must be valid. */
if(tm->tm_mday < 0 || tm->tm_mday > max_month_days)
{
SHOWVALUE(tm->tm_mday);
SHOWMSG("invalid day of month");
goto out;
}
/* The hour must be valid. */
if(tm->tm_hour < 0 || tm->tm_hour > 23)
{
SHOWVALUE(tm->tm_hour);
SHOWMSG("invalid hour");
goto out;
}
/* The minute must be valid. */
if(tm->tm_min < 0 || tm->tm_min > 59)
{
SHOWVALUE(tm->tm_min);
SHOWMSG("invalid minute");
goto out;
}
/* Note: the number of seconds can be larger than 59
in order to account for leap seconds. */
if(tm->tm_sec < 0 || tm->tm_sec > 60)
{
SHOWVALUE(tm->tm_sec);
SHOWMSG("invalid seconds");
goto out;
}
clock_data.sec = (tm->tm_sec > 59) ? 59 : tm->tm_sec;
clock_data.min = tm->tm_min;
clock_data.hour = tm->tm_hour;
clock_data.mday = tm->tm_mday;
clock_data.month = tm->tm_mon + 1;
clock_data.year = tm->tm_year + 1900;
seconds = Date2Amiga(&clock_data) + (tm->tm_sec - 59);
/* The AmigaOS "epoch" starts with January 1st, 1978, which was
a Sunday. */
tm->tm_wday = (seconds / (24 * 60 * 60)) % 7;
clock_data.mday = 1; clock_data.mday = 1;
clock_data.month = 1; clock_data.month = month;
clock_data.year = year;
delta = Date2Amiga(&clock_data); seconds = Date2Amiga(&clock_data);
tm->tm_yday = (seconds - delta) / (24 * 60 * 60); /* Put the combined number of seconds involved together,
covering the seconds/minutes/hours of the day as well
as the number of days of the month. This will be added
to the number of seconds for the date. */
combined_seconds = tm->tm_sec + 60 * (tm->tm_min + 60 * (tm->tm_hour + 24 * (tm->tm_mday-1)));
/* If the combined number of seconds is negative, adding it
* to the number of seconds for the date should not produce
* a negative value.
*/
if(combined_seconds < 0 && seconds < (ULONG)(-combined_seconds))
{
SHOWVALUE(seconds);
SHOWVALUE(combined_seconds);
SHOWMSG("invalid combined number of seconds");
goto out;
}
seconds += combined_seconds;
__locale_lock(); __locale_lock();
@ -193,10 +141,13 @@ mktime(struct tm *tm)
__locale_unlock(); __locale_unlock();
/* Finally, adjust for the difference between the Unix and the /* Adjust for the difference between the Unix and the
AmigaOS epochs, which differ by 8 years. */ AmigaOS epochs, which differ by 8 years. */
result = seconds + UNIX_TIME_OFFSET; result = seconds + UNIX_TIME_OFFSET;
/* Finally, normalize the provided time and date information. */
localtime_r(&result, tm);
out: out:
RETURN(result); RETURN(result);

48
library/time_tzset.c Normal file
View File

@ -0,0 +1,48 @@
/*
* $Id: $
*
* :ts=4
*
* Portable ISO 'C' (1994) runtime library for the Amiga computer
* Copyright (c) 2002-2017 by Olaf Barthel <obarthel (at) gmx.net>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Neither the name of Olaf Barthel nor the names of contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _TIME_HEADERS_H
#include "time_headers.h"
#endif /* _TIME_HEADERS_H */
#ifndef _LOCALE_HEADERS_H
#include "locale_headers.h"
#endif /* _LOCALE_HEADERS_H */
/****************************************************************************/
void
tzset(void)
{
/* For now, do nothing. */
}

View File

@ -184,7 +184,6 @@ __getcwd(char * buffer,size_t buffer_size,const char *file,int line)
if(__unix_path_semantics) if(__unix_path_semantics)
{ {
const char * path_name = buffer; const char * path_name = buffer;
size_t len;
if(__translate_amiga_to_unix_path_name(&path_name,&buffer_nti) != 0) if(__translate_amiga_to_unix_path_name(&path_name,&buffer_nti) != 0)
goto out; goto out;

View File

@ -69,7 +69,7 @@ CLIB_DESTRUCTOR(unistd_exit)
PROFILE_OFF(); PROFILE_OFF();
if(__unlink_list.mlh_Head != NULL && NOT IsListEmpty((struct List *)&__unlink_list)) if(__unlink_list.mlh_Head != NULL && NOT IsMinListEmpty(&__unlink_list))
{ {
struct UnlinkNode * uln; struct UnlinkNode * uln;
BPTR old_dir; BPTR old_dir;

View File

@ -1,5 +1,5 @@
/* /*
* $Id: unistd_translateu2a.c,v 1.12 2010-08-20 15:33:36 obarthel Exp $ * $Id: unistd_translateu2a.c,v 1.13 2015-06-26 11:22:00 obarthel Exp $
* *
* :ts=4 * :ts=4
* *
@ -477,7 +477,10 @@ __translate_unix_to_amiga_path_name(char const ** name_ptr,struct name_translati
for(i = j = 0 ; i < len ; i++) for(i = j = 0 ; i < len ; i++)
{ {
if(i < len - 3 && name[i] == '/' && name[i + 1] == '.' && name[i + 2] == '.' && name[i + 3] == '/') if(i < len - 3 && name[i] == '/' && name[i + 1] == '.' && name[i + 2] == '.' && name[i + 3] == '/')
i += 2; {
replace[j++] = '/';
i += 3;
}
replace[j++] = name[i]; replace[j++] = name[i];
} }

View File

@ -1,6 +1,6 @@
#define VERSION 1 #define VERSION 1
#define REVISION 211 #define REVISION 215
#define DATE "23.11.2016" #define DATE "26.6.2017"
#define VERS "unix.lib 1.211" #define VERS "unix.lib 1.215"
#define VSTRING "unix.lib 1.211 (23.11.2016)\r\n" #define VSTRING "unix.lib 1.215 (26.6.2017)\r\n"
#define VERSTAG "\0$VER: unix.lib 1.211 (23.11.2016)" #define VERSTAG "\0$VER: unix.lib 1.215 (26.6.2017)"

View File

@ -1 +1 @@
211 215

View File

@ -37,9 +37,12 @@
/****************************************************************************/ /****************************************************************************/
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
size_t size_t
mbrlen(wchar_t *pwc, const char * s, size_t n, mbstate_t *ps) mbrlen(const char *restrict s, size_t n, mbstate_t *restrict ps)
{ {
/* ZZZ unimplemented */ /* ZZZ unimplemented */
return(0); return(0);
} }
#endif /* __STDC_VERSION__ && __STDC_VERSION__ >= 199901L */

64
library/wchar_mbrtowc.c Normal file
View File

@ -0,0 +1,64 @@
/*
* $Id: wchar_mbrlen.c,v 1.3 2006-01-08 12:04:27 obarthel Exp $
*
* :ts=4
*
* Portable ISO 'C' (1994) runtime library for the Amiga computer
* Copyright (c) 2002-2015 by Olaf Barthel <obarthel (at) gmx.net>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Neither the name of Olaf Barthel nor the names of contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _WCHAR_HEADERS_H
#include "wchar_headers.h"
#endif /* _WCHAR_HEADERS_H */
/****************************************************************************/
/* Mostly non-working stub based on bionic */
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
size_t
mbrtowc(wchar_t *restrict pwc, const char *restrict s, size_t n, mbstate_t *restrict ps)
{
if (s == NULL)
{
s = "";
pwc = NULL;
}
if (n == 0)
{
if (pwc)
*pwc = 0;
return 0;
}
if (pwc)
*pwc = *s;
return (*s != 0);
}
#endif /* __STDC_VERSION__ && __STDC_VERSION__ >= 199901L */

View File

@ -40,6 +40,5 @@
int int
mbsinit(const mbstate_t *ps) mbsinit(const mbstate_t *ps)
{ {
/* ZZZ unimplemented */ return !ps || !*(unsigned *)ps;
return(0);
} }

View File

@ -38,7 +38,7 @@
/****************************************************************************/ /****************************************************************************/
int int
vswprintf(char *s, const wchar_t *format,va_list arg) vswprintf(wchar_t *s, size_t maxlen, const wchar_t *format, va_list arg)
{ {
/* ZZZ unimplemented */ /* ZZZ unimplemented */
return(0); return(0);

View File

@ -35,11 +35,13 @@
#include "wchar_headers.h" #include "wchar_headers.h"
#endif /* _WCHAR_HEADERS_H */ #endif /* _WCHAR_HEADERS_H */
/* Implementation based on musl */
/****************************************************************************/ /****************************************************************************/
wchar_t * wchar_t *
wcscat(wchar_t *dest, const wchar_t *src) wcscat(wchar_t *dest, const wchar_t *src)
{ {
/* ZZZ unimplemented */ wcscpy(dest + wcslen(dest), src);
return(NULL); return dest;
} }

View File

@ -37,9 +37,12 @@
/****************************************************************************/ /****************************************************************************/
/* Implementation based on musl */
wchar_t * wchar_t *
wcschr(const wchar_t *s, wchar_t c) wcschr(const wchar_t *s, wchar_t c)
{ {
/* ZZZ unimplemented */ if (!c) return (wchar_t *)s + wcslen(s);
return(NULL); for (; *s && *s != c; s++);
return *s ? (wchar_t *)s : 0;
} }

View File

@ -40,6 +40,6 @@
int int
wcscmp(const wchar_t *s1, const wchar_t * s2) wcscmp(const wchar_t *s1, const wchar_t * s2)
{ {
/* ZZZ unimplemented */ for (; *s1==*s2 && *s1 && *s2; s1++, s2++);
return(0); return *s1 - *s2;
} }

45
library/wchar_wcscoll.c Normal file
View File

@ -0,0 +1,45 @@
/*
* $Id: wchar_wscoll.c,v 1.3 2006-01-08 12:04:27 obarthel Exp $
*
* :ts=4
*
* Portable ISO 'C' (1994) runtime library for the Amiga computer
* Copyright (c) 2002-2015 by Olaf Barthel <obarthel (at) gmx.net>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Neither the name of Olaf Barthel nor the names of contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _WCHAR_HEADERS_H
#include "wchar_headers.h"
#endif /* _WCHAR_HEADERS_H */
/****************************************************************************/
int
wcscoll(const wchar_t *ws1, const wchar_t *ws2)
{
/* ZZZ unimplemented */
return(0);
}

View File

@ -40,6 +40,7 @@
wchar_t * wchar_t *
wcscpy(wchar_t *dest, const wchar_t *src) wcscpy(wchar_t *dest, const wchar_t *src)
{ {
/* ZZZ unimplemented */ wchar_t *a = dest;
return(NULL); while ((*dest++ = *src++));
return a;
} }

50
library/wchar_wcscspn.c Normal file
View File

@ -0,0 +1,50 @@
/*
* $Id: wchar_wcsspn.c,v 1.3 2006-01-08 12:04:27 obarthel Exp $
*
* :ts=4
*
* Portable ISO 'C' (1994) runtime library for the Amiga computer
* Copyright (c) 2002-2015 by Olaf Barthel <obarthel (at) gmx.net>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Neither the name of Olaf Barthel nor the names of contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _WCHAR_HEADERS_H
#include "wchar_headers.h"
#endif /* _WCHAR_HEADERS_H */
/****************************************************************************/
/* Implementation based on musl */
size_t
wcscspn(const wchar_t *s, const wchar_t *c)
{
const wchar_t *a;
if (!c[0]) return wcslen(s);
if (!c[1]) return (s=wcschr(a=s, *c)) ? (size_t)(s-a) : wcslen(a);
for (a=s; *s && !wcschr(c, *s); s++);
return s-a;
}

View File

@ -37,9 +37,12 @@
/****************************************************************************/ /****************************************************************************/
/* Implementation based on musl */
size_t size_t
wcslen(const wchar_t *s) wcslen(const wchar_t *s)
{ {
/* ZZZ unimplemented */ const wchar_t *a;
return(0); for (a=s; *s; s++);
return s-a;
} }

View File

@ -37,9 +37,14 @@
/****************************************************************************/ /****************************************************************************/
/* Implementation based on musl */
wchar_t * wchar_t *
wcsncat(wchar_t *dest, const wchar_t *src, size_t n) wcsncat(wchar_t *dest, const wchar_t *src, size_t n)
{ {
/* ZZZ unimplemented */ wchar_t *a = dest;
return(NULL); dest += wcslen(dest);
while (n && *src) n--, *dest++ = *src++;
*dest++ = 0;
return a;
} }

View File

@ -37,9 +37,11 @@
/****************************************************************************/ /****************************************************************************/
/* Implementation based on musl */
int int
wcsncmp(const wchar_t *s1, const wchar_t *s2, size_t n) wcsncmp(const wchar_t *s1, const wchar_t *s2, size_t n)
{ {
/* ZZZ unimplemented */ for (; n && *s1==*s2 && *s1 && *s2; n--, s1++, s2++);
return(0); return n ? *s1 - *s2 : 0;
} }

View File

@ -37,9 +37,13 @@
/****************************************************************************/ /****************************************************************************/
/* Implementation based on musl */
wchar_t * wchar_t *
wcsncpy(wchar_t *dest, const wchar_t *src, size_t n) wcsncpy(wchar_t *dest, const wchar_t *src, size_t n)
{ {
/* ZZZ unimplemented */ wchar_t *a = dest;
return(NULL); while (n && *src) n--, *dest++ = *src++;
wmemset(dest, 0, n);
return a;
} }

View File

@ -37,7 +37,7 @@
/****************************************************************************/ /****************************************************************************/
wchar_t wchar_t *
wcspbrk(const wchar_t *s, const wchar_t *set) wcspbrk(const wchar_t *s, const wchar_t *set)
{ {
/* ZZZ unimplemented */ /* ZZZ unimplemented */

45
library/wchar_wctob.c Normal file
View File

@ -0,0 +1,45 @@
/*
* $Id: wchar_wmemchr.c,v 1.3 2006-01-08 12:04:27 obarthel Exp $
*
* :ts=4
*
* Portable ISO 'C' (1994) runtime library for the Amiga computer
* Copyright (c) 2002-2015 by Olaf Barthel <obarthel (at) gmx.net>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Neither the name of Olaf Barthel nor the names of contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _WCHAR_HEADERS_H
#include "wchar_headers.h"
#endif /* _WCHAR_HEADERS_H */
/****************************************************************************/
int
wctob(wint_t c)
{
if (c < 128U) return c;
return EOF;
}

View File

@ -37,9 +37,11 @@
/****************************************************************************/ /****************************************************************************/
/* Implementation based on musl */
wchar_t * wchar_t *
wmemchr(const wchar_t *ptr, wchar_t val, size_t len) wmemchr(const wchar_t *ptr, wchar_t val, size_t len)
{ {
/* ZZZ unimplemented */ for (; len && *ptr != val; len--, ptr++);
return(NULL); return len ? (wchar_t *)ptr : 0;
} }

View File

@ -37,9 +37,11 @@
/****************************************************************************/ /****************************************************************************/
/* Implementation based on musl */
int int
wmemcmp(const wchar_t *ptr1, const wchar_t *ptr2, size_t len) wmemcmp(const wchar_t *ptr1, const wchar_t *ptr2, size_t len)
{ {
/* ZZZ unimplemented */ for (; len && *ptr1==*ptr2; len--, ptr1++, ptr2++);
return(0); return len ? *ptr1-*ptr2 : 0;
} }

View File

@ -37,9 +37,12 @@
/****************************************************************************/ /****************************************************************************/
/* Implementation based on musl */
wchar_t * wchar_t *
wmemcpy(wchar_t *dest, const wchar_t *src, size_t len) wmemcpy(wchar_t *dest, const wchar_t *src, size_t len)
{ {
/* ZZZ unimplemented */ wchar_t *a = dest;
return(NULL); while (len--) *dest++ = *src++;
return a;
} }

View File

@ -37,9 +37,15 @@
/****************************************************************************/ /****************************************************************************/
/* Implementation based on musl */
wchar_t * wchar_t *
wmemmove(wchar_t *dest, const wchar_t * src, size_t len) wmemmove(wchar_t *dest, const wchar_t * src, size_t len)
{ {
/* ZZZ unimplemented */ wchar_t *d0 = dest;
return(NULL); if ((size_t)(dest-src) < len)
while (len--) dest[len] = src[len];
else
while (len--) *dest++ = *src++;
return d0;
} }

View File

@ -37,9 +37,12 @@
/****************************************************************************/ /****************************************************************************/
/* Implementation based on musl */
wchar_t * wchar_t *
wmemset(wchar_t *ptr, int val, size_t len) wmemset(wchar_t *ptr, int val, size_t len)
{ {
/* ZZZ unimplemented */ wchar_t *ret = ptr;
return(NULL); while (len--) *ptr++ = val;
return ret;
} }

View File

@ -37,9 +37,10 @@
/****************************************************************************/ /****************************************************************************/
/* Implementation based on musl */
int int
iswalnum(wint_t c) iswalnum(wint_t c)
{ {
/* ZZZ unimplemented */ return iswdigit(c) || iswalpha(c);
return(0);
} }

View File

@ -35,11 +35,12 @@
#include <wctype.h> #include <wctype.h>
#endif /* _WCTYPE_HEADERS_H */ #endif /* _WCTYPE_HEADERS_H */
#include <ctype.h>
/****************************************************************************/ /****************************************************************************/
int int
iswalpha(wint_t c) iswalpha(wint_t c)
{ {
/* ZZZ unimplemented */ return isalpha(c);
return(0);
} }

View File

@ -35,11 +35,14 @@
#include <wctype.h> #include <wctype.h>
#endif /* _WCTYPE_HEADERS_H */ #endif /* _WCTYPE_HEADERS_H */
#include <ctype.h>
/****************************************************************************/ /****************************************************************************/
/* Implementation based on musl */
int int
iswblank(wint_t c) iswblank(wint_t c)
{ {
/* ZZZ unimplemented */ return isblank(c);
return(0);
} }

View File

@ -35,11 +35,12 @@
#include <wctype.h> #include <wctype.h>
#endif /* _WCTYPE_HEADERS_H */ #endif /* _WCTYPE_HEADERS_H */
#include <ctype.h>
/****************************************************************************/ /****************************************************************************/
int int
iswcntrl(wint_t c) iswcntrl(wint_t c)
{ {
/* ZZZ unimplemented */ return iscntrl(c);
return(0);
} }

View File

@ -35,11 +35,12 @@
#include <wctype.h> #include <wctype.h>
#endif /* _WCTYPE_HEADERS_H */ #endif /* _WCTYPE_HEADERS_H */
#include <ctype.h>
/****************************************************************************/ /****************************************************************************/
int int
iswdigit(wint_t c) iswdigit(wint_t c)
{ {
/* ZZZ unimplemented */ return isdigit(c);
return(0);
} }

View File

@ -35,11 +35,12 @@
#include <wctype.h> #include <wctype.h>
#endif /* _WCTYPE_HEADERS_H */ #endif /* _WCTYPE_HEADERS_H */
#include <ctype.h>
/****************************************************************************/ /****************************************************************************/
int int
iswgraph(wint_t c) iswgraph(wint_t c)
{ {
/* ZZZ unimplemented */ return isgraph(c);
return(0);
} }

View File

@ -35,11 +35,12 @@
#include <wctype.h> #include <wctype.h>
#endif /* _WCTYPE_HEADERS_H */ #endif /* _WCTYPE_HEADERS_H */
#include <ctype.h>
/****************************************************************************/ /****************************************************************************/
int int
iswlower(wint_t c) iswlower(wint_t c)
{ {
/* ZZZ unimplemented */ return islower(c);
return(0);
} }

View File

@ -35,11 +35,12 @@
#include <wctype.h> #include <wctype.h>
#endif /* _WCTYPE_HEADERS_H */ #endif /* _WCTYPE_HEADERS_H */
#include <ctype.h>
/****************************************************************************/ /****************************************************************************/
int int
iswpunc(wint_t c) iswpunct(wint_t c)
{ {
/* ZZZ unimplemented */ return ispunct(c);
return(0);
} }

Some files were not shown because too many files have changed in this diff Show More