mirror of
https://github.com/adtools/clib2.git
synced 2025-12-08 14:59:05 +00:00
Compare commits
40 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
428c82ed2e | ||
|
|
718574aae5 | ||
|
|
bdfdd84e38 | ||
|
|
eeb4e5d7aa | ||
|
|
a665fffff1 | ||
|
|
a436ebdad1 | ||
|
|
81e66075e2 | ||
|
|
6bc8108a39 | ||
|
|
f600c5e37a | ||
|
|
1bdfc0d143 | ||
|
|
37a1fdee4f | ||
|
|
d10027ece7 | ||
|
|
60fbee698e | ||
|
|
933483d365 | ||
|
|
4291a0564f | ||
|
|
8a1347e61d | ||
|
|
b9ad1fda3f | ||
|
|
f28dcf8ed1 | ||
|
|
8eac1027a5 | ||
|
|
0b19424148 | ||
|
|
f100199861 | ||
|
|
f727c0f4c4 | ||
|
|
6a149abc57 | ||
|
|
e3bde26409 | ||
|
|
bbc98790fe | ||
|
|
e7258bf939 | ||
|
|
4444438e8f | ||
|
|
6c50657673 | ||
|
|
7dcc410d0c | ||
|
|
f0503cd915 | ||
|
|
ca20eeab97 | ||
|
|
6148d06dca | ||
|
|
6578b303f7 | ||
|
|
6801a4fcf0 | ||
|
|
fa4223c544 | ||
|
|
91ccaa5ba9 | ||
|
|
234a17cc07 | ||
|
|
a41212e575 | ||
|
|
2591e249d7 | ||
|
|
5ea68e3265 |
@@ -1,13 +0,0 @@
|
||||
# The "checkoutlist" file is used to support additional version controlled
|
||||
# administrative files in $CVSROOT/CVSROOT, such as template files.
|
||||
#
|
||||
# The first entry on a line is a filename which will be checked out from
|
||||
# the corresponding RCS file in the $CVSROOT/CVSROOT directory.
|
||||
# The remainder of the line is an error message to use if the file cannot
|
||||
# be checked out.
|
||||
#
|
||||
# File format:
|
||||
#
|
||||
# [<whitespace>]<filename>[<whitespace><error message>]<end-of-line>
|
||||
#
|
||||
# comment lines begin with '#'
|
||||
@@ -1,15 +0,0 @@
|
||||
# The "commitinfo" file is used to control pre-commit checks.
|
||||
# The filter on the right is invoked with the repository and a list
|
||||
# of files to check. A non-zero exit of the filter program will
|
||||
# cause the commit to be aborted.
|
||||
#
|
||||
# The first entry on a line is a regular expression which is tested
|
||||
# against the directory that the change is being committed to, relative
|
||||
# to the $CVSROOT. For the first match that is found, then the remainder
|
||||
# of the line is the name of the filter to run.
|
||||
#
|
||||
# If the repository name does not match any of the regular expressions in this
|
||||
# file, the "DEFAULT" line is used, if it is specified.
|
||||
#
|
||||
# If the name "ALL" appears as a regular expression it is always used
|
||||
# in addition to the first matching regex or "DEFAULT".
|
||||
@@ -1,21 +0,0 @@
|
||||
# Set this to "no" if pserver shouldn't check system users/passwords
|
||||
#SystemAuth=no
|
||||
|
||||
# Put CVS lock files in this directory rather than directly in the repository.
|
||||
#LockDir=/var/lock/cvs
|
||||
|
||||
# Set `TopLevelAdmin' to `yes' to create a CVS directory at the top
|
||||
# level of the new working directory when using the `cvs checkout'
|
||||
# command.
|
||||
#TopLevelAdmin=no
|
||||
|
||||
# Set `LogHistory' to `all' or `TOEFWUPCGMAR' to log all transactions to the
|
||||
# history file, or a subset as needed (ie `TMAR' logs all write operations)
|
||||
#LogHistory=TOEFWUPCGMAR
|
||||
|
||||
# Set `RereadLogAfterVerify' to `always' (the default) to allow the verifymsg
|
||||
# script to change the log message. Set it to `stat' to force CVS to verify# that the file has changed before reading it (this can take up to an extra
|
||||
# second per directory being committed, so it is not recommended for large
|
||||
# repositories. Set it to `never' (the previous CVS behavior) to prevent
|
||||
# verifymsg scripts from changing the log message.
|
||||
#RereadLogAfterVerify=always
|
||||
@@ -1,19 +0,0 @@
|
||||
# This file affects handling of files based on their names.
|
||||
#
|
||||
# The -m option specifies whether CVS attempts to merge files.
|
||||
#
|
||||
# The -k option specifies keyword expansion (e.g. -kb for binary).
|
||||
#
|
||||
# Format of wrapper file ($CVSROOT/CVSROOT/cvswrappers or .cvswrappers)
|
||||
#
|
||||
# wildcard [option value][option value]...
|
||||
#
|
||||
# where option is one of
|
||||
# -f from cvs filter value: path to filter
|
||||
# -t to cvs filter value: path to filter
|
||||
# -m update methodology value: MERGE or COPY
|
||||
# -k expansion mode value: b, o, kkv, &c
|
||||
#
|
||||
# and value is a single-quote delimited value.
|
||||
# For example:
|
||||
#*.gif -k 'b'
|
||||
@@ -1,21 +0,0 @@
|
||||
# The "editinfo" file is used to allow verification of logging
|
||||
# information. It works best when a template (as specified in the
|
||||
# rcsinfo file) is provided for the logging procedure. Given a
|
||||
# template with locations for, a bug-id number, a list of people who
|
||||
# reviewed the code before it can be checked in, and an external
|
||||
# process to catalog the differences that were code reviewed, the
|
||||
# following test can be applied to the code:
|
||||
#
|
||||
# Making sure that the entered bug-id number is correct.
|
||||
# Validating that the code that was reviewed is indeed the code being
|
||||
# checked in (using the bug-id number or a seperate review
|
||||
# number to identify this particular code set.).
|
||||
#
|
||||
# If any of the above test failed, then the commit would be aborted.
|
||||
#
|
||||
# Actions such as mailing a copy of the report to each reviewer are
|
||||
# better handled by an entry in the loginfo file.
|
||||
#
|
||||
# One thing that should be noted is the the ALL keyword is not
|
||||
# supported. There can be only one entry that matches a given
|
||||
# repository.
|
||||
@@ -1,27 +0,0 @@
|
||||
# The "loginfo" file controls where "cvs commit" log information
|
||||
# is sent. The first entry on a line is a regular expression which must match
|
||||
# the directory that the change is being made to, relative to the
|
||||
# $CVSROOT. If a match is found, then the remainder of the line is a filter
|
||||
# program that should expect log information on its standard input.
|
||||
#
|
||||
# If the repository name does not match any of the regular expressions in this
|
||||
# file, the "DEFAULT" line is used, if it is specified.
|
||||
#
|
||||
# If the name ALL appears as a regular expression it is always used
|
||||
# in addition to the first matching regex or DEFAULT.
|
||||
#
|
||||
# You may specify a format string as part of the
|
||||
# filter. The string is composed of a `%' followed
|
||||
# by a single format character, or followed by a set of format
|
||||
# characters surrounded by `{' and `}' as separators. The format
|
||||
# characters are:
|
||||
#
|
||||
# s = file name
|
||||
# V = old version number (pre-checkin)
|
||||
# v = new version number (post-checkin)
|
||||
# t = tag or branch name
|
||||
#
|
||||
# For example:
|
||||
#DEFAULT (echo ""; id; echo %s; date; cat) >> $CVSROOT/CVSROOT/commitlog
|
||||
# or
|
||||
#DEFAULT (echo ""; id; echo %{sVv}; date; cat) >> $CVSROOT/CVSROOT/commitlog
|
||||
@@ -1,26 +0,0 @@
|
||||
# Three different line formats are valid:
|
||||
# key -a aliases...
|
||||
# key [options] directory
|
||||
# key [options] directory files...
|
||||
#
|
||||
# Where "options" are composed of:
|
||||
# -i prog Run "prog" on "cvs commit" from top-level of module.
|
||||
# -o prog Run "prog" on "cvs checkout" of module.
|
||||
# -e prog Run "prog" on "cvs export" of module.
|
||||
# -t prog Run "prog" on "cvs rtag" of module.
|
||||
# -u prog Run "prog" on "cvs update" of module.
|
||||
# -d dir Place module in directory "dir" instead of module name.
|
||||
# -l Top-level directory only -- do not recurse.
|
||||
#
|
||||
# NOTE: If you change any of the "Run" options above, you'll have to
|
||||
# release and re-checkout any working directories of these modules.
|
||||
#
|
||||
# And "directory" is a path to a directory relative to $CVSROOT.
|
||||
#
|
||||
# The "-a" option specifies an alias. An alias is interpreted as if
|
||||
# everything on the right of the "-a" had been typed on the command line.
|
||||
#
|
||||
# You can encode a module within a module by using the special '&'
|
||||
# character to interpose another module into the current module. This
|
||||
# can be useful for creating a module that consists of many directories
|
||||
# spread out over the entire source repository.
|
||||
@@ -1,12 +0,0 @@
|
||||
# The "notify" file controls where notifications from watches set by
|
||||
# "cvs watch add" or "cvs edit" are sent. The first entry on a line is
|
||||
# a regular expression which is tested against the directory that the
|
||||
# change is being made to, relative to the $CVSROOT. If it matches,
|
||||
# then the remainder of the line is a filter program that should contain
|
||||
# one occurrence of %s for the user to notify, and information on its
|
||||
# standard input.
|
||||
#
|
||||
# "ALL" or "DEFAULT" can be used in place of the regular expression.
|
||||
#
|
||||
# For example:
|
||||
#ALL mail -s "CVS notification" %s
|
||||
@@ -1,13 +0,0 @@
|
||||
# The "rcsinfo" file is used to control templates with which the editor
|
||||
# is invoked on commit and import.
|
||||
#
|
||||
# The first entry on a line is a regular expression which is tested
|
||||
# against the directory that the change is being made to, relative to the
|
||||
# $CVSROOT. For the first match that is found, then the remainder of the
|
||||
# line is the name of the file that contains the template.
|
||||
#
|
||||
# If the repository name does not match any of the regular expressions in this
|
||||
# file, the "DEFAULT" line is used, if it is specified.
|
||||
#
|
||||
# If the name "ALL" appears as a regular expression it is always used
|
||||
# in addition to the first matching regex or "DEFAULT".
|
||||
@@ -1,20 +0,0 @@
|
||||
# The "taginfo" file is used to control pre-tag checks.
|
||||
# The filter on the right is invoked with the following arguments:
|
||||
#
|
||||
# $1 -- tagname
|
||||
# $2 -- operation "add" for tag, "mov" for tag -F, and "del" for tag -d
|
||||
# $3 -- repository
|
||||
# $4-> file revision [file revision ...]
|
||||
#
|
||||
# A non-zero exit of the filter program will cause the tag to be aborted.
|
||||
#
|
||||
# The first entry on a line is a regular expression which is tested
|
||||
# against the directory that the change is being committed to, relative
|
||||
# to the $CVSROOT. For the first match that is found, then the remainder
|
||||
# of the line is the name of the filter to run.
|
||||
#
|
||||
# If the repository name does not match any of the regular expressions in this
|
||||
# file, the "DEFAULT" line is used, if it is specified.
|
||||
#
|
||||
# If the name "ALL" appears as a regular expression it is always used
|
||||
# in addition to the first matching regex or "DEFAULT".
|
||||
@@ -1,21 +0,0 @@
|
||||
# The "verifymsg" file is used to allow verification of logging
|
||||
# information. It works best when a template (as specified in the
|
||||
# rcsinfo file) is provided for the logging procedure. Given a
|
||||
# template with locations for, a bug-id number, a list of people who
|
||||
# reviewed the code before it can be checked in, and an external
|
||||
# process to catalog the differences that were code reviewed, the
|
||||
# following test can be applied to the code:
|
||||
#
|
||||
# Making sure that the entered bug-id number is correct.
|
||||
# Validating that the code that was reviewed is indeed the code being
|
||||
# checked in (using the bug-id number or a seperate review
|
||||
# number to identify this particular code set.).
|
||||
#
|
||||
# If any of the above test failed, then the commit would be aborted.
|
||||
#
|
||||
# Actions such as mailing a copy of the report to each reviewer are
|
||||
# better handled by an entry in the loginfo file.
|
||||
#
|
||||
# One thing that should be noted is the the ALL keyword is not
|
||||
# supported. There can be only one entry that matches a given
|
||||
# repository.
|
||||
@@ -1,30 +0,0 @@
|
||||
<!DOCTYPE html public "-//W3C//DTD HTML 3.2 Final//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>Notes on building the library</title>
|
||||
<body>
|
||||
|
||||
<h1>Notes on building the library</h1>
|
||||
|
||||
<p>In order to build the library, you need a 'C' compiler (obvious, isn't it?) and
|
||||
a set of header files for the networking API definitions. The networking header
|
||||
files go into a directory <tt>netinclude</tt> which has to sit in the same directory as
|
||||
the source code and the <tt>include</tt> directory you find in there. I'm not currently
|
||||
supplying these header files here. Drop me a line, and I'll take care of that.</p>
|
||||
|
||||
<p>The SAS/C flavour (<tt>smakefile</tt>) should get the library built using the "large data"
|
||||
model. This rules out the use of residentable programs as the startup code I'm
|
||||
using is very primitive (<tt>startup.o</tt>) and doesn't tinker with A4 relative data
|
||||
addressing (and how this may be set up).</p>
|
||||
|
||||
<p>There are two makefiles for GCC, each a different flavour. There is <tt>GNUmakefile.68k</tt>,
|
||||
which will build the library for GCC on the 68k platform ("classic" Amiga). This
|
||||
builds all variants of the library, for large data, small data, resident, whatever
|
||||
model. It's a lot of work and I don't recommend you do this on a plain 68k machine.
|
||||
It will literally (!) take hours. The other makefile flavour is for AmigaOS4 using
|
||||
the PowerPC hosted GCC system (<tt>GNUmakefile.os4</tt>). This builds only the large data
|
||||
version of the library, but this is usually all you need. Small data support is
|
||||
currently not implemented but might follow in the future.</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,67 +0,0 @@
|
||||
<!DOCTYPE html public "-//W3C//DTD HTML 3.2 Final//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>Notes on using the library with Amiga GCC (68k)</title>
|
||||
<body>
|
||||
|
||||
<h1>Notes on using the library with Amiga GCC (68k)</h1>
|
||||
|
||||
<p>You can use the 68k build of clib2 with the existing Amiga 68k ports of the
|
||||
GNU 'C' compiler. In order to do so, you need to modify the <tt>specs</tt> file which
|
||||
controls how the compiler(s) and the linker interact, and where the linker
|
||||
will look for the program startup code and library files. Also, you will need
|
||||
to copy the header files, startup code and library files to the locations
|
||||
where the 'C' compiler and linker expects them.</p>
|
||||
|
||||
<p>Please read the following description before you follow the instructions. The
|
||||
changes suggested may have unexpected side-effects!</p>
|
||||
|
||||
<p>I have provided a working <tt>specs</tt> file with this documentation file. To switch
|
||||
over an existing Amiga 68k port of GCC to use clib2, you would proceed as
|
||||
follows:</p>
|
||||
|
||||
<ul>
|
||||
<li> Locate the directory within which GCC is installed. For example, this
|
||||
could be within a directory to which the name <tt>ADE:</tt>, <tt>GG:</tt> or <tt>GCC:</tt>
|
||||
is assigned. For the sake of simplicity, the following notes assume
|
||||
that the assignment name is <tt>GCC:</tt>
|
||||
|
||||
<li> Make backup copies of the following directories and files:
|
||||
<ol>
|
||||
<li> <tt>GCC:lib/gcc-lib/amigaos/2.95.3/specs</tt><br>
|
||||
|
||||
<p>(NOTE: Check the directory called <tt>GCC:lib/gcc-lib/amigaos</tt>
|
||||
first; the "2.95.3" quoted above refers to the version,
|
||||
revision and patch number of the GCC installed and your
|
||||
version number may differ!)</p>
|
||||
|
||||
<li> <tt>GCC:include</tt>
|
||||
<li> <tt>GCC:lib</tt>
|
||||
|
||||
</ol>
|
||||
|
||||
<li> Now you can proceed to install clib2; just copy the <tt>include</tt> and <tt>lib</tt>
|
||||
directories over, like this:
|
||||
<ol>
|
||||
<li><kbd>Copy include GCC:include all quiet</kbd>
|
||||
<li><kbd>Copy lib GCC:lib all quiet</kbd>
|
||||
</ol>
|
||||
|
||||
<li> Finally, replace the <tt>specs</tt> file with the one provided:
|
||||
<ol>
|
||||
|
||||
<li> <kbd>Copy specs GCC:lib/gcc-lib/amigaos/2.95.3/specs</kbd><br>
|
||||
|
||||
<p>(NOTE: Check the directory called <tt>GCC:lib/gcc-lib/amigaos</tt>
|
||||
first; the "2.95.3" quoted above refers to the version,
|
||||
revision and patch number of the GCC installed and your
|
||||
version number may differ!)</p>
|
||||
</ol>
|
||||
</ul>
|
||||
|
||||
<p>Once you have completed these steps you should be able to build programs using
|
||||
the 68k build of clib2 and you currently installed GCC. Note that these
|
||||
changes may have the effect of rendering your C++ compiler unusable, so make
|
||||
sure that you've made backup copies of all files and directories first!</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,517 +0,0 @@
|
||||
<!DOCTYPE html public "-//W3C//DTD HTML 3.2 Final//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>An ISO 'C' (1994) compliant runtime library for the Amiga</title>
|
||||
<body>
|
||||
|
||||
<h1>An ISO 'C' (1994) compliant runtime library for the Amiga</h1>
|
||||
|
||||
<h2>1. What is this?</h2>
|
||||
|
||||
<p>This is my attempt to get Samba 2.2.x ported to the Amiga. My first Amiga
|
||||
port required SAS/C and a number of strange tricks had to be pulled to get
|
||||
it to support the kind of environment Samba needed. But with the
|
||||
introduction of Samba 2.2.x many of those tricks did not work any more,
|
||||
which is why I decided to attack the problem at the root, namely the
|
||||
runtime library.</p>
|
||||
|
||||
<p>Because it was no longer possible to build Samba with SAS/C on the new
|
||||
Amiga platform, the idea came up to move development to the GNU 'C'
|
||||
compiler. This turned out to be a challenge due to its somewhat
|
||||
underdeveloped runtime library and header files. Eventually, I decided to
|
||||
rewrite that library from scratch.</p>
|
||||
|
||||
|
||||
<h2>2. What does it do?</h2>
|
||||
|
||||
<p>Using <i>'C' - A reference manual</i> (4th edition) as a reference I wrote a set of
|
||||
header files, then proceeded to implement each single function referenced in
|
||||
them. With few exceptions in the area of wide character support, the result
|
||||
should be a feature complete implementation of the ISO 'C' (1994) runtime
|
||||
library. The library was subsequently updated to offer functionality defined in
|
||||
<i>ISO/IEC 9899:1999</i>, also known as <i>C99</i>.</p>
|
||||
|
||||
<p>Because Samba needs a few POSIX-like routines to be supported, the library
|
||||
functionality is complemented by a set of routines described in <i>Advanced
|
||||
programming in the Unix environent</i>.</p>
|
||||
|
||||
<p>This is not a portable implementation of the library in the sense that you
|
||||
could move it from one 'C' compiler on one operating system to another.
|
||||
This is an Amiga specific implementation.</p>
|
||||
|
||||
<p>The library supports floating point math, which, for the 68k platform, is
|
||||
limited to IEEE single and double precision or M68881 inline math. There is no
|
||||
support for the fast floating point (FFP) format or exclusive IEEE single
|
||||
precision. You either get double precision (IEEE math) or extended precision
|
||||
(M68881 inline math). What it is that you get is determined at compile time.
|
||||
Use the <tt>IEEE_FLOATING_POINT_SUPPORT</tt> preprocessor symbol to activate IEEE math
|
||||
code and the <tt>M68881_FLOATING_POINT_SUPPORT</tt> symbol for M68881 inline math.</p>
|
||||
|
||||
<p>For the PowerPC platform, the library uses code borrowed from <i>fdlibm 5.3</i>,
|
||||
which is a portable library of arithmetic functions developed by Sun
|
||||
Microsystems which, for example, is also used within the Java platform.</p>
|
||||
|
||||
<h2>3. What does it not do?</h2>
|
||||
|
||||
<p>This library is a departure from the typical 'C' runtime environments of the
|
||||
past which had to run on all AmigaOS releases, down to Kickstart 1.1. This
|
||||
very library was designed to take advantage of the routines available since
|
||||
Kickstart 2.04 was introduced and virtually nobody ever put to use. This helps
|
||||
to cut the code size, and it also helps to keep bugs out of the library by
|
||||
falling back onto well-tested implementations. However, the catch is that the
|
||||
code won't run under Kickstart 1.3 and below. But then these operating system
|
||||
releases have been obsolete for more than a decade, and you can always go back
|
||||
to a compiler environment which supports them.</p>
|
||||
|
||||
<p>There is very little support for <tt>amiga.lib</tt> functionality. There is <tt>NewList()</tt>,
|
||||
<tt>HookEntry()</tt>, <tt>CallHook()</tt>, <tt>CallHookA()</tt>, the <tt>DoMethod()</tt> family, the RexxVars
|
||||
family, but that's all. If you need more, you would have to implement it
|
||||
yourself. Put another way, if you absolutely need functionality that is only
|
||||
found in <tt>amiga.lib</tt>, you really shouldn't need it in the first place.</p>
|
||||
|
||||
|
||||
<h2>4. Where does the source code come from?</h2>
|
||||
|
||||
<p>I originally thought that it might be helpful to piece this library together
|
||||
from various sources, such as the BSD libc. It turned out that this code was so
|
||||
'portable' that it became much more complex than it ought to be. Also, some
|
||||
side-effects were present which considerably changed the behaviour of the
|
||||
library. For example, the BSD libc uses <tt>bcopy()</tt> as an alias for <tt>memcpy()</tt>, and
|
||||
unlike <tt>memcpy()</tt> is documented to, <tt>bcopy()</tt> supports overlapping copies.</p>
|
||||
|
||||
<p>Eventually, I wrote virtually all the code myself, borrowing algorithmic ideas
|
||||
from the BSD libc and the Manx Aztec 'C' runtime library. Because I don't know
|
||||
much about the environment GCC expects, I borrowed code snippets from libnix,
|
||||
which was written by Matthias Fleischer and Gunther Nikl. This in particular
|
||||
concerns the integer and floating point math support, the <tt>setjmp</tt>/<tt>longjmp</tt>
|
||||
routines and the startup code. The M68881 inline math code comes from the
|
||||
<tt><math-68881.h></tt> file written by Matthew Self <tt>(self [at] bayes.arc.nasa.gov)</tt>.</p>
|
||||
|
||||
|
||||
<h2>5. Limitations and caveats</h2>
|
||||
|
||||
<p>There is hardly any documentation on the code I wrote. In part this is due to
|
||||
the fact that the code itself is very simple in design. It should speak for
|
||||
itself. However, to make a usable runtime library you have to have a user
|
||||
documentation as in man pages or AutoDocs. We will eventually have to have
|
||||
autodocs for this library.</p>
|
||||
|
||||
<p>The exception handling in the math code is not particularly effective. For one
|
||||
part this is due to the fact that there is no exception handler installed by
|
||||
the runtime library when it starts up which could catch and process the error
|
||||
conditions the CPU or FPU generates. The idea was to provide for a portable
|
||||
runtime library with little to no assembly language involved. To make the
|
||||
exception handling complete, such code would be necessary.</p>
|
||||
|
||||
<p>The library currently builds under SAS/C, but because the 'normal' program
|
||||
startup code is not utilized, the base relative (A4) addressing does not work.
|
||||
If you are going to test it, use the <tt>data=faronly</tt> option to compile the
|
||||
library and the programs.</p>
|
||||
|
||||
<p>Different build makefiles are supplied for use with GCC. There is a
|
||||
<tt>GNUmakefile.68k</tt> for the 68k platform and a <tt>GNUmakefile.os4</tt> for the AmigaOS4
|
||||
PowerPC version.</p>
|
||||
|
||||
<h3>5.1 Floating point math and functions (<tt>scanf()</tt>, <tt>printf()</tt>, etc.) </h3>
|
||||
|
||||
<p>The plain <tt>libc.a</tt>, which your software would be linked against by default, does not contain
|
||||
any floating point support code. This means, for example, that <tt>printf("%f",...)</tt> will not produce
|
||||
the desired output and that <tt>scanf("%f",...)</tt> may not read any data at all. If your
|
||||
program needs functions such as these or <tt>atod()</tt> then you must link against <tt>libm.a</tt> or
|
||||
the equivalent.</p>
|
||||
|
||||
<p>To link the floating point support code with your software, use the <tt>-lm</tt> compiler option. <em>Careful!</em>
|
||||
The order in which you specify the libraries to link against is important here. Thus, <tt>gcc -o test test.c -lm -lc</tt>
|
||||
would correctly link the program <tt>test</tt> against the proper floating point math library, but
|
||||
<tt>gcc -o test test.c -lc -lm</tt> would not.</p>
|
||||
|
||||
<h3>5.2 The thread-safe library</h3>
|
||||
|
||||
<p>Thread-safety does not imply that you can have multiple callers
|
||||
access and close the same file. There is no resource tracking to that degree
|
||||
yet. All that the thread-safety tries to afford you is not to get into big trouble
|
||||
if simultaneous and overlapping accesses to files, memory allocation and other
|
||||
resources are taking place.</p>
|
||||
|
||||
<p>The library code is supposed to be thread-safe if built with the <tt>__THREAD_SAFE</tt>
|
||||
preprocesssor symbol defined. Note that 'thread-safe' does <em>not</em> mean
|
||||
'reentrant'. Multiple callers for certain library functions are permitted, but
|
||||
not for all of them. For example, <tt>mkdtemp()</tt> is not thread-safe, and neither is
|
||||
<tt>rand()</tt> or <tt>localtime()</tt>. But as per <i>POSIX 1003.1c-1995</i> there are thread-safe
|
||||
variants of <tt>rand()</tt> and <tt>localtime()</tt> called <tt>rand_r()</tt>, <tt>localtime_r()</tt>, and others.</p>
|
||||
|
||||
<p>The use of the socket I/O functions is problematic because the
|
||||
underlying <tt>bsdsocket.library</tt> API is not supposed to be used by any process
|
||||
other than the one which opened it. While one TCP/IP stack (my own "Roadshow") allows you
|
||||
to share the library base among different processes, if so configured, it is the
|
||||
exception. No other TCP/IP stack available for the Amiga robustly supports a similar
|
||||
feature. If the TCP/IP stack supports this feature, then the global variable
|
||||
<tt>__can_share_socket_library_base</tt> will be set to a non-zero value.</p>
|
||||
|
||||
<p>Errors reported by the socket I/O functions which modify the global variables
|
||||
<tt>errno</tt> and <tt>h_errno</tt> may be directed to call the <tt>__set_errno()</tt>
|
||||
and <tt>__set_h_errno()</tt> functions instead, if the TCP/IP stack supports this feature. The global
|
||||
variable <tt>__thread_safe_errno_h_errno</tt> will be set to a non-zero value if it does.</p>
|
||||
|
||||
<p>A much more serious problem resides with the <tt>exit()</tt>, <tt>abort()</tt>,
|
||||
<tt>assert()</tt> and <tt>raise()</tt> functions, and how the <tt>SIGINT</tt> signal is
|
||||
processed. In the thread-safe library only the <tt>main()</tt> function may directly
|
||||
or indirectly call the <tt>exit()</tt> function. No child process may do so, since this
|
||||
would wreck its stack context, crashing it instantly; the main program would be very
|
||||
likely to crash, too, because <tt>exit()</tt> will clean up after all memory allocations
|
||||
and files currently in use. Functions such as <tt>abort()</tt> and <tt>raise()</tt> may
|
||||
call the <tt>exit()</tt> function indirectly. And the <tt>raise()</tt> function may
|
||||
be invoked as part of the <tt>Control+C</tt> checking. You should make sure that the
|
||||
signal handling does not affect any child processes. This can be done by replacing the
|
||||
<tt>__check_abort()</tt> function or by disabling <tt>SIGINT</tt> processing altogether,
|
||||
such as through a <tt>signal(SIGINT,SIG_IGN)</tt> call.</p>
|
||||
|
||||
<p> Also take care with file I/O involving the <tt>stdin</tt>/<tt>stdout</tt>/<tt>stderr</tt>
|
||||
streams; read/write operations on these streams will be mapped to the <tt>Input()</tt>/<tt>Output()</tt>/<tt>ErrorOutput()</tt>
|
||||
file handles of the process performing these operations. Since only this small set of
|
||||
operations is mapped, functions such as <tt>fcntl()</tt> or <tt>select()</tt> will not
|
||||
work on the <tt>stdin</tt>/<tt>stdout</tt>/<tt>stderr</tt> streams and the corresponding
|
||||
file descriptors <tt>STDIN_FILENO</tt>/<tt>STDOUT_FILENO</tt>/<tt>STDERR_FILENO</tt>.
|
||||
It is therefore strongly recommended to use the thread-safe library only for applications
|
||||
which can cope with the limitations described above.</p>
|
||||
|
||||
<h3>5.3 Using gmon (PowerPC only)</h3>
|
||||
|
||||
<p>To use profiling, two steps are required. First of all, your program must be compiled with
|
||||
the gcc command line option <tt>-pg</tt>. This instructs the compiler to generate special
|
||||
profiling code in the prologue and epilogue of each function. Additionally, the program
|
||||
must be linked with <tt>libprofile.a</tt>. To do this, either manually add
|
||||
<tt>-lprofile</tt> to the linker command line, or modify the specs file as follows.
|
||||
Find the lines that look like this (it may actually differ silghtily from your specs file,
|
||||
but the important thing is that the line before the line to be modified reads <tt>lib:</tt>):
|
||||
<pre>
|
||||
lib:
|
||||
--start-group -lc --end-group
|
||||
</pre>
|
||||
You will have to modify this to look like this:
|
||||
<pre>
|
||||
lib:
|
||||
%{pg: -lprofile} --start-group -lc --end-group
|
||||
</pre>
|
||||
<p>Normally, the specs file is located at the compilers installation directory. For cross-compilers,
|
||||
this is <tt>/usr/local/amiga/lib/gcc/ppc-amigaos/<i>compiler-version</i>/specs</tt>. For a native compiler,
|
||||
it's in <tt>gcc:lib/gcc/ppc-amigaos/<i>compiler-version</i>/specs</tt>. Most likely, your compiler will already have this added to it's specs file.</p>
|
||||
|
||||
<p>Profiling makes use of a special PowerPC facility called the Performance Monitor. It
|
||||
allows to "mark" tasks and count only during while a marked task is running. This allows
|
||||
performance analysis to be made independant of the actual system load. The Performace Monitor
|
||||
is available on all PowerPC models supported by AmigaOS 4 except for the <tt>603e</tt>, and
|
||||
embedded versions of the PowerPC like the <tt>405</tt> and <tt>440</tt> series. Consult the manual
|
||||
of the appropriate chip for more information.</p>
|
||||
|
||||
<h3>5.4 Implementation defined behaviour</h3>
|
||||
|
||||
<h4>5.4.1. 'C' language</h4>
|
||||
|
||||
<h5>5.4.1.1. Environment</h5>
|
||||
|
||||
<p>The <tt>main(int argc,char **argv);</tt> function may be called with an <tt>argc</tt> value of 0,
|
||||
in which case the <tt>argv</tt> variable will contain a pointer to the Amiga Workbench startup
|
||||
message, which is of type <tt>struct WBStartup *</tt>, and is defined in the Amiga system header
|
||||
file <tt><workbench/startup.h></tt>.</p>
|
||||
|
||||
<h5>5.4.1.2. Characters</h5>
|
||||
|
||||
<p>The current locale is derived from the current Amiga operating system locale settings. The
|
||||
<tt>setlocale("")</tt> function call will choose the current Amiga operating system locale settings.
|
||||
Any other name passed to the <tt>setlocale()</tt> function, with the exception of <tt>"C"</tt>,
|
||||
which selects the 'C' locale, must be a locale name, as used by the Amiga operating system
|
||||
function <tt>OpenLocale()</tt> in <tt>locale.library</tt>.</p>
|
||||
|
||||
<h5>5.4.1.3. Floating-point</h5>
|
||||
|
||||
<p>The 68k version of clib2 supports single and double precision floating point numbers,
|
||||
according to the <i>IEEE 754</i> standard. The software floating point number support is built upon the Amiga
|
||||
operating system libraries <tt>mathieeesingbas.library</tt>, <tt>mathieeedoubbas.library</tt>
|
||||
and <tt>mathieeedoubtrans.library</tt>. The hardware floating point number support uses
|
||||
the M68881/M68882/M68040/M68060 floating point unit intead.</p>
|
||||
|
||||
<p>The PowerPC version of clib2 supports only double precision floating point numbers, according to
|
||||
the <i>IEEE 754</i> standard, because that is exactly what the PowerPC CPU supports. Single precision
|
||||
numbers may be implicitly converted to double precision numbers. This also means that the <i>C99</i>
|
||||
data type <tt>long double</tt> is identical to the <tt>double</tt> data type. Because there is no
|
||||
difference between these two, the library omits support for <i>C99</i> functions specifically designed
|
||||
to operate on <tt>long double</tt> data types, such as <tt>rintl()</tt>.</p>
|
||||
|
||||
<p>Both the 68k and the PowerPC versions of clib2 may call software floating point support
|
||||
routines in order to perform double and single precision operations that go beyond
|
||||
simple addition and multiplication, such as <tt>sqrt()</tt>. These functions come from
|
||||
Sun Microsystems <i>fdlibm 5.3</i> library.</p>
|
||||
|
||||
<p>Unless your software is linked against <tt>libm.a</tt> no floating point functions will
|
||||
be available to it, possibly causing a linker error. When using the GNU 'C' compiler, you will
|
||||
want to add the option <tt>-lm -lc</tt> to the linker command line.</p>
|
||||
|
||||
<p>The exception handling is currently entirely out of control of the developer
|
||||
and solely subject to the rules imposed by the operating system itself.</p>
|
||||
|
||||
<p>The <tt>fmod()</tt> function returns the value of the <tt>x</tt> parameter and
|
||||
sets <tt>errno</tt> to <tt>EDOM</tt> if the <tt>y</tt> parameter value is 0.</p>
|
||||
|
||||
<h4>5.4.2. Library functions</h4>
|
||||
|
||||
<h5>5.4.2.1. <tt>NULL</tt></h5>
|
||||
|
||||
<p>The <tt>NULL</tt> pointer constant is defined in the <tt><stddef.h></tt> header and
|
||||
will expand to <tt>((void *)0L)</tt> if the 'C' compiler is used. For a C++ compiler the constant
|
||||
will expand to <tt>0L</tt> instead.</p>
|
||||
|
||||
<h5>5.4.2.2. <tt>assert()</tt> diagnostic messages</h5>
|
||||
|
||||
<p>The diagnostic messages printed by the <tt>assert()</tt> function take the following form:</p>
|
||||
|
||||
<blockquote><tt>[<i>program name</i>] <i>file</i>:<i>line</i>: failed assertion "<i>condition</i>".</tt></blockquote>
|
||||
|
||||
<p>where:</p>
|
||||
<table border=0>
|
||||
<tr><th align=right>program name</th><td>Optional program name; if the program name is not yet known, then the
|
||||
entire text enclosed in square brackets will be omitted.</td></tr>
|
||||
<tr><th align=right>file</th><td>The value of the <tt>__FILE__</tt> symbol at the location of the <tt>assert()</tt> call.</td></tr>
|
||||
<tr><th align=right>line</th><td>The value of the <tt>__LINE__</tt> symbol at the location of the <tt>assert()</tt> call.</td></tr>
|
||||
<tr><th align=right>condition</th><td>The condition passed to the <tt>assert()</tt> function.</td></tr>
|
||||
</table>
|
||||
|
||||
<p>If available, the diagnostic messages will be sent to <tt>stderr</tt>.</p>
|
||||
|
||||
<p>If the program was launched from Workbench or if the global variable <tt>__no_standard_io</tt> is set
|
||||
to a non-zero value, then the assertion failure message will not be displayed in the shell window, but
|
||||
in a requester window. The diagnostic message shown in this window will take the following form:</p>
|
||||
|
||||
<blockquote><tt>Assertion of condition "<i>condition</i>" failed in file "<i>file</i>", line <i>line</i>.</tt></blockquote>
|
||||
|
||||
<p>The name of the program, if it is know at that time, will be displayed in the requester window title.</p>
|
||||
|
||||
<h5>5.4.2.3. Signal handling</h5>
|
||||
|
||||
<p>Only the minimum of required signals are supported by this library. These are <tt>SIGABRT</tt>, <tt>SIGFPE</tt>,
|
||||
<tt>SIGILL</tt>, <tt>SIGINT</tt>, <tt>SIGSEGV</tt> and <tt>SIGTERM</tt>.</p>
|
||||
|
||||
<p>As of this writing <tt>SIGFPE</tt> is never called by the floating point library functions.</p>
|
||||
|
||||
<p>The <tt>Ctrl+C</tt> event is translated into <tt>SIGINT</tt>. Signal delivery may be delayed
|
||||
until a library function which polls for the signal examines it. This means, for example, that
|
||||
a runaway program caught in an infinite loop cannot be aborted by sending it a <tt>Ctrl+C</tt> event unless special code
|
||||
is added which tests for the presence of the signal and calls the <tt>__check_abort()</tt> all on its own.</p>
|
||||
|
||||
<p>Processing of the <tt>Ctrl+C</tt> event involves the internal <tt>__check_abort()</tt> function which
|
||||
polls for the presence of the event and which will call <tt>raise(SIGINT);</tt>. The <tt>__check_abort()</tt>
|
||||
function may be replaced by user code.</p>
|
||||
|
||||
<h5>5.4.2.4. Files</h5>
|
||||
|
||||
<p>No new line characters are written unless specifically requested.</p>
|
||||
|
||||
<p>Space characters in a text stream before a new line character are read in and not discarded.</p>
|
||||
|
||||
<p>When data is read from a file, the last character does not have to be a new line character.</p>
|
||||
|
||||
<p>No NUL byte will be appended to data written to a binary stream.</p>
|
||||
|
||||
<p>There is no difference between text and binary streams.</p>
|
||||
|
||||
<p>Writing to a text or binary stream does not truncate the associated file. A stream may be
|
||||
truncated by the initial <tt>fopen()</tt> call if the <tt>mode</tt> parameter starts with
|
||||
the letter <tt>w</tt>.</p>
|
||||
|
||||
<p>The file position indicator is initially set to the end of an append mode stream.</p>
|
||||
|
||||
<h5>5.4.2.5. <tt>printf()</tt> family</h5>
|
||||
|
||||
<p>The <tt>%p</tt> conversion is the hexadecimal representation of the pointer, and
|
||||
it is preceded by the string <tt>0x</tt>.</p>
|
||||
|
||||
<p>The <tt>%a</tt>, <tt>%e</tt>, <tt>%f</tt>, <tt>%g</tt>, <tt>%A</tt>,
|
||||
<tt>%E</tt>, <tt>%F</tt> and <tt>%G</tt> specifiers will produce the string <tt>inf</tt>
|
||||
for infinity.</p>
|
||||
|
||||
<h5>5.4.2.6. <tt>scanf()</tt> family</h5>
|
||||
|
||||
<p>The input for the <tt>%p</tt> conversion must be a hexadecimal number,
|
||||
preceded by either the string <tt>0x</tt> or <tt>0X</tt>.</p>
|
||||
|
||||
<p>In the <tt>%[</tt> conversion a <tt>-</tt> (dash) character that is neither the
|
||||
first nor the last character in the scanset indicates that a subrange of
|
||||
characters should be used. Thus <tt>%[a-d]</tt> is equivalent to <tt>%[abcd]</tt>.</p>
|
||||
|
||||
<p>The period (.) is the decimal-point character. The locale specific decimal-point
|
||||
character is accepted as an alternative to the period (.).</p>
|
||||
|
||||
<h5>5.4.2.7. <tt>malloc()</tt>, <tt>realloc()</tt> and <tt>calloc()</tt></h5>
|
||||
|
||||
<p>In the standard <tt>libc.a</tt> implementation any request to allocate
|
||||
0 (zero) bytes will fail. A result value of <tt>NULL</tt> will be returned and
|
||||
the global <tt>errno</tt> variable will be set to <tt>EINVAL</tt>.</p>
|
||||
|
||||
<p>In the <tt>libunix.a</tt> implementation a request to allocate
|
||||
0 (zero) bytes will result in an allocation of at least 4 bytes, which will
|
||||
be set to zero. Each zero length allocation will return a different
|
||||
memory address.</p>
|
||||
|
||||
<h5>5.4.2.8. <tt>rename()</tt></h5>
|
||||
|
||||
<p>In the standard <tt>libc.a</tt> implementation the <tt>rename()</tt> function
|
||||
will fail if there already is a file or directory by the new name to be used.</p>
|
||||
|
||||
<p>In the <tt>libunix.a</tt> implementation the <tt>rename()</tt> function will
|
||||
delete any existing file or directory by the new name.</p>
|
||||
|
||||
<h5>5.4.2.9. <tt>remove()</tt></h5>
|
||||
|
||||
<p>In the standard <tt>libc.a</tt> implementation the <tt>remove()</tt> function
|
||||
will fail if the file is protected by deletion or currently in use.</p>
|
||||
|
||||
<p>In the <tt>libunix.a</tt> implementation the <tt>remove()</tt> function
|
||||
will remove the file when the program exits or the file is closed.</p>
|
||||
|
||||
<h5>5.4.2.10. <tt>abort()</tt></h5>
|
||||
|
||||
<p>The <tt>abort()</tt> function will flush all buffered files,
|
||||
close all the files currently open and delete temporary files.</p>
|
||||
|
||||
<h5>5.4.2.11. <tt>exit()</tt> and <tt>_Exit()</tt></h5>
|
||||
|
||||
<p>The value passed to the <tt>exit()</tt> function will be passed to the
|
||||
Amiga operating system. The value of <tt>EXIT_FAILURE</tt> is equivalent
|
||||
to <tt>RETURN_FAIL</tt> as defined in the Amiga system header file
|
||||
<tt><dos/dos.h></tt>; this value maps to the number 20. The value
|
||||
of <tt>EXIT_SUCCESS</tt> is equivalent to <tt>RETURN_OK</tt> as defined in
|
||||
the Amiga system header file <tt><dos/dos.h></tt>; this value maps to
|
||||
the number 0.</p>
|
||||
|
||||
<p>The <tt>_Exit()</tt> function will flush all buffered files,
|
||||
close all the files currently open and delete temporary files.</p>
|
||||
|
||||
<h5>5.4.2.12. <tt>getenv()</tt></h5>
|
||||
|
||||
<p>Environment data is retrieved from the global Amiga operating system environment
|
||||
storage area through the <tt>dos.library/GetEnv()</tt> function. Global variables are
|
||||
stored in files in the <tt>ENV:</tt> directory.</p>
|
||||
|
||||
<h5>5.4.2.13. <tt>system()</tt></h5>
|
||||
|
||||
<p>If the <tt>command</tt> parameter is not NULL and the <tt>system()</tt> function returns, then the result will
|
||||
be equivalent to the exit code of the program invoked, or -1 if the program could not be started.
|
||||
This follows the behaviour of the Amiga operating system function <tt>dos.library/System()</tt>.
|
||||
A return value of 0 typically indicates successful execution and a value > 0
|
||||
typically indicates failure.</p>
|
||||
|
||||
<h5>5.4.2.14. Time</h5>
|
||||
|
||||
<p>The default time zone is derived from the Amiga operating system locale
|
||||
settings and takes the form <tt>GMT+<i>hh</i></tt> or <tt>GMT-<i>hh</i></tt>,
|
||||
respectively, in which <i>hh</i> stands for the difference between the local
|
||||
time zone and Greenwich Mean Time.</p>
|
||||
|
||||
<p>The <tt>clock_t</tt> and <tt>time_t</tt> types are unsigned 32 bit integers.
|
||||
The <tt>time_t</tt> epoch starts with midnight January 1st, 1970.</p>
|
||||
|
||||
<p>Daylight savings time is not supported.</p>
|
||||
|
||||
<p>The reference point used by the <tt>clock()</tt> function is the time
|
||||
when the program was started.</p>
|
||||
|
||||
<h4>5.4.3. Locale specific behaviour</h4>
|
||||
|
||||
<p>The direction of printing is from left to right.</p>
|
||||
|
||||
<p>The period (.) is the decimal-point character.</p>
|
||||
|
||||
<p>The <tt>strftime()</tt> behaviour follows the Amiga operating system locale
|
||||
settings. If the 'C' locale is in effect, then the output generated by the
|
||||
<tt>%Z</tt> takes the form <tt>GMT+<i>hh</i></tt> or <tt>GMT-<i>hh</i></tt>,
|
||||
respectively, in which <i>hh</i> stands for the difference between the local
|
||||
time zone and Greenwich Mean Time.</p>
|
||||
|
||||
<h2>6. Conventions and design issues</h2>
|
||||
|
||||
<p>You will have noticed the 330+ files in this directory. This is not the best
|
||||
way to organize a runtime library, but at least all the bits and pieces are in
|
||||
plain sight. Each file stands for the one or two routines it contains. The
|
||||
name indicates what routine(s) that might be. Each file name is prefixed by
|
||||
the name of the header file in which the corresponding routine is defined. So,
|
||||
for example, you will find that <tt>unistd_lchown.c</tt> contains the definition of
|
||||
the <tt>lchown()</tt> routine, which has its prototype defined in the <tt><unistd.h></tt> header
|
||||
file.</p>
|
||||
|
||||
<p>Internal function and variables which need to be visible across several
|
||||
modules have names prefixed with two underscores, as in <tt>__stdio_init()</tt>.</p>
|
||||
|
||||
<p>By default all library routines follow the ISO 'C' conventions in that where
|
||||
implementation defined behaviour is permitted, the AmigaOS rules are followed.
|
||||
For example, <tt>unlink()</tt> will by default operate like <tt>DeleteFile()</tt> and <tt>rename()</tt>
|
||||
will return with an error code set if the name of the file/directory to be
|
||||
renamed would collide with an existing directory entry.</p>
|
||||
|
||||
|
||||
<h2>7. The startup code</h2>
|
||||
|
||||
<p>There are three program startup files provided. The most simplistic is in
|
||||
<tt>startup.c</tt> which I use for SAS/C. It just invokes the setup routine which
|
||||
eventually calls <tt>main()</tt> and drops straight into <tt>exit()</tt>.</p>
|
||||
|
||||
<p>The <tt>ncrt0.S</tt> file was adapted from the libnix startup code which sets up the
|
||||
base relative data area, if necessary (the <tt>SMALL_DATA</tt> preprocessor symbol must
|
||||
be defined).</p>
|
||||
|
||||
<p>The <tt>nrcrt0.S</tt> file was adapted from libnix startup code, too, and sets up the
|
||||
base relative data area for programs to be made resident. Note that the
|
||||
<tt>geta4()</tt> stub is missing here; it wouldn't work in a resident program anyway.</p>
|
||||
|
||||
<p>The <tt>ncrt0.S</tt> and <tt>nrcrt0.S</tt> files are considerably smaller and less complex than
|
||||
the libnix code they are based on. This is because in this library design all
|
||||
the more complex tasks are performed in the <tt>stdlib_main.c</tt> file rather than in
|
||||
assembly language.</p>
|
||||
|
||||
|
||||
<h2>8. Documentation</h2>
|
||||
|
||||
<p>Well, you're reading it. There isn't anything much yet. You can consult the book
|
||||
<i>'C' - A reference manual</i> and you could look at the
|
||||
<a href="http://www.opengroup.org/onlinepubs/007904975">Open Group's Single Unix
|
||||
Specification</a>.</p>
|
||||
|
||||
<p>It is recommended to browse the contents of the <tt>include</tt> directory. The
|
||||
header files contain information on library behaviour and not just data type and
|
||||
function prototype definitions. Specifically, the <tt><dos.h></tt> header file
|
||||
contains documentation about special libraries and global variables which may be
|
||||
used or replaced by user code.</p>
|
||||
|
||||
|
||||
<h2>9. Legal status</h2>
|
||||
|
||||
<p>Because this library is in part based upon free software it would be
|
||||
uncourteous not to make it free software itself. The BSD license would
|
||||
probably be appropriate here.</p>
|
||||
|
||||
<p>The PowerPC math library is based in part on work by Sun Microsystems:</p>
|
||||
|
||||
<pre>
|
||||
====================================================
|
||||
Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
|
||||
Developed at SunPro, a Sun Microsystems, Inc. business.
|
||||
Permission to use, copy, modify, and distribute this
|
||||
software is freely granted, provided that this notice
|
||||
is preserved.
|
||||
====================================================
|
||||
</pre>
|
||||
|
||||
<h2>10. Contacting the author</h2>
|
||||
|
||||
<p>The basic work was done by Olaf Barthel during two weeks in July 2002. You
|
||||
can reach me at:</p>
|
||||
|
||||
<p>Olaf Barthel<br>
|
||||
Gneisenaustr. 43<br>
|
||||
D-31275 Lehrte<br></p>
|
||||
|
||||
<p>Or via e-mail:</p>
|
||||
|
||||
<p>olsen [at] sourcery.han.de</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,64 +0,0 @@
|
||||
*asm:
|
||||
%{m68000:-mc68010} %{mc68000:-mc68010} %{m68020:-mc68020} %{mc68020:-mc68020} %{m68030:-mc68030} %{m68040:-mc68040} %{m68060:-mc68060} %{m68020-40:-mc68020} %{m68020-60:-mc68020} %{!mc68000:%{!m68000:%{!mc68020:%{!m68020:%{!m68030:%{!m68040:%{!m68060:%{!m68020-40:%{!m68020-60:-mc68010}}}}}}}}} %{msmall-code:-sc}
|
||||
|
||||
*asm_final:
|
||||
|
||||
|
||||
*cpp:
|
||||
%{m68881:-D__HAVE_68881__} %{!ansi:%{m68020:-Dmc68020} %{mc68020:-Dmc68020} %{m68020-40:-Dmc68020} %{m68020-60:-Dmc68020} %{m68030:-Dmc68030} %{m68040:-Dmc68040} %{m68060:-Dmc68060}} %{m68020:-D__mc68020__ -D__mc68020} %{mc68020:-D__mc68020__ -D__mc68020} %{m68020-40:-D__mc68020__ -D__mc68020} %{m68020-60:-D__mc68020__ -D__mc68020} %{m68030:-D__mc68030__ -D__mc68030} %{m68040:-D__mc68040__ -D__mc68040} %{m68060:-D__mc68060__ -D__mc68060}
|
||||
|
||||
*cc1:
|
||||
%{resident:-fbaserel} %{resident32:-fbaserel32} %{msmall-code:-fno-function-cse}
|
||||
|
||||
*cc1plus:
|
||||
|
||||
|
||||
*endfile:
|
||||
|
||||
|
||||
*link:
|
||||
%{fbaserel:%{!resident:-m amiga_bss -fl libb}} %{resident:-m amiga_bss -amiga-datadata-reloc -fl libb} %{fbaserel32:%{!resident32:-m amiga_bss -fl libb32}} %{resident32:-m amiga_bss -amiga-datadata-reloc -fl libb32} %{g:-amiga-debug-hunk} %{m68020:-fl libm020} %{mc68020:-fl libm020} %{m68030:-fl libm020} %{m68040:-fl libm020} %{m68060:-fl libm020} %{m68020-40:-fl libm020} %{m68020-60:-fl libm020} %{noixemul:}
|
||||
|
||||
*lib:
|
||||
%{mstackextend:-lstack} -lc -lamiga -ldebug -lgcc -lc
|
||||
|
||||
*libgcc:
|
||||
%{mstackextend:-lstack} -lc -lgcc
|
||||
|
||||
*startfile:
|
||||
%{resident32:nr32crt0.o%s}%{!resident32:%{fbaserel32:nb32crt0.o%s}%{!fbaserel32:%{resident:nrcrt0.o%s}%{!resident:%{fbaserel:nbcrt0.o%s}%{!fbaserel:ncrt0.o%s}}}}
|
||||
|
||||
*switches_need_spaces:
|
||||
|
||||
|
||||
*signed_char:
|
||||
%{funsigned-char:-D__CHAR_UNSIGNED__}
|
||||
|
||||
*predefines:
|
||||
-Dmc68000 -Damiga -Damigaos -DMCH_AMIGA -DAMIGA -D__CLIB2__ -D__chip=__attribute__((__chip__)) -D__saveds=__attribute__((__saveds__)) -D__interrupt=__attribute__((__interrupt__)) -D__stackext=__attribute__((__stackext__)) -D__regargs=__attribute__((__regparm__)) -D__stdargs=__attribute__((__stkparm__)) -D__aligned=__attribute__((__aligned__(4))) -Asystem(amigaos) -Acpu(m68k) -Amachine(m68k)
|
||||
|
||||
*cross_compile:
|
||||
0
|
||||
|
||||
*version:
|
||||
2.95.3
|
||||
|
||||
*multilib:
|
||||
. ;
|
||||
|
||||
*multilib_defaults:
|
||||
|
||||
|
||||
*multilib_extra:
|
||||
|
||||
|
||||
*multilib_matches:
|
||||
|
||||
|
||||
*linker:
|
||||
collect2
|
||||
|
||||
*link_command:
|
||||
%{!fsyntax-only: %{!c:%{!M:%{!MM:%{!E:%{!S:%(linker) %l %X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} %{r} %{s} %{t} %{u*} %{x} %{z} %{Z} %{!A:%{!nostdlib:%{!nostartfiles:%S}}} %{static:} %{L*} %D %o %{!nostdlib:%{!nodefaultlibs:%G %L %G}} %{!A:%{!nostdlib:%{!nostartfiles:%E}}} %{T*}
|
||||
}}}}}}
|
||||
|
||||
@@ -1,11 +1,19 @@
|
||||
#
|
||||
# $Id: GNUmakefile.68k,v 1.101 2007-01-06 10:09:48 obarthel Exp $
|
||||
# $Id: GNUmakefile.68k,v 1.107 2010-10-20 13:50:16 obarthel Exp $
|
||||
#
|
||||
# :ts=8
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
|
||||
############################################
|
||||
# find out the HOST operating system
|
||||
# on which this makefile is run (default to AmigaOS)
|
||||
HOST ?= $(shell uname)
|
||||
ifeq ($(HOST),)
|
||||
HOST = AmigaOS
|
||||
endif
|
||||
|
||||
CC = gcc
|
||||
AR = ar -q
|
||||
RANLIB = ranlib
|
||||
@@ -14,6 +22,16 @@ DELETE = delete all quiet
|
||||
MAKEDIR = makedir
|
||||
MAKE = $(MAKE_COMMAND) -f GNUmakefile.68k
|
||||
|
||||
# override certain things for non-native builds
|
||||
ifneq ($(HOST), AmigaOS)
|
||||
CC = m68k-amigaos-gcc
|
||||
AR = m68k-amigaos-ar -q
|
||||
RANLIB = m68k-amigaos-ranlib
|
||||
COPY = cp
|
||||
DELETE = rm -rf
|
||||
MAKEDIR = mkdir -p
|
||||
endif
|
||||
|
||||
##############################################################################
|
||||
|
||||
ifeq (,$(TYPE))
|
||||
@@ -50,11 +68,11 @@ $(LIBUNIX_OBJS)/%.o : %.c
|
||||
|
||||
$(LIBM_OBJS)/%.o : %.c
|
||||
@echo "Compiling $< [$(TYPE):m]"
|
||||
@$(CC) -o $(LIBM_OBJS)/$*.o -c $(CFLAGS) -DIEEE_FLOATING_POINT_SUPPORT $<
|
||||
@$(CC) -o $(LIBM_OBJS)/$*.o -c $(CFLAGS) -msoft-float -DIEEE_FLOATING_POINT_SUPPORT $<
|
||||
|
||||
$(LIBM881_OBJS)/%.o : %.c
|
||||
@echo "Compiling $< [$(TYPE):m881]"
|
||||
@$(CC) -o $(LIBM881_OBJS)/$*.o -c $(CFLAGS) -DM68881_FLOATING_POINT_SUPPORT -m68881 $<
|
||||
@$(CC) -o $(LIBM881_OBJS)/$*.o -c $(CFLAGS) -m68881 -DM68881_FLOATING_POINT_SUPPORT $<
|
||||
|
||||
$(LIBNET_OBJS)/%.o : %.c
|
||||
@echo "Compiling $< [$(TYPE):net]"
|
||||
@@ -109,13 +127,14 @@ INCLUDES = -Iinclude -I. -Inetinclude
|
||||
#OPTIONS = -fno-builtin -fno-common -DNDEBUG -D__THREAD_SAFE
|
||||
#OPTIONS = -fno-builtin -fno-common -D__MEM_DEBUG
|
||||
#OPTIONS = -fno-builtin -fno-common -DDEBUG -D__MEM_DEBUG -DNO_INLINE_STDARG
|
||||
OPTIMIZE = -O -fomit-frame-pointer -fstrength-reduce -finline-functions
|
||||
#OPTIMIZE = -O3 -fomit-frame-pointer -funroll-loops -finline-functions
|
||||
OPTIMIZE = -O -fomit-frame-pointer -fstrength-reduce -finline-functions
|
||||
#OPTIMIZE = -O2 -fomit-frame-pointer
|
||||
#DEBUG = -g
|
||||
|
||||
CFLAGS = \
|
||||
$(WARNINGS) $(OPTIMIZE) $(DEBUG) $(OPTIONS) \
|
||||
$(CODE_FLAGS) $(CODE_TYPE) $(INCLUDES)
|
||||
$(CODE_FLAGS) $(INCLUDES) $(CODE_TYPE)
|
||||
|
||||
##############################################################################
|
||||
|
||||
@@ -350,10 +369,6 @@ C_LIB = \
|
||||
stdlib_shell_escape.o \
|
||||
stdlib_showerror.o \
|
||||
stdlib_srand.o \
|
||||
stdlib_stackargbytes.o \
|
||||
stdlib_stackcheck.o \
|
||||
stdlib_stackoverflow.o \
|
||||
stdlib_stacksafezone.o \
|
||||
stdlib_stacksize.o \
|
||||
stdlib_stack_usage.o \
|
||||
stdlib_arg.o \
|
||||
@@ -1295,8 +1310,6 @@ CONSTRUCTOR_FILES = \
|
||||
stdlib_malloc.c \
|
||||
stdlib_program_name.c \
|
||||
stdlib_setenv.c \
|
||||
stdlib_stackcheck.c \
|
||||
stdlib_stackextension.c \
|
||||
time_clock.c \
|
||||
unistd_chdir_exit.c \
|
||||
unistd_init_exit.c \
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# $Id: GNUmakefile.os4,v 1.111 2007-01-06 10:09:48 obarthel Exp $
|
||||
# $Id: GNUmakefile.os4,v 1.116 2008-11-06 14:44:07 obarthel Exp $
|
||||
#
|
||||
# :ts=8
|
||||
#
|
||||
@@ -26,10 +26,15 @@ NET_INCLUDE := netinclude
|
||||
CC := ppc-amigaos-gcc
|
||||
AR := ppc-amigaos-ar -q
|
||||
RANLIB := ppc-amigaos-ranlib
|
||||
COPY := cp -a
|
||||
COPY := cp -p
|
||||
DELETE := rm -rf
|
||||
MAKEDIR := mkdir -p
|
||||
LOG_COMMAND := 2>&1 | tee -a compiler.log
|
||||
# You may need to request a specific compiler version in order to
|
||||
# build the baserel versions of the library. At this time of
|
||||
# writing (2008-11-06) GCC 4.0.4 and below support the -mbaserel
|
||||
# feature, but more recent versions, including GCC 4.2.4, do not.
|
||||
#COMPILER_VERSION := -V4.0.2
|
||||
|
||||
# The following are for the native OS4 compiler; note that the
|
||||
# LOG_COMMAND should not be enabled unless you have a shell
|
||||
@@ -42,6 +47,7 @@ LOG_COMMAND := 2>&1 | tee -a compiler.log
|
||||
#COPY := copy
|
||||
#DELETE := delete all quiet force
|
||||
#MAKEDIR := makedir all force
|
||||
#COMPILER_VERSION := -V4.0.2
|
||||
#LOG_COMMAND := *>< | tee >>compiler.log
|
||||
|
||||
##############################################################################
|
||||
@@ -53,14 +59,14 @@ WARNINGS := \
|
||||
# -Wconversion -Wshadow
|
||||
|
||||
INCLUDES := -Iinclude -I. -I$(SDK_INCLUDE)
|
||||
OPTIONS := -DUSE_64_BIT_INTS -D__USE_INLINE__ -Wa,-mregnames -fno-common -std=gnu99
|
||||
OPTIONS := -DUSE_64_BIT_INTS -D__USE_INLINE__ -Wa,-mregnames -fno-common -std=gnu99 -mcrt=clib2
|
||||
OPTIMIZE := -DNDEBUG -O3
|
||||
|
||||
#DEBUG := -ggdb
|
||||
#MEMDEBUG := -D__USE_MEM_TREES -D__MEM_DEBUG
|
||||
|
||||
CFLAGS := $(WARNINGS) $(OPTIMIZE) $(DEBUG) $(MEMDEBUG) $(OPTIONS) $(INCLUDES)
|
||||
AFLAGS := -Wa,-mregnames
|
||||
CFLAGS := $(COMPILER_VERSION) $(WARNINGS) $(OPTIMIZE) $(DEBUG) $(MEMDEBUG) $(OPTIONS) $(INCLUDES)
|
||||
AFLAGS := $(COMPILER_VERSION) -Wa,-mregnames
|
||||
|
||||
LARGEDATA := -msdata=data
|
||||
SOFTFLOAT := -msdata=data -msoft-float
|
||||
@@ -212,19 +218,19 @@ lib.threadsafe/baserel/%.o : %.c
|
||||
##############################################################################
|
||||
|
||||
define COMPILE
|
||||
$(MAKEDIR) $(@D)
|
||||
-$(MAKEDIR) $(@D)
|
||||
echo "Compiling $< [$(@D)]"
|
||||
$(CC) -o $@ -c $(CFLAGS) $< $(LOG_COMMAND)
|
||||
$(CC) $(CFLAGS) -o $@ -c $< $(LOG_COMMAND)
|
||||
endef
|
||||
|
||||
define ASSEMBLE
|
||||
$(MAKEDIR) $(@D)
|
||||
-$(MAKEDIR) $(@D)
|
||||
echo "Assembling $< [$(@D)]"
|
||||
$(CC) -o $@ -c $(AFLAGS) $< $(LOG_COMMAND)
|
||||
$(CC) $(AFLAGS) -o $@ -c $< $(LOG_COMMAND)
|
||||
endef
|
||||
|
||||
define MAKELIB
|
||||
$(MAKEDIR) $@
|
||||
-$(MAKEDIR) $@
|
||||
$(DELETE) $@
|
||||
echo "Making $@"
|
||||
$(AR) $@ $^ $(LOG_COMMAND)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#define VERSION 1
|
||||
#define REVISION 202
|
||||
#define DATE "16.1.2007"
|
||||
#define VERS "amiga.lib 1.202"
|
||||
#define VSTRING "amiga.lib 1.202 (16.1.2007)\r\n"
|
||||
#define VERSTAG "\0$VER: amiga.lib 1.202 (16.1.2007)"
|
||||
#define REVISION 205
|
||||
#define DATE "21.8.2010"
|
||||
#define VERS "amiga.lib 1.205"
|
||||
#define VSTRING "amiga.lib 1.205 (21.8.2010)\r\n"
|
||||
#define VERSTAG "\0$VER: amiga.lib 1.205 (21.8.2010)"
|
||||
|
||||
@@ -1 +1 @@
|
||||
202
|
||||
205
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: amiga_argarrayinit.c,v 1.6 2006-09-22 09:02:51 obarthel Exp $
|
||||
* $Id: amiga_argarrayinit.c,v 1.7 2008-09-30 14:09:00 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@@ -52,6 +52,14 @@
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#ifdef __amigaos4__
|
||||
#define MEMORY_TYPE MEMF_PRIVATE
|
||||
#else
|
||||
#define MEMORY_TYPE MEMF_ANY
|
||||
#endif /* __amigaos4__ */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
const unsigned char ** CXLIB_argarray;
|
||||
|
||||
struct DiskObject * CXLIB_disko;
|
||||
@@ -70,7 +78,7 @@ ArgArrayInit(LONG argc, CONST_STRPTR * argv)
|
||||
if(argc == 1)
|
||||
goto out; /* skip command name */
|
||||
|
||||
CXLIB_argarray = (const unsigned char **)AllocVec(sizeof(char *) * argc,MEMF_ANY|MEMF_CLEAR);
|
||||
CXLIB_argarray = (const unsigned char **)AllocVec(sizeof(char *) * argc,MEMORY_TYPE|MEMF_CLEAR);
|
||||
if(CXLIB_argarray == NULL)
|
||||
goto out;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: amiga_rexxvars.c,v 1.10 2006-09-25 18:19:44 obarthel Exp $
|
||||
* $Id: amiga_rexxvars.c,v 1.19 2008-04-18 10:11:59 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@@ -53,6 +53,12 @@
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* This is used by the stub function prototypes. The ARexx header files
|
||||
do not define it, though. */
|
||||
struct Environment;
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#define __NOLIBBASE__
|
||||
#include <proto/rexxsyslib.h>
|
||||
|
||||
@@ -70,7 +76,7 @@ static struct RexxSysIFace * IRexxSys;
|
||||
|
||||
BOOL CheckRexxMsg(struct RexxMsg *message);
|
||||
LONG GetRexxVar(struct RexxMsg *message,STRPTR variable_name,STRPTR *buffer_pointer);
|
||||
LONG SetRexxVar(struct RexxMsg *message,STRPTR variable_name,STRPTR value,ULONG length);
|
||||
LONG SetRexxVar(struct RexxMsg *message,STRPTR variable_name,STRPTR value,LONG length);
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
@@ -142,7 +148,7 @@ CheckRexxMsg(struct RexxMsg *message)
|
||||
if(message->rm_TaskBlock == NULL)
|
||||
goto out;
|
||||
|
||||
if(NOT IsRexxMsg((struct Message *)message))
|
||||
if(NOT IsRexxMsg(message))
|
||||
goto out;
|
||||
|
||||
result = TRUE;
|
||||
@@ -154,56 +160,583 @@ CheckRexxMsg(struct RexxMsg *message)
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* The following function works in about like the original, except that it's
|
||||
not reentrant, does not fill in a pointer to the variable itself and
|
||||
requires rexxsyslib.library V45. */
|
||||
LONG
|
||||
GetRexxVar(struct RexxMsg *message,STRPTR variable_name,STRPTR *buffer_pointer)
|
||||
#if defined(__amigaos4__)
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#include <exec/emulation.h>
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
STATIC VOID
|
||||
_FreeSpace(struct Environment * env,APTR mem,LONG size)
|
||||
{
|
||||
static TEXT buffer[256];
|
||||
STATIC CONST UWORD code[] = { 0x4EAE,0xFF88,0x4E75 }; /* jsr -120(a6) ; rts */
|
||||
|
||||
EmulateTags(code,
|
||||
ET_RegisterA0,env,
|
||||
ET_RegisterA1,mem,
|
||||
ET_RegisterD0,size,
|
||||
ET_RegisterA6,RexxSysBase,
|
||||
TAG_END);
|
||||
}
|
||||
|
||||
STATIC APTR
|
||||
_GetSpace(struct Environment * env,LONG size)
|
||||
{
|
||||
STATIC CONST UWORD code[] = { 0x4EAE,0xFF8E,0x4E75 }; /* jsr -114(a6) ; rts */
|
||||
APTR result;
|
||||
|
||||
result = (APTR)EmulateTags(code,
|
||||
ET_RegisterA0,env,
|
||||
ET_RegisterD0,size,
|
||||
ET_RegisterA6,RexxSysBase,
|
||||
TAG_END);
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
STATIC LONG
|
||||
_IsSymbol(STRPTR name,LONG * symbol_length_ptr)
|
||||
{
|
||||
STATIC CONST UWORD code[] = { 0x4EAE,0xFF9A,0x2481,0x4E75 }; /* jsr -102(a6) ; move.l d1,(a2) ; rts */
|
||||
LONG result;
|
||||
|
||||
/* The following uses a function which was added to rexxsyslib.library V45.
|
||||
We therefore have a minimum library version requirement. */
|
||||
if(RexxSysBase == NULL || RexxSysBase->lib_Version < 45 || NOT IsRexxMsg((struct Message *)message))
|
||||
{
|
||||
result = ERR10_010; /* invalid message packet */
|
||||
goto out;
|
||||
}
|
||||
result = (LONG)EmulateTags(code,
|
||||
ET_RegisterA0,name,
|
||||
ET_RegisterA2,symbol_length_ptr,
|
||||
ET_RegisterA6,RexxSysBase,
|
||||
TAG_END);
|
||||
|
||||
/* The 256 character limit isn't good. This should be done differently. */
|
||||
result = GetRexxVarFromMsg(variable_name,buffer,message);
|
||||
if(result != 0)
|
||||
goto out;
|
||||
return(result);
|
||||
}
|
||||
|
||||
(*buffer_pointer) = buffer;
|
||||
STATIC VOID
|
||||
_CurrentEnv(struct RexxTask *task,struct Environment ** environment_ptr)
|
||||
{
|
||||
STATIC CONST UWORD code[] = { 0x4EAE,0xFF94,0x2488,0x4E75 }; /* jsr -108(a6) ; move.l a0,(a2) ; rts */
|
||||
|
||||
out:
|
||||
EmulateTags(code,
|
||||
ET_RegisterA0,task,
|
||||
ET_RegisterA2,environment_ptr,
|
||||
ET_RegisterA6,RexxSysBase,
|
||||
TAG_END);
|
||||
}
|
||||
|
||||
STATIC struct Node *
|
||||
_FetchValue(struct Environment * env,struct NexxStr * stem,struct NexxStr * compound,struct Node *symbol_table_node,LONG * is_literal_ptr,struct NexxStr ** value_ptr)
|
||||
{
|
||||
STATIC CONST UWORD code[] = { 0x4EAE,0xFFB8,0x2488,0x2681,0x4E75 }; /* jsr -72(a6) ; move.l a0,(a2) ; move.l d1,(a3) ; rts */
|
||||
struct Node * result;
|
||||
|
||||
result = (struct Node *)EmulateTags(code,
|
||||
ET_RegisterA0,env,
|
||||
ET_RegisterA1,stem,
|
||||
ET_RegisterD0,compound,
|
||||
ET_RegisterD1,symbol_table_node,
|
||||
ET_RegisterA2,is_literal_ptr,
|
||||
ET_RegisterA3,value_ptr,
|
||||
ET_RegisterA6,RexxSysBase,
|
||||
TAG_END);
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
STATIC struct Node *
|
||||
_EnterSymbol(struct Environment * env,struct NexxStr * stem,struct NexxStr * compound)
|
||||
{
|
||||
STATIC CONST UWORD code[] = { 0x4EAE,0xFFBE,0x4E75 }; /* jsr -66(a6) ; rts */
|
||||
struct Node * result;
|
||||
|
||||
result = (struct Node *)EmulateTags(code,
|
||||
ET_RegisterA0,env,
|
||||
ET_RegisterA1,stem,
|
||||
ET_RegisterD0,compound,
|
||||
ET_RegisterA6,RexxSysBase,
|
||||
TAG_END);
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
STATIC VOID
|
||||
_SetValue(struct Environment * env,struct NexxStr * value,struct Node * symbol_table_node)
|
||||
{
|
||||
STATIC CONST UWORD code[] = { 0x4EAE,0xFFAC,0x4E75 }; /* jsr -84(a6) ; rts */
|
||||
struct Node * result;
|
||||
|
||||
result = (struct Node *)EmulateTags(code,
|
||||
ET_RegisterA0,env,
|
||||
ET_RegisterA1,value,
|
||||
ET_RegisterD0,symbol_table_node,
|
||||
ET_RegisterA6,RexxSysBase,
|
||||
TAG_END);
|
||||
}
|
||||
|
||||
STATIC ULONG
|
||||
_StrcpyN(STRPTR destination,STRPTR source,LONG length)
|
||||
{
|
||||
STATIC CONST UWORD code[] = { 0x4EAE,0xFEF2,0x4E75 }; /* jsr -270(a6) ; rts */
|
||||
ULONG result;
|
||||
|
||||
result = (ULONG)EmulateTags(code,
|
||||
ET_RegisterA0,destination,
|
||||
ET_RegisterA1,source,
|
||||
ET_RegisterD0,length,
|
||||
ET_RegisterA6,RexxSysBase,
|
||||
TAG_END);
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* The following function works in about like the original, except that it
|
||||
ignores the length parameter (the value needs to be a NUL-terminated string)
|
||||
and requires rexxsyslib.library V45. */
|
||||
LONG
|
||||
SetRexxVar(struct RexxMsg *message,STRPTR variable_name,STRPTR value,ULONG length)
|
||||
#elif defined(__GNUC__) && !defined(__amigaos4__)
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* A selection of lovingly hand-crafted 68k stub functions which call
|
||||
into rexxsyslib.library LVOs that still used to be documented back
|
||||
in 1987. */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#if defined(SMALL_DATA)
|
||||
#define A4(x) "a4@(" #x ":W)"
|
||||
#elif defined(SMALL_DATA32)
|
||||
#define A4(x) "a4@(" #x ":L)"
|
||||
#else
|
||||
#define A4(x) #x
|
||||
#endif /* SMALL_DATA */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* struct Environment * a0,APTR block a1,LONG d0 */
|
||||
asm("
|
||||
|
||||
.text
|
||||
.even
|
||||
|
||||
.globl __FreeSpace
|
||||
|
||||
__FreeSpace:
|
||||
|
||||
moveal sp@(4),a0
|
||||
moveal sp@(8),a1
|
||||
movel sp@(12),d0
|
||||
|
||||
movel a6,sp@-
|
||||
moveal "A4(_RexxSysBase)",a6
|
||||
jsr a6@(-120)
|
||||
moveal sp@+,a6
|
||||
|
||||
rts
|
||||
|
||||
");
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* struct Environment * a0,LONG d0 : APTR d0 */
|
||||
asm("
|
||||
|
||||
.text
|
||||
.even
|
||||
|
||||
.globl __GetSpace
|
||||
|
||||
__GetSpace:
|
||||
|
||||
moveal sp@(4),a0
|
||||
movel sp@(8),d0
|
||||
|
||||
movel a6,sp@-
|
||||
moveal "A4(_RexxSysBase)",a6
|
||||
jsr a6@(-114)
|
||||
moveal sp@+,a6
|
||||
|
||||
rts
|
||||
|
||||
");
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* STRPTR a0 : LONG d0, LONG d1 */
|
||||
asm("
|
||||
|
||||
.text
|
||||
.even
|
||||
|
||||
.globl __IsSymbol
|
||||
|
||||
__IsSymbol:
|
||||
|
||||
moveal sp@(4),a0
|
||||
|
||||
movel a6,sp@-
|
||||
moveal "A4(_RexxSysBase)",a6
|
||||
jsr a6@(-102)
|
||||
moveal sp@+,a6
|
||||
|
||||
moveal sp@(8),a1
|
||||
movel d1,a1@
|
||||
|
||||
rts
|
||||
|
||||
");
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* struct RexxTask * a0 : struct Environment * a0 */
|
||||
asm("
|
||||
|
||||
.text
|
||||
.even
|
||||
|
||||
.globl __CurrentEnv
|
||||
|
||||
__CurrentEnv:
|
||||
|
||||
moveal sp@(4),a0
|
||||
|
||||
movel a6,sp@-
|
||||
moveal "A4(_RexxSysBase)",a6
|
||||
jsr a6@(-108)
|
||||
moveal sp@+,a6
|
||||
|
||||
moveal sp@(8),a1
|
||||
movel a0,a1@
|
||||
|
||||
rts
|
||||
|
||||
");
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* struct Environment * a0,struct NexxStr * a1,struct NexxStr * d0,struct Node * d1 : struct NexxStr * a0, LONG d1 */
|
||||
asm("
|
||||
|
||||
.text
|
||||
.even
|
||||
|
||||
.globl __FetchValue
|
||||
|
||||
__FetchValue:
|
||||
|
||||
moveal sp@(4),a0
|
||||
moveal sp@(8),a1
|
||||
movel sp@(12),d0
|
||||
movel sp@(16),d1
|
||||
|
||||
movel a6,sp@-
|
||||
moveal "A4(_RexxSysBase)",a6
|
||||
jsr a6@(-72)
|
||||
moveal sp@+,a6
|
||||
|
||||
moveal sp@(20),a1
|
||||
movel a0,a1@
|
||||
moveal sp@(24),a1
|
||||
movel d1,a1@
|
||||
|
||||
rts
|
||||
|
||||
");
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* struct Environment a0, struct NexxStr *a1, struct NexxStr * d0 : struct Node * d0 */
|
||||
asm("
|
||||
|
||||
.text
|
||||
.even
|
||||
|
||||
.globl __EnterSymbol
|
||||
|
||||
__EnterSymbol:
|
||||
|
||||
moveal sp@(4),a0
|
||||
moveal sp@(8),a1
|
||||
movel sp@(12),d0
|
||||
|
||||
movel a6,sp@-
|
||||
moveal "A4(_RexxSysBase)",a6
|
||||
jsr a6@(-66)
|
||||
moveal sp@+,a6
|
||||
|
||||
rts
|
||||
|
||||
");
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* struct Environment *a0, struct NexxStr *a1, struct Node * d0 */
|
||||
asm("
|
||||
|
||||
.text
|
||||
.even
|
||||
|
||||
.globl __SetValue
|
||||
|
||||
__SetValue:
|
||||
|
||||
moveal sp@(4),a0
|
||||
moveal sp@(8),a1
|
||||
movel sp@(12),d0
|
||||
|
||||
movel a6,sp@-
|
||||
moveal "A4(_RexxSysBase)",a6
|
||||
jsr a6@(-84)
|
||||
moveal sp@+,a6
|
||||
|
||||
rts
|
||||
|
||||
");
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* STRPTR a0,STRPTR a1,LONG d0 : ULONG d0 */
|
||||
asm("
|
||||
|
||||
.text
|
||||
.even
|
||||
|
||||
.globl __StrcpyN
|
||||
|
||||
__StrcpyN:
|
||||
|
||||
moveal sp@(4),a0
|
||||
moveal sp@(8),a1
|
||||
movel sp@(12),d0
|
||||
|
||||
movel a6,sp@-
|
||||
moveal "A4(_RexxSysBase)",a6
|
||||
jsr a6@(-270)
|
||||
moveal sp@+,a6
|
||||
|
||||
rts
|
||||
|
||||
");
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* Function prototypes for the 68k stubs. */
|
||||
extern VOID _FreeSpace(struct Environment * env,APTR mem,LONG size);
|
||||
extern APTR _GetSpace(struct Environment * env,LONG size);
|
||||
extern LONG _IsSymbol(STRPTR name,LONG * symbol_length_ptr);
|
||||
extern VOID _CurrentEnv(struct RexxTask *task,struct Environment ** environment_ptr);
|
||||
extern struct Node * _FetchValue(struct Environment * env,struct NexxStr * stem,struct NexxStr * compound,struct Node *symbol_table_node,LONG * is_literal_ptr,struct NexxStr ** value_ptr);
|
||||
extern struct Node * _EnterSymbol(struct Environment * env,struct NexxStr * stem,struct NexxStr * compound);
|
||||
extern VOID _SetValue(struct Environment * env,struct NexxStr * value,struct Node * symbol_table_node);
|
||||
extern ULONG _StrcpyN(STRPTR destination,STRPTR source,LONG length);
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#endif /* __GNUC__ && !__amigaos4__ */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* Releases a string structure, if it's not owned at the time. */
|
||||
STATIC VOID
|
||||
FreeString(struct Environment * environment,struct NexxStr * ns)
|
||||
{
|
||||
LONG result;
|
||||
/* Not currently owned? */
|
||||
if(!(ns->ns_Flags & NSF_KEEP))
|
||||
_FreeSpace(environment,ns,sizeof(*ns) + ns->ns_Length + 1);
|
||||
}
|
||||
|
||||
/* The following uses a function which was added to rexxsyslib.library V45.
|
||||
We therefore have a minimum library version requirement. */
|
||||
if(RexxSysBase == NULL || RexxSysBase->lib_Version < 45 || NOT IsRexxMsg((struct Message *)message))
|
||||
{
|
||||
result = ERR10_010; /* invalid message packet */
|
||||
/****************************************************************************/
|
||||
|
||||
/* Allocates and initializes a string structure. */
|
||||
STATIC struct NexxStr *
|
||||
MakeString(struct Environment * environment,STRPTR value,LONG length)
|
||||
{
|
||||
struct NexxStr * result = NULL;
|
||||
struct NexxStr * ns;
|
||||
|
||||
/* Allocate memory for the NexxStr and the NUL-terminated string itself. */
|
||||
ns = _GetSpace(environment,sizeof(*ns) + length + 1);
|
||||
if(ns == NULL)
|
||||
goto out;
|
||||
}
|
||||
|
||||
result = SetRexxVarFromMsg(variable_name,value,message);
|
||||
/* Fill in the NexxStr structure, copy the string and remember the hash value for it. */
|
||||
ns->ns_Ivalue = 0;
|
||||
ns->ns_Length = length;
|
||||
ns->ns_Flags = NSF_STRING;
|
||||
ns->ns_Hash = _StrcpyN((STRPTR)ns->ns_Buff,value,length);
|
||||
|
||||
out:
|
||||
/* Copying the string did not NUL-terminate it. */
|
||||
ns->ns_Buff[length] = '\0';
|
||||
|
||||
result = ns;
|
||||
|
||||
out:
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* Classifies a symbol and returns the stem and compound parts. */
|
||||
STATIC LONG
|
||||
TypeString(STRPTR variable_name,struct Environment * environment,struct NexxStr ** compound_ptr,struct NexxStr ** stem_ptr)
|
||||
{
|
||||
struct NexxStr * compound;
|
||||
struct NexxStr * stem = NULL;
|
||||
LONG error = ERR10_003; /* no memory available */
|
||||
LONG stem_length;
|
||||
LONG symbol_length;
|
||||
STRPTR dot;
|
||||
|
||||
(*compound_ptr) = NULL;
|
||||
(*stem_ptr) = NULL;
|
||||
|
||||
/* The 'compound' part is the entire variable name, including all dots and
|
||||
what's in between them. */
|
||||
compound = MakeString(environment,variable_name,strlen(variable_name));
|
||||
if(compound == NULL)
|
||||
goto out;
|
||||
|
||||
/* Find the first dot in the variable name. Everything in front of it
|
||||
and including the dot constitutes the 'stem' part. If there is no dot
|
||||
in the name, then the 'compound' and 'stem' parts are identical. */
|
||||
dot = memchr(compound->ns_Buff,'.',compound->ns_Length);
|
||||
if(dot != NULL)
|
||||
stem_length = ((char *)dot - (char *)compound->ns_Buff) + 1;
|
||||
else
|
||||
stem_length = compound->ns_Length;
|
||||
|
||||
/* Make a copy of the 'stem' part. */
|
||||
stem = MakeString(environment,variable_name,stem_length);
|
||||
if(stem == NULL)
|
||||
goto out;
|
||||
|
||||
/* Figure out if this is a symbol after all. */
|
||||
_IsSymbol((STRPTR)stem->ns_Buff,&symbol_length);
|
||||
|
||||
/* The entire name must match the stem part. */
|
||||
if(symbol_length != stem->ns_Length)
|
||||
{
|
||||
error = ERR10_040; /* invalid variable name */
|
||||
goto out;
|
||||
}
|
||||
|
||||
(*compound_ptr) = compound;
|
||||
(*stem_ptr) = stem;
|
||||
|
||||
error = 0;
|
||||
|
||||
out:
|
||||
|
||||
if(error != 0)
|
||||
{
|
||||
if(compound != NULL)
|
||||
FreeString(environment,compound);
|
||||
|
||||
if(stem != NULL)
|
||||
FreeString(environment,stem);
|
||||
}
|
||||
|
||||
return(error);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* Retrieves the value of a variable from the current storage environment. */
|
||||
LONG
|
||||
GetRexxVar(struct RexxMsg *context,STRPTR variable_name,STRPTR * return_value)
|
||||
{
|
||||
struct Environment * environment;
|
||||
struct NexxStr * ns;
|
||||
struct NexxStr * compound_string;
|
||||
struct NexxStr * stem_string;
|
||||
LONG is_literal;
|
||||
LONG error;
|
||||
|
||||
(*return_value) = NULL;
|
||||
|
||||
if(!CheckRexxMsg(context))
|
||||
{
|
||||
error = ERR10_010; /* invalid message packet */
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Find the current storage environment. */
|
||||
_CurrentEnv(context->rm_TaskBlock,&environment);
|
||||
|
||||
/* Create the stem and component parts. */
|
||||
error = TypeString(variable_name,environment,&compound_string,&stem_string);
|
||||
if(error != 0)
|
||||
goto out;
|
||||
|
||||
/* Look up the value. NOTE: _FetchValue() will free the two 'struct NexxStr *' provided. */
|
||||
_FetchValue(environment,stem_string,compound_string,NULL,&is_literal,&ns);
|
||||
|
||||
/* If this is not a literal, return a pointer to the string. */
|
||||
if(!is_literal)
|
||||
(*return_value) = (STRPTR)ns->ns_Buff;
|
||||
|
||||
error = 0;
|
||||
|
||||
out:
|
||||
|
||||
return(error);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* Assigns a value to a variable in the current storage environment. */
|
||||
LONG
|
||||
SetRexxVar(struct RexxMsg *context,STRPTR variable_name,STRPTR value,LONG length)
|
||||
{
|
||||
struct Environment * environment;
|
||||
struct NexxStr * compound_string;
|
||||
struct NexxStr * stem_string;
|
||||
struct Node * symbol_table_node;
|
||||
struct NexxStr *value_string;
|
||||
LONG error;
|
||||
|
||||
/* Make sure the value string is not too long */
|
||||
if(length > 65535)
|
||||
{
|
||||
error = ERR10_009; /* symbol or string too long */
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(!CheckRexxMsg(context))
|
||||
{
|
||||
error = ERR10_010; /* invalid message packet */
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Find the current storage environment. */
|
||||
_CurrentEnv(context->rm_TaskBlock,&environment);
|
||||
|
||||
/* Create the stem and compound parts */
|
||||
error = TypeString(variable_name,environment,&compound_string,&stem_string);
|
||||
if(error != 0)
|
||||
goto out;
|
||||
|
||||
/* Locate or create the symbol node. NOTE: _EnterSymbol() will put the two 'struct NexxStr *' into
|
||||
the symbol table. It is not nececessary to free them. */
|
||||
symbol_table_node = _EnterSymbol(environment,stem_string,compound_string);
|
||||
if(symbol_table_node == NULL)
|
||||
{
|
||||
error = ERR10_003; /* no memory available */
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Create the value string. */
|
||||
value_string = MakeString(environment,value,length);
|
||||
if(value_string == NULL)
|
||||
{
|
||||
error = ERR10_003; /* no memory available */
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Install the value string. */
|
||||
_SetValue(environment,value_string,symbol_table_node);
|
||||
|
||||
error = 0;
|
||||
|
||||
out:
|
||||
|
||||
return(error);
|
||||
}
|
||||
|
||||
@@ -13,9 +13,9 @@ rm -rf $dir_name
|
||||
# Create the directory, copy all the libraries, header files
|
||||
# and release note files inside.
|
||||
mkdir $dir_name
|
||||
cp -a lib $dir_name
|
||||
cp -a lib.threadsafe $dir_name
|
||||
cp -a include $dir_name
|
||||
cp -pR lib $dir_name
|
||||
cp -pR lib.threadsafe $dir_name
|
||||
cp -pR include $dir_name
|
||||
cp changes $dir_name
|
||||
|
||||
# Delete the CVS data from the include directory
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#define VERSION 1
|
||||
#define REVISION 202
|
||||
#define DATE "16.1.2007"
|
||||
#define VERS "c.lib 1.202"
|
||||
#define VSTRING "c.lib 1.202 (16.1.2007)\r\n"
|
||||
#define VERSTAG "\0$VER: c.lib 1.202 (16.1.2007)"
|
||||
#define REVISION 206
|
||||
#define DATE "24.4.2015"
|
||||
#define VERS "c.lib 1.206"
|
||||
#define VSTRING "c.lib 1.206 (24.4.2015)\r\n"
|
||||
#define VERSTAG "\0$VER: c.lib 1.206 (24.4.2015)"
|
||||
|
||||
@@ -1 +1 @@
|
||||
202
|
||||
206
|
||||
|
||||
108
library/changes
108
library/changes
@@ -1,3 +1,111 @@
|
||||
m.lib 1.206 (24.4.2015)
|
||||
|
||||
- The fscanf() family failed to parse and convert %f parameters correctly
|
||||
if the respective number did not begin with a digit, but a decimal
|
||||
point. Hence ".7" would not be processed, but "0.7" would.
|
||||
|
||||
c.lib 1.206 (24.4.2015)
|
||||
|
||||
- Reworked the __putc() and putc() macros to reference the 'c' input
|
||||
parameter only once, and to be free of side-effects when tinkering
|
||||
with the buffer position.
|
||||
|
||||
- isatty() had the __fd_lock() call in the wrong place, which could have
|
||||
led to cleanup problems later.
|
||||
|
||||
- The close action in the stdio, socket and termios hook code now
|
||||
also zaps the fd pointer itself after cleaning up the file descriptor
|
||||
table entry.
|
||||
|
||||
- Removed the remains of all the stack extension and stack overflow/underflow
|
||||
checking code. It never actually worked. The bit that does work is the stack
|
||||
usage measurement code, plus the bit that sets up the the custom stack
|
||||
according to local setting or by calling a query function.
|
||||
|
||||
|
||||
c.lib 1.205 (21.8.2010)
|
||||
|
||||
- Added dlclose(), dlerror(), dlopen() and dlsym() functions, which are
|
||||
available only under OS4. There is a variant of dlopen() in libunix.a
|
||||
which will perform a path name conversion. Note that these functions
|
||||
will not work in the thread-safe variant of the library because it
|
||||
would be unwise to tinker with the currently running program's binary.
|
||||
|
||||
- Added support for ELF shared objects and libraries. This is implemented through
|
||||
constructor/destructor functions, which means that you can use this
|
||||
functionality even in Amiga Exec style shared libraries, with the proper
|
||||
library initialization code to invoke the constructor/destructor functions
|
||||
for you.
|
||||
|
||||
- Updated uname() to recognize AmigaOS 4.1.
|
||||
|
||||
- The translation from Unix to Amiga path names did not properly process
|
||||
multiple occurences of "/./" in the path name. Thanks go to Steven Solie
|
||||
for finding the issue.
|
||||
|
||||
- The detection of "/./" and "/../" patterns in Unix path names to be
|
||||
translated into Amiga path names did not test if it was overrunning
|
||||
the end of the string.
|
||||
|
||||
- If strcmp(), strncmp() and memcmp() detect a pair of different
|
||||
characters, then the function result must be calculated as if the
|
||||
characters were of type "unsigned char". This is a requirement
|
||||
according to the ISO 'C' (1994) standard. Thanks go to Georg Steger
|
||||
for finding the issue.
|
||||
|
||||
- The definitions for INT_MIN, INT_MAX and UINT_MAX in <limits.h> no
|
||||
longer use long integer types, as prompted by Steven Solie.
|
||||
|
||||
|
||||
c.lib 1.204 (11.11.2008)
|
||||
|
||||
- The memory allocated by malloc() and friends is now of type MEMF_PRIVATE
|
||||
under OS4 and beyond. The AmigaOS 2.x/3.x compatible code will still
|
||||
use MEMF_ANY in the same situation, though. Other uses of MEMF_ANY have
|
||||
been replaced as well where MEMF_PRIVATE would have made better sense.
|
||||
|
||||
- I/O buffers allocated are now aligned according to the CPU cache line size,
|
||||
if the operating system can supply such detailed information.
|
||||
|
||||
- unsetenv() now returns a status value.
|
||||
|
||||
- Corrected the function prototype for wcspbrk().
|
||||
|
||||
- Added function prototypes for mbrtowc_l(), wcscoll_l(), wcscspn() and wcsrchr().
|
||||
|
||||
|
||||
c.lib 1.203 (28.4.2008)
|
||||
|
||||
- Added 68k stubs to amiga_rexxvars.c for the OS4 build to use. The new code now
|
||||
works just about exactly like the amiga.lib RVI code used to do, which means
|
||||
that there is no artificial length limit for the number of characters a string
|
||||
retrieved may have, and the code is largely reentrant.
|
||||
|
||||
- To work around a bug in the Roadshow TCP/IP stack (since fixed), the waitselect()
|
||||
function now substitutes a 10 microsecond timeout for a zero length timeout.
|
||||
|
||||
- isatty() no longer crashes if passed a socket rather than a file.
|
||||
|
||||
- Rewrote the GetRexxVar()/SetRexxVar() functions (mostly) in 'C', using available
|
||||
code as a reference. The 68k stubs currently only work for the 68k version of
|
||||
the library, and a solution for the OS4 build still needs to be found. The code
|
||||
is currently untested, but it should be complete.
|
||||
|
||||
- The printf() family now ignores argument specifications, as in "%2$d %1$d",
|
||||
which are used for localization on some platforms. This is a non-standard
|
||||
feature and the way clib2 treats it for now is just intended to avoid
|
||||
trouble while performing the conversion.
|
||||
|
||||
- [tboeckel]: when compiling amiga_rexxvars.c for m68k/OS3 the GetRexxVarFromMsg()
|
||||
and SetRexxVarFromMsg() can no longer cause linkage errors if the header files
|
||||
predate the SDK for OS 3.5.
|
||||
|
||||
- [jlangner]: the log() and log10() functions always returned -inf() even if the
|
||||
arguments was within the valid range for a log() function. Using DBL_EPSILON as
|
||||
the threshold was not correct as EPSILON is 2.2204460492503131E-16 whereas
|
||||
values like 1E-200 are still valid double values for a log().
|
||||
|
||||
|
||||
c.lib 1.202 (16.1.2007)
|
||||
|
||||
- Added llrint() function contributed by Henning Nielsen Lund. Thank you
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: crtbegin.c,v 1.11 2006-09-22 09:02:51 obarthel Exp $
|
||||
* $Id: crtbegin.c,v 1.13 2010-08-21 11:37:03 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@@ -35,9 +35,14 @@ void _fini(void);
|
||||
void
|
||||
_init(void)
|
||||
{
|
||||
extern void shared_obj_init(void);
|
||||
int num_ctors,i;
|
||||
int j;
|
||||
|
||||
/* The shared objects need to be set up before any local
|
||||
constructors are invoked. */
|
||||
shared_obj_init();
|
||||
|
||||
for(i = 1, num_ctors = 0 ; __CTOR_LIST__[i] != NULL ; i++)
|
||||
num_ctors++;
|
||||
|
||||
@@ -50,6 +55,7 @@ _init(void)
|
||||
void
|
||||
_fini(void)
|
||||
{
|
||||
extern void shared_obj_exit(void);
|
||||
int num_dtors,i;
|
||||
static int j;
|
||||
|
||||
@@ -58,6 +64,10 @@ _fini(void)
|
||||
|
||||
while(j++ < num_dtors)
|
||||
__DTOR_LIST__[j]();
|
||||
|
||||
/* The shared objects need to be cleaned up after all local
|
||||
destructors have been invoked. */
|
||||
shared_obj_exit();
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#define VERSION 1
|
||||
#define REVISION 202
|
||||
#define DATE "16.1.2007"
|
||||
#define VERS "debug.lib 1.202"
|
||||
#define VSTRING "debug.lib 1.202 (16.1.2007)\r\n"
|
||||
#define VERSTAG "\0$VER: debug.lib 1.202 (16.1.2007)"
|
||||
#define REVISION 205
|
||||
#define DATE "21.8.2010"
|
||||
#define VERS "debug.lib 1.205"
|
||||
#define VSTRING "debug.lib 1.205 (21.8.2010)\r\n"
|
||||
#define VERSTAG "\0$VER: debug.lib 1.205 (21.8.2010)"
|
||||
|
||||
@@ -1 +1 @@
|
||||
202
|
||||
205
|
||||
|
||||
87
library/include/dlfcn.h
Normal file
87
library/include/dlfcn.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* $Id: dlfcn.h,v 1.2 2010-08-21 11:37:03 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
* Portable ISO 'C' (1994) runtime library for the Amiga computer
|
||||
* Copyright (c) 2002-2010 by Olaf Barthel <olsen (at) sourcery.han.de>
|
||||
* 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 <http://sourceforge.net/projects/clib2>.
|
||||
*
|
||||
*****************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _DLFCN_H
|
||||
#define _DLFCN_H
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* The following is not part of the ISO 'C' (1994) standard. */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* The shared object API is available only on AmigaOS 4.0. */
|
||||
#if defined(__amigaos4__)
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* We only support a subset of the flags available on Unix systems. */
|
||||
#define RTLD_LAZY 1
|
||||
#define RTLD_NOW 2
|
||||
#define RTLD_LOCAL 4
|
||||
#define RTLD_GLOBAL 8
|
||||
#define RTLD_DEFAULT ((void *)0)
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
extern int dlclose(void * __handle);
|
||||
extern const char * dlerror(void);
|
||||
extern void * dlopen(const char * __path_name,int __mode);
|
||||
extern void * dlsym(void * __handle,const char * __symbol_name);
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#endif /* __amigaos4__ */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#endif /* _DLFCN_H */
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: limits.h,v 1.11 2006-01-08 12:06:14 obarthel Exp $
|
||||
* $Id: limits.h,v 1.12 2010-08-20 15:33:36 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@@ -78,9 +78,9 @@
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#define INT_MIN (-2147483647L - 1)
|
||||
#define INT_MAX 2147483647L
|
||||
#define UINT_MAX 4294967295UL
|
||||
#define INT_MIN (-2147483647 - 1)
|
||||
#define INT_MAX 2147483647
|
||||
#define UINT_MAX 4294967295U
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
@@ -109,7 +109,7 @@
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#define SSIZE_MAX 2147483647L
|
||||
#define SSIZE_MAX LONG_MAX
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: stdio.h,v 1.22 2006-03-06 08:43:48 obarthel Exp $
|
||||
* $Id: stdio.h,v 1.24 2010-10-20 13:12:59 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@@ -285,11 +285,11 @@ extern char *tmpnam(char *buf);
|
||||
(((((FILE *)(f))->flags & (__FILE_IN_USE|__FILE_WRITABLE)) == (__FILE_IN_USE|__FILE_WRITABLE) && \
|
||||
(((FILE *)(f))->flags & __FILE_BUFFER_MASK) != _IONBF && \
|
||||
(((FILE *)(f))->num_write_bytes < ((FILE *)(f))->size)) ? \
|
||||
(((FILE *)(f))->buffer[((FILE *)(f))->num_write_bytes++] = (c), \
|
||||
(((FILE *)(f))->buffer[((FILE *)(f))->num_write_bytes] = (c), \
|
||||
(((((FILE *)(f))->flags & __FILE_BUFFER_MASK) == _IOLBF && \
|
||||
((FILE *)(f))->buffer[((FILE *)(f))->num_write_bytes-1] == '\n') ? \
|
||||
__flush(f) : \
|
||||
(((FILE *)(f))->buffer[((FILE *)(f))->num_write_bytes-1]))) : \
|
||||
((FILE *)(f))->buffer[((FILE *)(f))->num_write_bytes] == '\n') ? \
|
||||
((FILE *)(f))->num_write_bytes++, __flush(f) : \
|
||||
((FILE *)(f))->buffer[((FILE *)(f))->num_write_bytes++])) : \
|
||||
fputc((c),(f)))
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: stdlib.h,v 1.18 2006-11-13 09:51:53 obarthel Exp $
|
||||
* $Id: stdlib.h,v 1.19 2008-04-30 14:34:03 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@@ -195,7 +195,7 @@ extern int rand_r(unsigned int * seed);
|
||||
|
||||
extern int setenv(const char *name, const char *value, int overwrite);
|
||||
extern int putenv(const char *string);
|
||||
extern void unsetenv(const char *name);
|
||||
extern int unsetenv(const char *name);
|
||||
extern char * mktemp(char * name_template);
|
||||
extern int mkstemp(char *name_template);
|
||||
extern char * mkdtemp(char *name_template);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: wchar.h,v 1.7 2006-01-08 12:06:14 obarthel Exp $
|
||||
* $Id: wchar.h,v 1.8 2008-04-30 14:34:03 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@@ -97,7 +97,7 @@ extern wchar_t * wcsncpy(wchar_t *dest, const wchar_t *src, size_t n);
|
||||
extern size_t wcslen(const wchar_t *s);
|
||||
extern wchar_t * wcschr(const wchar_t *s, wchar_t c);
|
||||
extern size_t wcsspn(const wchar_t *s, const wchar_t *set);
|
||||
extern wchar_t wcspbrk(const wchar_t *s, const wchar_t *set);
|
||||
extern wchar_t *wcspbrk(const wchar_t *s, const wchar_t *set);
|
||||
extern wchar_t *wcstok(wchar_t *str, const wchar_t *set);
|
||||
extern wchar_t *wcsstr(const wchar_t *src, const wchar_t *sub);
|
||||
|
||||
@@ -179,6 +179,11 @@ extern size_t wcsftime(wchar_t *s, size_t maxsize, const wchar_t *format, const
|
||||
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 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 */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: wctype.h,v 1.7 2006-01-08 12:06:14 obarthel Exp $
|
||||
* $Id: wctype.h,v 1.8 2008-04-30 14:41:28 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@@ -68,7 +68,7 @@ extern int iswdigit(wint_t c);
|
||||
extern int iswxdigit(wint_t c);
|
||||
|
||||
extern int iswgraph(wint_t c);
|
||||
extern int iswpunc(wint_t c);
|
||||
extern int iswpunct(wint_t c);
|
||||
extern int iswprint(wint_t c);
|
||||
|
||||
extern int iswlower(wint_t c);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# $Id: libc.gmk,v 1.4 2006-11-16 14:39:23 obarthel Exp $
|
||||
# $Id: libc.gmk,v 1.9 2010-10-20 13:50:17 obarthel Exp $
|
||||
#
|
||||
# :ts=8
|
||||
#
|
||||
@@ -205,6 +205,10 @@ C_LIB := \
|
||||
stdlib_div.o \
|
||||
stdlib_divsi3.o \
|
||||
stdlib_divsi4.o \
|
||||
stdlib_dlclose.o \
|
||||
stdlib_dlerror.o \
|
||||
stdlib_dlopen.o \
|
||||
stdlib_dlsym.o \
|
||||
stdlib_dosbase.o \
|
||||
stdlib_exit.o \
|
||||
stdlib_free.o \
|
||||
@@ -248,13 +252,10 @@ C_LIB := \
|
||||
stdlib_setjmp.o \
|
||||
stdlib_set_errno.o \
|
||||
stdlib_set_process_window.o \
|
||||
stdlib_shared_objs.o \
|
||||
stdlib_shell_escape.o \
|
||||
stdlib_showerror.o \
|
||||
stdlib_srand.o \
|
||||
stdlib_stackargbytes.o \
|
||||
stdlib_stackcheck.o \
|
||||
stdlib_stackoverflow.o \
|
||||
stdlib_stacksafezone.o \
|
||||
stdlib_stacksize.o \
|
||||
stdlib_stack_usage.o \
|
||||
stdlib_arg.o \
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# $Id: libunix.gmk,v 1.3 2006-11-13 09:25:28 obarthel Exp $
|
||||
# $Id: libunix.gmk,v 1.4 2010-08-21 10:59:34 obarthel Exp $
|
||||
#
|
||||
# :ts=8
|
||||
#
|
||||
@@ -57,6 +57,7 @@ UNIX_LIB := \
|
||||
stdlib_alloca_cleanup.o \
|
||||
stdlib_alloca_trap.o \
|
||||
stdlib_arg.o \
|
||||
stdlib_dlopen.o \
|
||||
stdlib_expand_wildcard.o \
|
||||
stdlib_expand_wildcard_check.o \
|
||||
stdlib_getmemstats.o \
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#define VERSION 1
|
||||
#define REVISION 202
|
||||
#define DATE "16.1.2007"
|
||||
#define VERS "m.lib 1.202"
|
||||
#define VSTRING "m.lib 1.202 (16.1.2007)\r\n"
|
||||
#define VERSTAG "\0$VER: m.lib 1.202 (16.1.2007)"
|
||||
#define REVISION 206
|
||||
#define DATE "24.4.2015"
|
||||
#define VERS "m.lib 1.206"
|
||||
#define VSTRING "m.lib 1.206 (24.4.2015)\r\n"
|
||||
#define VERSTAG "\0$VER: m.lib 1.206 (24.4.2015)"
|
||||
|
||||
@@ -1 +1 @@
|
||||
202
|
||||
206
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#define VERSION 1
|
||||
#define REVISION 202
|
||||
#define DATE "16.1.2007"
|
||||
#define VERS "m881.lib 1.202"
|
||||
#define VSTRING "m881.lib 1.202 (16.1.2007)\r\n"
|
||||
#define VERSTAG "\0$VER: m881.lib 1.202 (16.1.2007)"
|
||||
#define REVISION 206
|
||||
#define DATE "24.4.2015"
|
||||
#define VERS "m881.lib 1.206"
|
||||
#define VSTRING "m881.lib 1.206 (24.4.2015)\r\n"
|
||||
#define VERSTAG "\0$VER: m881.lib 1.206 (24.4.2015)"
|
||||
|
||||
@@ -1 +1 @@
|
||||
202
|
||||
206
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: math_log.c,v 1.9 2006-01-08 12:04:23 obarthel Exp $
|
||||
* $Id: math_log.c,v 1.10 2007-11-08 11:23:53 damato Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@@ -244,7 +244,7 @@ log(double x)
|
||||
{
|
||||
double result;
|
||||
|
||||
if(x > DBL_EPSILON)
|
||||
if(x > 0)
|
||||
{
|
||||
result = __log(x);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: math_log10.c,v 1.8 2006-01-08 12:04:23 obarthel Exp $
|
||||
* $Id: math_log10.c,v 1.9 2007-11-08 11:23:53 damato Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@@ -186,7 +186,7 @@ log10(double x)
|
||||
{
|
||||
double result;
|
||||
|
||||
if(x > DBL_EPSILON)
|
||||
if(x > 0)
|
||||
{
|
||||
result = __log10(x);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: mount_convertinfo.c,v 1.6 2006-01-08 12:04:24 obarthel Exp $
|
||||
* $Id: mount_convertinfo.c,v 1.7 2008-04-16 07:38:10 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@@ -42,6 +42,20 @@
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#ifndef ID_BUSY_DISK
|
||||
#define ID_BUSY_DISK (0x42555359L) /* 'BUSY' */
|
||||
#endif /* ID_LONGNAME_DOS_DISK */
|
||||
|
||||
#ifndef ID_LONGNAME_DOS_DISK
|
||||
#define ID_LONGNAME_DOS_DISK (0x444F5306L) /* 'DOS\6' */
|
||||
#endif /* ID_LONGNAME_DOS_DISK */
|
||||
|
||||
#ifndef ID_LONGNAME_FFS_DISK
|
||||
#define ID_LONGNAME_FFS_DISK (0x444F5307L) /* 'DOS\7' */
|
||||
#endif /* ID_LONGNAME_FFS_DISK */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
void
|
||||
__convert_info_to_statfs(struct InfoData * id,struct statfs * f)
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#define VERSION 1
|
||||
#define REVISION 202
|
||||
#define DATE "16.1.2007"
|
||||
#define VERS "net.lib 1.202"
|
||||
#define VSTRING "net.lib 1.202 (16.1.2007)\r\n"
|
||||
#define VERSTAG "\0$VER: net.lib 1.202 (16.1.2007)"
|
||||
#define REVISION 205
|
||||
#define DATE "21.8.2010"
|
||||
#define VERS "net.lib 1.205"
|
||||
#define VSTRING "net.lib 1.205 (21.8.2010)\r\n"
|
||||
#define VERSTAG "\0$VER: net.lib 1.205 (21.8.2010)"
|
||||
|
||||
@@ -1 +1 @@
|
||||
202
|
||||
205
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: socket_hook_entry.c,v 1.17 2006-11-16 10:41:15 obarthel Exp $
|
||||
* $Id: socket_hook_entry.c,v 1.18 2010-10-20 13:12:58 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@@ -145,6 +145,8 @@ __socket_hook_entry(
|
||||
/* And that's the last for this file descriptor. */
|
||||
memset(fd,0,sizeof(*fd));
|
||||
|
||||
fd = NULL;
|
||||
|
||||
break;
|
||||
|
||||
case file_action_seek:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: socket_wait_select.c,v 1.3 2006-04-10 15:08:10 obarthel Exp $
|
||||
* $Id: socket_wait_select.c,v 1.4 2008-04-16 07:53:40 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@@ -44,8 +44,22 @@
|
||||
int
|
||||
waitselect(int num_fds,fd_set *read_fds,fd_set *write_fds,fd_set *except_fds,struct timeval *timeout,unsigned long * signal_mask)
|
||||
{
|
||||
struct timeval other_timeout;
|
||||
int result;
|
||||
|
||||
/* This is a workaround for a bug in the Roadshow TCP/IP stack which has been
|
||||
fixed long ago: if a signal is received, as given in the 'signal_mask'
|
||||
parameter, the WaitSelect() function may not detect it if the timeout
|
||||
is zero. */
|
||||
if(signal_mask != NULL && timeout != NULL && timeout->tv_secs == 0 && timeout->tv_micro == 0)
|
||||
{
|
||||
/* Substitute a ten microsecond timeout. */
|
||||
other_timeout.tv_secs = 0;
|
||||
other_timeout.tv_micro = 10000;
|
||||
|
||||
timeout = &other_timeout;
|
||||
}
|
||||
|
||||
result = __select(num_fds,read_fds,write_fds,except_fds,timeout,signal_mask);
|
||||
|
||||
return(result);
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
#define VERSION 1
|
||||
#define REVISION 202
|
||||
#define DATE "16.1.2007"
|
||||
#define VERS "stack.lib 1.202"
|
||||
#define VSTRING "stack.lib 1.202 (16.1.2007)\r\n"
|
||||
#define VERSTAG "\0$VER: stack.lib 1.202 (16.1.2007)"
|
||||
@@ -1 +0,0 @@
|
||||
202
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: stdio_fdhookentry.c,v 1.34 2006-11-16 14:39:23 obarthel Exp $
|
||||
* $Id: stdio_fdhookentry.c,v 1.35 2010-10-20 13:12:58 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@@ -367,6 +367,7 @@ __fd_hook_entry(
|
||||
|
||||
/* And that's the last for this file descriptor. */
|
||||
memset(fd,0,sizeof(*fd));
|
||||
fd = NULL;
|
||||
|
||||
break;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: stdio_file_init.c,v 1.12 2006-11-16 14:39:23 obarthel Exp $
|
||||
* $Id: stdio_file_init.c,v 1.13 2008-09-04 12:07:58 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@@ -76,6 +76,11 @@ struct WBStartup * NOCOMMON __WBenchMsg;
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* CPU cache line size; used to align I/O buffers for best performance. */
|
||||
ULONG __cache_line_size = 32;
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
FILE_DESTRUCTOR(workbench_exit)
|
||||
{
|
||||
ENTER();
|
||||
@@ -215,6 +220,24 @@ FILE_CONSTRUCTOR(stdio_file_init)
|
||||
|
||||
ENTER();
|
||||
|
||||
/* Figure out the proper address alignment for the memory we are
|
||||
going to use for disk I/O. The default is 32 bytes, which should
|
||||
be OK for most cases. If possible, ask the operating system for
|
||||
its preferred alignment size. */
|
||||
#if defined(__amigaos4__)
|
||||
{
|
||||
if(SysBase->lib_Version >= 50)
|
||||
{
|
||||
uint32 physical_alignment = 0;
|
||||
|
||||
GetCPUInfoTags(GCIT_CacheLineSize,&physical_alignment,TAG_DONE);
|
||||
|
||||
if(__cache_line_size < physical_alignment)
|
||||
__cache_line_size = physical_alignment;
|
||||
}
|
||||
}
|
||||
#endif /* __amigaos4__ */
|
||||
|
||||
/* If we were invoked from Workbench, set up the standard I/O streams. */
|
||||
if(__WBenchMsg != NULL)
|
||||
{
|
||||
@@ -255,7 +278,7 @@ FILE_CONSTRUCTOR(stdio_file_init)
|
||||
PROFILE_ON();
|
||||
|
||||
/* Allocate a little more memory than necessary. */
|
||||
buffer = malloc(BUFSIZ + (CACHE_LINE_SIZE-1));
|
||||
buffer = malloc(BUFSIZ + (__cache_line_size - 1));
|
||||
if(buffer == NULL)
|
||||
goto out;
|
||||
|
||||
@@ -300,7 +323,7 @@ FILE_CONSTRUCTOR(stdio_file_init)
|
||||
#endif /* __THREAD_SAFE */
|
||||
|
||||
/* Align the buffer start address to a cache line boundary. */
|
||||
aligned_buffer = (char *)((ULONG)(buffer + (CACHE_LINE_SIZE-1)) & ~(CACHE_LINE_SIZE-1));
|
||||
aligned_buffer = (char *)((ULONG)(buffer + (__cache_line_size-1)) & ~(__cache_line_size-1));
|
||||
|
||||
__initialize_fd(__fd[i],__fd_hook_entry,default_file,fd_flags,fd_lock);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: stdio_fwrite.c,v 1.11 2006-09-25 15:38:21 obarthel Exp $
|
||||
* $Id: stdio_fwrite.c,v 1.12 2010-10-20 13:12:58 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@@ -134,7 +134,7 @@ fwrite(const void *ptr,size_t element_size,size_t count,FILE *stream)
|
||||
{
|
||||
c = (*data++);
|
||||
|
||||
if(__putc_line_buffered(c,(FILE *)file) < 0)
|
||||
if(__putc_line_buffered(c,(FILE *)file) == EOF)
|
||||
goto out;
|
||||
|
||||
total_bytes_written++;
|
||||
@@ -146,7 +146,7 @@ fwrite(const void *ptr,size_t element_size,size_t count,FILE *stream)
|
||||
{
|
||||
c = (*data++);
|
||||
|
||||
if(__putc_fully_buffered(c,(FILE *)file) < 0)
|
||||
if(__putc_fully_buffered(c,(FILE *)file) == EOF)
|
||||
goto out;
|
||||
|
||||
total_bytes_written++;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: stdio_grow_file.c,v 1.7 2006-11-16 14:39:23 obarthel Exp $
|
||||
* $Id: stdio_grow_file.c,v 1.8 2008-09-04 12:07:58 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@@ -90,7 +90,7 @@ __grow_file_size(struct fd * fd,int num_bytes)
|
||||
/* Allocate a little more memory than required to allow for
|
||||
* the buffer to be aligned to a cache line boundary.
|
||||
*/
|
||||
buffer = malloc((size_t)buffer_size + (CACHE_LINE_SIZE-1));
|
||||
buffer = malloc((size_t)buffer_size + (__cache_line_size-1));
|
||||
if(buffer == NULL)
|
||||
{
|
||||
SHOWMSG("not enough memory for write buffer");
|
||||
@@ -100,7 +100,7 @@ __grow_file_size(struct fd * fd,int num_bytes)
|
||||
}
|
||||
|
||||
/* Align the buffer to a cache line boundary. */
|
||||
aligned_buffer = (unsigned char *)(((ULONG)(buffer + (CACHE_LINE_SIZE-1))) & ~(CACHE_LINE_SIZE-1));
|
||||
aligned_buffer = (unsigned char *)(((ULONG)(buffer + (__cache_line_size-1))) & ~(__cache_line_size-1));
|
||||
|
||||
memset(aligned_buffer,0,(size_t)buffer_size);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: stdio_headers.h,v 1.30 2006-11-16 14:39:23 obarthel Exp $
|
||||
* $Id: stdio_headers.h,v 1.33 2010-10-20 13:12:59 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@@ -156,18 +156,6 @@ struct iob;
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* CPU cache line size; used for alignment purposes with some data structures.
|
||||
This should be determined dynamically rather than preset here. For the
|
||||
68040/68060 the cache line size is 16 bytes, for the PowerPC G4 it's
|
||||
32 bytes and 128 bytes (gross!) for the PowerPC G5. */
|
||||
#if defined(__PPC__)
|
||||
#define CACHE_LINE_SIZE 32UL
|
||||
#else
|
||||
#define CACHE_LINE_SIZE 16UL
|
||||
#endif /* __PPC__ */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* The directory entry type a socket is identified with (in a FileInfoBlock). */
|
||||
#define ST_SOCKET (31082002)
|
||||
|
||||
@@ -288,13 +276,13 @@ struct iob
|
||||
((struct iob *)(f))->iob_Buffer[((struct iob *)(f))->iob_BufferPosition++] : \
|
||||
__fgetc((FILE *)(f)))
|
||||
|
||||
/* Caution: this putc() variant will evaluate the 'c' parameter more than once. */
|
||||
#define __putc(c,f,m) \
|
||||
(((((struct iob *)(f))->iob_BufferWriteBytes < ((struct iob *)(f))->iob_BufferSize)) ? \
|
||||
(((struct iob *)(f))->iob_Buffer[((struct iob *)(f))->iob_BufferWriteBytes++] = (c), \
|
||||
(((m) == IOBF_BUFFER_MODE_LINE && \
|
||||
((struct iob *)(f))->iob_Buffer[((struct iob *)(f))->iob_BufferWriteBytes-1] == '\n') ? \
|
||||
(((m) == IOBF_BUFFER_MODE_LINE && (c) == '\n') ? \
|
||||
__flush(f) : \
|
||||
(((struct iob *)(f))->iob_Buffer[((struct iob *)(f))->iob_BufferWriteBytes-1]))) : \
|
||||
((c) & 255))) : \
|
||||
__fputc((c),(f),(m)))
|
||||
|
||||
#define __putc_fully_buffered(c,f) \
|
||||
@@ -302,12 +290,13 @@ struct iob
|
||||
(((struct iob *)(f))->iob_Buffer[((struct iob *)(f))->iob_BufferWriteBytes++] = (c)) : \
|
||||
__fputc((c),(f),IOBF_BUFFER_MODE_FULL))
|
||||
|
||||
/* Caution: this putc() variant will evaluate the 'c' parameter more than once. */
|
||||
#define __putc_line_buffered(c,f) \
|
||||
(((((struct iob *)(f))->iob_BufferWriteBytes < ((struct iob *)(f))->iob_BufferSize)) ? \
|
||||
(((struct iob *)(f))->iob_Buffer[((struct iob *)(f))->iob_BufferWriteBytes++] = (c), \
|
||||
(((c) == '\n') ? \
|
||||
__flush(f) : \
|
||||
((c)))) : \
|
||||
((c) & 255))) : \
|
||||
__fputc((c),(f),IOBF_BUFFER_MODE_LINE))
|
||||
|
||||
/****************************************************************************/
|
||||
@@ -399,6 +388,11 @@ extern BOOL NOCOMMON __no_standard_io;
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* CPU cache line size; used to align I/O buffers for best performance. */
|
||||
extern ULONG __cache_line_size;
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/*extern int __iob_write_buffer_is_full(struct iob * file);*/
|
||||
|
||||
#define __iob_write_buffer_is_full(file) \
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: stdio_openiob.c,v 1.14 2006-01-08 12:04:24 obarthel Exp $
|
||||
* $Id: stdio_openiob.c,v 1.15 2008-09-04 12:07:58 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@@ -133,7 +133,7 @@ __open_iob(const char *filename, const char *mode, int file_descriptor, int slot
|
||||
SHOWMSG("allocating file buffer");
|
||||
|
||||
/* Allocate a little more memory than necessary. */
|
||||
buffer = malloc(BUFSIZ + (CACHE_LINE_SIZE-1));
|
||||
buffer = malloc(BUFSIZ + (__cache_line_size-1));
|
||||
if(buffer == NULL)
|
||||
{
|
||||
SHOWMSG("that didn't work");
|
||||
@@ -143,7 +143,7 @@ __open_iob(const char *filename, const char *mode, int file_descriptor, int slot
|
||||
}
|
||||
|
||||
/* Align the buffer start address to a cache line boundary. */
|
||||
aligned_buffer = (char *)((ULONG)(buffer + (CACHE_LINE_SIZE-1)) & ~(CACHE_LINE_SIZE-1));
|
||||
aligned_buffer = (char *)((ULONG)(buffer + (__cache_line_size-1)) & ~(__cache_line_size-1));
|
||||
|
||||
if(file_descriptor < 0)
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: stdio_popen.c,v 1.9 2006-01-08 12:04:24 obarthel Exp $
|
||||
* $Id: stdio_popen.c,v 1.10 2008-05-07 09:33:55 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@@ -154,7 +154,9 @@ popen(const char *command, const char *type)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* The current PIPE: device only supports unidirectional connections. */
|
||||
/* The current PIPE: device only supports unidirectional connections. Worse: even if
|
||||
a PIPE: device with bidirectional connection support were available, we would
|
||||
be unable to detect this property. */
|
||||
if((type[1] == '+') || (type[1] != '\0' && type[2] == '+'))
|
||||
{
|
||||
D(("unsupported access mode '%s'",type));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: stdio_setvbuf.c,v 1.10 2006-09-22 09:02:51 obarthel Exp $
|
||||
* $Id: stdio_setvbuf.c,v 1.11 2008-09-04 12:07:58 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@@ -123,7 +123,7 @@ setvbuf(FILE *stream,char *buf,int bufmode,size_t size)
|
||||
if(size > 0 && buf == NULL)
|
||||
{
|
||||
/* Allocate a little more memory than necessary. */
|
||||
new_buffer = malloc(size + (CACHE_LINE_SIZE-1));
|
||||
new_buffer = malloc(size + (__cache_line_size-1));
|
||||
if(new_buffer == NULL)
|
||||
{
|
||||
__set_errno(ENOBUFS);
|
||||
@@ -170,7 +170,7 @@ setvbuf(FILE *stream,char *buf,int bufmode,size_t size)
|
||||
file->iob_CustomBuffer = new_buffer;
|
||||
|
||||
/* Align the buffer start address to a cache line boundary. */
|
||||
new_buffer = (char *)((ULONG)(new_buffer + (CACHE_LINE_SIZE-1)) & ~(CACHE_LINE_SIZE-1));
|
||||
new_buffer = (char *)((ULONG)(new_buffer + (__cache_line_size-1)) & ~(__cache_line_size-1));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: stdio_vfprintf.c,v 1.25 2006-11-13 09:32:28 obarthel Exp $
|
||||
* $Id: stdio_vfprintf.c,v 1.26 2008-03-10 15:28:11 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@@ -143,8 +143,12 @@ vfprintf(FILE * stream,const char * format, va_list arg)
|
||||
int output_len;
|
||||
const char *prefix;
|
||||
char prefix_buffer[8];
|
||||
int argument_digits;
|
||||
int argument_number;
|
||||
int argument_index;
|
||||
int result = EOF;
|
||||
int len = 0;
|
||||
int i;
|
||||
int c;
|
||||
|
||||
#if defined(FLOATING_POINT_SUPPORT)
|
||||
@@ -203,6 +207,36 @@ vfprintf(FILE * stream,const char * format, va_list arg)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If a string of digits, terminated by a '$' character appears here,
|
||||
it indicates which argument should be accessed. We evaluate this
|
||||
data but for now will ignore it altogether. */
|
||||
argument_index = argument_number = argument_digits = 0;
|
||||
|
||||
for(i = 0 ; format[i] != '\0' ; i++)
|
||||
{
|
||||
if(format[i] == '$')
|
||||
{
|
||||
if(argument_digits > 0)
|
||||
{
|
||||
argument_index = argument_number;
|
||||
|
||||
format = &format[i+1];
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
else if ('0' <= format[i] && format[i] <= '9')
|
||||
{
|
||||
argument_number = (10 * argument_number) + (format[i] - '0');
|
||||
|
||||
argument_digits++;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
format_flags = 0;
|
||||
fill_character = ' ';
|
||||
|
||||
@@ -772,7 +806,6 @@ vfprintf(FILE * stream,const char * format, va_list arg)
|
||||
int max_digits = -1;
|
||||
int exponent = 0;
|
||||
int digit;
|
||||
int i;
|
||||
|
||||
/* This takes care of the sign. */
|
||||
if(v < 0.0)
|
||||
@@ -1352,8 +1385,6 @@ vfprintf(FILE * stream,const char * format, va_list arg)
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
|
||||
output_len = precision;
|
||||
|
||||
for(i = 0 ; i < precision ; i++)
|
||||
@@ -1532,8 +1563,6 @@ vfprintf(FILE * stream,const char * format, va_list arg)
|
||||
|
||||
if(FLAG_IS_SET(format_flags,FORMATF_LeftJustified))
|
||||
{
|
||||
int i;
|
||||
|
||||
if(prefix != NULL)
|
||||
{
|
||||
for(i = 0 ; prefix[i] != '\0' ; i++)
|
||||
@@ -1590,8 +1619,6 @@ vfprintf(FILE * stream,const char * format, va_list arg)
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
|
||||
/* If we have to add the prefix later, make sure that
|
||||
we don't add too many fill characters in front of
|
||||
it now. */
|
||||
@@ -1644,7 +1671,6 @@ vfprintf(FILE * stream,const char * format, va_list arg)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for(i = 0 ; i < output_len ; i++)
|
||||
{
|
||||
if(__putc(output_buffer[i],stream,buffer_mode) == EOF)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: stdio_vfscanf.c,v 1.21 2006-09-25 14:51:15 obarthel Exp $
|
||||
* $Id: stdio_vfscanf.c,v 1.22 2015-04-24 13:00:12 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@@ -775,6 +775,8 @@ vfscanf(FILE *stream, const char *format, va_list arg)
|
||||
/* Check if there's a hex prefix introducing this number. */
|
||||
if(maximum_field_width != 0 && (c = __getc(stream)) != EOF)
|
||||
{
|
||||
D(("c = '%lc'",c));
|
||||
|
||||
if(c == '0')
|
||||
{
|
||||
/* Use the leading zero as is. */
|
||||
@@ -889,6 +891,8 @@ vfscanf(FILE *stream, const char *format, va_list arg)
|
||||
c = __getc(stream);
|
||||
if(c != EOF)
|
||||
{
|
||||
D(("c = '%lc'",c));
|
||||
|
||||
__locale_lock();
|
||||
|
||||
/* Did we find the decimal point? We accept both the
|
||||
@@ -963,6 +967,7 @@ vfscanf(FILE *stream, const char *format, va_list arg)
|
||||
int digit;
|
||||
|
||||
SHOWMSG("found a decimal point");
|
||||
num_chars_processed++;
|
||||
|
||||
/* Process all digits following the decimal point. */
|
||||
while(maximum_field_width != 0 && (c = __getc(stream)) != EOF)
|
||||
@@ -1004,6 +1009,7 @@ vfscanf(FILE *stream, const char *format, va_list arg)
|
||||
}
|
||||
|
||||
total_num_chars_read++;
|
||||
num_chars_processed++;
|
||||
|
||||
if(maximum_field_width > 0)
|
||||
maximum_field_width--;
|
||||
@@ -1014,6 +1020,7 @@ vfscanf(FILE *stream, const char *format, va_list arg)
|
||||
SHOWMSG("found an exponent specifier");
|
||||
|
||||
total_num_chars_read++;
|
||||
num_chars_processed++;
|
||||
|
||||
if(maximum_field_width > 0)
|
||||
maximum_field_width--;
|
||||
@@ -1056,12 +1063,15 @@ vfscanf(FILE *stream, const char *format, va_list arg)
|
||||
{
|
||||
int digit;
|
||||
|
||||
D(("c = '%lc'",c));
|
||||
|
||||
/* Skip the sign. */
|
||||
if(c == '-')
|
||||
{
|
||||
exponent_is_negative = TRUE;
|
||||
|
||||
total_num_chars_read++;
|
||||
num_chars_processed++;
|
||||
|
||||
if(maximum_field_width > 0)
|
||||
maximum_field_width--;
|
||||
@@ -1069,6 +1079,7 @@ vfscanf(FILE *stream, const char *format, va_list arg)
|
||||
else if (c == '+')
|
||||
{
|
||||
total_num_chars_read++;
|
||||
num_chars_processed++;
|
||||
|
||||
if(maximum_field_width > 0)
|
||||
maximum_field_width--;
|
||||
@@ -1097,6 +1108,8 @@ vfscanf(FILE *stream, const char *format, va_list arg)
|
||||
new_exponent = (exponent_radix * exponent) + digit;
|
||||
if(new_exponent < exponent) /* overflow? */
|
||||
{
|
||||
SHOWMSG("overflow!");
|
||||
|
||||
if(ungetc(c,stream) == EOF)
|
||||
{
|
||||
SHOWMSG("couldn't push this character back");
|
||||
@@ -1109,12 +1122,15 @@ vfscanf(FILE *stream, const char *format, va_list arg)
|
||||
exponent = new_exponent;
|
||||
|
||||
total_num_chars_read++;
|
||||
num_chars_processed++;
|
||||
|
||||
if(maximum_field_width > 0)
|
||||
maximum_field_width--;
|
||||
}
|
||||
else
|
||||
{
|
||||
SHOWMSG("invalid digit");
|
||||
|
||||
if(ungetc(c,stream) == EOF)
|
||||
{
|
||||
SHOWMSG("couldn't push this character back");
|
||||
@@ -1178,9 +1194,17 @@ vfscanf(FILE *stream, const char *format, va_list arg)
|
||||
}
|
||||
|
||||
num_assignments++;
|
||||
|
||||
D(("number of assignments = %ld\n", num_assignments));
|
||||
}
|
||||
|
||||
num_conversions++;
|
||||
|
||||
D(("number of conversions = %ld\n", num_conversions));
|
||||
}
|
||||
else
|
||||
{
|
||||
SHOWMSG("no characters were actually processed");
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
/*
|
||||
* $Id: stdlib_stackoverflow.c,v 1.4 2006-01-08 12:04:26 obarthel Exp $
|
||||
* $Id: stdlib_dlclose.c,v 1.2 2010-08-21 11:37:03 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
* Portable ISO 'C' (1994) runtime library for the Amiga computer
|
||||
* Copyright (c) 2002-2006 by Olaf Barthel <olsen (at) sourcery.han.de>
|
||||
* Copyright (c) 2002-2010 by Olaf Barthel <olsen (at) sourcery.han.de>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -37,48 +37,50 @@
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
extern BOOL NOCOMMON __stack_overflow;
|
||||
/* The shared object API is available only on AmigaOS 4.0. */
|
||||
#if defined(__amigaos4__)
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#include <dlfcn.h>
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
void
|
||||
__stkovf(void)
|
||||
#include <libraries/elf.h>
|
||||
#include <proto/elf.h>
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
extern struct ElfIFace * __IElf;
|
||||
extern Elf32_Handle __dl_elf_handle;
|
||||
extern Elf32_Error __elf_error_code;
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
int dlclose(void * handle)
|
||||
{
|
||||
/* We're in trouble. */
|
||||
__stack_overflow = TRUE;
|
||||
int result = -1;
|
||||
|
||||
/* This will restore things to a sane state, display an
|
||||
* error requester and drop into _exit().
|
||||
*/
|
||||
longjmp(__exit_jmp_buf,1);
|
||||
if(__dl_elf_handle != NULL)
|
||||
{
|
||||
struct ElfIFace * IElf = __IElf;
|
||||
Elf32_Error error;
|
||||
|
||||
error = DLClose(__dl_elf_handle,handle);
|
||||
if(error != ELF32_NO_ERROR)
|
||||
{
|
||||
__elf_error_code = error;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
result = 0;
|
||||
|
||||
out:
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#if defined(__SASC)
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
VOID
|
||||
_XCOVF(VOID)
|
||||
{
|
||||
/* We're in trouble. */
|
||||
__stack_overflow = TRUE;
|
||||
|
||||
/* This will restore things to a sane state, display an
|
||||
* error requester and drop into _exit().
|
||||
*/
|
||||
longjmp(__exit_jmp_buf,1);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#endif /* __SASC */
|
||||
#endif /* __amigaos4__ */
|
||||
132
library/stdlib_dlerror.c
Normal file
132
library/stdlib_dlerror.c
Normal file
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* $Id: stdlib_dlerror.c,v 1.2 2010-08-21 11:37:03 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
* Portable ISO 'C' (1994) runtime library for the Amiga computer
|
||||
* Copyright (c) 2002-2010 by Olaf Barthel <olsen (at) sourcery.han.de>
|
||||
* 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 */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* The shared object API is available only on AmigaOS 4.0. */
|
||||
#if defined(__amigaos4__)
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#include <libraries/elf.h>
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
extern Elf32_Error __elf_error_code;
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
const char * dlerror(void)
|
||||
{
|
||||
const char * result;
|
||||
|
||||
switch(__elf_error_code)
|
||||
{
|
||||
case ELF32_NO_ERROR:
|
||||
|
||||
result = NULL;
|
||||
break;
|
||||
|
||||
case ELF32_OUT_OF_MEMORY:
|
||||
|
||||
result = "out of memory";
|
||||
break;
|
||||
|
||||
case ELF32_INVALID_HANDLE:
|
||||
|
||||
result = "invalid handle";
|
||||
break;
|
||||
|
||||
case ELF32_NO_MORE_RELOCS:
|
||||
|
||||
result = "no more relocs";
|
||||
break;
|
||||
|
||||
case ELF32_SECTION_NOT_LOADED:
|
||||
|
||||
result = "section not loaded";
|
||||
break;
|
||||
|
||||
case ELF32_UNKNOWN_RELOC:
|
||||
|
||||
result = "unknown reloc";
|
||||
break;
|
||||
|
||||
case ELF32_READ_ERROR:
|
||||
|
||||
result = "read error";
|
||||
break;
|
||||
|
||||
case ELF32_INVALID_SDA_BASE:
|
||||
|
||||
result = "invalid SDA base";
|
||||
break;
|
||||
|
||||
case ELF32_SYMBOL_NOT_FOUND:
|
||||
|
||||
result = "symbol not found";
|
||||
break;
|
||||
|
||||
case ELF32_INVALID_NAME:
|
||||
|
||||
result = "invalid name";
|
||||
break;
|
||||
|
||||
case ELF32_REQUIRED_OBJECT_MISSING:
|
||||
|
||||
result = "required object missing";
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
result = "unknown error";
|
||||
break;
|
||||
}
|
||||
|
||||
/* Calling dlerror() will clear the error code. */
|
||||
__elf_error_code = ELF32_NO_ERROR;
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#endif /* __amigaos4__ */
|
||||
112
library/stdlib_dlopen.c
Normal file
112
library/stdlib_dlopen.c
Normal file
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* $Id: stdlib_dlopen.c,v 1.2 2010-08-21 11:37:03 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
* Portable ISO 'C' (1994) runtime library for the Amiga computer
|
||||
* Copyright (c) 2002-2010 by Olaf Barthel <olsen (at) sourcery.han.de>
|
||||
* 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 */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* The shared object API is available only on AmigaOS 4.0. */
|
||||
#if defined(__amigaos4__)
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#include <libraries/elf.h>
|
||||
#include <proto/elf.h>
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
extern struct ElfIFace * __IElf;
|
||||
extern Elf32_Handle __dl_elf_handle;
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
void * dlopen(const char * path_name,int mode)
|
||||
{
|
||||
#if defined(UNIX_PATH_SEMANTICS)
|
||||
struct name_translation_info path_name_nti;
|
||||
#endif /* UNIX_PATH_SEMANTICS */
|
||||
|
||||
void * result = NULL;
|
||||
|
||||
#if defined(UNIX_PATH_SEMANTICS)
|
||||
{
|
||||
if(__unix_path_semantics)
|
||||
{
|
||||
if(path_name[0] == '\0')
|
||||
{
|
||||
SHOWMSG("no name given");
|
||||
|
||||
__set_errno(ENOENT);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(__translate_unix_to_amiga_path_name(&path_name,&path_name_nti) != 0)
|
||||
goto out;
|
||||
|
||||
if(path_name_nti.is_root)
|
||||
{
|
||||
__set_errno(EACCES);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* UNIX_PATH_SEMANTICS */
|
||||
|
||||
if(__dl_elf_handle != NULL)
|
||||
{
|
||||
struct ElfIFace * IElf = __IElf;
|
||||
uint32 flags = 0;
|
||||
|
||||
if(mode & RTLD_LOCAL)
|
||||
flags = ELF32_RTLD_LOCAL;
|
||||
|
||||
if(mode & RTLD_GLOBAL)
|
||||
flags = ELF32_RTLD_GLOBAL;
|
||||
|
||||
result = DLOpen(__dl_elf_handle,path_name,flags);
|
||||
}
|
||||
|
||||
out:
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#endif /* __amigaos4__ */
|
||||
@@ -1,10 +1,10 @@
|
||||
/*
|
||||
* $Id: stack.lib_rev.c,v 1.3 2006-01-08 12:04:24 obarthel Exp $
|
||||
* $Id: stdlib_dlsym.c,v 1.2 2010-08-21 11:37:03 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
* Portable ISO 'C' (1994) runtime library for the Amiga computer
|
||||
* Copyright (c) 2002-2006 by Olaf Barthel <olsen (at) sourcery.han.de>
|
||||
* Copyright (c) 2002-2010 by Olaf Barthel <olsen (at) sourcery.han.de>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -31,8 +31,57 @@
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "stack.lib_rev.h"
|
||||
#ifndef _STDLIB_HEADERS_H
|
||||
#include "stdlib_headers.h"
|
||||
#endif /* _STDLIB_HEADERS_H */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
char __stack_lib_version[] = VERSTAG;
|
||||
/* The shared object API is available only on AmigaOS 4.0. */
|
||||
#if defined(__amigaos4__)
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#include <libraries/elf.h>
|
||||
#include <proto/elf.h>
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
extern struct ElfIFace * __IElf;
|
||||
extern Elf32_Handle __dl_elf_handle;
|
||||
extern Elf32_Error __elf_error_code;
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
void * dlsym(void * handle,const char * symbol_name)
|
||||
{
|
||||
void * result = NULL;
|
||||
|
||||
if(__dl_elf_handle != NULL)
|
||||
{
|
||||
struct ElfIFace * IElf = __IElf;
|
||||
APTR symbol_data = NULL;
|
||||
Elf32_Error error;
|
||||
|
||||
error = DLSym(__dl_elf_handle,handle,symbol_name,&symbol_data);
|
||||
if(error != ELF32_NO_ERROR)
|
||||
{
|
||||
__elf_error_code = error;
|
||||
goto out;
|
||||
}
|
||||
|
||||
result = symbol_data;
|
||||
}
|
||||
|
||||
out:
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#endif /* __amigaos4__ */
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: stdlib_headers.h,v 1.21 2006-01-08 12:04:25 obarthel Exp $
|
||||
* $Id: stdlib_headers.h,v 1.22 2010-10-20 13:50:17 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@@ -162,21 +162,7 @@ extern unsigned int NOCOMMON (* __get_default_stack_size)(void);
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
extern unsigned int NOCOMMON __stack_size;
|
||||
extern UBYTE * NOCOMMON __stk_limit;
|
||||
extern UBYTE * NOCOMMON __base;
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
extern ULONG NOCOMMON __stk_extensions;
|
||||
extern ULONG NOCOMMON __stk_maxsize;
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
extern ULONG NOCOMMON __stk_argbytes;
|
||||
extern ULONG NOCOMMON __stk_safezone;
|
||||
extern ULONG NOCOMMON __stk_size;
|
||||
extern ULONG NOCOMMON __stk_minframe;
|
||||
extern unsigned int NOCOMMON __stack_size;
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: stdlib_main.c,v 1.33 2006-09-25 14:51:15 obarthel Exp $
|
||||
* $Id: stdlib_main.c,v 1.34 2008-09-30 14:09:00 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@@ -61,6 +61,16 @@
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* On OS4 memory of type MEMF_ANY may not be paged out. Where this is desirable
|
||||
MEMF_PRIVATE should be used instead. */
|
||||
#ifdef __amigaos4__
|
||||
#define MEMORY_TYPE MEMF_PRIVATE
|
||||
#else
|
||||
#define MEMORY_TYPE MEMF_ANY
|
||||
#endif /* __amigaos4__ */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
extern int main(int arg_c,char ** arg_v);
|
||||
|
||||
/****************************************************************************/
|
||||
@@ -107,7 +117,7 @@ call_main(void)
|
||||
struct Process * this_process = (struct Process *)FindTask(NULL);
|
||||
UBYTE * arg_str = GetArgStr();
|
||||
size_t arg_str_len = strlen(arg_str);
|
||||
UBYTE * arg_str_copy = AllocVec(arg_str_len+1,MEMF_ANY);
|
||||
UBYTE * arg_str_copy = AllocVec(arg_str_len+1,MEMF_PRIVATE);
|
||||
UBYTE current_dir_name[256];
|
||||
|
||||
if(arg_str_copy != NULL && NameFromLock(this_process->pr_CurrentDir,current_dir_name,sizeof(current_dir_name)))
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: stdlib_malloc.c,v 1.19 2006-01-08 12:04:25 obarthel Exp $
|
||||
* $Id: stdlib_malloc.c,v 1.20 2008-09-30 14:09:00 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@@ -143,9 +143,21 @@ __allocate_memory(size_t size,BOOL never_free,const char * UNUSED unused_file,in
|
||||
#endif /* __MEM_DEBUG */
|
||||
|
||||
if(__memory_pool != NULL)
|
||||
{
|
||||
mn = AllocPooled(__memory_pool,allocation_size);
|
||||
}
|
||||
else
|
||||
mn = AllocMem(allocation_size,MEMF_ANY);
|
||||
{
|
||||
#if defined(__amigaos4__)
|
||||
{
|
||||
mn = AllocMem(allocation_size,MEMF_PRIVATE);
|
||||
}
|
||||
#else
|
||||
{
|
||||
mn = AllocMem(allocation_size,MEMF_ANY);
|
||||
}
|
||||
#endif /* __amigaos4__ */
|
||||
}
|
||||
|
||||
if(mn == NULL)
|
||||
{
|
||||
@@ -401,7 +413,7 @@ STDLIB_CONSTRUCTOR(stdlib_memory_init)
|
||||
|
||||
#if defined(__amigaos4__)
|
||||
{
|
||||
__memory_pool = CreatePool(MEMF_ANY,(ULONG)__default_pool_size,(ULONG)__default_puddle_size);
|
||||
__memory_pool = CreatePool(MEMF_PRIVATE,(ULONG)__default_pool_size,(ULONG)__default_puddle_size);
|
||||
}
|
||||
#else
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: stdlib_program_name.c,v 1.2 2006-01-08 12:04:26 obarthel Exp $
|
||||
* $Id: stdlib_program_name.c,v 1.3 2008-09-30 14:09:00 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@@ -49,6 +49,14 @@
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#ifdef __amigaos4__
|
||||
#define MEMORY_TYPE MEMF_PRIVATE
|
||||
#else
|
||||
#define MEMORY_TYPE MEMF_ANY
|
||||
#endif /* __amigaos4__ */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
static BOOL free_program_name;
|
||||
|
||||
/****************************************************************************/
|
||||
@@ -83,7 +91,7 @@ STDLIB_CONSTRUCTOR(stdlib_program_name_init)
|
||||
const size_t program_name_size = 256;
|
||||
|
||||
/* Make a copy of the current command name string. */
|
||||
__program_name = AllocVec((ULONG)program_name_size,MEMF_ANY);
|
||||
__program_name = AllocVec((ULONG)program_name_size,MEMORY_TYPE);
|
||||
if(__program_name == NULL)
|
||||
goto out;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: stdlib_protos.h,v 1.17 2006-01-08 12:04:26 obarthel Exp $
|
||||
* $Id: stdlib_protos.h,v 1.18 2010-10-20 13:50:17 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@@ -168,11 +168,6 @@ extern void __assertion_failure(const char *file_name,int line_number,const char
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* stdlib_stackoverflow.c */
|
||||
extern void __stkovf(void);
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* stdlib_termination_message.c */
|
||||
extern void __print_termination_message(const char * termination_message);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: stdlib_setjmp.c,v 1.5 2006-11-16 10:09:20 obarthel Exp $
|
||||
* $Id: stdlib_setjmp.c,v 1.6 2010-10-20 13:50:17 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@@ -81,55 +81,6 @@ l0: moveq #0,d0 | always return 0 \n\
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#if defined(STACK_EXTENSION)
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
asm(" \n\
|
||||
\n\
|
||||
AFB_68881 = 4 \n\
|
||||
AttnFlags = 297 \n\
|
||||
\n\
|
||||
.text \n\
|
||||
.even \n\
|
||||
\n\
|
||||
.globl _longjmp \n\
|
||||
.globl ___stkrst \n\
|
||||
\n\
|
||||
_longjmp: \n\
|
||||
\n\
|
||||
moveal sp@(4),a0 | (struct __jmp_buf *) env \n\
|
||||
movel sp@(8),d2 | (int) status \n\
|
||||
\n\
|
||||
tstl d2 \n\
|
||||
bne l1 | skip the following if result is non-zero \n\
|
||||
\n\
|
||||
moveq #1,d2 | make sure that the result is always non-zero \n\
|
||||
\n\
|
||||
l1: movel a0@(60:W),d0 | get the stack pointer address to restore \n\
|
||||
jbsr ___stkrst | restore the stack frame \n\
|
||||
movel d2,d0 | get the return code back \n\
|
||||
\n\
|
||||
moveal "A4(_SysBase)",a1 \n\
|
||||
btst #AFB_68881,a1@(AttnFlags:W) | is there an FPU installed? \n\
|
||||
beq l2 | skip the following if not \n\
|
||||
\n\
|
||||
fmovemx a0@(64:W),fp0-fp7 | restore all floating point registers \n\
|
||||
\n\
|
||||
l2: moveml a0@(4:W),d1-d7 | restore all data registers \n\
|
||||
moveml a0@(36:W),a1-a7 | restore almost all address registers, except for A0 \n\
|
||||
movel a0@,sp@ | restore A0 \n\
|
||||
moveal a0@(32:W),a0 | and return to the address setjmp() was called from \n\
|
||||
rts \n\
|
||||
\n\
|
||||
");
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#else
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
asm(" \n\
|
||||
\n\
|
||||
AFB_68881 = 4 \n\
|
||||
@@ -166,10 +117,6 @@ l2: moveml a0@(4:W),d1-d7 | restore all data registers \n\
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#endif /* STACK_EXTENSION */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#elif defined(__mc68000__)
|
||||
|
||||
/****************************************************************************/
|
||||
@@ -196,46 +143,6 @@ _setjmp: \n\
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#if defined(STACK_EXTENSION)
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
asm(" \n\
|
||||
\n\
|
||||
.text \n\
|
||||
.even \n\
|
||||
\n\
|
||||
.globl _longjmp \n\
|
||||
.globl ___stkrst \n\
|
||||
\n\
|
||||
_longjmp: \n\
|
||||
\n\
|
||||
moveal sp@(4),a0 | (struct __jmp_buf *) env \n\
|
||||
movel sp@(8),d2 | (int) status \n\
|
||||
\n\
|
||||
tstl d2 \n\
|
||||
bne l1 | skip the following if result is non-zero \n\
|
||||
\n\
|
||||
moveq #1,d2 | make sure that the result is always non-zero \n\
|
||||
\n\
|
||||
l1: movel a0@(60:W),d0 | get the stack pointer address to restore \n\
|
||||
jbsr ___stkrst | restore the stack frame \n\
|
||||
movel d2,d0 | get the return code back \n\
|
||||
\n\
|
||||
moveml a0@(4:W),d1-d7 | restore all data registers \n\
|
||||
moveml a0@(36:W),a1-a7 | restore almost all address registers, except for A0 \n\
|
||||
movel a0@,sp@ | restore A0 \n\
|
||||
moveal a0@(32:W),a0 | and return to the address setjmp() was called from \n\
|
||||
rts \n\
|
||||
\n\
|
||||
");
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#else
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
asm(" \n\
|
||||
\n\
|
||||
.text \n\
|
||||
@@ -263,26 +170,10 @@ l1: moveml a0@(4:W),d1-d7 | restore all data registers \n\
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#endif /* STACK_EXTENSION */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#elif defined(__PPC__)
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#if defined(STACK_EXTENSION)
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#error "STACK_EXTENSION is not supported on the PowerPC"
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#else
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#ifdef PPC_FLOATING_POINT_SUPPORT
|
||||
|
||||
__asm(" \n\
|
||||
@@ -403,8 +294,6 @@ longjmp: \n\
|
||||
|
||||
#endif /* defined PPC_FLOATING_POINT_SUPPORT */
|
||||
|
||||
#endif /* defined STACK_EXTENSION */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#endif /* PPC */
|
||||
|
||||
192
library/stdlib_shared_objs.c
Normal file
192
library/stdlib_shared_objs.c
Normal file
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
* $Id: stdlib_shared_objs.c,v 1.1 2010-08-21 11:37:03 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
* Portable ISO 'C' (1994) runtime library for the Amiga computer
|
||||
* Copyright (c) 2002-2010 by Olaf Barthel <olsen (at) sourcery.han.de>
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if defined(__amigaos4__)
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#ifndef _STDLIB_HEADERS_H
|
||||
#include "stdlib_headers.h"
|
||||
#endif /* _STDLIB_HEADERS_H */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#include <libraries/elf.h>
|
||||
#include <proto/elf.h>
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* These are used to initialize the shared objects linked to this binary,
|
||||
and for the dlopen(), dlclose() and dlsym() functions. */
|
||||
struct Library * __ElfBase;
|
||||
struct ElfIFace * __IElf;
|
||||
|
||||
/* This is used with the dlopen(), dlclose() and dlsym() functions. */
|
||||
Elf32_Handle __dl_elf_handle;
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* This is used to initialize the shared objects only. */
|
||||
static Elf32_Handle elf_handle;
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
void shared_obj_init(void);
|
||||
void shared_obj_exit(void);
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
static VOID close_elf_library(void)
|
||||
{
|
||||
if(__IElf != NULL)
|
||||
{
|
||||
DropInterface((struct Interface *)__IElf);
|
||||
__IElf = NULL;
|
||||
}
|
||||
|
||||
if(__ElfBase != NULL)
|
||||
{
|
||||
CloseLibrary(__ElfBase);
|
||||
__ElfBase = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
static BOOL open_elf_library(void)
|
||||
{
|
||||
BOOL success = FALSE;
|
||||
|
||||
/* We need elf.library V52.2 or higher. */
|
||||
__ElfBase = OpenLibrary("elf.library",0);
|
||||
if(__ElfBase == NULL || (__ElfBase->lib_Version < 52) || (__ElfBase->lib_Version == 52 && __ElfBase->lib_Revision < 2))
|
||||
goto out;
|
||||
|
||||
__IElf = (struct ElfIFace *)GetInterface(__ElfBase,"main",1,NULL);
|
||||
if(__IElf == NULL)
|
||||
goto out;
|
||||
|
||||
success = TRUE;
|
||||
|
||||
out:
|
||||
|
||||
return(success);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
void shared_obj_exit(void)
|
||||
{
|
||||
struct ElfIFace * IElf = __IElf;
|
||||
|
||||
#ifndef __THREAD_SAFE
|
||||
{
|
||||
/* Release this program's Elf handle, if we grabbed it below. */
|
||||
if(__dl_elf_handle != NULL)
|
||||
{
|
||||
CloseElfTags(__dl_elf_handle,
|
||||
CET_ReClose,TRUE,
|
||||
TAG_DONE);
|
||||
|
||||
__dl_elf_handle = NULL;
|
||||
}
|
||||
}
|
||||
#endif /* __THREAD_SAFE */
|
||||
|
||||
/* If we got what we wanted, trigger the destructors,
|
||||
etc. in the shared objects linked to this binary. */
|
||||
if(elf_handle != NULL)
|
||||
{
|
||||
InitSHLibs(elf_handle,FALSE);
|
||||
elf_handle = NULL;
|
||||
}
|
||||
|
||||
close_elf_library();
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
void shared_obj_init(void)
|
||||
{
|
||||
if(open_elf_library())
|
||||
{
|
||||
struct ElfIFace * IElf = __IElf;
|
||||
BPTR segment_list;
|
||||
|
||||
/* Try to find the Elf handle associated with this
|
||||
program's segment list. */
|
||||
segment_list = GetProcSegList(NULL,GPSLF_CLI | GPSLF_SEG);
|
||||
if(segment_list != ZERO)
|
||||
{
|
||||
if(GetSegListInfoTags(segment_list,
|
||||
GSLI_ElfHandle,&elf_handle,
|
||||
TAG_DONE) == 1)
|
||||
{
|
||||
if(elf_handle != NULL)
|
||||
{
|
||||
/* Trigger the constructors, etc. in the shared objects
|
||||
linked to this binary. */
|
||||
InitSHLibs(elf_handle,TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Next: try to grab the Elf handle associated with the currently
|
||||
running process. This is not thread-safe! */
|
||||
#ifndef __THREAD_SAFE
|
||||
{
|
||||
segment_list = GetProcSegList(NULL,GPSLF_RUN);
|
||||
if(segment_list != ZERO)
|
||||
{
|
||||
Elf32_Handle handle = NULL;
|
||||
|
||||
if(GetSegListInfoTags(segment_list,
|
||||
GSLI_ElfHandle,&handle,
|
||||
TAG_DONE) == 1)
|
||||
{
|
||||
if(handle != NULL)
|
||||
{
|
||||
__dl_elf_handle = OpenElfTags(
|
||||
OET_ElfHandle,handle,
|
||||
TAG_DONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* __THREAD_SAFE */
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#endif /*__amigaos4__ */
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: stdlib_stack_usage.c,v 1.7 2006-01-08 12:04:26 obarthel Exp $
|
||||
* $Id: stdlib_stack_usage.c,v 1.8 2010-10-20 13:50:17 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@@ -43,11 +43,6 @@ static struct StackSwapStruct stack_swap_struct;
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
ULONG __stk_extensions; /* number of stack extensions performed */
|
||||
ULONG __stk_maxsize; /* maximum amount of memory allocated for stack extension */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#define STACK_FILL_COOKIE 0xA1
|
||||
|
||||
/****************************************************************************/
|
||||
@@ -96,17 +91,6 @@ __stack_usage_exit(void)
|
||||
stack_swap_struct.stk_Lower = NULL;
|
||||
stack_swap_struct.stk_Upper = 0;
|
||||
}
|
||||
|
||||
if(__stk_maxsize == 0)
|
||||
{
|
||||
kprintf("[%s] no stack extension was performed\n",
|
||||
__program_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
kprintf("[%s] maximum size of extended stack = %ld bytes, stack was extended %ld times\n",
|
||||
__program_name,__stk_maxsize,__stk_extensions);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* $Id: stdlib_stackargbytes.c,v 1.4 2006-01-08 12:04:26 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
* Portable ISO 'C' (1994) runtime library for the Amiga computer
|
||||
* Copyright (c) 2002-2006 by Olaf Barthel <olsen (at) sourcery.han.de>
|
||||
* 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 EXEC_TYPES_H
|
||||
#include <exec/types.h>
|
||||
#endif /* EXEC_TYPES_H */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
ULONG __stk_argbytes = 256;
|
||||
@@ -1,142 +0,0 @@
|
||||
/*
|
||||
* $Id: stdlib_stackcheck.c,v 1.10 2006-01-08 12:04:26 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
* Portable ISO 'C' (1994) runtime library for the Amiga computer
|
||||
* Copyright (c) 2002-2006 by Olaf Barthel <olsen (at) sourcery.han.de>
|
||||
* 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_CONSTRUCTOR_H
|
||||
#include "stdlib_constructor.h"
|
||||
#endif /* _STDLIB_CONSTRUCTOR_H */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#if (defined(__GNUC__) && !defined(__PPC__))
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* The stack extension code has its own set of these routines. */
|
||||
#ifndef STACK_EXTENSION
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#if defined(SMALL_DATA)
|
||||
#define A4(x) "a4@(" #x ":W)"
|
||||
#elif defined(SMALL_DATA32)
|
||||
#define A4(x) "a4@(" #x ":L)"
|
||||
#else
|
||||
#define A4(x) #x
|
||||
#endif /* SMALL_DATA */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
asm(" \n\
|
||||
\n\
|
||||
.text \n\
|
||||
.even \n\
|
||||
\n\
|
||||
.globl ___stkovf \n\
|
||||
.globl ___stk_limit \n\
|
||||
\n\
|
||||
.globl ___stkchk_d0 \n\
|
||||
\n\
|
||||
___stkchk_d0: \n\
|
||||
\n\
|
||||
negl d0 \n\
|
||||
addl sp,d0 \n\
|
||||
cmpl "A4(___stk_limit)",d0 \n\
|
||||
jcs overflow | if (sp-d0) < __stk_limit then we have an overflow\n\
|
||||
rts \n\
|
||||
\n\
|
||||
.globl ___stkchk_0 \n\
|
||||
\n\
|
||||
___stkchk_0: \n\
|
||||
\n\
|
||||
cmpl "A4(___stk_limit)",sp \n\
|
||||
jcs overflow | if sp < __stk_limit then we have an overflow\n\
|
||||
rts \n\
|
||||
\n\
|
||||
overflow: \n\
|
||||
\n\
|
||||
movel #0,"A4(___stk_limit)" | disable stack checking \n\
|
||||
jra ___stkovf \n\
|
||||
\n\
|
||||
");
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#endif /* STACK_EXTENSION && !__PPC__ */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
UBYTE * NOCOMMON __stk_limit;
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#if defined(__SASC)
|
||||
|
||||
UBYTE * __base;
|
||||
|
||||
#endif /* __SASC */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
STK_CONSTRUCTOR(stk_init)
|
||||
{
|
||||
struct Task * this_task = FindTask(NULL);
|
||||
ULONG lower = (ULONG)this_task->tc_SPLower;
|
||||
|
||||
ENTER();
|
||||
|
||||
#if defined(__GNUC__)
|
||||
{
|
||||
__stk_limit = (UBYTE *)(lower + __stk_safezone + __stk_argbytes);
|
||||
}
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#if defined(__SASC)
|
||||
{
|
||||
__base = (UBYTE *)(lower + __stk_safezone + __stk_argbytes);
|
||||
}
|
||||
#endif /* __SASC */
|
||||
|
||||
LEAVE();
|
||||
|
||||
CONSTRUCTOR_SUCCEED();
|
||||
}
|
||||
@@ -1,649 +0,0 @@
|
||||
/*
|
||||
* $Id: stdlib_stackextension.c,v 1.13 2006-01-08 12:04:26 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
* Portable ISO 'C' (1994) runtime library for the Amiga computer
|
||||
* Copyright (c) 2002-2006 by Olaf Barthel <olsen (at) sourcery.han.de>
|
||||
* 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 */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#ifndef _STDLIB_CONSTRUCTOR_H
|
||||
#include "stdlib_constructor.h"
|
||||
#endif /* _STDLIB_CONSTRUCTOR_H */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#if (defined(__GNUC__) && !defined(__PPC__))
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#if defined(STACK_EXTENSION)
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* internal structure used by the stackextend code */
|
||||
struct stackframe
|
||||
{
|
||||
struct stackframe * next; /* NULL if there is no next one */
|
||||
void * savesp; /* stored sp for next underlying stackframe */
|
||||
void * upper; /* end of this stackframe+1 */
|
||||
};
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* Local stack extension variables */
|
||||
static void * __stk_sp_lower; /* original entries of task structure */
|
||||
static void * __stk_sp_upper; /* to restore them at exit */
|
||||
static void * __stk_initial_sp_lower; /* original stackborders */
|
||||
static void * __stk_initial_sp_upper;
|
||||
static struct stackframe * __stk_used; /* used stackframes */
|
||||
static struct stackframe * __stk_spare; /* spare stackframes */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
ULONG NOCOMMON __stk_extensions; /* number of stack extensions performed */
|
||||
ULONG NOCOMMON __stk_maxsize; /* maximum amount of memory allocated for stack extension */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#if defined(SMALL_DATA)
|
||||
#define A4(x) "a4@(" #x ":W)"
|
||||
#elif defined(SMALL_DATA32)
|
||||
#define A4(x) "a4@(" #x ":L)"
|
||||
#else
|
||||
#define A4(x) #x
|
||||
#endif /* SMALL_DATA */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* Glue code */
|
||||
asm("
|
||||
|
||||
_LVOStackSwap = -0x2dc
|
||||
StackSwapStruct_SIZEOF = 12
|
||||
|
||||
.globl _SysBase
|
||||
.globl ___stk_limit
|
||||
|
||||
|-----------------------------------------------------------------------------
|
||||
|
||||
.globl ___link_a5_0_f
|
||||
|
||||
___link_a5_0_f:
|
||||
|
||||
movel sp@+,a0 | load the return address into A0
|
||||
cmpl "A4(___stk_limit)",sp
|
||||
jcc l0 | if SP >= __stk_limit then we are well within bounds
|
||||
jbsr l2 | try to extend the stack
|
||||
l0: link a5,#0:W | restore frame pointer
|
||||
jmp a0@ | go to the return address
|
||||
|
||||
|-----------------------------------------------------------------------------
|
||||
|
||||
.globl ___sub_0_sp_f
|
||||
|
||||
___sub_0_sp_f:
|
||||
movel sp@+,a0 | load the return address into A0
|
||||
cmpl "A4(___stk_limit)",sp
|
||||
jcc l1 | if SP >= __stk_limit then we are well within bounds
|
||||
jbsr l2 | try to extend the stack
|
||||
l1: jmp a0@ | go to the return address
|
||||
|
||||
l2: moveq #0,d0
|
||||
moveq #0,d1
|
||||
jra ___stkext_f | try stack extension
|
||||
|
||||
|-----------------------------------------------------------------------------
|
||||
|
||||
.globl ___link_a5_d0_f
|
||||
|
||||
___link_a5_d0_f:
|
||||
movel sp@+,a0 | load the return address into A0
|
||||
movel sp,d1
|
||||
subl d0,d1 | D0 holds size of stack adjustment to make
|
||||
cmpl "A4(___stk_limit)",d1
|
||||
jcc l3 | if (SP-D0) >= __stk_limit then we are well within bounds
|
||||
jbsr l5 | try stack extension
|
||||
l3: link a5,#0:W | restore the frame pointer
|
||||
subl d0,sp | adjust the stack pointer, as required
|
||||
jmp a0@ | go to the return address
|
||||
|
||||
|-----------------------------------------------------------------------------
|
||||
|
||||
.globl ___sub_d0_sp_f
|
||||
|
||||
___sub_d0_sp_f:
|
||||
movel sp@+,a0 | load the return address into A0
|
||||
movel sp,d1
|
||||
subl d0,d1 | D0 holds size of stack adjustment to make
|
||||
cmpl "A4(___stk_limit)",d1
|
||||
jcc l4 | if (SP-D0) >= __stk_limit then we are well within bounds
|
||||
jbsr l5 | try stack extension
|
||||
l4: subl d0,sp | adjust the stack pointer, as required
|
||||
jmp a0@ | go to the return address
|
||||
|
||||
l5: moveq #0,d1
|
||||
jra ___stkext_f | try stack extension
|
||||
|
||||
|-----------------------------------------------------------------------------
|
||||
|
||||
.globl ___sub_d0_sp
|
||||
|
||||
___sub_d0_sp:
|
||||
movel sp@+,a0 | load the return address into A0
|
||||
movel sp,d1
|
||||
subl d0,d1 | D0 holds size of stack adjustment to make
|
||||
cmpl "A4(___stk_limit)",d1
|
||||
jcc l6 | if (SP-D0) >= __stk_limit then we are well within bounds
|
||||
jbsr ___stkext | try stack extension
|
||||
l6: subl d0,sp | adjust the stack pointer, as required
|
||||
jmp a0@ | go to the return address
|
||||
|
||||
|-----------------------------------------------------------------------------
|
||||
|
||||
.globl ___move_d0_sp
|
||||
|
||||
___move_d0_sp:
|
||||
jra ___stkrst | Straight jump into ___stkrst
|
||||
|
||||
|-----------------------------------------------------------------------------
|
||||
|
||||
.globl ___unlk_a5_rts
|
||||
|
||||
___unlk_a5_rts:
|
||||
movel d0,a0 | Preserve D0
|
||||
movel a5,d0 | A5 is stack pointer to be restored
|
||||
jbsr ___stkrst
|
||||
movel a0,d0 | Restore D0
|
||||
movel sp@+,a5 | Restore A5, thus performing 'unlink A5'
|
||||
rts
|
||||
|
||||
|-----------------------------------------------------------------------------
|
||||
|
||||
.globl ___stkext
|
||||
|
||||
___stkext:
|
||||
moveml d0/d1/a0/a1/a6,sp@-
|
||||
subw #StackSwapStruct_SIZEOF,sp
|
||||
jbsr _stkext
|
||||
tstl d0
|
||||
jeq s_noext
|
||||
movel "A4(_SysBase)",a6
|
||||
movel sp,a0
|
||||
jsr a6@(_LVOStackSwap)
|
||||
s_ret:
|
||||
moveml sp@+,d0/d1/a0/a1/a6
|
||||
rts
|
||||
s_noext:
|
||||
addw #StackSwapStruct_SIZEOF,sp
|
||||
jra s_ret
|
||||
|
||||
|-----------------------------------------------------------------------------
|
||||
|
||||
.globl ___stkext_f
|
||||
|
||||
___stkext_f:
|
||||
moveml d0/d1/a0/a1/a6,sp@-
|
||||
subw #StackSwapStruct_SIZEOF,sp
|
||||
jbsr _stkext_f
|
||||
tstl d0
|
||||
jeq sf_noext
|
||||
movel "A4(_SysBase)",a6
|
||||
movel sp,a0
|
||||
jsr a6@(_LVOStackSwap)
|
||||
sf_ret:
|
||||
moveml sp@+,d0/d1/a0/a1/a6
|
||||
rts
|
||||
sf_noext:
|
||||
addw #StackSwapStruct_SIZEOF,sp
|
||||
jra sf_ret
|
||||
|
||||
|-----------------------------------------------------------------------------
|
||||
|
||||
.globl ___stkrst_f
|
||||
|
||||
___stkrst_f:
|
||||
moveml d0/d1/a0/a1/a6,sp@-
|
||||
subw #StackSwapStruct_SIZEOF,sp
|
||||
jbsr _stkrst_f
|
||||
movel "A4(_SysBase)",a6
|
||||
movel sp,a0
|
||||
jsr a6@(_LVOStackSwap)
|
||||
moveml sp@+,d0/d1/a0/a1/a6
|
||||
rts
|
||||
|
||||
|-----------------------------------------------------------------------------
|
||||
|
||||
.globl ___stkrst
|
||||
|
||||
___stkrst:
|
||||
moveml d0/d1/a0/a1/a6,sp@-
|
||||
subw #StackSwapStruct_SIZEOF,sp
|
||||
jbsr _stkrst | calculate either target sp or StackSwapStruct
|
||||
tstl d0 | set target sp?
|
||||
jeq swpfrm | jump if not
|
||||
movel d0,a0 | I have a lot of preserved registers and
|
||||
| returnadresses on the stack. It's necessary
|
||||
| to copy them to the new location
|
||||
moveq #6,d0 | 1 rts, 5 regs and 1 signal mask to copy (1+5+1)-1=6
|
||||
lea sp@(40:W),a1 | get address of uppermost byte+1 (1+5+1)*4+StackSwapStruct_SIZEOF=40
|
||||
cmpl a0,a1 | compare with target location
|
||||
jls lp1 | jump if source<=target
|
||||
lea a0@(-28:W),a0 | else start at lower bound (1+5+1)*4=28
|
||||
lea a1@(-28:W),a1
|
||||
movel a0,sp | set sp to reserve the room
|
||||
lp0:
|
||||
movel a1@+,a0@+ | copy with raising addresses
|
||||
dbra d0,lp0 | as long as d0>=0.
|
||||
jra endlp | ready
|
||||
lp1:
|
||||
movel a1@-,a0@- | copy with falling addresses
|
||||
dbra d0,lp1 | as long as d0>=0
|
||||
movel a0,sp | finally set sp
|
||||
jra endlp | ready
|
||||
swpfrm:
|
||||
movel "A4(_SysBase)",a6
|
||||
movel sp,a0
|
||||
jsr a6@(_LVOStackSwap)
|
||||
endlp:
|
||||
moveml sp@+,d0/d1/a0/a1/a6 | restore registers
|
||||
rts | and return
|
||||
|
||||
");
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
UBYTE * __stk_limit;
|
||||
ULONG __stk_size;
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
STK_CONSTRUCTOR(stk_init)
|
||||
{
|
||||
struct Task *task = FindTask(NULL);
|
||||
|
||||
ENTER();
|
||||
|
||||
__stk_initial_sp_lower = __stk_sp_lower = task->tc_SPLower; /* Lower stack bound */
|
||||
__stk_initial_sp_upper = __stk_sp_upper = task->tc_SPUpper; /* Upper stack bound +1 */
|
||||
|
||||
SHOWPOINTER(__stk_sp_lower);
|
||||
SHOWPOINTER(__stk_sp_upper);
|
||||
|
||||
D(("stack size = %ld",(ULONG)__stk_sp_upper - (ULONG)__stk_sp_lower));
|
||||
|
||||
LEAVE();
|
||||
|
||||
CONSTRUCTOR_SUCCEED();
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* Free all spare stackframes */
|
||||
STK_DESTRUCTOR(stk_exit)
|
||||
{
|
||||
ENTER();
|
||||
|
||||
if(__memory_pool == NULL)
|
||||
{
|
||||
struct stackframe *sf, *sf_next;
|
||||
|
||||
SHOWMSG("we don't have a memory pool; cleaning up the stack frames manually");
|
||||
|
||||
for(sf = __stk_spare ; sf != NULL ; sf = sf_next)
|
||||
{
|
||||
sf_next = sf->next;
|
||||
|
||||
FreeMem(sf, (char *)sf->upper - (char *)sf);
|
||||
}
|
||||
}
|
||||
|
||||
__stk_spare = NULL;
|
||||
|
||||
LEAVE();
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* Move a stackframe with a minimum of requiredstack bytes to the used list
|
||||
and fill the StackSwapStruct structure. */
|
||||
STATIC VOID
|
||||
pushframe(ULONG requiredstack, struct StackSwapStruct *sss)
|
||||
{
|
||||
struct stackframe *sf;
|
||||
ULONG recommendedstack;
|
||||
|
||||
ENTER();
|
||||
|
||||
requiredstack += __stk_safezone + __stk_argbytes;
|
||||
if (requiredstack < __stk_minframe)
|
||||
requiredstack = __stk_minframe;
|
||||
|
||||
SHOWVALUE(requiredstack);
|
||||
|
||||
recommendedstack = __stk_maxsize - __stk_size;
|
||||
if (recommendedstack < requiredstack)
|
||||
recommendedstack = requiredstack;
|
||||
|
||||
SHOWVALUE(recommendedstack);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
sf = __stk_spare; /* get a stackframe from the spares list */
|
||||
if (sf == NULL) /* stack overflown */
|
||||
{
|
||||
for ( ; recommendedstack >= requiredstack ; recommendedstack /= 2)
|
||||
{
|
||||
D(("allocating %ld bytes for a stack frame",recommendedstack + sizeof(struct stackframe)));
|
||||
|
||||
if(__memory_pool != NULL)
|
||||
{
|
||||
__memory_lock();
|
||||
|
||||
sf = AllocPooled(__memory_pool,recommendedstack + sizeof(struct stackframe));
|
||||
|
||||
__memory_unlock();
|
||||
}
|
||||
else
|
||||
{
|
||||
sf = AllocMem(recommendedstack + sizeof(struct stackframe), MEMF_ANY);
|
||||
}
|
||||
|
||||
if (sf != NULL)
|
||||
break;
|
||||
|
||||
SHOWMSG("that didn't work");
|
||||
}
|
||||
|
||||
if (sf == NULL) /* and we have no way to extend it :-| */
|
||||
{
|
||||
SHOWMSG("bad luck... stack overflow!");
|
||||
__stkovf();
|
||||
}
|
||||
|
||||
sf->upper = (char *)(sf + 1) + recommendedstack;
|
||||
break;
|
||||
}
|
||||
|
||||
__stk_spare = sf->next;
|
||||
if ((ULONG)((char *)sf->upper - (char *)(sf + 1)) >= recommendedstack)
|
||||
break;
|
||||
|
||||
if(__memory_pool != NULL)
|
||||
{
|
||||
__memory_lock();
|
||||
|
||||
FreePooled(__memory_pool, sf, (char *)sf->upper - (char *)sf);
|
||||
|
||||
__memory_unlock();
|
||||
}
|
||||
else
|
||||
{
|
||||
FreeMem(sf, (char *)sf->upper - (char *)sf);
|
||||
}
|
||||
}
|
||||
|
||||
/* Add stackframe to the used list */
|
||||
sf->next = __stk_used;
|
||||
__stk_used = sf;
|
||||
__stk_limit = (char *)(sf + 1) + __stk_safezone + __stk_argbytes;
|
||||
|
||||
/* prepare StackSwapStruct */
|
||||
(void *)sss->stk_Pointer = (void *)sf->upper;
|
||||
sss->stk_Lower = sf + 1;
|
||||
(ULONG)sss->stk_Upper = (ULONG)sf->upper;
|
||||
|
||||
/* Update stack statistics. */
|
||||
__stk_size += (char *)sf->upper - (char *)(sf + 1);
|
||||
if (__stk_size > __stk_maxsize)
|
||||
__stk_maxsize = __stk_size;
|
||||
|
||||
__stk_extensions++;
|
||||
|
||||
SHOWVALUE(__stk_size);
|
||||
SHOWVALUE(__stk_maxsize);
|
||||
SHOWVALUE(__stk_extensions);
|
||||
|
||||
LEAVE();
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#define STK_UPPER (__stk_used != NULL ? __stk_used->upper : __stk_initial_sp_upper)
|
||||
#define STK_LOWER (__stk_used != NULL ? (void *)(__stk_used + 1) : __stk_initial_sp_lower)
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* Allocate a new stackframe with d0 bytes minimum. */
|
||||
int
|
||||
stkext(struct StackSwapStruct sss, long d0, long d1, long a0, long a1, long a6, long ret1)
|
||||
{
|
||||
void *callsp = &ret1 + 1;
|
||||
int cpsize = (char *)callsp - (char *)&d0;
|
||||
int result;
|
||||
|
||||
ENTER();
|
||||
|
||||
D(("new stack frame with at least %ld bytes space is required", d0));
|
||||
|
||||
if (callsp >= STK_UPPER || callsp < STK_LOWER)
|
||||
{
|
||||
SHOWMSG("that didn't turn out right");
|
||||
|
||||
result = 0; /* User intentionally left area of stackextension */
|
||||
}
|
||||
else
|
||||
{
|
||||
pushframe((ULONG)d0, &sss);
|
||||
*(char **)&sss.stk_Pointer -= cpsize;
|
||||
CopyMem(&d0, sss.stk_Pointer, cpsize);
|
||||
|
||||
SHOWMSG("done");
|
||||
|
||||
result = 1;
|
||||
}
|
||||
|
||||
RETURN (result);
|
||||
return (result);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* Defined in the glue code above. */
|
||||
extern void __stkrst_f(void);
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* Allocate a new stackframe with d0 bytes minimum, copy the callers arguments
|
||||
and set his returnaddress (offset d1 from the sp when called) to stk_rst_f */
|
||||
int
|
||||
stkext_f(struct StackSwapStruct sss, long d0, long d1, long a0, long a1, long a6, long ret1)
|
||||
{
|
||||
void *argtop, *callsp = &ret1 + 1;
|
||||
int cpsize;
|
||||
int result;
|
||||
|
||||
ENTER();
|
||||
|
||||
D(("new stack frame with at least %ld bytes space is required", d0));
|
||||
|
||||
if (callsp >= STK_UPPER || callsp < STK_LOWER)
|
||||
{
|
||||
SHOWMSG("that didn't turn out right");
|
||||
|
||||
result = 0; /* User intentionally left area of stackextension */
|
||||
}
|
||||
else
|
||||
{
|
||||
argtop = (char *)callsp + __stk_argbytes; /* Top of area with arguments */
|
||||
if (argtop > STK_UPPER)
|
||||
argtop = STK_UPPER;
|
||||
|
||||
cpsize = (char *)argtop - (char *)&d0;
|
||||
|
||||
pushframe((ULONG)d0, &sss);
|
||||
*(char **)&sss.stk_Pointer -= cpsize;
|
||||
CopyMem(&d0, sss.stk_Pointer, cpsize);
|
||||
|
||||
__stk_used->savesp = (char *)callsp + d1; /* store sp */
|
||||
*(void **)((char *)sss.stk_Upper - ((char *)argtop - (char *)callsp) + d1) = &__stkrst_f; /* set returnaddress */
|
||||
|
||||
SHOWMSG("done");
|
||||
|
||||
result = 1;
|
||||
}
|
||||
|
||||
RETURN (result);
|
||||
return (result);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* Move all used stackframes upto (and including) sf to the spares list
|
||||
and fill the StackSwapStruct structure. */
|
||||
STATIC VOID
|
||||
popframes(struct stackframe *sf, struct StackSwapStruct *sss)
|
||||
{
|
||||
struct stackframe *sf2;
|
||||
|
||||
ENTER();
|
||||
|
||||
if (sf->next != NULL)
|
||||
{
|
||||
sss->stk_Lower = sf->next + 1;
|
||||
(ULONG)sss->stk_Upper = (ULONG)sf->next->upper;
|
||||
__stk_limit = (char *)(sf->next + 1) + __stk_safezone + __stk_argbytes;
|
||||
}
|
||||
else
|
||||
{
|
||||
sss->stk_Lower = __stk_sp_lower;
|
||||
(ULONG)sss->stk_Upper = (ULONG)__stk_sp_upper;
|
||||
__stk_limit = (char *)__stk_initial_sp_lower + __stk_safezone + __stk_argbytes;
|
||||
}
|
||||
|
||||
sf2 = __stk_spare;
|
||||
__stk_spare = __stk_used;
|
||||
__stk_used = sf->next;
|
||||
sf->next = sf2;
|
||||
|
||||
/* Update stack statistics. */
|
||||
for (sf2 = __stk_spare ; sf2 != sf->next ; sf2 = sf2->next)
|
||||
__stk_size -= (char *)sf2->upper - (char *)(sf2 + 1);
|
||||
|
||||
SHOWVALUE(__stk_size);
|
||||
|
||||
LEAVE();
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* Set stackpointer back to some previous value
|
||||
!= NULL: on the same stackframe (returns sp)
|
||||
== NULL: on another stackframe */
|
||||
void *
|
||||
stkrst(struct StackSwapStruct sss, void *d0, long d1, long a0, long a1, long a6, long ret1)
|
||||
{
|
||||
void *callsp = &ret1 + 1;
|
||||
int cpsize = (char *)callsp - (char *)&d0;
|
||||
struct stackframe *sf1, *sf2;
|
||||
void * result = d0;
|
||||
|
||||
ENTER();
|
||||
|
||||
if (d0 >= STK_LOWER && d0 < STK_UPPER)
|
||||
goto out;
|
||||
|
||||
sf1 = __stk_used;
|
||||
if (sf1 == NULL)
|
||||
goto out;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
sf2 = sf1->next;
|
||||
if (sf2 == NULL)
|
||||
{
|
||||
if (d0 < __stk_initial_sp_lower || d0 >= __stk_initial_sp_upper)
|
||||
goto out;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (d0 >= (void *)(sf2 + 1) && d0 < sf2->upper) /* This stackframe fits */
|
||||
break;
|
||||
|
||||
sf1 = sf2;
|
||||
}
|
||||
|
||||
popframes(sf1, &sss);
|
||||
sss.stk_Pointer = (char *)d0 - cpsize;
|
||||
CopyMem(&d0, sss.stk_Pointer,cpsize);
|
||||
|
||||
result = NULL;
|
||||
|
||||
out:
|
||||
|
||||
RETURN (result);
|
||||
return (result);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* return to last stackframe */
|
||||
void
|
||||
stkrst_f(struct StackSwapStruct sss, long d0, long d1, long a0, long a1, long a6)
|
||||
{
|
||||
void *callsp = &a6 + 1; /* This one has no returnaddress - it's a fallback for rts */
|
||||
int cpsize = (char *)callsp - (char *)&d0;
|
||||
|
||||
ENTER();
|
||||
|
||||
sss.stk_Pointer = (char *)__stk_used->savesp - cpsize;
|
||||
popframes(__stk_used, &sss);
|
||||
CopyMem(&d0, sss.stk_Pointer, cpsize);
|
||||
|
||||
LEAVE();
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#endif /* STACK_EXTENSION */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#endif /* __GNUC__ && !__PPC__ */
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* $Id: stdlib_stackminframe.c,v 1.4 2006-01-08 12:04:26 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
* Portable ISO 'C' (1994) runtime library for the Amiga computer
|
||||
* Copyright (c) 2002-2006 by Olaf Barthel <olsen (at) sourcery.han.de>
|
||||
* 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 EXEC_TYPES_H
|
||||
#include <exec/types.h>
|
||||
#endif /* EXEC_TYPES_H */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
ULONG __stk_minframe = 32768;
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* $Id: stdlib_stacksafezone.c,v 1.4 2006-01-08 12:04:26 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
* Portable ISO 'C' (1994) runtime library for the Amiga computer
|
||||
* Copyright (c) 2002-2006 by Olaf Barthel <olsen (at) sourcery.han.de>
|
||||
* 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 EXEC_TYPES_H
|
||||
#include <exec/types.h>
|
||||
#endif /* EXEC_TYPES_H */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
ULONG __stk_safezone = 2048;
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: stdlib_unsetenv.c,v 1.8 2006-09-25 14:51:15 obarthel Exp $
|
||||
* $Id: stdlib_unsetenv.c,v 1.10 2008-04-30 16:32:49 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@@ -43,6 +43,12 @@
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#ifndef _STDIO_HEADERS_H
|
||||
#include "stdio_headers.h"
|
||||
#endif /* _STDIO_HEADERS_H */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#ifndef _STDLIB_MEMORY_H
|
||||
#include "stdlib_memory.h"
|
||||
#endif /* _STDLIB_MEMORY_H */
|
||||
@@ -53,10 +59,12 @@
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
void
|
||||
int
|
||||
unsetenv(const char *name)
|
||||
{
|
||||
char * name_copy = NULL;
|
||||
int result = -1;
|
||||
LONG status;
|
||||
size_t i;
|
||||
|
||||
if(__check_abort_enabled)
|
||||
@@ -91,11 +99,21 @@ unsetenv(const char *name)
|
||||
}
|
||||
|
||||
PROFILE_OFF();
|
||||
DeleteVar((STRPTR)name,0);
|
||||
status = DeleteVar((STRPTR)name,0);
|
||||
PROFILE_ON();
|
||||
|
||||
if(status == DOSFALSE)
|
||||
{
|
||||
__set_errno(__translate_access_io_error_to_errno(IoErr()));
|
||||
goto out;
|
||||
}
|
||||
|
||||
result = 0;
|
||||
|
||||
out:
|
||||
|
||||
if(name_copy != NULL)
|
||||
free(name_copy);
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: string_memcmp.c,v 1.7 2006-01-08 12:04:26 obarthel Exp $
|
||||
* $Id: string_memcmp.c,v 1.8 2010-08-20 15:33:36 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@@ -135,7 +135,14 @@ __memcmp(const char *m1,const char *m2,size_t len)
|
||||
{
|
||||
if((*m1) != (*m2))
|
||||
{
|
||||
result = (*m1) - (*m2);
|
||||
int b1,b2;
|
||||
|
||||
/* The comparison must be performed as if the
|
||||
bytes were unsigned characters. */
|
||||
b1 = *(unsigned char *)m1;
|
||||
b2 = *(unsigned char *)m2;
|
||||
|
||||
result = b1 - b2;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -185,7 +192,12 @@ memcmp(const void *ptr1, const void *ptr2, size_t len)
|
||||
{
|
||||
if((*m1) != (*m2))
|
||||
{
|
||||
result = (*m1) - (*m2);
|
||||
int b1,b2;
|
||||
|
||||
b1 = *(unsigned char *)m1;
|
||||
b2 = *(unsigned char *)m2;
|
||||
|
||||
result = b1 - b2;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: string_strcmp.c,v 1.4 2006-01-08 12:04:27 obarthel Exp $
|
||||
* $Id: string_strcmp.c,v 1.5 2010-08-20 15:33:36 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@@ -62,6 +62,8 @@ strcmp(const char *s1, const char * s2)
|
||||
|
||||
if(s1 != s2)
|
||||
{
|
||||
int c1,c2;
|
||||
|
||||
while((*s1) == (*s2))
|
||||
{
|
||||
if((*s1) == '\0')
|
||||
@@ -71,7 +73,12 @@ strcmp(const char *s1, const char * s2)
|
||||
s2++;
|
||||
}
|
||||
|
||||
result = (*s1) - (*s2);
|
||||
/* The comparison must be performed as if the
|
||||
characters were unsigned characters. */
|
||||
c1 = *(unsigned char *)s1;
|
||||
c2 = *(unsigned char *)s2;
|
||||
|
||||
result = c1 - c2;
|
||||
}
|
||||
|
||||
out:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: string_strncmp.c,v 1.4 2006-01-08 12:04:27 obarthel Exp $
|
||||
* $Id: string_strncmp.c,v 1.5 2010-08-20 15:33:36 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@@ -78,7 +78,14 @@ strncmp(const char *s1, const char *s2, size_t n)
|
||||
}
|
||||
else
|
||||
{
|
||||
result = (*s1) - (*s2);
|
||||
int c1,c2;
|
||||
|
||||
/* The comparison must be performed as if the
|
||||
characters were unsigned characters. */
|
||||
c1 = *(unsigned char *)s1;
|
||||
c2 = *(unsigned char *)s2;
|
||||
|
||||
result = c1 - c2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: systeminfo_sysinfo.c,v 1.5 2006-09-22 09:02:51 obarthel Exp $
|
||||
* $Id: systeminfo_sysinfo.c,v 1.6 2010-08-20 15:33:36 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@@ -141,7 +141,7 @@ sysinfo(int cmd,char *buf,long buflen)
|
||||
|
||||
GetCPUInfoTags(GCIT_VectorUnit,&vecu,TAG_DONE);
|
||||
|
||||
if(vecu == VECTORTYPE_ALTIVEC || vecu == VECTORTYPE_VMX) /* AltiVec and VMX are the same. */
|
||||
if(vecu == VECTORTYPE_ALTIVEC || vecu == 2 /* VECTORTYPE_VMX == 2 */) /* AltiVec and VMX are the same. */
|
||||
s = "ppc+altivec ppc common";
|
||||
else
|
||||
s = "ppc common";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: termios_console_fdhookentry.c,v 1.5 2006-11-16 14:39:23 obarthel Exp $
|
||||
* $Id: termios_console_fdhookentry.c,v 1.6 2010-10-20 13:12:59 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@@ -474,6 +474,7 @@ __termios_console_hook(
|
||||
|
||||
/* And that's the last for this file descriptor. */
|
||||
memset(fd,0,sizeof(*fd));
|
||||
fd = NULL;
|
||||
|
||||
break;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: unistd_common_pathconf.c,v 1.3 2006-09-21 09:24:20 obarthel Exp $
|
||||
* $Id: unistd_common_pathconf.c,v 1.4 2008-04-16 07:38:10 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@@ -55,6 +55,18 @@
|
||||
#define ID_RAWCON (0x52415700L) /* 'RAW\0' */
|
||||
#endif /* ID_RAWCON */
|
||||
|
||||
#ifndef ID_BUSY_DISK
|
||||
#define ID_BUSY_DISK (0x42555359L) /* 'BUSY' */
|
||||
#endif /* ID_LONGNAME_DOS_DISK */
|
||||
|
||||
#ifndef ID_LONGNAME_DOS_DISK
|
||||
#define ID_LONGNAME_DOS_DISK (0x444F5306L) /* 'DOS\6' */
|
||||
#endif /* ID_LONGNAME_DOS_DISK */
|
||||
|
||||
#ifndef ID_LONGNAME_FFS_DISK
|
||||
#define ID_LONGNAME_FFS_DISK (0x444F5307L) /* 'DOS\7' */
|
||||
#endif /* ID_LONGNAME_FFS_DISK */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
struct fs_info
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: unistd_isatty.c,v 1.9 2006-11-16 14:39:23 obarthel Exp $
|
||||
* $Id: unistd_isatty.c,v 1.11 2010-10-20 13:12:59 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@@ -69,6 +69,12 @@ isatty(int file_descriptor)
|
||||
|
||||
__fd_lock(fd);
|
||||
|
||||
if(FLAG_IS_SET(fd->fd_Flags,FDF_IS_SOCKET))
|
||||
{
|
||||
__set_errno(ENOTTY);
|
||||
goto out;
|
||||
}
|
||||
|
||||
result = 1;
|
||||
|
||||
if(FLAG_IS_CLEAR(fd->fd_Flags,FDF_IS_INTERACTIVE))
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: unistd_translateu2a.c,v 1.11 2006-10-03 16:36:47 obarthel Exp $
|
||||
* $Id: unistd_translateu2a.c,v 1.12 2010-08-20 15:33:36 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@@ -50,6 +50,7 @@
|
||||
* ././foo
|
||||
* foo/./baz
|
||||
* foo/./bar/./baz
|
||||
* foo/./././bar
|
||||
* foo/.
|
||||
* /.
|
||||
* /tmp
|
||||
@@ -260,7 +261,7 @@ __translate_unix_to_amiga_path_name(char const ** name_ptr,struct name_translati
|
||||
D(("name = '%s' (line %ld)",name,__LINE__));
|
||||
}
|
||||
|
||||
/* Ditch all embedded '/./' ('foo/./bar' -> 'foo/bar'). */
|
||||
/* Ditch all embedded '/./' ('foo/./bar' -> 'foo/bar', 'foo/././bar' -> 'foo/bar'). */
|
||||
if(len > 2)
|
||||
{
|
||||
BOOL have_slash_dot_slash = FALSE;
|
||||
@@ -278,10 +279,11 @@ __translate_unix_to_amiga_path_name(char const ** name_ptr,struct name_translati
|
||||
{
|
||||
for(i = j = 0 ; i < len ; i++)
|
||||
{
|
||||
replace[j++] = name[i];
|
||||
|
||||
if(name[i] == '/' && name[i + 1] == '.' && name[i + 2] == '/')
|
||||
while(i < len - 2 && name[i] == '/' && name[i + 1] == '.' && name[i + 2] == '/')
|
||||
i += 2;
|
||||
|
||||
if(i < len)
|
||||
replace[j++] = name[i];
|
||||
}
|
||||
|
||||
len = j;
|
||||
@@ -474,10 +476,10 @@ __translate_unix_to_amiga_path_name(char const ** name_ptr,struct name_translati
|
||||
{
|
||||
for(i = j = 0 ; i < len ; i++)
|
||||
{
|
||||
replace[j++] = name[i];
|
||||
|
||||
if(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++] = name[i];
|
||||
}
|
||||
|
||||
len = j;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#define VERSION 1
|
||||
#define REVISION 202
|
||||
#define DATE "16.1.2007"
|
||||
#define VERS "unix.lib 1.202"
|
||||
#define VSTRING "unix.lib 1.202 (16.1.2007)\r\n"
|
||||
#define VERSTAG "\0$VER: unix.lib 1.202 (16.1.2007)"
|
||||
#define REVISION 205
|
||||
#define DATE "21.8.2010"
|
||||
#define VERS "unix.lib 1.205"
|
||||
#define VSTRING "unix.lib 1.205 (21.8.2010)\r\n"
|
||||
#define VERSTAG "\0$VER: unix.lib 1.205 (21.8.2010)"
|
||||
|
||||
@@ -1 +1 @@
|
||||
202
|
||||
205
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: utsname_uname.c,v 1.7 2006-11-13 09:25:28 obarthel Exp $
|
||||
* $Id: utsname_uname.c,v 1.8 2010-08-20 15:33:36 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@@ -135,7 +135,9 @@ uname(struct utsname *info)
|
||||
* 45.3 3.9-BB2
|
||||
*/
|
||||
|
||||
if (46 <= Version && Version <= 52)
|
||||
if (Version == 53)
|
||||
version_string = "4.1";
|
||||
else if (46 <= Version && Version <= 52)
|
||||
version_string = "4.0";
|
||||
else if (Version == 45)
|
||||
version_string = "3.9";
|
||||
|
||||
@@ -1,152 +0,0 @@
|
||||
#
|
||||
# $Id: GNUmakefile.68k,v 1.15 2006-09-25 18:20:09 obarthel Exp $
|
||||
#
|
||||
# :ts=8
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
|
||||
CC = gcc
|
||||
DELETE = delete all quiet
|
||||
|
||||
##############################################################################
|
||||
|
||||
.c.o:
|
||||
@echo "Compiling $<"
|
||||
@$(CC) -c $(CFLAGS) $<
|
||||
|
||||
##############################################################################
|
||||
|
||||
#CODE_TYPE := -fbaserel -DSMALL_DATA -m68020-60 -DM68020
|
||||
#CODE_TYPE := -fbaserel -DSMALL_DATA -m68000
|
||||
#CODE_TYPE := -fbaserel32 -DSMALL_DATA32 -m68020-60 -DM68020
|
||||
CODE_TYPE := -m68020-60 -DM68020
|
||||
#CODE_TYPE := -m68000
|
||||
|
||||
##############################################################################
|
||||
|
||||
WARNINGS = \
|
||||
-Wall -W -Wshadow -Wpointer-arith -Wsign-compare -Wmissing-prototypes \
|
||||
-Wundef -Wbad-function-cast -Wmissing-declarations -Wconversion
|
||||
|
||||
INCLUDE = -I../library/include
|
||||
LIB = -L../library/lib
|
||||
OPTIONS = -DNDEBUG -fno-builtin -fwritable-strings -DNO_INLINE_STDARG -DIEEE_FLOATING_POINT_SUPPORT
|
||||
#OPTIONS = -D__MEM_DEBUG -fno-builtin
|
||||
#OPTIONS = -DDEBUG -D__MEM_DEBUG -DNO_INLINE_STDARG -fno-builtin
|
||||
OPTIMIZE = -O
|
||||
#OPTIMIZE = -O2 -fomit-frame-pointer
|
||||
DEBUG = -ggdb
|
||||
|
||||
CFLAGS = $(WARNINGS) $(OPTIMIZE) $(DEBUG) $(OPTIONS) $(CODE_TYPE) $(INCLUDE) $(LIB)
|
||||
|
||||
##############################################################################
|
||||
|
||||
LIBS = -lm -lc -lgcc
|
||||
|
||||
##############################################################################
|
||||
|
||||
all: test fgets_test iotest sscanf_test printf_test sprintf_test \
|
||||
stack_size_test translate_test strtok_test uname simple \
|
||||
fstat_stdout_test simple_sprintf date_test sscanf_64 factorial \
|
||||
execvp_test setlocale rand fstat_test base_dir_nametest
|
||||
|
||||
clean:
|
||||
$(DELETE) #?.o #?.map test fgets_test iotest sscanf_test printf_test \
|
||||
sprintf_test stack_size_test translate_test strtok_test uname \
|
||||
simple fstat_stdout_test fstat_test simple_sprintf date_test sscanf_64 \
|
||||
factorial execvp_test setlocale rand base_dir_nametest
|
||||
|
||||
##############################################################################
|
||||
|
||||
setlocale : setlocale.o
|
||||
@echo "Linking $@"
|
||||
$(CC) $(CFLAGS) -o $@ setlocale.o $(LIBS) -Wl,--cref,-M,-Map=$@.map
|
||||
|
||||
test : test.o
|
||||
@echo "Linking $@"
|
||||
$(CC) $(CFLAGS) -o $@ test.o $(LIBS) -Wl,--cref,-M,-Map=$@.map
|
||||
|
||||
fgets_test : fgets_test.o
|
||||
@echo "Linking $@"
|
||||
$(CC) $(CFLAGS) -o $@ fgets_test.o $(LIBS) -Wl,--cref,-M,-Map=$@.map
|
||||
|
||||
strtok_test : strtok_test.o
|
||||
@echo "Linking $@"
|
||||
$(CC) $(CFLAGS) -o $@ strtok_test.o $(LIBS) -Wl,--cref,-M,-Map=$@.map
|
||||
|
||||
iotest : iotest.o
|
||||
@echo "Linking $@"
|
||||
$(CC) $(CFLAGS) -o $@ iotest.o $(LIBS) -Wl,--cref,-M,-Map=$@.map
|
||||
|
||||
sscanf_test : sscanf_test.o
|
||||
@echo "Linking $@"
|
||||
$(CC) $(CFLAGS) -o $@ sscanf_test.o $(LIBS) -Wl,--cref,-M,-Map=$@.map
|
||||
|
||||
printf_test : printf_test.o
|
||||
@echo "Linking $@"
|
||||
$(CC) $(CFLAGS) -o $@ printf_test.o $(LIBS) -Wl,--cref,-M,-Map=$@.map
|
||||
|
||||
sprintf_test : sprintf_test.o
|
||||
@echo "Linking $@"
|
||||
$(CC) $(CFLAGS) -o $@ sprintf_test.o $(LIBS) -Wl,--cref,-M,-Map=$@.map
|
||||
|
||||
stack_size_test : stack_size_test.o
|
||||
@echo "Linking $@"
|
||||
$(CC) $(CFLAGS) -o $@ stack_size_test.o $(LIBS) -Wl,--cref,-M,-Map=$@.map
|
||||
|
||||
translate_test : translate_test.o
|
||||
@echo "Linking $@"
|
||||
$(CC) $(CFLAGS) -o $@ translate_test.o -lunix $(LIBS) -Wl,--cref,-M,-Map=$@.map
|
||||
|
||||
uname : uname.o
|
||||
@echo "Linking $@"
|
||||
$(CC) $(CFLAGS) -o $@ uname.o -lunix $(LIBS) -Wl,--cref,-M,-Map=$@.map
|
||||
|
||||
simple : simple.o
|
||||
@echo "Linking $@"
|
||||
$(CC) $(CFLAGS) -o $@ simple.o $(LIBS) -Wl,--cref,-M,-Map=$@.map
|
||||
|
||||
fstat_stdout_test : fstat_stdout_test.o
|
||||
@echo "Linking $@"
|
||||
$(CC) $(CFLAGS) -o $@ fstat_stdout_test.o $(LIBS) -Wl,--cref,-M,-Map=$@.map
|
||||
|
||||
fstat_test : fstat_test.o
|
||||
@echo "Linking $@"
|
||||
$(CC) $(CFLAGS) -o $@ fstat_test.o -lunix $(LIBS) -Wl,--cref,-M,-Map=$@.map
|
||||
|
||||
simple_sprintf : simple_sprintf.o
|
||||
@echo "Linking $@"
|
||||
$(CC) -nostdlib $(CFLAGS) -o $@ simple_sprintf.o -lc -Wl,--cref,-M,-Map=$@.map
|
||||
|
||||
date_test : date_test.o
|
||||
@echo "Linking $@"
|
||||
$(CC) $(CFLAGS) -o $@ date_test.o $(LIBS) -Wl,--cref,-M,-Map=$@.map
|
||||
|
||||
sscanf_64 : sscanf_64.o
|
||||
@echo "Linking $@"
|
||||
$(CC) $(CFLAGS) -o $@ sscanf_64.o $(LIBS) -Wl,--cref,-M,-Map=$@.map
|
||||
|
||||
factorial : factorial.o
|
||||
@echo "Linking $@"
|
||||
$(CC) $(CFLAGS) -o $@ factorial.o $(LIBS) -Wl,--cref,-M,-Map=$@.map
|
||||
|
||||
execvp_test : execvp_test.o
|
||||
@echo "Linking $@"
|
||||
$(CC) $(CFLAGS) -o $@ execvp_test.o -lunix $(LIBS) -Wl,--cref,-M,-Map=$@.map
|
||||
|
||||
base_dir_nametest : base_dir_nametest.o
|
||||
@echo "Linking $@"
|
||||
$(CC) $(CFLAGS) -o $@ base_dir_nametest.o -lunix $(LIBS) -Wl,--cref,-M,-Map=$@.map
|
||||
|
||||
rand : rand.o
|
||||
@echo "Linking $@"
|
||||
$(CC) $(CFLAGS) -o $@ rand.o $(LIBS) -Wl,--cref,-M,-Map=$@.map
|
||||
|
||||
##############################################################################
|
||||
|
||||
mkid:
|
||||
mkid -v #?.(c|h|asm|i)
|
||||
|
||||
update:
|
||||
mkid -v -u
|
||||
@@ -1,124 +0,0 @@
|
||||
#
|
||||
# $Id: GNUmakefile.os4,v 1.13 2006-04-18 08:29:46 obarthel Exp $
|
||||
#
|
||||
# :ts=8
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
|
||||
CC = ppc-amigaos-gcc
|
||||
DELETE = rm -r
|
||||
|
||||
##############################################################################
|
||||
|
||||
.c.o:
|
||||
@echo "Compiling $<"
|
||||
@$(CC) -c $(CFLAGS) $<
|
||||
|
||||
##############################################################################
|
||||
|
||||
WARNINGS = \
|
||||
-Wall -W -Wshadow -Wpointer-arith -Wsign-compare -Wmissing-prototypes \
|
||||
-Wundef -Wbad-function-cast -Wmissing-declarations -Wconversion
|
||||
|
||||
INCLUDE = -I$(V)/include -I../library/include
|
||||
LIB = -L../library/lib
|
||||
#OPTIONS = -DNDEBUG -fno-builtin -DNO_INLINE_STDARG -DIEEE_FLOATING_POINT_SUPPORT
|
||||
#OPTIONS = -D__MEM_DEBUG -fno-builtin
|
||||
OPTIONS = -DDEBUG -DNO_INLINE_STDARG -fno-builtin
|
||||
#OPTIMIZE = -O
|
||||
#OPTIMIZE = -O2 -fomit-frame-pointer
|
||||
DEBUG = -ggdb
|
||||
|
||||
CFLAGS = $(WARNINGS) $(OPTIMIZE) $(DEBUG) $(OPTIONS) $(CODE_TYPE) $(INCLUDE) $(LIB)
|
||||
|
||||
##############################################################################
|
||||
|
||||
LIBS = -lm -lc -ldebug -lgcc
|
||||
|
||||
##############################################################################
|
||||
|
||||
all: test fgets_test iotest sscanf_test printf_test sprintf_test \
|
||||
stack_size_test translate_test strtok_test uname simple \
|
||||
fstat_stdout_test simple_sprintf date_test sscanf_64 \
|
||||
factorial setlocale
|
||||
|
||||
clean:
|
||||
$(DELETE) *.o *.map test fgets_test iotest sscanf_test printf_test \
|
||||
sprintf_test stack_size_test translate_test strtok_test \
|
||||
uname simple fstat_stdout_test simple_sprintf date_test \
|
||||
sscanf_64 factorial setlocale rand
|
||||
|
||||
##############################################################################
|
||||
|
||||
setlocale : setlocale.o
|
||||
@echo "Linking $@"
|
||||
$(CC) $(CFLAGS) -o $@ setlocale.o $(LIBS) -Wl,--cref,-M,-Map=$@.map
|
||||
|
||||
test : test.o
|
||||
@echo "Linking $@"
|
||||
$(CC) $(CFLAGS) -o $@ test.o $(LIBS) -Wl,--cref,-M,-Map=$@.map
|
||||
|
||||
date_test : date_test.o
|
||||
@echo "Linking $@"
|
||||
$(CC) $(CFLAGS) -o $@ test.o $(LIBS) -Wl,--cref,-M,-Map=$@.map
|
||||
|
||||
fgets_test : fgets_test.o
|
||||
@echo "Linking $@"
|
||||
$(CC) $(CFLAGS) -o $@ fgets_test.o $(LIBS) -Wl,--cref,-M,-Map=$@.map
|
||||
|
||||
strtok_test : strtok_test.o
|
||||
@echo "Linking $@"
|
||||
$(CC) $(CFLAGS) -o $@ strtok_test.o $(LIBS) -Wl,--cref,-M,-Map=$@.map
|
||||
|
||||
iotest : iotest.o
|
||||
@echo "Linking $@"
|
||||
$(CC) $(CFLAGS) -o $@ iotest.o $(LIBS) -Wl,--cref,-M,-Map=$@.map
|
||||
|
||||
sscanf_test : sscanf_test.o
|
||||
@echo "Linking $@"
|
||||
$(CC) $(CFLAGS) -o $@ sscanf_test.o $(LIBS) -Wl,--cref,-M,-Map=$@.map
|
||||
|
||||
printf_test : printf_test.o
|
||||
@echo "Linking $@"
|
||||
$(CC) $(CFLAGS) -o $@ printf_test.o $(LIBS) -Wl,--cref,-M,-Map=$@.map
|
||||
|
||||
sprintf_test : sprintf_test.o
|
||||
@echo "Linking $@"
|
||||
$(CC) $(CFLAGS) -o $@ sprintf_test.o $(LIBS) -Wl,--cref,-M,-Map=$@.map
|
||||
|
||||
stack_size_test : stack_size_test.o
|
||||
@echo "Linking $@"
|
||||
$(CC) $(CFLAGS) -o $@ stack_size_test.o $(LIBS) -Wl,--cref,-M,-Map=$@.map
|
||||
|
||||
translate_test : translate_test.o
|
||||
@echo "Linking $@"
|
||||
$(CC) $(CFLAGS) -o $@ translate_test.o -lunix $(LIBS) -Wl,--cref,-M,-Map=$@.map
|
||||
|
||||
uname : uname.o
|
||||
@echo "Linking $@"
|
||||
$(CC) $(CFLAGS) -o $@ uname.o -lunix $(LIBS) -Wl,--cref,-M,-Map=$@.map
|
||||
|
||||
simple : simple.o
|
||||
@echo "Linking $@"
|
||||
$(CC) $(CFLAGS) -o $@ simple.o $(LIBS) -Wl,--cref,-M,-Map=$@.map
|
||||
|
||||
fstat_stdout_test : fstat_stdout_test.o
|
||||
@echo "Linking $@"
|
||||
$(CC) $(CFLAGS) -o $@ fstat_stdout_test.o $(LIBS) -Wl,--cref,-M,-Map=$@.map
|
||||
|
||||
simple_sprintf : simple_sprintf.o
|
||||
@echo "Linking $@"
|
||||
$(CC) -nostdlib $(CFLAGS) -o $@ simple_sprintf.o -lc -lgcc -Wl,--cref,-M,-Map=$@.map
|
||||
|
||||
sscanf_64 : sscanf_64.o
|
||||
@echo "Linking $@"
|
||||
$(CC) -nostdlib $(CFLAGS) -o $@ sscanf_64.o -lc -lgcc -Wl,--cref,-M,-Map=$@.map
|
||||
|
||||
factorial : factorial.o
|
||||
@echo "Linking $@"
|
||||
$(CC) -nostdlib $(CFLAGS) -o $@ factorial.o -lc -lgcc -Wl,--cref,-M,-Map=$@.map
|
||||
|
||||
rand : rand.o
|
||||
@echo "Linking $@"
|
||||
$(CC) -nostdlib $(CFLAGS) -o $@ rand.o -lc -lgcc -Wl,--cref,-M,-Map=$@.map
|
||||
@@ -1,4 +0,0 @@
|
||||
This is a collection of programs I'm using to test the library. These
|
||||
are functional tests: the library is supposed to do something, and produce
|
||||
a particular result. For example, "printf_test" exercises a bunch of
|
||||
output formatting rules.
|
||||
@@ -1,20 +0,0 @@
|
||||
/*
|
||||
* $Id: base_dir_nametest.c,v 1.1 2006-09-25 18:20:09 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <libgen.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int
|
||||
main(int argc,char ** argv)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 1 ; i < argc ; i++)
|
||||
printf("%s\n\tbasename=%s\n\t dirname=%s\n",argv[i],basename(argv[i]),dirname(argv[i]));
|
||||
|
||||
return(0);
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define LINEBUFLENGTH 180
|
||||
|
||||
#define STRIP_LF(str) (str[strlen(str)-1]=0)
|
||||
void invert_str(char * in)
|
||||
{
|
||||
char t;
|
||||
while(t=*in)
|
||||
{
|
||||
*in++=~t;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int i, char *c[])
|
||||
{
|
||||
char dest_fname[80], in_linebuffer[LINEBUFLENGTH];
|
||||
FILE * fileout, * filein;
|
||||
|
||||
if(i>1)
|
||||
{
|
||||
sprintf(dest_fname, "%s.c", c[1]);
|
||||
|
||||
fileout=fopen(dest_fname, "w");
|
||||
filein =fopen(c[1], "r");
|
||||
|
||||
if(fileout && filein)
|
||||
{
|
||||
fgets(in_linebuffer, LINEBUFLENGTH, filein);
|
||||
STRIP_LF(in_linebuffer);
|
||||
invert_str(in_linebuffer);
|
||||
fputs("char *s_leading=\"", fileout);
|
||||
fputs(in_linebuffer, fileout);
|
||||
fputs("\";\n", fileout);
|
||||
|
||||
fputs("char *s_messages[]={\n", fileout);
|
||||
|
||||
while(fgets(in_linebuffer, LINEBUFLENGTH, filein))
|
||||
{
|
||||
STRIP_LF(in_linebuffer);
|
||||
invert_str(in_linebuffer);
|
||||
|
||||
fputs("\"", fileout);
|
||||
fputs(in_linebuffer, fileout);
|
||||
fputs("\",\n", fileout);
|
||||
}
|
||||
fputs("};\n", fileout);
|
||||
fputs("unsigned s_mess_num = sizeof(s_messages)/sizeof(char *);\n", fileout);
|
||||
fclose(filein);
|
||||
fclose(fileout);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
What's this stuff for ? I use it in SP_Engine to hide the usual bunch of "secret
|
||||
messages". As you can see, the strings are simply not'ed .
|
||||
This source shows both flaws: fgets() and the missing buffer flush. You can
|
||||
change the while() statement with
|
||||
|
||||
while(!feof(filein))
|
||||
{
|
||||
fgets(in_linebuffer, LINEBUFLENGTH, filein);
|
||||
....
|
||||
|
||||
This way you'll workaround the first problem.
|
||||
The second issue manifests itself this way: the last two fputs() followed by the
|
||||
fclose() don't do anything: no "};\n" and no "unsigned....." lines are output to
|
||||
'fileout'. With SAS, it works perfectly. Converting the source to dos.library
|
||||
calls also works perfectly. I wonder if there's some kind of strange interaction
|
||||
with the dos/shell updates.
|
||||
*/
|
||||
@@ -1,22 +0,0 @@
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
#include <locale.h>
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
time_t tm;
|
||||
struct tm *ptr;
|
||||
char str[60];
|
||||
|
||||
setlocale(LC_ALL, "C");
|
||||
|
||||
tm = time(NULL);
|
||||
ptr = localtime(&tm);
|
||||
|
||||
strftime(str, sizeof(str), "%x\n", ptr);
|
||||
|
||||
printf(str);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
/*
|
||||
* $Id: execvp_test.c,v 1.2 2006-08-07 08:39:56 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
int
|
||||
main(int argc,char ** argv)
|
||||
{
|
||||
if(argc > 1)
|
||||
execvp(argv[1],&argv[1]);
|
||||
|
||||
return(0);
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
gcc -std=c99 -mcrt=clib2 -o factorial factorial.c -lm
|
||||
output is:
|
||||
16! = 20922789888 <- Wrong
|
||||
|
||||
gcc -std=c99 -mcrt=newlib -o factorial factorial.c
|
||||
output is:
|
||||
16! = 20922789888000 <- Correct
|
||||
*/
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
double result = 1.0;
|
||||
int i;
|
||||
|
||||
for ( i = 2; i < 17; ++i )
|
||||
result = result * i;
|
||||
|
||||
printf("16! = %.14g\n", result);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* $Id: fgets_test.c,v 1.1.1.1 2004-07-26 16:36:07 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*/
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
int
|
||||
main(int argc,char ** argv)
|
||||
{
|
||||
char line[256];
|
||||
size_t len;
|
||||
FILE * in;
|
||||
int i;
|
||||
|
||||
for(i = 1 ; i < argc ; i++)
|
||||
{
|
||||
in = fopen(argv[i],"rb");
|
||||
if(in != NULL)
|
||||
{
|
||||
while(fgets(line,sizeof(line),in) != NULL)
|
||||
{
|
||||
len = strlen(line);
|
||||
while(len > 0 && (line[len-1] == '\n' || line[len-1] == '\r'))
|
||||
line[--len] = '\0';
|
||||
|
||||
printf("%s\n",line);
|
||||
}
|
||||
|
||||
fclose(in);
|
||||
}
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* $Id: fstat_stdout_test.c,v 1.1 2005-05-08 16:27:25 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*/
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
int
|
||||
main(int argc,char ** argv)
|
||||
{
|
||||
struct stat st;
|
||||
int fd;
|
||||
|
||||
fd = dup(STDOUT_FILENO);
|
||||
if(fd < 0)
|
||||
{
|
||||
perror("dup(STDOUT_FILENO)");
|
||||
return(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if(fstat(fd,&st) < 0)
|
||||
{
|
||||
perror("fstat(fd,&st)");
|
||||
return(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
return(EXIT_SUCCESS);
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* $Id: fstat_test.c,v 1.1 2006-09-20 19:46:37 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*/
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
int
|
||||
main(int argc,char ** argv)
|
||||
{
|
||||
struct stat st;
|
||||
int fd;
|
||||
|
||||
if(argc <= 1)
|
||||
return(EXIT_FAILURE);
|
||||
|
||||
fd = open(argv[1],O_RDONLY);
|
||||
if(fd == -1)
|
||||
{
|
||||
perror("open");
|
||||
return(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if(fstat(fd,&st) == -1)
|
||||
{
|
||||
perror("fstat");
|
||||
return(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
return(EXIT_SUCCESS);
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define FILE_SIZE 2048
|
||||
#define WRITE_SIZE 32
|
||||
|
||||
char FileData[FILE_SIZE];
|
||||
|
||||
void CreateFile(char *filename)
|
||||
{
|
||||
FILE *file;
|
||||
|
||||
if (file = fopen(filename,"w")) {
|
||||
memset(FileData,'0',FILE_SIZE);
|
||||
memset(FileData,'-',WRITE_SIZE);
|
||||
fwrite(FileData,1,FILE_SIZE,file);
|
||||
fclose(file);
|
||||
}
|
||||
}
|
||||
|
||||
void ReadWriteFile(char *filename)
|
||||
{
|
||||
FILE *file;
|
||||
|
||||
if (file = fopen(filename,"r+")) {
|
||||
fseek(file,0,SEEK_SET);
|
||||
fread(FileData,1,FILE_SIZE,file);
|
||||
fseek(file,0,SEEK_SET);
|
||||
memset(FileData,'1',WRITE_SIZE);
|
||||
fwrite(FileData,1,WRITE_SIZE,file);
|
||||
fclose(file);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc > 1) {
|
||||
CreateFile(argv[1]);
|
||||
ReadWriteFile(argv[1]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user