commit f078da1a93e2f05a5925b14c5c3206f524def121 Author: jshepher <> Date: Thu Sep 9 22:09:30 2004 +0000 libnix 1.2 import diff --git a/libnix/Makefile.in b/libnix/Makefile.in new file mode 100644 index 0000000..7fe84ba --- /dev/null +++ b/libnix/Makefile.in @@ -0,0 +1,187 @@ +# Build all models of the libnix libraries. +# +# CFLAGS=-Wall -O3 +# +# -fbaserel -DSMALL_DATA for small data model +# -fbaserel32 for large baserel model +# -m68020 for 68020 specific code +# -m68060 for 68060 specific code +# -m68881 for 68881 specific code (FPU) +# -DIXPATHS for Un*x path option +# -DDEBUG_LIB build a library for debugging (not yet fully working) + +#### Start of system configuration section. #### + +srcdir = @srcdir@ +VPATH = @srcdir@ + +# Common prefix for machine-independent installed files. +prefix = @prefix@ + +# Common prefix for machine-dependent installed files. +exec_prefix = @exec_prefix@ + +libdir = $(exec_prefix)/lib +infodir = $(exec_prefix)/info +guidedir = $(exec_prefix)/guide + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ + +CC = @CC@ +CPP = @CPP@ +AS = as + +RANLIB = @RANLIB@ + +#### End system configuration section #### + +V=VER: libnix 1.2 (14.7.98) + +CURDIR := $(shell pwd) + +MAKE=make -f $(CURDIR)/sources/Makefile + +SUBDIRS=startup lib libb lib020 libb020 lib881 libb881#lib060 libb060 libb32 libb32881 + +all: libnix.guide libnix.info $(SUBDIRS) + cd sources; make filelists + cd startup; make -f $(CURDIR)/sources/startup/Makefile V="$(V)" + cd lib; $(MAKE) V="$(V)" CFLAGS="-Wall -O3 -fomit-frame-pointer" + cd libb; $(MAKE) V="$(V)" CFLAGS="-Wall -O3 -fomit-frame-pointer -fbaserel -DSMALL_DATA" + cd lib020; $(MAKE) V="$(V)" CFLAGS="-Wall -O3 -fomit-frame-pointer -m68020" + cd libb020; $(MAKE) V="$(V)" CFLAGS="-Wall -O3 -fomit-frame-pointer -fbaserel -DSMALL_DATA -m68020" + cd lib881; $(MAKE) V="$(V)" CFLAGS="-Wall -O3 -fomit-frame-pointer -m68020 -m68881" + cd libb881; $(MAKE) V="$(V)" CFLAGS="-Wall -O3 -fomit-frame-pointer -fbaserel -DSMALL_DATA -m68020 -m68881" +# cd lib060; $(MAKE) V="$(V)" CFLAGS="-Wall -O3 -fomit-frame-pointer -m68060 -m68881" +# cd libb060; $(MAKE) V="$(V)" CFLAGS="-Wall -O3 -fomit-frame-pointer -fbaserel -DSMALL_DATA -m68060 -m68881" +# cd libb32; $(MAKE) V="$(V)" CFLAGS="-Wall -O3 -fomit-frame-pointer -fbaserel32 -DSMALL_DATA -m68020" +# cd libb32881; $(MAKE) V="$(V)" CFLAGS="-Wall -O3 -fomit-frame-pointer -fbaserel32 -DSMALL_DATA -m68020 -m68881" +# cd libix; $(MAKE) V="$(V)" CFLAGS="-Wall -O3 -fomit-frame-pointer -DIXPATHS" + +$(SUBDIRS): + mkdir $@ + +libamiga: + if [ ! -d lib ] ; then mkdir lib ; else true ; fi + if [ ! -d libb ] ; then mkdir libb ; else true ; fi + if [ ! -d libb32 ] ; then mkdir libb32 ; else true ; fi + cd sources; make filelists + cd lib; $(MAKE) libamiga CFLAGS="-O3 -fomit-frame-pointer" + cd libb; $(MAKE) libamiga CFLAGS="-O3 -fomit-frame-pointer -fbaserel" + cd libb32; $(MAKE) libamiga CFLAGS="-O3 -fomit-frame-pointer -fbaserel32 -m68020" + +clean: + cd lib; $(MAKE) clean + cd libb; $(MAKE) clean + cd lib020; $(MAKE) clean + cd libb020; $(MAKE) clean + cd lib881; $(MAKE) clean + cd libb881; $(MAKE) clean +# cd lib060; $(MAKE) clean +# cd libb060; $(MAKE) clean +# cd lib32; $(MAKE) clean +# cd libb32881; $(MAKE) clean +# cd libix; $(MAKE) clean + -rm -f sources/*/filelist sources/stubs/libbases/* sources/stubs/libnames/* + +veryclean: + cd lib; $(MAKE) veryclean + cd libb; $(MAKE) veryclean + cd lib020; $(MAKE) veryclean + cd libb020; $(MAKE) veryclean + cd lib881; $(MAKE) veryclean + cd libb881; $(MAKE) veryclean +# cd lib060; $(MAKE) veryclean +# cd libb060; $(MAKE) veryclean +# cd lib32; $(MAKE) veryclean +# cd libb32881; $(MAKE) veryclean +# cd libix; $(MAKE) veryclean + -rm sources/*/filelist + +libnix.guide: libnix.texi + makeinfo --amiga $(srcdir)/libnix.texi -o libnix.guide + +libnix.info: libnix.texi + makeinfo $(srcdir)/libnix.texi -o libnix.info + +install: installdirs + $(INSTALL) startup/*.o $(prefix)/lib/libnix + $(INSTALL) lib/*/lib*.a $(prefix)/lib/libnix + $(INSTALL) lib/misc/*.o $(prefix)/lib/libnix + $(INSTALL) libb/*/lib*.a $(prefix)/lib/libb/libnix + $(INSTALL) libb/misc/*.o $(prefix)/lib/libb/libnix + $(INSTALL) lib020/*/lib*.a $(prefix)/lib/libm020/libnix + $(INSTALL) lib020/misc/*.o $(prefix)/lib/libm020/libnix + $(INSTALL) libb020/*/lib*.a $(prefix)/lib/libb/libm020/libnix + $(INSTALL) libb020/misc/*.o $(prefix)/lib/libb/libm020/libnix + $(INSTALL) lib881/*/lib*.a $(prefix)/lib/libm020/libm881/libnix + $(INSTALL) lib881/misc/*.o $(prefix)/lib/libm020/libm881/libnix + $(INSTALL) libb881/*/lib*.a $(prefix)/lib/libb/libm020/libm881/libnix + $(INSTALL) libb881/misc/*.o $(prefix)/lib/libb/libm020/libm881/libnix + $(INSTALL_DATA) *.info* $(infodir) + $(INSTALL_DATA) libnix.guide $(guidedir)/libnix.guide +# $(INSTALL) lib060/*/lib*.a $(prefix)/lib/libm060/libnix +# $(INSTALL) lib060/misc/*.o $(prefix)/lib/libm060/libnix +# $(INSTALL) libb060/*/lib*.a $(prefix)/lib/libb/libm060/libnix +# $(INSTALL) libb060/misc/*.o $(prefix)/lib/libb/libm060/libnix +# $(INSTALL) libb32/*/lib*.a $(prefix)/lib/libb32/libm020/libnix +# $(INSTALL) libb32/misc/*.o $(prefix)/lib/libb32/libm020/libnix +# $(INSTALL) libb32881/*/lib*.a $(prefix)/lib/libb32/libm020/libm881/libnix +# $(INSTALL) libb32881/misc/*.o $(prefix)/lib/libb32/libm020/libm881/libnix + +installdirs: mkinstalldirs + $(srcdir)/mkinstalldirs \ + $(infodir) \ + $(guidedir) \ + $(libdir) \ + $(libdir)/libnix \ + $(libdir)/libm020 \ + $(libdir)/libm020/libnix \ + $(libdir)/libm020/libm881 \ + $(libdir)/libm020/libm881/libnix \ + $(libdir)/libb \ + $(libdir)/libb/libnix \ + $(libdir)/libb/libm020 \ + $(libdir)/libb/libm020/libnix \ + $(libdir)/libb/libm020/libm881 \ + $(libdir)/libb/libm020/libm881/libnix +# $(libdir)/libm060 \ +# $(libdir)/libm060/libnix \ +# $(libdir)/libb/libm060 \ +# $(libdir)/libb/libm060/libnix +# $(libdir)/libb32 \ +# $(libdir)/libb32/libnix \ +# $(libdir)/libb32/libm020 \ +# $(libdir)/libb32/libm020/libnix \ +# $(libdir)/libb32/libm020/libm881 \ +# $(libdir)/libb32/libm020/libm881/libnix + +distribution: + mkdir t:gg t:gg/lib t:gg/lib/libnix + lha a -mraxez t:gg/libnix-sources.lha Makefile libnix.texi + lha a -mraxez t:gg/libnix-sources.lha sources examples + mkdir t:gg/lib/libm020 t:gg/lib/libm020/libnix \ + t:gg/lib/libm020/libm881 t:gg/lib/libm020/libm881/libnix \ + t:gg/lib/libb t:gg/lib/libb/libnix \ + t:gg/lib/libb/libm020 t:gg/lib/libb/libm020/libnix \ + t:gg/lib/libb/libm020/libm881 t:gg/lib/libb/libm020/libm881/libnix + cp -p startup/*.o t:gg/lib/libnix + cp -p lib/*/*.a t:gg/lib/libnix + cp -p lib/misc/*.o t:gg/lib/libnix + cp -p libb/*/*.a t:gg/lib/libb/libnix + cp -p libb/misc/*.o t:gg/lib/libb/libnix + cp -p lib020/*/*.a t:gg/lib/libm020/libnix + cp -p lib020/misc/*.o t:gg/lib/libm020/libnix + cp -p libb020/*/*.a t:gg/lib/libb/libm020/libnix + cp -p libb020/misc/*.o t:gg/lib/libb/libm020/libnix + cp -p lib881/*/*.a t:gg/lib/libm020/libm881/libnix + cp -p lib881/misc/*.o t:gg/lib/libm020/libm881/libnix + cp -p libb881/*/*.a t:gg/lib/libb/libm020/libm881/libnix + cp -p libb881/misc/*.o t:gg/lib/libb/libm020/libm881/libnix + -rm t:gg/lib/libnix/libglue.a t:gg/lib/libb/libnix/libglue.a + -cp * t:gg + rm t:gg/Makefile t:gg/libnix.texi + cd t:gg;lha m -mraxeZ libnix.lha * + rm -rf t:gg diff --git a/libnix/configure b/libnix/configure new file mode 100755 index 0000000..4f4379d --- /dev/null +++ b/libnix/configure @@ -0,0 +1,1400 @@ +#! /bin/sh + +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 2.13 +# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +guidedir='${prefix}/guide' +htmldir='${prefix}/html' +psdir='${prefix}/ps' +dvidir='${prefix}/dvi' +mandir='${prefix}/man' + +# Initialize some other variables. +subdirs= +MFLAGS= MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} +# Maximum number of lines to put in a shell here document. +ac_max_here_lines=12 + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case "$ac_option" in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir="$ac_optarg" ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build="$ac_optarg" ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file="$ac_optarg" ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [same as prefix] + --bindir=DIR user executables in DIR [EPREFIX/bin] + --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] + --libexecdir=DIR program executables in DIR [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data in DIR + [PREFIX/share] + --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data in DIR + [PREFIX/com] + --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] + --libdir=DIR object code libraries in DIR [EPREFIX/lib] + --includedir=DIR C header files in DIR [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] + --infodir=DIR info documentation in DIR [PREFIX/info] + --guidedir=DIR Amigaguide documentation in DIR [PREFIX/guide] + --htmldir=DIR HTML documentation in DIR [PREFIX/html] + --psdir=DIR postscript documentation in DIR [PREFIX/ps] + --dvidir=DIR TeX dvi documentation in DIR [PREFIX/dvi] + --mandir=DIR man documentation in DIR [PREFIX/man] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM + run sed PROGRAM on installed program names +EOF + cat << EOF +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +EOF + if test -n "$ac_help"; then + echo "--enable and --with options recognized:$ac_help" + fi + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir="$ac_optarg" ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir="$ac_optarg" ;; + + -guidedir | --guidedir | --guidedi | --guided | --guide | --gui) + ac_prev=guidedir ;; + -guidedir=* | --guidedir=* | --guidedi=* | --guided=* | --guide=* |--gui=*)+ guidedir="$ac_optarg" ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* |--htm=*)+ htmldir="$ac_optarg" ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)+ psdir="$ac_optarg" ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* |--dv=*)+ dvidir="$ac_optarg" ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir="$ac_optarg" ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir="$ac_optarg" ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir="$ac_optarg" ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir="$ac_optarg" ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir="$ac_optarg" ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir="$ac_optarg" ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir="$ac_optarg" ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site="$ac_optarg" ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.13" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 6 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set these to C if already set. These must not be set unconditionally +# because not all systems understand e.g. LANG=C (notably SCO). +# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! +# Non-C LC_CTYPE values break the ctype check. +if test "${LANG+set}" = set; then LANG=C; export LANG; fi +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi +if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file= + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +ac_exeext= +ac_objext=o +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + + +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:553: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$CC"; then + # Extract the first word of "bcc", so it can be a program name with args. +set dummy bcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:583: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="bcc" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +fi +if test -z "$CC"; then + machine=`(uname -m 2>/dev/null)` || machine=unknown + case "$machine" in + BePC) # Extract the first word of "mwccx86", so it can be a program name with args. +set dummy mwccx86; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:616: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="mwccx86" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + ;; + BeBox | BeMac ) # Extract the first word of "mwcc", so it can be a program name with args. +set dummy mwcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:645: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="mwcc" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + ;; + *) ;; + esac +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:678: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_prog_rejected=no + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + break + fi + done + IFS="$ac_save_ifs" +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$ac_dir/$ac_word" "$@" + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +fi +if test -z "$CC"; then + case "`uname -s`" in + *win32* | *WIN32*) + # Extract the first word of "cl", so it can be a program name with args. +set dummy cl; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:730: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="cl" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + ;; + esac +fi +test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } + +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:761: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +cat > conftest.$ac_ext << EOF + +#line 772 "configure" +#include "confdefs.h" + +main(){return(0);} +EOF +if { (eval echo configure:777: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + ac_cv_prog_cc_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cc_cross=no + else + ac_cv_prog_cc_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cc_works=no +fi +rm -fr conftest* +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 +if test $ac_cv_prog_cc_works = no; then + { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:803: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 +cross_compiling=$ac_cv_prog_cc_cross + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +echo "configure:808: checking whether we are using GNU C" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gcc" 1>&6 + +if test $ac_cv_prog_gcc = yes; then + GCC=yes +else + GCC= +fi + +ac_test_CFLAGS="${CFLAGS+set}" +ac_save_CFLAGS="$CFLAGS" +CFLAGS= +echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:836: checking whether ${CC-cc} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then + ac_cv_prog_cc_g=yes +else + ac_cv_prog_cc_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +case "$CC" in + bcc ) + AR=${AR-mwld} + LD=${LD-mwld} + RANLIB=${RANLIB-true};; + mwcc ) + CC="mwcc -I- -I. -I/boot/apps/GeekGadgets/include -L/boot/apps/GeekGadgets/lib -opt global -nodup" + AR=${AR-mwld} + LD=${LD-mwld} + RANLIB=${RANLIB-true};; + mwccx86 ) + CC="mwccx86 -I- -I. -I/boot/apps/GeekGadgets/include -L/boot/apps/GeekGadgets/lib" + AR=${AR-mwldx86} + LD=${LD-mwldx86} + RANLIB=${RANLIB-true};; + ${host_alias}-gcc) + ;; + *) + AR=${AR-ar} + LD=${LD-ld} + RANLIB=${RANLIB-ranlib};; +esac + + +echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 +echo "configure:891: checking how to run the C preprocessor" >&5 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then +if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # This must be in double quotes, not single quotes, because CPP may get + # substituted into the Makefile and "${CC-cc}" will confuse make. + CPP="${CC-cc} -E" + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:912: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -E -traditional-cpp" + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:929: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -nologo -E" + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:946: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP=/lib/cpp +fi +rm -f conftest* +fi +rm -f conftest* +fi +rm -f conftest* + ac_cv_prog_CPP="$CPP" +fi + CPP="$ac_cv_prog_CPP" +else + ac_cv_prog_CPP="$CPP" +fi +echo "$ac_t""$CPP" 1>&6 + +for ac_prog in mawk gawk nawk awk +do +# Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:975: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_AWK'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_AWK="$ac_prog" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +AWK="$ac_cv_prog_AWK" +if test -n "$AWK"; then + echo "$ac_t""$AWK" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +test -n "$AWK" && break +done + +# Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1007: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_RANLIB="ranlib" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":" +fi +fi +RANLIB="$ac_cv_prog_RANLIB" +if test -n "$RANLIB"; then + echo "$ac_t""$RANLIB" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } +fi +ac_config_guess=$ac_aux_dir/config.guess +ac_config_sub=$ac_aux_dir/config.sub +ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /c/install +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 +echo "configure:1066: checking for a BSD compatible install" >&5 +if test -z "$INSTALL"; then +if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/c/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done + IFS="$ac_save_IFS" + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL="$ac_cv_path_install" + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL="$ac_install_sh" + fi +fi +echo "$ac_t""$INSTALL" 1>&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + + +trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +cat > conftest.defs <<\EOF +s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g +s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g +s%\[%\\&%g +s%\]%\\&%g +s%\$%$$%g +EOF +DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '` +rm -f conftest.defs + + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +# Some systems, like AmigaOS, won't allow you to remove a script that is +# being executed, so just move it out of the way instead. +if test -f $CONFIG_STATUS; then mv $CONFIG_STATUS $CONFIG_STATUS.old; else true; fi +cat > $CONFIG_STATUS </dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.13" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir +ac_given_INSTALL="$INSTALL" + +trap 'rm -fr `echo "Makefile sources/Makefile sources/amiga/Makefile + sources/math/Makefile sources/misc/Makefile + sources/nix/Makefile sources/nix13/Makefile + sources/nixmain/Makefile sources/nix_main/Makefile + sources/stack/Makefile sources/startup/Makefile + sources/stubs/Makefile examples/Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +EOF +cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF +$ac_vpsub +$extrasub +s%@SHELL@%$SHELL%g +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@FFLAGS@%$FFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@bindir@%$bindir%g +s%@sbindir@%$sbindir%g +s%@libexecdir@%$libexecdir%g +s%@datadir@%$datadir%g +s%@sysconfdir@%$sysconfdir%g +s%@sharedstatedir@%$sharedstatedir%g +s%@localstatedir@%$localstatedir%g +s%@libdir@%$libdir%g +s%@includedir@%$includedir%g +s%@oldincludedir@%$oldincludedir%g +s%@infodir@%$infodir%g +s%@guidedir@%$guidedir%g +s%@htmldir@%$htmldir%g +s%@psdir@%$psdir%g +s%@dvidir@%$dvidir%g +s%@mandir@%$mandir%g +s%@CC@%$CC%g +s%@AR@%$AR%g +s%@RANLIB@%$RANLIB%g +s%@CPP@%$CPP%g +s%@AWK@%$AWK%g +s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g +s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g +s%@INSTALL_DATA@%$INSTALL_DATA%g + +CEOF +EOF + +cat >> $CONFIG_STATUS <<\EOF + +# Split the substitutions into bite-sized pieces for seds with +# small command number limits, like on Digital OSF/1 and HP-UX. +ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. +ac_file=1 # Number of current file. +ac_beg=1 # First line for current file. +ac_end=$ac_max_sed_cmds # Line after last line for current file. +ac_more_lines=: +ac_sed_cmds="" +while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file + else + sed "${ac_end}q" conftest.subs > conftest.s$ac_file + fi + if test ! -s conftest.s$ac_file; then + ac_more_lines=false + rm -f conftest.s$ac_file + else + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f conftest.s$ac_file" + else + ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + fi + ac_file=`expr $ac_file + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_cmds` + fi +done +if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat +fi +EOF + +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + case "$ac_given_INSTALL" in + [/$]*) INSTALL="$ac_given_INSTALL" ;; + *) INSTALL="$ac_dots$ac_given_INSTALL" ;; + esac + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +s%@INSTALL@%$INSTALL%g +" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file +fi; done +rm -f conftest.s* + +EOF +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF + +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -f CONFIG.STATUS.old +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 + diff --git a/libnix/configure.in b/libnix/configure.in new file mode 100644 index 0000000..a9bfbef --- /dev/null +++ b/libnix/configure.in @@ -0,0 +1,16 @@ +dnl Process this file with autoconf to produce a configure script. + +AC_INIT() + +AC_PROG_CC +AC_PROG_CPP +AC_PROG_AWK +AC_PROG_RANLIB +AC_PROG_INSTALL + +AC_OUTPUT(Makefile sources/Makefile sources/amiga/Makefile + sources/math/Makefile sources/misc/Makefile + sources/nix/Makefile sources/nix13/Makefile + sources/nixmain/Makefile sources/nix_main/Makefile + sources/stack/Makefile sources/startup/Makefile + sources/stubs/Makefile examples/Makefile) diff --git a/libnix/examples/Makefile.in b/libnix/examples/Makefile.in new file mode 100644 index 0000000..5aec7c4 --- /dev/null +++ b/libnix/examples/Makefile.in @@ -0,0 +1,30 @@ +#### Start of system configuration section. #### + +srcdir = @srcdir@ +VPATH = @srcdir@ + +CC = @CC@ + +#### End system configuration section #### + +# Some examples + +.PHONY: all + +all: lib libr dev helloworld + +# normal library +lib: libinit.o simplelib.c + $(CC) -nostdlib -O3 -fomit-frame-pointer -fbaserel $^ -o $@ + +# multibase library +libr: libinitr.o simplelib.c + $(CC) -nostdlib -O3 -fomit-frame-pointer -resident $^ -o $@ + +# device +dev: devinit.o simpledev.c + $(CC) -nostdlib -O3 -fomit-frame-pointer -fbaserel $^ -o $@ + +# helloworld +helloworld: nbcrt0.o helloworld.c libstubs.a + $(CC) -nostdlib -O3 -fomit-frame-pointer -s -fbaserel $^ -o $@ diff --git a/libnix/examples/helloworld.c b/libnix/examples/helloworld.c new file mode 100755 index 0000000..9de0032 --- /dev/null +++ b/libnix/examples/helloworld.c @@ -0,0 +1,20 @@ +#include +#include +#include +#include + +int __nocommandline=1; /* Disable commandline parsing */ +int __initlibraries=0; /* Disable auto-library-opening */ + +struct DosLibrary *DOSBase=NULL; + +extern struct WBStartup *_WBenchMsg; + +int main(void) +{ if(_WBenchMsg==NULL) + { if((DOSBase=(struct DosLibrary *)OpenLibrary("dos.library",33))!=NULL) + { Write(Output(),"Hello world\n",12); + CloseLibrary((struct Library *)DOSBase); } } + return 0; +} + diff --git a/libnix/examples/simpledev.c b/libnix/examples/simpledev.c new file mode 100755 index 0000000..ac301b5 --- /dev/null +++ b/libnix/examples/simpledev.c @@ -0,0 +1,152 @@ +/******************************************************************************/ +/* */ +/* includes */ +/* */ +/******************************************************************************/ + +#include +#include +#include +#include +#include "stabs.h" + +/******************************************************************************/ +/* */ +/* exports */ +/* */ +/******************************************************************************/ + +const BYTE DevName[]="simple.device"; +const BYTE DevIdString[]="version 1.0"; + +const UWORD DevVersion=1; +const UWORD DevRevision=0; + +/******************************************************************************/ +/* */ +/* global declarations */ +/* */ +/******************************************************************************/ + +struct Device *myDevPtr; +struct ExecBase *SysBase; + +/******************************************************************************/ +/* */ +/* user device initialization */ +/* */ +/* !!! CAUTION: This function runs in a forbidden state !!! */ +/* */ +/******************************************************************************/ + +int __UserDevInit(struct Device *myDev) +{ + /* required !!! */ + SysBase=*(struct ExecBase **)4; + + /* setup your device base - to access device functions over *this* basePtr! */ + + myDevPtr = myDev; + + /* now do your initialization */ + + /* ... */ + + /* return a bool to indicate success */ + + return 0; +} + +/******************************************************************************/ +/* */ +/* user device cleanup */ +/* */ +/* !!! CAUTION: This function runs in a forbidden state !!! */ +/* */ +/******************************************************************************/ + +void __UserDevCleanup() +{ + /* your cleanup comes here */ + + /* ... */ + + /* nothing to return */ +} + +/******************************************************************************/ +/* */ +/* device dependent open function */ +/* */ +/* !!! CAUTION: This function runs in a forbidden state !!! */ +/* */ +/******************************************************************************/ + +int __UserDevOpen(struct IORequest *iorq,ULONG unit,ULONG flags) +{ + int io_err=IOERR_OPENFAIL; + + /* return a bool to indicate success */ + + return io_err; +} + +/******************************************************************************/ +/* */ +/* device dependent close function */ +/* */ +/* !!! CAUTION: This function runs in a forbidden state !!! */ +/* */ +/******************************************************************************/ + +void __UserDevClose(struct IORequest *iorq) +{ + + /* nothing to return */ +} + +/******************************************************************************/ +/* */ +/* device dependent beginio function */ +/* */ +/******************************************************************************/ + +ADDTABL_1(__BeginIO,a1); + +void __BeginIO(struct IORequest *iorq) +{ +}; + +/******************************************************************************/ +/* */ +/* device dependent abortio function */ +/* */ +/******************************************************************************/ + +ADDTABL_1(__AbortIO,a1); + +void __AbortIO(struct IORequest *iorq) +{ +}; + +/******************************************************************************/ +/* */ +/* additional device dependent functions */ +/* */ +/******************************************************************************/ + + + +/******************************************************************************/ +/* */ +/* endtable marker (required!) */ +/* */ +/******************************************************************************/ + +ADDTABL_END(); + +/******************************************************************************/ +/* */ +/* end of simpledev.c */ +/* */ +/******************************************************************************/ diff --git a/libnix/examples/simplelib.c b/libnix/examples/simplelib.c new file mode 100755 index 0000000..82decd7 --- /dev/null +++ b/libnix/examples/simplelib.c @@ -0,0 +1,93 @@ +/******************************************************************************/ +/* */ +/* includes */ +/* */ +/******************************************************************************/ + +#include +#include +#include +#include +#include "stabs.h" + +/******************************************************************************/ +/* */ +/* exports */ +/* */ +/******************************************************************************/ + +const BYTE LibName[]="simple.library"; +const BYTE LibIdString[]="version 1.0"; + +const UWORD LibVersion=1; +const UWORD LibRevision=0; + +/******************************************************************************/ +/* */ +/* global declarations */ +/* */ +/******************************************************************************/ + +struct Library *myLibPtr; +struct ExecBase *SysBase; +struct DosLibrary *DOSBase; + +/******************************************************************************/ +/* */ +/* user library initialization */ +/* */ +/* !!! CAUTION: This function may run in a forbidden state !!! */ +/* */ +/******************************************************************************/ + +int __UserLibInit(struct Library *myLib) +{ + /* setup your library base - to access library functions over *this* basePtr! */ + + myLibPtr = myLib; + + /* required !!! */ + SysBase=*(struct ExecBase **)4; + + return (DOSBase=(struct DosLibrary *)OpenLibrary("dos.library",33))==NULL; +} + +/******************************************************************************/ +/* */ +/* user library cleanup */ +/* */ +/* !!! CAUTION: This function runs in a forbidden state !!! */ +/* */ +/******************************************************************************/ + +void __UserLibCleanup() +{ + CloseLibrary((struct Library *)DOSBase); +} + +/******************************************************************************/ +/* */ +/* library dependent function(s) */ +/* */ +/******************************************************************************/ + +ADDTABL_1(__UserFunc,d0); /* One Argument in d0 */ + +int __UserFunc(long a) +{ + return a*2; +} + +/******************************************************************************/ +/* */ +/* endtable marker (required!) */ +/* */ +/******************************************************************************/ + +ADDTABL_END(); + +/******************************************************************************/ +/* */ +/* end of simplelib.c */ +/* */ +/******************************************************************************/ diff --git a/libnix/libnix.texi b/libnix/libnix.texi new file mode 100755 index 0000000..016db87 --- /dev/null +++ b/libnix/libnix.texi @@ -0,0 +1,1391 @@ +\input texinfo +@setfilename libnix.info +@settitle libnix - a static library for GCC on the amiga +@setchapternewpage odd + +@ifinfo +This is libnix.texi the documentation of the libnix library. +Since this document is part of the libnix package it stands +under the same copyright as the library itself, i.e. it's +public domain. +@end ifinfo +@titlepage +@title libnix +@subtitle a static library for GCC on the amiga +@author Matthias Fleischer & Gunther Nikl +@end titlepage + +@node Top,Description,(dir),(dir) +@ifinfo +This is the documentation of libnix. The following is a list +of chapters. You need not read all of them - but reading +the chapter Features is recommended. +@end ifinfo + +@menu +* Description:: What is libnix? +* Authors:: Who did it? +* Disclaimer:: Copyright and other legal stuff. +* Naming:: Naming conventions. +* Usage:: How to use it ;-) +* Features:: Details of the implementation (and more). +* Special startups:: How to write shared libraries and devices with gcc. +* Set elements:: A nice feature of gnu ld. +* geta4:: Some words on code and data models +* Library bases:: And how they work. +* Code size:: How to write small programs with gcc +* FAQs:: Frequently asked questions and answers. +@end menu +@node Description,Authors,Top,Top +@chapter What is libnix? + +libnix is a static (i.e. link) library for usage on amiga computers +together with gcc 2.3.3 or above. It is very amigalike and contains +a lot of features you probably don't want to miss: + +@itemize @bullet +@item +auto-open-library feature +@item +SAS compatible handling of WB startup message +@item +auto-detach startup code +@item +is very short +@item +does not require a shared library +@item +auto stack-extend +@item +and much more +@end itemize + +So if you want to write amiga specific programs or if you only need ANSI support +instead of unix compatibility - and if you don't want to redistribute ixemul.library - +this can be your choice. + +But be aware - libnix requires Amiga OS 2.0 or higher :(. + +@node Authors,Disclaimer,Description,Top +@chapter Authors + +If you want to change anything in the library please contact one of us first - +we know how to do it best since we wrote it. If you want to report +bugs please contact us, too. If we don't know about them we cannot fix them. + +Matthias Fleischer +@*fleischr@@izfm.uni-stuttgart.de + +Gunther Nikl +@*gnikl@@informatik.uni-rostock.de + +Special thanks go to Gerhard Müller for writing gerlib, Philippe Brand for +finding a name for this beast and Kriton Kyrimis who contributed some +of the non-ANSI functions and a lot of ideas. + +@node Disclaimer,Naming,Authors,Top +@chapter Disclaimer + +This package is public domain. That means that you can copy, use and modify it +without any problems and that you can get it for free. If you actually +paid for getting it this is completely your fault - I didn't see a cent +of that money. It also means that I cannot be made responsible for any damage +resulting out of the use of it - you simply shouldn't trust anything you didn't +pay for :-). + +@node Naming,Usage,Disclaimer,Top +@chapter Naming conventions + +This library is not only for the end user but also for the library +programmer (if you want to write your own startup, etc). + +If you want to write code for it you should be aware of the normal +naming conventions for ANSI libraries: + +@itemize @bullet +@item +Names with no underscore @samp{foo} are ANSI or POSIX compliant - there is absolutely +no risk in using them. If you use only these you can write portable +programs. +@item +Names with a single underscore @samp{_foo} are ANSI extensions for the +end user. Usually they are very common on certain systems but not used on +others. +@item +Names with two underscores @samp{__foo} are for the library programmers only. +If they are not documented you cannot rely on them. And even if they are +you should use them only for writing library code. +@end itemize + +There is only one exception of these conventions (@samp{__chkabort()}) +and this is for compatibility reasons. + +@node Usage,Features,Naming,Top +@chapter Usage + +The usage of this library is like any other link library. The only +important thing is the right linkage order: + +@enumerate +@item +The startup code has to be used first :-) +@item +The stubs-library has to be used last since it contains the library base pointers. +@item +The commandline parser should be used after your code but before most +other things or you will run into problems. +@end enumerate + +Normally this is handled by the specs file of gcc. + +@code{gcc (-fbaserel) (-resident) -noixemul YOUR_OBJECTS (-lnix_main) (-lm)} + +If you use @samp{-lnix_main} you get a different commandline parser. +@samp{-lm} uses the math library. + +Be aware that the formatted I/O-functions need the math library +to work correctly for floating point numbers. Without the math +library you get only floating point support for simple operators +like @samp{+}, @samp{*}, casts and that like. + +If you don't use the assembler inline functions of gcc you will have +to use @samp{libamiga.a} if you want to use any Amiga OS function. +gcc comes with a free version of libamiga.a which is a subset +of the original one. You can build it yourself if you unpack the sources, +but be prepared that it may take some time. + +For compiling a4-relative programs you should choose the +@samp{-fbaserel} option. You get resident (pure) programs if +you set the @samp{-resident} option. Anything else necessary for these options +is handled by the specs-file (choosing the right startups and libraries). + +If you (for some reason) don't trust you specs-file you can call everything +by hand: + +@code{gcc -nostdlib ncrt0.o YOUR_OBJECTS libnixmain.a (libm.a) libnix.a +libstubs.a} + +But that's not the recommended way. Therefore I don't explain this in +detail here - use the @samp{-v} option of gcc for more details. + +@node Features,Special startups,Usage,Top +@chapter Features - what you get + +The following list contains the elements of this package in +the right linkage order. This means if you follow the list from +top to bottom and take one file of each menu entry you will get +a working configuration. + +@menu +* Startup codes:: Does all work necessary for startup. + Your objects Need I say anything about that? +* Commandline parser:: Calculates argc and argv. + libm.a The math library (optional). +* libstack.a:: Stack extension code (optional). +* libnix.a:: The library itself. +* libamiga.a:: If you have one. +* detach.o:: Auto detaching +* libstubs.a:: The library bases. +@end menu + +@node Startup codes,Commandline parser,Features,Features +@chapter Startup codes + +There is a lot of work to do before your @samp{main} function +can be called - open shared libraries, open stdin, stdout, etc. +Depending on the compiler options and the ANSI functions you use. +This work is done by the startup code. + +@menu +* Startup interface:: +* Startup usage:: +@end menu + +To get a short startup all the necessary modules are optional - +they get only linked in if you use them. There are 2 exceptions +from this (since the linker cannot check for it): + +@itemize @bullet +@item +The commandline parser. It can be deactivated by declaring + +@code{__nocommandline} + +somewhere in your program (the type doesn't matter). +@item +The shared-library-opening module. You should not disable it unless +you know what you are doing since most library functions depend on it. +@end itemize + +The startup codes itself are written in assembly to be as short as +possible. + +Here is a little program to get the point: + +@example +#include +#include +#include +#include + +int __nocommandline=1; /* Disable commandline parsing */ +int __initlibraries=0; /* Disable auto-library-opening */ + +struct DosLibrary *DOSBase=NULL; + +extern struct WBStartup *_WBenchMsg; + +int main(void) +@{ if(_WBenchMsg==NULL) + @{ if((DOSBase=(struct DosLibrary *)OpenLibrary("dos.library",37))!=NULL) + @{ Write(Output(),"Hello world\n",12); + CloseLibrary((struct Library *)DOSBase); @} @} + return 0; +@} +@end example + +compiled and linked with + +@code{gcc -noixemul -s -O2 -fbaserel helloworld.c} + +gives an executable of 492 bytes. And this with the normal @samp{main} +function! + +So you never need to try to write a program without a startup code. + +@node Startup interface,Startup usage,Startup codes,Startup codes +@chapter Startup code interface + +The startup codes do the following: + +@itemize @bullet +@item +They catch the workbench startup message and place it into the +variable + +@code{extern struct WBStartup *_WBenchMsg} + +you can simply look into this place (and test for a @samp{NULL} pointer) to +check if your program was started from WB. If this is a @samp{NULL} pointer + +@code{extern char *__commandline} + +contains the (@samp{\n} terminated) parameters of the commandline. +@item +They call all functions in the + +@code{long __INIT_LIST__[];} + +with ascending priority. +@item +They call the function + +@code{int main(int argc,char *argv[])} + +You can exit by simply falling through the end of @samp{main} or by calling + +@code{__volatile void exit(int returncode)} + +which does the cleanup: +@item +It calls all functions in the + +@code{long __EXIT_LIST__[];} + +with descending priority. +@item +It replys the WB startup message if necessary, resets the stackpointer +and returns to the shell. +@end itemize + +@samp{__INIT_LIST__} and @samp{__EXIT_LIST__} are two set elements +which are a speciality of the gnu ld. Since everything that needs +initialization works over these two lists the bare startups are +very short. In fact they are even shorter then some low-level-startups + +You can easily add your +own functions to the startup procedure by using the macros +in the file @samp{headers/stabs.h} - but keep in mind that this +is non-portable. Priority values <=0 are reserved for library implementors. + +@node Startup usage,,Startup interface,Startup codes +@chapter Startup code usage + +There are currently 3 startup codes in this package (maybe there will be more +in the future). Depending on the code and data model you use and some other +things you should choose one of them: + +@table @samp +@item ncrt0.o +This is the normal (i.e. large code, large data model) startup. +It contains a @samp{geta4()} entry point to enable you to use one source +for two code models. There is no other need for this function. +@item nbcrt0.o +This one is for compiling small data model (a4 relative) programs. +There is a @samp{geta4()} entry that places the right information into a4. +Use this startup code if you compiled with @samp{-fbaserel}. +@item nrcrt0.o +This startup code allocates a new data area every time you call it. +Even if you don't call it at all the data are is there once. +This gives you multientrant and reentrant code. +Therefore this startup code is for compiling resident (pure) programs. +Resident programs are always small data model if you let the compiler +do the work. + +There is no @samp{geta4()} entry - I just don't know how this could be done. +(If you start your code 10 times and want to access global data +out of a hook you cannot tell which one of the 10 data areas to use +because you want to access the data from a different task!) +@end table + +@node Commandline parser,libstack.a,Startup codes,Features +@chapter Commandline parser + +There are currently 2 commandline parser modules in the libnix package. +You can easily write your own by looking into the examples + +@table @code +@item libnixmain.a +This is the normal one, i.e. it does all the work necessary for +ANSI compatibility and gives you the normal @samp{main} calling +convention. You can shut down the commandline parsing (if you want +to use the amiga OS commandline parser) by declaring + +@code{__nocommandline} + +somewhere in your code (the type of it actually doesn't matter). This +spares some bytes and is compatible to every other compiler. + +And you can declare your own WB shell window by declaring a + +@code{char __stdiowin[]} + +variable somewhere in your code (but only if you parse the commandline - +without the commandline parser you get no window at all!). + +@item libnix_main.a +This is a special version of a commandline parser - it doesn't call +the normal @samp{main} but + +@code{int main(char *commandline)} + +@samp{commandline} is the complete commandline - including the quoted +filename of your program (it's only quoted, not escaped - this is +for compatibility reasons :-( ). You might think the name of the game +should be @samp{_main} and not @samp{main} - and you are completely +right. You can use @samp{_main} for @samp{main} and @samp{_exit} for +@samp{exit} - there are symbol redirections for these and the linker +does the work. + +This commandline parser is useful for compatibility. +You can use it as a second example or for recompiling PD programs that +use the single argument. You cannot use it for compiling ANSI code. +@end table + +@node libstack.a,libnix.a,Commandline parser,Features +@chapter special stack handling facilities + +The current Amiga OS (V3.1) has a very limited stack handling compared +to most other OSs: Every process has it's own fixed sized stack - and that's +all about it. The usual default for this stack is 4k, but that's not enough +for more complicated purposes (like for example compilers). Setting a higher +default is no real solution because it costs a lot of (widely unused) memory +and may be overrun, too :-(. + +But fortunately you can get stack extension with a little help of the compiler ;-). +Starting with V0.9 of libnix and V2.7.0 of gcc you get a fully featured stack +extension facility. The old stack swap method is still provided (not only for +compatibility but also because it's simpler) but please don't try to mix it with +the newer check/extend methods. +@menu +* swapstack:: Old method. +* stackextend implementation:: How stack extend works. +* stackextend usage:: Usage. @strong{read} +* Advanced:: Fine tuning. +* Costs:: Some damned lies (Benchmarks ;-) ). +@end menu +@node swapstack,stackextend implementation,libstack.a,libstack.a +@chapter Minimum stack setting + +Most large tools need more stack than the default 4096 bytes. If your tool is +one of them you can either rely on the user being able to raise the current stack +or you can let libnix raise the stack for you. At startup this module checks if the +current stack is large enough for your needs and switches to a new one if not. +All you have to do is to provide a variable + +@samp{unsigned long __stack=@{required stacksize@};} + +somewhere in your code and to link with the appropriate swapstack.o module. +@node stackextend implementation,stackextend usage,swapstack,libstack.a +@chapter Implementation of stack checking and extension + +The basic principle of stack checking is that the compiler emits special code +to check if the stack is large enough whenever there's need for a bigger chunk +of stackspace, i.e. at function entry when local arrays are allocated, at +the start of blocks with local variable sized arrays and when calling @samp{alloca()}. +If the needed stackchunk is bigger than the left stackspace the program ends. + +Since this special code costs memory and CPU time smaller stackneeds (e.g. when +calling library functions) are handled by not really checking against the hard border +of the stackframe but against one that leaves a certain amount of stackspace left +(@xref{Advanced}.). If you like to call functions with a lot of arguments +(more than 256 bytes) you should raise this value. + +Stack extension builds on the same basic principle but allocates a new stackframe +whenever necessary. If this happens at the entry of a function with arguments +they have to be copied to the new stackframe so that the function may use them. +Since C allows for a variable number of arguments the compiler doesn't always know +how many arguments there are. Therefore only a fixed number of bytes is copied. +If your functions may have lots of arguments (again more than 256 bytes) you +should raise this number. + +Since allocation and freeing of memory through OS functions costs a lot of +time (while a stack tends to be very dynamic) libnix caches once used stackframes +and utilizes them again if necessary. The memory needed for this doesn't accumulate +or such but just sticks to a maximum value raised once. This may look like a memory leak +(while in fact it isn't). Be prepared for it. +@node stackextend usage,Advanced,stackextend implementation,libstack.a +@chapter Using stack checking or extension +To utilize the stack checking or extension feature you need at least V2.7.0 of +gcc. With this compiler you get 2 new amiga specific options that emit special +code whenever necessary: + +@itemize @bullet +@item +@samp{-mstackcheck} Emits code that checks if there is enough stack left. +The program exits if not. +@item +@samp{-mstackextend} Tries to extend the stack before exiting (this may +happen due to low or fragmented memory). +@end itemize + +Always use those switches together with @samp{-lstack} to link with the stack +extension code or you will get a lot of undefined references ;-). +You can mix functions compiled with or without stack checking and extention +without problems. + +@strong{Caution:} + +Do not use stack checking and/or extension switches when +compiling hook or interrupt code. Both run in alien contexts with a different +stack and all stack magic must fail. Also don't try to do some other stack magic +on your own if you want to use stack extension. + +Also note that a program compiled with stack extension/checking may @samp{exit()} at +@emph{any} function entry or when using alloca or variable sized arrays. Either prepare +your cleanup function accordingly (use @samp{atexit()}) or don't use this feature. + +If you like to write or call functions with more than 256 bytes of arguments +(64 ints, longs or pointers) you should adjust the behaviour of the +stack extension code (@xref{Advanced}.). + +@node Advanced,Costs,stackextend usage,libstack.a +@chapter Stack extension fine tuning + +To adjust the behaviour of the stack extension code to your personal needs +you may set some of the following variables (or functions) + +@samp{unsigned long __stk_minframe} (default: 32768) + +Minimum amount of memory to allocate for a new stackframe. Setting a higher +value speeds the code up but costs more memory if it is unused. + +@samp{unsigned long __stk_safezone} (default: 2048) + +Size of the safety zone. Set this to a higher value +if you want to @emph{call} functions with lots of arguments. + +@samp{unsigned long __stk_argbytes} (default: 256) + +Number of bytes copied as arguments. Set this to a higher +value if @emph{your} functions may have lots of arguments. + +@samp{void _CXOVF(void)} + +Is a user replaceable stack overflow handler. The default one just pops +up a requester, then exits. This function is not allowed to return. + +@node Costs,,Advanced,libstack.a +@chapter Overhead of stack extension + +The additional code needed for stack extension (or checking) costs memory +and CPU power. Here are some numbers to give you a very rough idea for it. +(Times are in 1/60s, sizes in bytes): + +@example +Test normal checking extending extending + (big stack) (big stack) (big stack) (small stack) + +Simple recursive +function runtime 152 221 225 226 +(function calling +overhead) + +Variable sized 52 136 398 468 +array runtime + +alloca runtime 31 118 118 118 + +Own code size 1040 1160 1140 + +Library code size 0 184 788 +@end example + +@node libnix.a,libamiga.a,libstack.a,Features +@chapter Some ANSI (mis)features + +I suppose you are familiar with C and especially ANSI C - if not +you should read a good book about it +@footnote{I recommend this one: + +Brian W. Kernighan, Dennis M.Ritchie: +@*The C Programming Language (Second Edition) +@*Prentice Hall, Englewood Cliffs, 1988}. +This chapter only contains some special features of the +implementation - you should know these if you want to +use this library. + +@menu +* Locale:: +* Formatted I/O:: +* atof strtod:: +* Memory management:: +* Standard I/O:: +* Signal handling:: +* setjmp longjmp:: +* ctype:: +* clock:: +* Multibyte character functions:: +@end menu + +@node Locale,Formatted I/O,libnix.a,libnix.a +@chapter Locale + +One feature of a complete ANSI compatible library is locale support. The +ANSI standard only knows of two locales: + +@itemize @bullet +@item +"C" locale (normal C behaviour). +@item +Default locale. +@end itemize + +Every other locale depends very heavily on the implementation. + +To do locale support on the amiga I decided to use locale.library (what else). +This means that you normally have only these two locales - to have more than that +you must make some extra preferences files with the locale preferences editor +and give the path of these to the setlocale()-call. If you do not have locale.library +you will get only "C" locale. This is the default then :-(. + +Another important point is that the ANSI standard requires the default locale to be +loaded at program startup. i.e. if you use german locale (for example) you +will just get it - printf and scanf will not work as expected but use the +decimal comma @samp{,} instead of the decimal point @samp{.} for their floating +point numbers, ctype functions will behave differently, too. + +This can be very annoying if you don't want to use ANSI locale but rather +locale.library (which is not portable but IMHO much better) or if +you don't need locale support. And even dangerous if you don't +test your program under different locales. + +To get around this problem I decided to do some nasty thing: +To get locale support you have to make up a reference to setlocale. You can do +this by just calling + +setlocale(LC_ALL,"C"); + +immediately after program startup. (And get "C" locale then after program start which +is a much better choice). Or by just using setlocale anywhere in your program - +you will get default locale at program startup then. + +@node Formatted I/O,atof strtod,Locale,libnix.a +@chapter Formatted I/O + +The formatted I/O specifications are all there (remember: this library tries to +be ANSI compliant). But there are two things you should know about them: + +@itemize @bullet +@item +The formatted I/O is affected by the setlocale() call - this is no bug, +just an ANSI feature. +@item +Half of the code of a full blown printf handles floating point numbers - +but not everybody needs them. So there are two functions for both +@samp{vfprintf} and @samp{vfscanf} - one in @samp{libnix.a} not including +floating point support and one in @samp{libm.a} including floating +point support. + +So if you want to use one of the formatted I/O specifiers for floats +you should link with the math library @samp{-lm}. +@end itemize + +@node atof strtod,Memory management,Formatted I/O,libnix.a +@chapter atof strtod + +The two functions @samp{atof} and @samp{strtod} require a working +@samp{%f} specifier in @samp{vfscanf} - therefore they +require the formatted I/O functions in the math library. +Since @samp{libm.a} is linked before @samp{libnix.a} these +two functions have been gone into the math library. + +@node Memory management,Standard I/O,atof strtod,libnix.a +@chapter Memory management + +Most of the memory management of this library runs through malloc(). +Only the commandline parser uses AllocVec() - so you can use it without +having the malloc function somewere in your program. + +The memory management uses a local (to this task) memory pool to reduce +memory fragmentation. It uses the system functions to do so (not the +new pooled memory functions but just the older Allocate(), Deallocate() pair +which are the <3.0 fallback for libamiga.a's pooled memory functions, too) +so there should be no problems with it - these functions are tested very good. + +The default blocksize for memory allocations is 16384 bytes - equivalent +to 4 MMU pages. Bigger allocations are blown up to a multiple of 4096 bytes. +So don't be alarmed if your program uses more memory then expected. + +If you don't like this value (if you use bigger portions frequently or only +use very little memory) you can replace it by declaring + +@code{unsigned long _MSTEP} + +You should use a multiple of MMU pages. If you don't use a full MMU page +you gain nothing - malloc rounds up anyway. + +@node Standard I/O,Signal handling,Memory management,libnix.a +@chapter Standard I/O - where stdin, stdout, stderr come from + +2 of the 3 standard I/O streams are no real problem: + +@itemize @bullet +@item +@samp{stdin} is set to the value the @samp{Input()} function of @samp{dos.library} +serves, +@item +@samp{stdout} is set to the @samp{Output()} value. +@end itemize + +Both streams are managed by the OS and the library need not take much +care about them. But @samp{stderr} is a different thing since +there is no @samp{Errput()} ;-) function. So @samp{stderr} is handled +as follows: + +@enumerate +@item +If @samp{process->pr_CES} is set, this value is taken. There are not +much shells that set this value so most of the time this leads to NULL. +@item +If this didn't work and your program was started from CLI the library +opens @samp{Open("*",MODE_NEWFILE)}. +This opens the last interactive terminal attached to stdout, i.e. +if you use the normal Amiga shell and redirect your output to a file you +get the terminal, if you redirect your output to @samp{NIL:} you get @samp{NIL:}. +@item +If this didn't work too (you never know) or your program was started from WB +you simply get the same stream as in @samp{stdout}. +@end enumerate + +@node Signal handling,setjmp longjmp,Standard I/O,libnix.a +@chapter Signal handling + +There is only support for the two signals SIGABRT and SIGINT. The library +knows of some other signals but cannot generate them. The support for +SIGABRT is simple - but SIGINT is a completely different thing: + +You cannot use exec signal handlers since they are called at any time - +even in the middle of a library call. And if your library just blocked +a private semaphore and you jump out of the library code you will get a nice +deadlock :-(. (And for people who don't know: signal handlers are bogus +upto OS 2.0 (even there you need a good setpatch)). + +So SIGINT (CTRL-C) is just polled at the start of most I/O-functions by +calling the function + +@code{void __chkabort(void)} + +Other signals are even more difficult to implement: + +@itemize @bullet +@item +SIGSEGV simply doesn't exist - and if it does it's due +to a VM system and should not be generated. +@item +SIGFPE is not generated by the math libraries - so it would +be a bad thing to generate it by the mathematical coprocessor. +@item +SIGILL should never happen - your program must be faulty if you get one. +Most of the time this happens if you try to run a 68020+ compiled program +on a plain 68000. +@item +SIGTERM couldn't be disabled - even if it was there ;-). +@end itemize + +You can disable CTRL-C handling by replacing @samp{__chkabort} with a do-nothing +stub function - but there is a better way. Just call + +@code{signal(SIGINT,SIG_IGN)} + +Replacing __chkabort is used very often by amiga-programs and if +your application does not need CTRL-C handling at all and is +amiga specific you can use this. The second method is the +ANSI standard method and works on all types of machines. + +@node setjmp longjmp,ctype,Signal handling,libnix.a +@chapter setjmp, longjmp + +This library is compatible to the header files that come with gcc - +and the jmp_buf in there is not large enough for the FPU registers. +So they are not restored! The ANSI standard doesn't even require to +restore any of the other local variables (they are restored :-) ), +so this is NO incompatibility to the ANSI standard. + +@node ctype,clock,setjmp longjmp,libnix.a +@chapter ctype.h functions + +If you look into ctype.h you will see that the functions in there are +just macros - and that they are duplicate in the library as functions. +This is NOT a mistake. The ANSI standard requires such macros to be +duplicate as functions. + +And remember: These functions are affected by the setlocale() call. + +@node clock,Multibyte character functions,ctype,libnix.a +@chapter The clock function + +The clock() function's work is to measure processor time for the specific +task - but there is no information like this in the amiga OS :-(. +So it just measures the time from program start on - and is compatible with +this behaviour to all single tasking OSs around. + +@node Multibyte character functions,,clock,libnix.a +@chapter Multibyte character functions + +The multibyte character functions are all there - but since the +Amiga OS uses no other character set than ECMA Latin I they simulate +just "C" locale. This means they do nothing useful. + +@node libstubs.a,detach.o,libamiga.a,Features +@chapter libstubs - automatic library opening + +The Amiga OS shared libraries are a nice thing. All the tasks can +use them in parallel, they eat up memory only if you use them and +they are simple to use - and all this works even without a +memory management unit (MMU). + +Another nice feature is the fact that you can open them under +program control, i.e. you can take some action if they do not +exist - warn the user, disable some features, etc. This nice +feature becomes a misfeature if you only need a certain list +of functions that are there all the time - exec, dos, intuition - +you still have to open the shared libraries. + +So most Amiga compilers have a feature called automatic library +opening feature. This means that all libraries you reference +(by calling one of the functions) but don't open yourself get +opened for you by the compiler. + +@menu +* Auto-library-opening usage:: How to use it. +* Auto-library-opening interface:: How it works. +@end menu + +@node Auto-library-opening usage,Auto-library-opening interface,libstubs.a,libstubs.a +@chapter Usage + +To use this feature you have to do nothing (therefore it's called +automatic). But you can control the library version if you wish +by declaring + +@code{long __oslibversion;} + +somewhere in your program. But don't set this lower than 37 - most functions +of libnix (including the commandline parsers) need 37 or more. + +@node Auto-library-opening interface,,Auto-library-opening usage,libstubs.a +@chapter Interface + +Implementing such a feature is no hard work if you know how - this +implementation uses a (not so good known) feature of the gnu linker +called set elements: + +@enumerate +@item +You write a library entry for every library base and link this library as the +last one. This means that the linker uses this library for every library base +pointer that is not defined but referenced somewhere. +@item +You tell the linker to collect these library bases together into a set element. +@item +You write a function that opens all libraries in the set element at +program start and cleans them up later. +@end enumerate + +Some details: + +There are two object files in the library for every library base pointer. +The first one is a + +@example +struct lib +@{ struct Library *base; + char *name; @}; +@end example + +containing the library base pointer (a @samp{NULL} pointer at program start) +and a pointer to the name of the library. This name + +@samp{extern char name[]} + +is the second object. All these structs are collected together into one +single set element called + +@samp{extern struct lib *__LIB_LIST__[]} + +To open and close the shared libraries there are two functions in +libstubs: + +@code{void __initlibraries(void)} + +and + +@code{void __exitlibraries(void)} + +Since it is still possible to open the shared libraries by hand I had +to take care about the library base pointers for libnix itself - +they are used in the commandline parsers - even before anybody could +open them. There exists a (library private) duplicate library base +pointer for each of these. They have normal names with +two underscores in front. + +So don't be alarmed if some system monitor tells you that your program +opened dos.library twice - this is normal behaviour, most libraries +do this. + +Opening libraries by hand works exactly the same way as on any other compiler: +@itemize @bullet +@item +You declare the library base variable somewhere globally: + +@code{struct DosLibrary *DOSBase=NULL;} + +The initialization @samp{=NULL} is necessary! Uninitialized variables +get overwritten by initialized ones in other object files - and +the library base pointers in @samp{libstubs.a} are initialized with @samp{NULL}. +This is a feature of the GNU ld and I cannot do much about it :(. +@item +You open the library before using it: + +@code{DOSBase=(struct DosLibrary *)OpenLibrary("dos.library",37);} + +and do some action if it fails :). +@end itemize + +@node detach.o,,libstubs.a,Features +@chapter Detaching from the current CLI + +Some people like multitasking that much that they tend to start everything +in the background. Some tools are able to do this automatically - and with +libnix you can write such tools, too. @footnote{ Please be aware that you +lose the ability to synchronize your tool with the calling CLI - this can be +very nasty if one needs to. Use this feature very sparse: Most of the time +it's better to just rely on the user being able to type @samp{Run >NIL: + +int max=100; +int count; +char string[]="Hello, world\n"; + +int main(void) +@{ int i; + for(i=0;i +stack 300000 +sh +Hunk2GCC amiga.lib +ar -q libamiga.a obj* +rm *.o +ranlib libamiga.a +exit +@end example + +Doing this on @samp{RAM:} will improve performance a lot. + +This doesn't give you the baserelative version blib/libamiga.a - +you will be unable to compile resident programs. To get a baserelative +version of amiga.lib try to get the @samp{libtos} program of the +@samp{DICE} compiler of M. Dillon (from fishdisk or somewhere else) - +it converts libraries to baserelative ones: + +@example +cd +lha x amigalibdisk491:dice/dice206_21.lzh #?/libtos +netdcc/bin/libtos amiga.lib amigas.lib +@end example + +Then do the same as above. + +@node Code size,FAQs,Library bases,Top +@chapter Writing small programs + +Writing very small programs is a trivial thing - if you know how to do it. +Here are some basic tips and tricks: + +@table @asis +@item Do not use printf: +@samp{printf} is the most high-level function of +usual ANSI C libraries and builds on almost everything else. Often this function +can be replaced by simpler routines like e.g. @samp{puts}. The same is true +for the other formatted I/O functions. + +If you write amiga-only programs you can use the @samp{sprintf} routine of +libamiga.a by linking with @samp{-lamiga}. + +@item Try to avoid using buffered I/O: +A lot of programs can be written using the low-level I/O-functions @samp{read} and +@samp{write}. This saves the code responsible for buffered I/O. + +@item Avoid -O3: +@samp{-O3} activates all those optimizations that sacrifice code size for speed. +An exception is @samp{-fstrength-reduce} which costs compile time but not +code size. @samp{-O2 -fstrength-reduce} will give small programs. + +@item Strip your executables: +gcc doesn't strip executables by default. Setting @samp{-s} will give worse +debugable but small programs. + +@item Use small code and data model: +@samp{-msmall-code -fbaserel} do this. Be aware that this won't work for +larger programs. + +@item Don't use libgcc.a: +@samp{libgcc.a} which calls global C++ constructors and destructors builds +on @samp{atexit} which builds on @samp{malloc}, ... If your program doesn't +use them you can save some memory by linking by hand (@samp{-nostdlib}). + +@item Set __nocommandline: +If you use @samp{ReadArgs} instead of @samp{argc, argv} you can save some +memory by setting a global variable named @samp{__nocommandline} to drop +parsing of commandline arguments. +@end table + +@node FAQs,,Code size,Top +@chapter FAQs + +@table @asis +@item Q: +I do not get a working executable out of it - my debugger +tells me the library bases are broken. +@item A: +The GNU ld that comes with GCC 2.5.8 (or lower) has some +serious bugs in conjunction with set elements. +Use the fixed version of ld that comes with gcc 2.6.0 (or above). + +@item Q: +There are some prototypes missing in stdio.h. +@item A: +This stdio.h is only for internal use - use the normal GCC +stdio.h to compile your programs. + +@item Q: +While printing floats printf prints weird characters. +@item A: +This problem should be fixed with the current release of libnix. It was caused +by a bug in the system math libraries which happens if you open them in the +wrong order. You can use the SetMathPatch program by Andreas Wolff to fix this +and another more serious bug with mc68040 processors. +@end table +@printindex cp +@contents +@bye diff --git a/libnix/mkinstalldirs b/libnix/mkinstalldirs new file mode 100644 index 0000000..66c8d76 --- /dev/null +++ b/libnix/mkinstalldirs @@ -0,0 +1,30 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# Created: 1993-05-16 +# Last modified: 1994-03-25 +# Public domain + +errstatus=0 + +for file in ${1+"$@"} ; do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d in ${1+"$@"} ; do + pathcomp="$pathcomp$d" + case "$pathcomp" in + -* ) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" 1>&2 + mkdir "$pathcomp" || errstatus=$? + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus diff --git a/libnix/sources/Makefile.in b/libnix/sources/Makefile.in new file mode 100644 index 0000000..734624c --- /dev/null +++ b/libnix/sources/Makefile.in @@ -0,0 +1,98 @@ +# Built one model of the libnix libraries - use +# make CFLAGS="what you like" to built them. +# +# Combine +# +# CFLAGS=-Wall -O3 +# +# -fbaserel -DSMALL_DATA for small data model +# -fbaserel32 for large baserel model +# -m68020 for 68020 specific code +# -m68060 for 68060 specific code +# -m68881 for 68881 specific code +# -DIXPATHS for Un*x path option +# -DDEBUG_LIB build a library for debugging (not recommended) + +#### Start of system configuration section. #### + +srcdir = @srcdir@ +VPATH = @srcdir@ + +CC = @CC@ +CPP = @CPP@ +AS = as + +RANLIB = @RANLIB@ +AWK = @AWK@ + +#### End system configuration section #### + +CURDIR = $(shell pwd) + +MAKELIST=make -f $(CURDIR)/Makefile + +SUBDIRS=nixmain nix_main misc nix nix13 math stack stubs + +all: $(foreach f,$(SUBDIRS),$(CURDIR)/$(f)) + for subdir in $(SUBDIRS); do \ + ( cd $$subdir;make -f ../../sources/$$subdir/Makefile V="$(V)" \ + CFLAGS="$(CFLAGS)" ); \ + done + +$(foreach f,$(SUBDIRS),$(CURDIR)/$(f)): + mkdir $@ + +libamiga: + if [ ! -d amiga ] ; then mkdir amiga ; else true ; fi + cd amiga;make -f $(CURDIR)/../sources/amiga/Makefile CFLAGS="$(CFLAGS)" + +filelists: + -cd $(srcdir)/math; $(MAKELIST) SOURCEFILES="*/*" FLDIR=$(CURDIR)/math $(CURDIR)/math/filelist + -cd $(srcdir)/stack; $(MAKELIST) SOURCEFILES="*.c" FLDIR=$(CURDIR)/stack $(CURDIR)/stack/filelist + -cd $(srcdir)/nix; $(MAKELIST) SOURCEFILES="*/*" FLDIR=$(CURDIR)/nix $(CURDIR)/nix/filelist + -cd $(srcdir)/nix13; $(MAKELIST) SOURCEFILES="*/*" FLDIR=$(CURDIR)/nix13 $(CURDIR)/nix13/filelist + -cd $(srcdir)/stubs; make -f $(CURDIR)/Makefile STUBDIR=$(CURDIR)/stubs libbases/dos.c; \ + $(MAKELIST) SOURCEFILES=" \ + libbases/* misc/__DOSBase.c misc/__UtilityBase.c \ + misc/__MathIeeeSingBasBase.c misc/__MathIeeeDoubBasBase.c \ + misc/__MathIeeeSingTransBase.c misc/__MathIeeeDoubTransBase.c \ + misc/__initlibraries.c misc/__flush_cache.c misc/__cpucheck.c \ + libnames/* stubs/*" \ + FLDIR=$(CURDIR)/stubs $(CURDIR)/stubs/filelist + -cd $(srcdir)/amiga; $(MAKELIST) SOURCEFILES="*/*" FLDIR=$(CURDIR)/amiga $(CURDIR)/amiga/filelist + +$(FLDIR)/filelist: + echo "#Computer generated partial Makefile-do not edit" >$(FLDIR)/filelist + echo "OBJECTS= \\" >>$(FLDIR)/filelist + ( for file in $(SOURCEFILES); do echo $$file; done ) | \ + $(AWK) '{ if($$0 !~ /CVS/) { print substr($$0,1,length($$0)-2) ".o \\" } }' >>$(FLDIR)/filelist + echo >>$(FLDIR)/filelist + echo "SUBDIRS= \\" >>$(FLDIR)/filelist + ls -d -F *|$(AWK) '/\// { if($$0 !~ /CVS/) { print substr($$0,1,length($$0)-1) " \\" } }' >>$(FLDIR)/filelist + +# build stubs for library base pointers +libbases/dos.c: $(STUBDIR)/Makefile library.list + -rm -f libbases/* libnames/* + $(AWK) fname; \ + print "#include " >fname; \ + print "extern char __" sname "name[];" >fname; \ + print "void *" $$1 "[2]={ 0l,__" sname "name };" >fname; \ + print "ADD2LIB(" $$1 ");" >fname; \ + fname="libnames/" sname ".c"; \ + print "/* Machine-generated C-file- do not edit ! */" >fname; \ + print "char __" sname "name[]=\"" $$2 "\";" >fname;}' + +clean: + if [ -d nixmain ] ; then (cd nixmain; make -f ../../sources/nixmain/Makefile TARGET=clean clean) ; else true ; fi + if [ -d nix_main ] ; then (cd nix_main; make -f ../../sources/nix_main/Makefile TARGET=clean clean) ; else true ; fi + if [ -d misc ] ; then (cd misc; make -f ../../sources/misc/Makefile TARGET=clean clean) ; else true ; fi + if [ -d math ] ; then (cd math; make -f ../../sources/math/Makefile TARGET=clean clean) ; else true ; fi + if [ -d stack ] ; then (cd stack; make -f ../../sources/stack/Makefile TARGET=clean clean) ; else true ; fi + if [ -d nix ] ; then (cd nix; make -f ../../sources/nix/Makefile TARGET=clean clean) ; else true ; fi + if [ -d nix13 ] ; then (cd nix13; make -f ../../sources/nix13/Makefile TARGET=clean clean) ; else true ; fi + if [ -d stubs ] ; then (cd stubs; make -f ../../sources/stubs/Makefile TARGET=clean clean) ; else true ; fi + +veryclean: + -rm -rf * diff --git a/libnix/sources/amiga/Makefile.in b/libnix/sources/amiga/Makefile.in new file mode 100644 index 0000000..cba2584 --- /dev/null +++ b/libnix/sources/amiga/Makefile.in @@ -0,0 +1,134 @@ +#### Start of system configuration section. #### + +srcdir = @srcdir@ +VPATH = @srcdir@ + +CC = @CC@ +CPP = @CPP@ +AS = as + +RANLIB = @RANLIB@ +AWK = @AWK@ +FD2INLINE = fd2inline + +CLIBPATH = $(prefix)/os-include/clib/ +FDPATH = $(prefix)/os-lib/fd/ + +#### End system configuration section #### + +include ../../sources/amiga/filelist + +CURDIR = $(shell pwd) + +OPTIONS=-I $(srcdir)/../headers -I../../sources/headers $(CFLAGS) + +SOURCEFILES=*/* + +FDFILES = $(wildcard $(FDPATH)*.fd) +CLIB = $(addprefix $(CLIBPATH),$(subst _lib.fd,_protos.h,$(notdir $(fd)))) +STUB = $(subst _lib.fd,,$(notdir $(fd))) + + +%.o: %.c + $(CC) $(OPTIONS) -c $^ -o $@ 2>&1|tee $*.err + -if test ! -s $*.err; then rm $*.err; fi + +%.o: %.S + $(CC) $(OPTIONS) -c $^ -o $@ 2>&1|tee $*.err + -if test ! -s $*.err; then rm $*.err; fi + +.PHONY: all clean veryclean splitinline + +all: libamiga.a + +clean: + -rm -rf $(SUBDIRS) + +veryclean: + -rm -rf * + +$(foreach f,$(SUBDIRS),$(CURDIR)/$(f)): + mkdir $@ + +##libamiga.a: $(foreach f,$(SUBDIRS),$(CURDIR)/$(f)) $(OBJECTS) libglue.a ../../sources/amiga/makefile ../../sources/amiga/filelist +libamiga.a: $(foreach f,$(SUBDIRS),$(CURDIR)/$(f)) $(OBJECTS) newlibglue.a ../../sources/amiga/makefile ../../sources/amiga/filelist + -rm -f libamiga.a +## -cp libglue.a libamiga.a + -cp newlibglue.a libamiga.a + ar -q libamiga.a $(OBJECTS) + $(RANLIB) libamiga.a + +libglue.a: + if [ -d tmp ] ; then rm -rf tmp ; else true ; fi + -mkdir tmp +# Build assembler stubs out of inline headers: +# * First transform all vararg #defines into real functions +# * Compile all functions with 'extern' and '__inline' disabled +# * Split resulting assembler output at function entries +# * This needs old-style inlines! + -cd tmp; \ + echo "" >dummy.c; \ + for file in /gg/include/inline/*.h; do \ + ( $(AWK) 'nf==1 { fn=$$1;nf=0 } \ + /inline/ { vs="long";rs="return ";nf=1 } \ + /void/ { vs="void";rs="";nf=1 } \ + /\.\.\./ \ + { st=substr($$0,1,index($$0,"tags...")-1); \ + st=substr(st,index(st," ")); \ + st2=st;gsub(/\(/,"(long ",st2);gsub(/,/,",long ",st2); \ + print "#undef" substr(st,1,index(st,"(")-1) "\n" vs st2 "tags,...)"; \ + print "{ " rs fn substr(st,index(st,"(")) "&tags); }\n" \ + }' $$file >vararg.c; \ + ( $(CC) $(CFLAGS) -w -include $$file vararg.c -S -o -; \ + $(CC) -Dextern= -D__inline= -D_STRSUP_H -include $$file $(CFLAGS) dummy.c -S -o - ) | \ + $(AWK) '/.even/ { next } /.comm/ { next } \ + /.globl/ { if(file!="") close(file); file=$$2 ".s"; \ + print "\t.even\n" $$0 >file; next; } \ + { if(file!="") print $$0 >file; }' ); done + -cd tmp;rm vararg.c dummy.c;$(CC) -c *.s + -rm libglue.a + -cd tmp;ar -q ../libglue.a *.o + -rm -rf tmp + +newlibglue.a: stublibs + if [ ! -f stamp-libglue ];\ + then\ + pwd;\ + rm -f $@;\ + $(foreach fd, $(FDFILES),\ + echo "adding $(STUB) stubs to $@ ...";\ + ar -q $@ stubs/$(STUB)/*.o;)\ + touch stamp-libglue;\ + else\ + true;\ + fi; + +stublibs: stubsrcs + cd stubs;\ + $(foreach fd, $(FDFILES),\ + if [ ! -f stamp-$(STUB)-stubs ];\ + then\ + echo "building $(STUB) stubs...";\ + cd $(STUB);\ + $(CC) $(OPTIONS) -c *.c;\ + cd ..;\ + touch stamp-$(STUB)-stubs;\ + else\ + true;\ + fi;\ + ) + +stubsrcs: + if [ ! -d stubs ] ; then mkdir stubs ; else true ; fi + cd stubs;\ + $(foreach fd, $(FDFILES),\ + if [ ! -f stamp-$(STUB)-srcs ];\ + then\ + echo "creating $(STUB) stubs sources...";\ + rm -rf $(STUB);\ + $(FD2INLINE) --splitstubs $(fd) $(CLIB) -o $(STUB);\ + touch stamp-$(STUB)-srcs;\ + else\ + true;\ + fi;\ + ) diff --git a/libnix/sources/amiga/misc/AbsExecBase.c b/libnix/sources/amiga/misc/AbsExecBase.c new file mode 100755 index 0000000..714c6f5 --- /dev/null +++ b/libnix/sources/amiga/misc/AbsExecBase.c @@ -0,0 +1,7 @@ +#include + +ABSDEF(AbsExecBase,0x00000004); +ABSDEF(cartridge, 0x00f00000); +ABSDEF(bootrom, 0x00f80000); +ABSDEF(romstart, 0x00fc0000); +ABSDEF(romend, 0x00ffffff); diff --git a/libnix/sources/amiga/misc/AddTOF.c b/libnix/sources/amiga/misc/AddTOF.c new file mode 100755 index 0000000..00ade62 --- /dev/null +++ b/libnix/sources/amiga/misc/AddTOF.c @@ -0,0 +1,27 @@ +#include +#include +#include +#include +#include +#include + +STATIC int stub(struct Isrvstr *intr asm("a1")) +{ + (*intr->ccode)(intr->Carg); return 0; +} + +VOID AddTOF(struct Isrvstr *intr,LONG (*code)(),LONG arg) +{ APTR SysBase = *(APTR *)4L; + + intr->Iptr = intr; + intr->code = (int (*)())stub; + intr->ccode = (int (*)())code; + intr->Carg = (int)arg; + AddIntServer(INTB_VERTB,(struct Interrupt *)intr); +} + +VOID RemTOF(struct Isrvstr *intr) +{ APTR SysBase = *(APTR *)4L; + + RemIntServer(INTB_VERTB,(struct Interrupt *)intr); +} diff --git a/libnix/sources/amiga/misc/ArgArray.c b/libnix/sources/amiga/misc/ArgArray.c new file mode 100755 index 0000000..74bebf6 --- /dev/null +++ b/libnix/sources/amiga/misc/ArgArray.c @@ -0,0 +1,89 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef NEW_ARGARRAY +static UBYTE **argArray; +#endif +static struct DiskObject *dObj; + +UBYTE **ArgArrayInit(long argc, UBYTE **argv) +{ + if (argc) { + if (argc>1) +#ifdef NEW_ARGARRAY + if ((argArray=AllocVec(argc*sizeof(char *),MEMF_ANY))) { + UBYTE **p,**p1; + + p=p1=argArray; + argv++; + do + { + *p1++=*argv++; + } + while(--argc); + return p; + } +#else + { + argv++; return argv; + } +#endif + } + else + if ((dObj=GetDiskObject(((struct WBStartup *)argv)->sm_ArgList->wa_Name))) + return (UBYTE **)dObj->do_ToolTypes; + return NULL; + +} + +STRPTR ArgString(UBYTE **tt, STRPTR entry, STRPTR defstr) +{ + STRPTR str; + + if (!entry || !(str=FindToolType(tt,entry))) + str=defstr; + return str; +} + +LONG ArgInt(UBYTE **tt, STRPTR entry, long defval) +{ + STRPTR str; + + if (entry && (str=FindToolType(tt,entry))) + StrToLong(str,&defval); + return defval; +} + +#ifdef 0 /* only a example ??? */ + +CxObj *UserFilter(UBYTE **tt, STRPTR entry, STRPTR defstr) +{ + STRPTR str; + + if (!entry || !(str=FindToolType(tt,entry))) + str=defstr; + return (CreateCxObj(CX_FILTER,(long)str,NULL)); +} + +#endif + +void ArgArrayDone(void) +{ + struct DiskObject **d; +#ifdef NEW_ARGARRAY + UBYTE ***a; + + if (*(a=&argArray)) { + FreeVec(*a); *a=NULL; + } +#endif + if (*(d=&dObj)) { + FreeDiskObject(*d); *d=NULL; + } +} diff --git a/libnix/sources/amiga/misc/AsmAllocPooled.c b/libnix/sources/amiga/misc/AsmAllocPooled.c new file mode 100644 index 0000000..ae13362 --- /dev/null +++ b/libnix/sources/amiga/misc/AsmAllocPooled.c @@ -0,0 +1,62 @@ +#include + +APTR ASM AsmAllocPooled(REG(a0,POOL *poolHeader),REG(d0,ULONG memSize),REG(a6,APTR SysBase)) +{ + if (((struct Library *)SysBase)->lib_Version>=39) + return (AllocPooled(poolHeader,memSize)); + else { + + ULONG *puddle=NULL; + + if (poolHeader!=NULL && memSize!=0) { + + ULONG *p,size; + + if (poolHeader->ThreshSize>memSize) { + + struct MemHeader *a=(struct MemHeader *)poolHeader->PuddleList.mlh_Head; + + for(;;) { + if (a->mh_Node.ln_Succ!=NULL) { + if (a->mh_Node.ln_Type && (puddle=(ULONG *)Allocate(a,memSize))!=NULL) + break; + a=(struct MemHeader *)a->mh_Node.ln_Succ; continue; + } + + size=poolHeader->PuddleSize+sizeof(struct MemHeader)+2*sizeof(ULONG); + if ((puddle=(ULONG *)AllocMem(size,poolHeader->MemoryFlags))==NULL) + goto out; /* why is gcc so dumb ??? */ + + *puddle++=size; + a=(struct MemHeader *)puddle; + a->mh_Node.ln_Type=NT_MEMORY; + a->mh_Lower=a->mh_First=(struct MemChunk *)((UBYTE *)a+sizeof(struct MemHeader)+sizeof(UBYTE *)); + a->mh_First->mc_Next=NULL; + a->mh_Free=a->mh_First->mc_Bytes=poolHeader->PuddleSize; + a->mh_Upper=(char *)a->mh_First+a->mh_Free; + AddHead((struct List *)&poolHeader->PuddleList,&a->mh_Node); + puddle=(ULONG *)Allocate(a,memSize); + break; + } + + if (poolHeader->MemoryFlags&MEMF_CLEAR) { + p=puddle; memSize+=7; memSize>>=3; + do { *p++=0; *p++=0; } while(--memSize); + } + } + else { + + size=memSize+sizeof(struct MinNode)+2*sizeof(ULONG); + + if ((puddle=(ULONG *)AllocMem(size,poolHeader->MemoryFlags))!=NULL) { + *puddle++=size; + AddTail((struct List *)&poolHeader->PuddleList,(struct Node *)puddle); + puddle=(ULONG *)((struct MinNode *)puddle+1); + *puddle++=0; + } + } + } +out: + return puddle; + } +} diff --git a/libnix/sources/amiga/misc/AsmCreatePool.c b/libnix/sources/amiga/misc/AsmCreatePool.c new file mode 100644 index 0000000..ebd3bd2 --- /dev/null +++ b/libnix/sources/amiga/misc/AsmCreatePool.c @@ -0,0 +1,37 @@ +#include + +#define NEWLIST(l) ((l)->mlh_Head = (struct MinNode *)&(l)->mlh_Tail, \ + (l)->mlh_Tail = NULL, \ + (l)->mlh_TailPred = (struct MinNode *)&(l)->mlh_Head) + +APTR ASM AsmCreatePool(REG(d0,ULONG requirements),REG(d1,ULONG puddleSize),REG(d2,ULONG threshSize),REG(a6,APTR SysBase)) +{ + if (((struct Library *)SysBase)->lib_Version>=39) + return (CreatePool(requirements,puddleSize,threshSize)); + else { + POOL *pool=NULL; + if (threshSize<=puddleSize) { + puddleSize+=7; + if ((pool=(POOL *)AllocMem(sizeof(POOL),MEMF_ANY))!=NULL) { + NEWLIST(&pool->PuddleList); + pool->MemoryFlags=requirements; + pool->PuddleSize=puddleSize&~7; + pool->ThreshSize=threshSize; + } + } + return pool; + } +} + +VOID ASM AsmDeletePool(REG(a0,POOL *poolHeader),REG(a6,APTR SysBase)) +{ ULONG *pool,size; + + if (((struct Library *)SysBase)->lib_Version>=39) + DeletePool(poolHeader); + else if (poolHeader!=NULL) { + while((pool=(ULONG *)RemHead((struct List *)&poolHeader->PuddleList))!=NULL) { + size=*--pool; FreeMem(pool,size); + } + FreeMem(poolHeader,sizeof(POOL)); + } +} diff --git a/libnix/sources/amiga/misc/AsmFreePooled.c b/libnix/sources/amiga/misc/AsmFreePooled.c new file mode 100644 index 0000000..c7a2706 --- /dev/null +++ b/libnix/sources/amiga/misc/AsmFreePooled.c @@ -0,0 +1,30 @@ +#include + +VOID ASM AsmFreePooled(REG(a0,POOL *poolHeader),REG(a1,APTR memory),REG(d0,ULONG memSize),REG(a6,APTR SysBase)) +{ + if (((struct Library *)SysBase)->lib_Version>=39) + return (FreePooled(poolHeader,memory,memSize)); + else if (poolHeader!=NULL && memory!=NULL) { + + ULONG size,*puddle=(ULONG *)((struct MinNode *)memory-1)-1; + + if (poolHeader->ThreshSize>memSize) { + + struct MemHeader *a=(struct MemHeader *)&poolHeader->PuddleList.mlh_Head; + + for(;;) { + a=(struct MemHeader *)a->mh_Node.ln_Succ; + if (a->mh_Node.ln_Succ==NULL) + return; + if (a->mh_Node.ln_Type && memory>=a->mh_Lower && memorymh_Upper) + break; + } + Deallocate(a,memory,memSize); + if (a->mh_Free!=poolHeader->PuddleSize) + return; + puddle=(ULONG *)&a->mh_Node; + } + Remove((struct Node *)puddle); + size=*--puddle; FreeMem(puddle,size); + } +} diff --git a/libnix/sources/amiga/misc/BeginIO.c b/libnix/sources/amiga/misc/BeginIO.c new file mode 100755 index 0000000..c4dc0a6 --- /dev/null +++ b/libnix/sources/amiga/misc/BeginIO.c @@ -0,0 +1,10 @@ +#ifdef __GNUC__ +#include +#include + +void BeginIO(struct IORequest *iorequest) +{ register struct IORequest *a1 asm("a1")=iorequest; + register struct Device *a6 asm("a6")=iorequest->io_Device; + asm("jsr a6@(-30)"::"r"(a1),"r"(a6):"a0","a1","d0","d1"); +} +#endif diff --git a/libnix/sources/amiga/misc/CallHook.c b/libnix/sources/amiga/misc/CallHook.c new file mode 100755 index 0000000..547b481 --- /dev/null +++ b/libnix/sources/amiga/misc/CallHook.c @@ -0,0 +1,23 @@ +asm(" + .text + + .globl _CallHook + .globl _CallHookA + +_CallHook: lea sp@(12:W),a1 + jra L_CallHook + +_CallHookA: movel sp@(12:W),a1 + +L_CallHook: movel a6,sp@- + movel a2,sp@- + movel sp@(12:W),a0 + movel sp@(16:W),a2 + jbsr L_callit + movel sp@+,a2 + movel sp@+,a6 + rts + +L_callit: movel a0@(8:W),sp@- + rts +"); diff --git a/libnix/sources/amiga/misc/Cia.c b/libnix/sources/amiga/misc/Cia.c new file mode 100755 index 0000000..76a9b16 --- /dev/null +++ b/libnix/sources/amiga/misc/Cia.c @@ -0,0 +1,39 @@ +#include + +/* Absolute definitions for the cia registers + * some of the are recommended to use + * and very useful when hacking hardware ;-) + */ + +ABSDEF(ciab, 0x00bfd000); +ABSDEF(ciabpra, 0x00bfd000); +ABSDEF(ciabprb, 0x00bfd100); +ABSDEF(ciabddra, 0x00bfd200); +ABSDEF(ciabddrb, 0x00bfd300); +ABSDEF(ciabtalo, 0x00bfd400); +ABSDEF(ciabtahi, 0x00bfd500); +ABSDEF(ciabtblo, 0x00bfd600); +ABSDEF(ciabtbhi, 0x00bfd700); +ABSDEF(ciabtodlow,0x00bfd800); +ABSDEF(ciabtodmid,0x00bfd900); +ABSDEF(ciabtodhi, 0x00bfda00); +ABSDEF(ciabsdr, 0x00bfdc00); +ABSDEF(ciabicr, 0x00bfdd00); +ABSDEF(ciabcra, 0x00bfde00); +ABSDEF(ciabcrb, 0x00bfdf00); +ABSDEF(ciaa, 0x00bfe001); +ABSDEF(ciaapra, 0x00bfe001); +ABSDEF(ciaaprb, 0x00bfe101); +ABSDEF(ciaaddra, 0x00bfe201); +ABSDEF(ciaaddrb, 0x00bfe301); +ABSDEF(ciaatalo, 0x00bfe401); +ABSDEF(ciaatahi, 0x00bfe501); +ABSDEF(ciaatblo, 0x00bfe601); +ABSDEF(ciaatbhi, 0x00bfe701); +ABSDEF(ciaatodlow,0x00bfe801); +ABSDEF(ciaatodmid,0x00bfe901); +ABSDEF(ciaatodhi, 0x00bfea01); +ABSDEF(ciaasdr, 0x00bfec01); +ABSDEF(ciaaicr, 0x00bfed01); +ABSDEF(ciaacra, 0x00bfee01); +ABSDEF(ciaacrb, 0x00bfef01); diff --git a/libnix/sources/amiga/misc/CoerceMethod.c b/libnix/sources/amiga/misc/CoerceMethod.c new file mode 100755 index 0000000..ed5eaf3 --- /dev/null +++ b/libnix/sources/amiga/misc/CoerceMethod.c @@ -0,0 +1,24 @@ +asm(" + .text + + .globl _CoerceMethod + .globl _CoerceMethodA + +_CoerceMethod: lea sp@(12:W),a1 + jra L_CoerceMethod + +_CoerceMethodA: movel sp@(12:W),a1 + +L_CoerceMethod: movel a2,sp@- + moveml sp@(8:W),a0/a2 + movel a0,d0 + beqs L_Null + movel a2,d0 + beqs L_Null + jbsr L_Invoke +L_Null: movel sp@+,a2 + rts + +L_Invoke: movel a0@(8:W),sp@- + rts +"); diff --git a/libnix/sources/amiga/misc/CreateIO.c b/libnix/sources/amiga/misc/CreateIO.c new file mode 100755 index 0000000..15348e6 --- /dev/null +++ b/libnix/sources/amiga/misc/CreateIO.c @@ -0,0 +1,35 @@ +#include +#include +#include +#include +#include + +struct IORequest *CreateExtIO(struct MsgPort *port,LONG iosize) +{ APTR SysBase = *(APTR *)4L; + struct IORequest *ioreq = NULL; + + if (port && (ioreq=AllocMem(iosize,MEMF_CLEAR|MEMF_PUBLIC))) { + ioreq->io_Message.mn_Node.ln_Type = NT_REPLYMSG; + ioreq->io_Message.mn_ReplyPort = port; + ioreq->io_Message.mn_Length = iosize; + } + return ioreq; +} + +struct IOStdReq *CreateStdIO(struct MsgPort *port) +{ + return (struct IOStdReq *)CreateExtIO(port,sizeof(struct IOStdReq)); +} + +VOID DeleteExtIO(struct IORequest *ioreq) +{ APTR SysBase = *(APTR *)4L; + LONG i; + + i = -1; + ioreq->io_Message.mn_Node.ln_Type = i; + ioreq->io_Device = (struct Device *)i; + ioreq->io_Unit = (struct Unit *)i; + FreeMem(ioreq,ioreq->io_Message.mn_Length); +} + +ALIAS(DeleteStdIO,DeleteExtIO); diff --git a/libnix/sources/amiga/misc/CreatePort.c b/libnix/sources/amiga/misc/CreatePort.c new file mode 100755 index 0000000..f8d5228 --- /dev/null +++ b/libnix/sources/amiga/misc/CreatePort.c @@ -0,0 +1,41 @@ +#include +#include +#include +#include + +#define NEWLIST(l) ((l)->lh_Head = (struct Node *)&(l)->lh_Tail, \ + /*(l)->lh_Tail = NULL,*/ \ + (l)->lh_TailPred = (struct Node *)&(l)->lh_Head) + +struct MsgPort *CreatePort(STRPTR name,LONG pri) +{ APTR SysBase = *(APTR *)4L; + struct MsgPort *port = NULL; + UBYTE portsig; + + if ((BYTE)(portsig=AllocSignal(-1)) >= 0) { + if (!(port=AllocMem(sizeof(*port),MEMF_CLEAR|MEMF_PUBLIC))) + FreeSignal(portsig); + else { + port->mp_Node.ln_Type = NT_MSGPORT; + port->mp_Node.ln_Pri = pri; + port->mp_Node.ln_Name = name; + /* done via AllocMem + port->mp_Flags = PA_SIGNAL; + */ + port->mp_SigBit = portsig; + port->mp_SigTask = FindTask(NULL); + NEWLIST(&port->mp_MsgList); + if (port->mp_Node.ln_Name) + AddPort(port); + } + } + return port; +} + +VOID DeletePort(struct MsgPort *port) +{ APTR SysBase = *(APTR *)4L; + + if (port->mp_Node.ln_Name) + RemPort(port); + FreeSignal(port->mp_SigBit); FreeMem(port,sizeof(*port)); +} diff --git a/libnix/sources/amiga/misc/CreateTask.c b/libnix/sources/amiga/misc/CreateTask.c new file mode 100755 index 0000000..e08c524 --- /dev/null +++ b/libnix/sources/amiga/misc/CreateTask.c @@ -0,0 +1,126 @@ +#if 1 + +#include +#include +#include + +struct newMemList { + struct Node nml_Node; + UWORD nml_NumEntries; + struct MemEntry nml_ME[2]; +}; + +const struct newMemList MemTemplate = { + {0,}, + 2, + { {MEMF_CLEAR|MEMF_PUBLIC, sizeof(struct Task)}, + {MEMF_CLEAR, 0} } +}; + +#define NEWLIST(l) ((l)->lh_Head = (struct Node *)&(l)->lh_Tail, \ + /*(l)->lh_Tail = NULL,*/ \ + (l)->lh_TailPred = (struct Node *)&(l)->lh_Head) + +struct Task *CreateTask(STRPTR name, LONG pri, APTR initpc, ULONG stacksize) +{ struct Library *SysBase = *(struct Library **)4L; + struct newMemList nml; + struct MemList *ml; + struct Task *newtask; + APTR task2; + + stacksize=(stacksize+3)&~3; + + { + long *p1,*p2; + int i; + + for (p1=(long *)&nml,p2=(long*)&MemTemplate,i=7; i; *p1++=*p2++,i--) ; + *p1=stacksize; + } + + if (!(((unsigned int)ml=AllocEntry((struct MemList *)&nml)) & (1<<31))) { + newtask=ml->ml_ME[0].me_Addr; + newtask->tc_Node.ln_Type = NT_TASK; + newtask->tc_Node.ln_Pri = pri; + newtask->tc_Node.ln_Name = name; + newtask->tc_SPReg = (APTR)((ULONG)ml->ml_ME[1].me_Addr+stacksize); + newtask->tc_SPLower = ml->ml_ME[1].me_Addr; + newtask->tc_SPUpper = newtask->tc_SPReg; + NEWLIST(&newtask->tc_MemEntry); + AddHead(&newtask->tc_MemEntry,&ml->ml_Node); + task2=AddTask(newtask,initpc,0); + if (SysBase->lib_Version>36 && !task2) { + FreeEntry(ml); newtask = NULL; + } + } + else + newtask = NULL; + + return newtask; +} + +#else +asm(" + .globl _CreateTask + +_CreateTask: moveml d2/d3/a2/a3/a6,sp@- + movel sp@(12+6*4:W),d0 + addql #3,d0 + moveq #-4,d2 + andl d0,d2 | stack adjusted + movel d2,sp@- + lea pc@(Lmemlist-.+2+7*4),a0 + moveq #6,d0 +L3: movel a0@-,sp@- | copy memlist + dbra d0,L3 + movel sp,a0 + movel 4:W,a6 + jsr a6@(-222:W) | AllocEntry() + movel d0,a2 + movel a2,d0 + lea sp@(32:W),sp + blts L2 + movel a2@(16:W),a3 + moveb #1,a3@(8:W) | ln_Type + moveb sp@(7+6*4:W),a3@(9:W) | ln_Pri + movel sp@(0+6*4:W),a3@(10:W) | ln_Name + movel a2@(24:W),d0 + addl d0,d2 + movel d2,a3@(54:W) | tc_SPReg + movel d0,a3@(58:W) | tc_SPLower + movel d2,a3@(62:W) | tc_SPUpper + lea a3@(74:W),a0 | tc_MemList + movel a0,a0@(8:W) + addqw #4,a0 + movel a0,a0@- + movel a2,a1 + jsr a6@(-240:W) | AddHead() + movel a3,d3 + movel d3,a1 + movel sp@(8+6*4:W),d2 + exg d2,a2 + subal a3,a3 + jsr a6@(-282:W) | AddTask() + cmpw #37,a6@(20:W) + bcss L1 | kick2.0+ ? + tstl d0 + bnes L1 | task added + movel d2,a0 + jsr a6@(-228:W) | FreeEntry() +L2: moveq #0,d3 +L1: movel d3,d0 | new task + moveml sp@+,d2/d3/a2/a3/a6 + rts + + .align 2 + +Lmemlist: .long 0,0 | Succ,Pred + .byte 0,0 | Pri,Type + .long 0 | Name + .word 2 | NumEntries + .long 0x10001 | MemType + .long 92 | Length + .long 0x10000 | MemType +| .long 0 | Length +"); +#endif diff --git a/libnix/sources/amiga/misc/Custom.c b/libnix/sources/amiga/misc/Custom.c new file mode 100755 index 0000000..4989a83 --- /dev/null +++ b/libnix/sources/amiga/misc/Custom.c @@ -0,0 +1,75 @@ +#include + +/* Absolute definitions for the custom chips + * Most of them are recommended not to use + */ + +ABSDEF(custom, 0x00dff000); +ABSDEF(bltddat,0x00dff000); +ABSDEF(dmaconr,0x00dff002); +ABSDEF(vposr, 0x00dff004); +ABSDEF(vhposr, 0x00dff006); +ABSDEF(dskdatr,0x00dff008); +ABSDEF(joy0dat,0x00dff00a); +ABSDEF(joy1dat,0x00dff00c); +ABSDEF(clxdat, 0x00dff00e); +ABSDEF(adkconr,0x00dff010); +ABSDEF(pot0dat,0x00dff012); +ABSDEF(pot1dat,0x00dff014); +ABSDEF(potinp, 0x00dff016); +ABSDEF(serdatr,0x00dff018); +ABSDEF(dskbytr,0x00dff01a); +ABSDEF(intenar,0x00dff01c); +ABSDEF(intreqr,0x00dff01e); +ABSDEF(dskpt, 0x00dff020); +ABSDEF(dsklen, 0x00dff024); +ABSDEF(dskdat, 0x00dff026); +ABSDEF(refptr, 0x00dff028); +ABSDEF(vposw, 0x00dff02a); +ABSDEF(vhposw, 0x00dff02c); +ABSDEF(copcon, 0x00dff02e); +ABSDEF(serdat, 0x00dff030); +ABSDEF(serper, 0x00dff032); +ABSDEF(potgo, 0x00dff034); +ABSDEF(joytest,0x00dff036); +ABSDEF(bltcon0,0x00dff040); +ABSDEF(bltcon1,0x00dff042); +ABSDEF(bltafwm,0x00dff044); +ABSDEF(bltalwm,0x00dff046); +ABSDEF(bltcpt, 0x00dff048); +ABSDEF(bltbpt, 0x00dff04c); +ABSDEF(bltapt, 0x00dff050); +ABSDEF(bltdpt, 0x00dff054); +ABSDEF(bltsize,0x00dff058); +ABSDEF(bltcmod,0x00dff060); +ABSDEF(bltbmod,0x00dff062); +ABSDEF(bltamod,0x00dff064); +ABSDEF(bltdmod,0x00dff066); +ABSDEF(bltcdat,0x00dff070); +ABSDEF(bltbdat,0x00dff072); +ABSDEF(bltadat,0x00dff074); +ABSDEF(cop1lc, 0x00dff080); +ABSDEF(cop2lc, 0x00dff084); +ABSDEF(copjmp1,0x00dff088); +ABSDEF(copjmp2,0x00dff08a); +ABSDEF(copins, 0x00dff08c); +ABSDEF(diwstrt,0x00dff08e); +ABSDEF(diwstop,0x00dff090); +ABSDEF(ddfstrt,0x00dff092); +ABSDEF(ddfstop,0x00dff094); +ABSDEF(dmacon, 0x00dff096); +ABSDEF(clxcon, 0x00dff098); +ABSDEF(intena, 0x00dff09a); +ABSDEF(intreq, 0x00dff09c); +ABSDEF(adkcon, 0x00dff09e); +ABSDEF(aud, 0x00dff0a0); +ABSDEF(bplpt, 0x00dff0e0); +ABSDEF(bplcon0,0x00dff100); +ABSDEF(bplcon1,0x00dff102); +ABSDEF(bplcon2,0x00dff104); +ABSDEF(bpl1mod,0x00dff108); +ABSDEF(bpl2mod,0x00dff10a); +ABSDEF(bpldat, 0x00dff110); +ABSDEF(sprpt, 0x00dff120); +ABSDEF(spr, 0x00dff140); +ABSDEF(color, 0x00dff180); diff --git a/libnix/sources/amiga/misc/DeleteTask.c b/libnix/sources/amiga/misc/DeleteTask.c new file mode 100755 index 0000000..1148deb --- /dev/null +++ b/libnix/sources/amiga/misc/DeleteTask.c @@ -0,0 +1,3 @@ +#include + +ALIAS (DeleteTask,RemTask); diff --git a/libnix/sources/amiga/misc/DoMethod.c b/libnix/sources/amiga/misc/DoMethod.c new file mode 100755 index 0000000..af3ae4a --- /dev/null +++ b/libnix/sources/amiga/misc/DoMethod.c @@ -0,0 +1,23 @@ +asm(" + .text + + .globl _DoMethod + .globl _DoMethodA + + +_DoMethod: lea sp@(8:W),a1 + jra L_DoMethod + +_DoMethodA: movel sp@(8:W),a1 +L_DoMethod: movel sp@(4:W),d0 + beqs L_Null + movel a2,sp@- + movel d0,a2 + movel a2@(-4:W),a0 + jbsr L_Invoke + movel sp@+,a2 +L_Null: rts + +L_Invoke: movel a0@(8:W),sp@- + rts +"); diff --git a/libnix/sources/amiga/misc/DoSuperMethod.c b/libnix/sources/amiga/misc/DoSuperMethod.c new file mode 100755 index 0000000..5dcb358 --- /dev/null +++ b/libnix/sources/amiga/misc/DoSuperMethod.c @@ -0,0 +1,28 @@ +asm(" + .text + + .globl _DoSuperMethod + .globl _DoSuperMethodA + + +_DoSuperMethod: lea sp@(12:W),a1 + jra L_DoSuperMethod + +_DoSuperMethodA: + movel sp@(12:W),a1 + +L_DoSuperMethod: + movel a2,sp@- + moveml sp@(8:W),a0/a2 + movel a2,d0 + beqs L_Null + movel a0,d0 + beqs L_Null + movel a0@(24:W),a0 + jbsr L_Invoke +L_Null: movel sp@+,a2 + rts + +L_Invoke: movel a0@(8:W),sp@- + rts +"); diff --git a/libnix/sources/amiga/misc/FastRand.c b/libnix/sources/amiga/misc/FastRand.c new file mode 100755 index 0000000..4dd91cf --- /dev/null +++ b/libnix/sources/amiga/misc/FastRand.c @@ -0,0 +1,26 @@ +#if 1 + +#include + +ULONG FastRand(ULONG seed) +{ ULONG a=seed<<1; + if((LONG)seed<=0) + a^=0x1d872b41; + return a; +} + +#else + +asm(" + .text + + .globl _FastRand + +_FastRand: movel sp@(4:W),d0 + addl d0,d0 + bhis L1 + eoril #0x1D872B41,d0 +L1: rts +"); + +#endif diff --git a/libnix/sources/amiga/misc/FreeIEvents.c b/libnix/sources/amiga/misc/FreeIEvents.c new file mode 100755 index 0000000..4532129 --- /dev/null +++ b/libnix/sources/amiga/misc/FreeIEvents.c @@ -0,0 +1,13 @@ +#include +#include + +VOID FreeIEvents(struct InputEvent *events) +{ APTR SysBase = *(APTR *)4L; + struct InputEvent *next; + + while (events != NULL) { + next = events->ie_NextEvent; + FreeMem(events,sizeof(*events)); + events = next; + } +} diff --git a/libnix/sources/amiga/misc/HookEntry.c b/libnix/sources/amiga/misc/HookEntry.c new file mode 100755 index 0000000..026424b --- /dev/null +++ b/libnix/sources/amiga/misc/HookEntry.c @@ -0,0 +1,26 @@ +#if 0 + +#include + +ULONG HookEntry(struct Hook *hook asm("a0"),APTR obj asm("a2"),APTR msg asm("a1")) +{ + return (*hook->h_SubEntry)(hook,obj,msg); +} + +#else + +asm(" + .text + + .globl _HookEntry + +_HookEntry: movel a1,sp@- + movel a2,sp@- + movel a0,sp@- + movel a0@(12:W),a0 + jsr a0@ + lea sp@(12:W),sp + rts +"); + +#endif diff --git a/libnix/sources/amiga/misc/HotKey.c b/libnix/sources/amiga/misc/HotKey.c new file mode 100755 index 0000000..23adbfa --- /dev/null +++ b/libnix/sources/amiga/misc/HotKey.c @@ -0,0 +1,15 @@ +#include +#include + +CxObj *HotKey(STRPTR description,struct MsgPort *port,LONG id) +{ CxObj *filter; + + if ((filter=CreateCxObj(CX_FILTER,(LONG)description,NULL))) { + AttachCxObj(filter,CreateCxObj(CX_SEND,(LONG)port,id)); + AttachCxObj(filter,CreateCxObj(CX_TRANSLATE,NULL,NULL)); + if (CxObjError(filter)) { + DeleteCxObjAll(filter); filter=NULL; + } + } + return filter; +} diff --git a/libnix/sources/amiga/misc/LibAllocPooled.c b/libnix/sources/amiga/misc/LibAllocPooled.c new file mode 100755 index 0000000..545a613 --- /dev/null +++ b/libnix/sources/amiga/misc/LibAllocPooled.c @@ -0,0 +1,6 @@ +#include + +APTR LibAllocPooled(APTR poolHeader, ULONG memSize) +{ + return AsmAllocPooled(poolHeader,memSize,*(APTR *)4L); +} diff --git a/libnix/sources/amiga/misc/LibCreatePool.c b/libnix/sources/amiga/misc/LibCreatePool.c new file mode 100755 index 0000000..e1de3a6 --- /dev/null +++ b/libnix/sources/amiga/misc/LibCreatePool.c @@ -0,0 +1,11 @@ +#include + +APTR LibCreatePool(ULONG requirements, ULONG puddleSize, ULONG threshSize) +{ + return AsmCreatePool(requirements,puddleSize,threshSize,*(APTR *)4L); +} + +VOID LibDeletePool(APTR poolHeader) +{ + AsmDeletePool(poolHeader,*(APTR *)4L); +} diff --git a/libnix/sources/amiga/misc/LibFreePooled.c b/libnix/sources/amiga/misc/LibFreePooled.c new file mode 100755 index 0000000..b934b3b --- /dev/null +++ b/libnix/sources/amiga/misc/LibFreePooled.c @@ -0,0 +1,6 @@ +#include + +VOID LibFreePooled(APTR poolHeader, APTR memory, ULONG memSize) +{ + AsmFreePooled(poolHeader,memory,memSize,*(APTR *)4L); +} diff --git a/libnix/sources/amiga/misc/NewList.c b/libnix/sources/amiga/misc/NewList.c new file mode 100755 index 0000000..1800573 --- /dev/null +++ b/libnix/sources/amiga/misc/NewList.c @@ -0,0 +1,11 @@ +#include +#include + +VOID NewList(struct List *list) +{ LONG *p; + + list->lh_TailPred=(struct Node *)list; + ((LONG *)list)++; + *(LONG *)list=0; + p=(LONG *)list; *--p=(LONG)list; +} diff --git a/libnix/sources/amiga/misc/RangeRand.c b/libnix/sources/amiga/misc/RangeRand.c new file mode 100755 index 0000000..17e8e33 --- /dev/null +++ b/libnix/sources/amiga/misc/RangeRand.c @@ -0,0 +1,18 @@ +#include + +ULONG RangeSeed; + +ULONG RangeRand(ULONG maxValue) +{ ULONG a=RangeSeed; + UWORD i=maxValue-1; + do + { ULONG b=a; + a<<=1; + if((LONG)b<=0) + a^=0x1d872b41; + }while((i>>=1)); + RangeSeed=a; + if((UWORD)maxValue) + return (UWORD)((UWORD)a*(UWORD)maxValue>>16); + return (UWORD)a; +} diff --git a/libnix/sources/amiga/misc/SetSuperAttrs.c b/libnix/sources/amiga/misc/SetSuperAttrs.c new file mode 100755 index 0000000..27294ad --- /dev/null +++ b/libnix/sources/amiga/misc/SetSuperAttrs.c @@ -0,0 +1,24 @@ +asm(" + .text + + .globl _SetSuperAttrs + +_SetSuperAttrs: movel a2,sp@- + moveml sp@(8:W),a0/a2 + movel a2,d0 + beqs L_Null + movel a0,d0 + beqs L_Null + clrl sp@- + pea sp@(20:W) + pea 259:W + movel sp,a1 + movel sp@(24:W),a0 + jbsr L_Invoke + lea sp@(12:W),sp +L_Null: movel sp@+,a2 + rts + +L_Invoke: movel a0@(8:W),sp@- + rts +"); diff --git a/libnix/sources/amiga/misc/TimeDelay.c b/libnix/sources/amiga/misc/TimeDelay.c new file mode 100755 index 0000000..a758fa9 --- /dev/null +++ b/libnix/sources/amiga/misc/TimeDelay.c @@ -0,0 +1,38 @@ +#include +#include +#include + +#define NEWLIST(l) ((l)->lh_Head = (struct Node *)&(l)->lh_Tail, \ + /*(l)->lh_Tail = NULL,*/ \ + (l)->lh_TailPred = (struct Node *)&(l)->lh_Head) + +LONG TimeDelay(LONG unit,ULONG secs,ULONG microsecs) +{ APTR SysBase = *(APTR *)4L; + struct PortIO { + struct timerequest treq; + struct MsgPort port; + } *portio; + LONG ret=-1; + + if ((portio=(struct PortIO *)AllocMem(sizeof(*portio),MEMF_CLEAR|MEMF_PUBLIC))) { + portio->port.mp_Node.ln_Type=NT_MSGPORT; + if ((BYTE)(portio->port.mp_SigBit=AllocSignal(-1))>=0) { + portio->port.mp_SigTask=FindTask(NULL); + NEWLIST(&portio->port.mp_MsgList); + portio->treq.tr_node.io_Message.mn_Node.ln_Type=NT_REPLYMSG; + portio->treq.tr_node.io_Message.mn_ReplyPort=&portio->port; + if (!(OpenDevice(TIMERNAME,unit,&portio->treq.tr_node,0))) { + portio->treq.tr_node.io_Command=TR_ADDREQUEST; + portio->treq.tr_time.tv_secs=secs; + portio->treq.tr_time.tv_micro=microsecs; + if (!DoIO(&portio->treq.tr_node)) + ret=0; + CloseDevice(&portio->treq.tr_node); + } + FreeSignal(portio->port.mp_SigBit); + } + FreeMem(portio,sizeof(*portio)); + } + + return ret; +} diff --git a/libnix/sources/amiga/misc/WaitBeam.c b/libnix/sources/amiga/misc/WaitBeam.c new file mode 100755 index 0000000..2bdf43e --- /dev/null +++ b/libnix/sources/amiga/misc/WaitBeam.c @@ -0,0 +1,7 @@ +#include +#include + +VOID waitbeam(LONG pos) +{ + do {} while(pos>VBeamPos()); +} diff --git a/libnix/sources/amiga/misc/sprintf.c b/libnix/sources/amiga/misc/sprintf.c new file mode 100755 index 0000000..bf9c121 --- /dev/null +++ b/libnix/sources/amiga/misc/sprintf.c @@ -0,0 +1,10 @@ +#include + +STATIC const ULONG tricky=0x16c04e75; /* move.b d0,(a3)+ ; rts */ + +VOID sprintf(STRPTR buffer,STRPTR fmt,...) +{ APTR SysBase = *(APTR *)4L; + STRPTR *arg = &fmt+1; + + RawDoFmt(fmt,arg,(void (*)())&tricky,buffer); +} /* Not very clean, but ... */ diff --git a/libnix/sources/headers/bases.h b/libnix/sources/headers/bases.h new file mode 100755 index 0000000..44790b8 --- /dev/null +++ b/libnix/sources/headers/bases.h @@ -0,0 +1,24 @@ +#ifndef _BASE_H_ +#define _BASE_H_ + +#ifndef SMALL_DATA +#define A4(x) #x +#else +#define A4(x) "a4@(" #x ":W)" +#endif + +#define GETAGBASE movel A4(_AmigaGuideBase),a6 +#define GETASLBASE movel A4(_AslBase),a6 +#define GETBULBASE movel A4(_BulletBase),a6 +#define GETDOSBASE movel A4(_DOSBase),a6 +#define GETDTBASE movel A4(_DataTypesBase),a6 +#define GETGADBASE movel A4(_GadToolsBase),a6 +#define GETGFXBASE movel A4(_GfxBase),a6 +#define GETINTBASE movel A4(_IntuitionBase),a6 +#define GETLOCBASE movel A4(_LocaleBase),a6 +#define GETLOWBASE movel A4(_LowLevelBase),a6 +#define GETRETBASE movel A4(_RealTimeBase),a6 +#define GETUTLBASE movel A4(_UtilityBase),a6 +#define GETWBBASE movel A4(_WorkbenchBase),a6 + +#endif _BASE_H_ diff --git a/libnix/sources/headers/debuglib.h b/libnix/sources/headers/debuglib.h new file mode 100755 index 0000000..20a49a6 --- /dev/null +++ b/libnix/sources/headers/debuglib.h @@ -0,0 +1,14 @@ +#ifdef DEBUG_LIB +#ifndef _DEBUGLIB_H_ +#define _DEBUGLIB_H_ + +/* Yet nothing - could be a debug-requester or something */ + +/* + + #define FATALERROR(a) + +*/ + +#endif +#endif diff --git a/libnix/sources/headers/dirent.h b/libnix/sources/headers/dirent.h new file mode 100755 index 0000000..f2fad48 --- /dev/null +++ b/libnix/sources/headers/dirent.h @@ -0,0 +1,33 @@ +#include +#include + +struct dirent { + ULONG d_fileno; + USHORT d_reclen; + USHORT d_namlen; + BYTE d_name[256]; +}; + +typedef struct _dirdesc { + int dd_fd; + struct dirent dd_ent; + BPTR d_lock; + ULONG d_count; + LONG d_more; + struct ExAllControl *d_eac; + struct ExAllData *current; + union { + char ead[2048]; + struct FileInfoBlock fib; + } _dirun; +} DIR; + +#define d_ead _dirun.ead +#define d_info _dirun.fib + +/* prototypes */ + +DIR *opendir(const char *dirname); +struct dirent *readdir(DIR *dirp); +void rewinddir(DIR *dirp); +int closedir(DIR *dirp); diff --git a/libnix/sources/headers/libinit.h b/libnix/sources/headers/libinit.h new file mode 100755 index 0000000..470a449 --- /dev/null +++ b/libnix/sources/headers/libinit.h @@ -0,0 +1,81 @@ +/******************************************************************************/ +/* */ +/* special define(s) */ +/* */ +/******************************************************************************/ + +#if !defined(REG) +#define REG(reg,arg) arg __asm(#reg) +#endif + +#include +#include +#include +#include "stabs.h" + +/******************************************************************************/ +/* */ +/* structure definition for a *** PRIVATE *** library/device base */ +/* */ +/******************************************************************************/ + +struct LibBase { + struct Library LibNode; + UWORD Pad; + LONG SegList; + APTR DataSeg, + SysBase; +#ifdef EXTENDED + ULONG DataSize; + struct LibBase *Parent; +#endif +}; + +/******************************************************************************/ +/* */ +/* prototypes for basic library functions */ +/* */ +/******************************************************************************/ + +LONG LibExtFunc(VOID); +LONG LibExpunge(REG(a6,struct LibBase *)); +LONG LibClose(REG(a6,struct LibBase *)); +APTR LibOpen(REG(a6,struct LibBase *)); +APTR LibInit(REG(a0,LONG),REG(d0,struct LibBase *),REG(a6,struct Library *)); + +/******************************************************************************/ +/* */ +/* prototypes for basic device functions */ +/* */ +/******************************************************************************/ + +APTR DevInit(); +VOID DevOpen(); +APTR DevClose(); +APTR DevExpunge(); +APTR DevExtFunc(); + +/******************************************************************************/ +/* */ +/* imports */ +/* */ +/******************************************************************************/ + +extern LONG __stdargs __UserLibInit(struct Library *,REG(a4,APTR)); +extern VOID __stdargs __UserLibCleanup(REG(a4,APTR)); + +extern const UWORD LibVersion; +extern const UWORD LibRevision; +extern const char LibIdString[]; +extern const char LibName[]; + +extern APTR __LibTable__[]; +extern APTR __FuncTable__[]; + +extern LONG __datadata_relocs[]; + +/******************************************************************************/ +/* */ +/* end of libinit.h */ +/* */ +/******************************************************************************/ diff --git a/libnix/sources/headers/pool.h b/libnix/sources/headers/pool.h new file mode 100755 index 0000000..1af70f7 --- /dev/null +++ b/libnix/sources/headers/pool.h @@ -0,0 +1,34 @@ +#include + +#if defined(__GNUC__) +#define ASM +#define REG(reg,arg) arg __asm(#reg) +#else +#define ASM __asm +#define REG(reg,arg) register __##reg arg +#endif + +#include +#include +#include + +/* +** our PRIVATE! memory pool structure +** (_NOT_ compatible with original amiga.lib!) +*/ + +typedef struct Pool { + struct MinList PuddleList; + ULONG MemoryFlags; + ULONG PuddleSize; + ULONG ThreshSize; +} POOL; + +/* +** required prototypes ;) +*/ + +APTR ASM AsmCreatePool(REG(d0,ULONG),REG(d1,ULONG),REG(d2,ULONG),REG(a6,APTR)); +APTR ASM AsmAllocPooled(REG(a0,POOL *),REG(d0,ULONG),REG(a6,APTR)); +VOID ASM AsmFreePooled(REG(a0,POOL *),REG(a1,APTR),REG(d0,ULONG),REG(a6,APTR)); +VOID ASM AsmDeletePool(REG(a0,POOL *),REG(a6,APTR)); diff --git a/libnix/sources/headers/rand48.h b/libnix/sources/headers/rand48.h new file mode 100755 index 0000000..d8225af --- /dev/null +++ b/libnix/sources/headers/rand48.h @@ -0,0 +1,9 @@ +void srand48(long); +unsigned short *seed48(unsigned short *); +void lcong48(unsigned short *); +long lrand48(void); +long nrand48(unsigned short *); +long mrand48(void); +long jrand48(unsigned short *); +double drand48(void); +double erand48(unsigned short *seed); diff --git a/libnix/sources/headers/regparm.h b/libnix/sources/headers/regparm.h new file mode 100755 index 0000000..38be755 --- /dev/null +++ b/libnix/sources/headers/regparm.h @@ -0,0 +1,31 @@ +#define ___PUSH(a) "movel\t" #a ",sp@-\n" +#define ___POP(a) "movel\tsp@+," #a "\n" + +#ifndef SMALL_DATA + +#define __REGP(functype,funcname,pushlist,popval) \ +asm(".even\n" ".globl _" #funcname "\n" "_" #funcname ":\n" \ +pushlist "jbsr\t___" #funcname "\n" "addqw\t#" #popval ",sp\n" \ +"rts\n"); functype __##funcname + +#else + +#define __REGP(functype,funcname,pushlist,popval) \ +asm(".even\n" ".globl _" #funcname "\n" "_" #funcname ":\n" ___PUSH(a4) \ +pushlist "jbsr\t_geta4\n" "jbsr\t___" #funcname "\n" "addqw\t#" #popval ",sp\n" \ +___POP(a4) "rts\n"); functype __##funcname + +#endif + +#define REGPARM1(functype,funcname,a1,r1) \ +__REGP(functype,funcname,___PUSH(r1),4) (a1) + +#define REGPARM2(functype,funcname,a1,r1,a2,r2) \ +__REGP(functype,funcname,___PUSH(r2)___PUSH(r1),8) (a1,a2) + +#define REGPARM3(functype,funcname,a1,r1,a2,r2,a3,r3) \ +__REGP(functype,funcname,___PUSH(r3)___PUSH(r2)___PUSH(r1),12) (a1,a2,a3) + +#define REGPARM4(functype,funcname,a1,r1,a2,r2,a3,r3,a4,r4) \ +__REGP(functype,funcname,___PUSH(r4)___PUSH(r3)___PUSH(r2)___PUSH(r1),16) (a1,a2,a3,a4) + diff --git a/libnix/sources/headers/stabs.h b/libnix/sources/headers/stabs.h new file mode 100755 index 0000000..e4051f3 --- /dev/null +++ b/libnix/sources/headers/stabs.h @@ -0,0 +1,102 @@ +#ifndef _STABS_H_ +#define _STABS_H_ + +/* These are some macros for handling of symboltable information + */ + +/* linker can use symbol b for symbol a if a is not defined */ +#define ALIAS(a,b) asm(".stabs \"_" #a "\",11,0,0,0\n.stabs \"_" #b "\",1,0,0,0") + +/* add symbol a to list b (type c (22=text 24=data 26=bss)) */ +#define ADD2LIST(a,b,c) asm(".stabs \"_" #b "\"," #c ",0,0,_" #a ) + +/* Install private constructors and destructors pri MUST be -127<=pri<=127 */ +#define ADD2INIT(a,pri) ADD2LIST(a,__INIT_LIST__,22); \ + asm(".stabs \"___INIT_LIST__\",20,0,0," #pri "+128") +#define ADD2EXIT(a,pri) ADD2LIST(a,__EXIT_LIST__,22); \ + asm(".stabs \"___EXIT_LIST__\",20,0,0," #pri "+128") + +/* Add to library list */ +#define ADD2LIB(a) ADD2LIST(a,__LIB_LIST__,24) + +/* This one does not really handle symbol tables + * it's just pointless to write a header file for one macro + * + * define a as a label for an absolute address b + */ +#define ABSDEF(a,b) asm("_" #a "=" #b ";.globl _" #a ) + +/* Generate assembler stub for a shared library entry + * and add it to the jump table + * ADDTABL_X(name,...) means function with X arguments + * ADDTABL_END() ends the list + * Usage: ADDTABL_2(AddHead,a0,a1); + * No more than 4 arguments supported, use structures! + */ + +#define _ADDTABL_START(name) \ +asm(".globl ___" #name); \ +asm("___" #name ":\tmovel a4,sp@-") + +#define _ADDTABL_ARG(arg) \ +asm("\tmovel " #arg ",sp@-") + +#define _ADDTABL_CALL(name) \ +asm("\tmovel a6@(40:W),a4"); \ +asm("\tbsr _" #name) + +#define _ADDTABL_END0(name,numargs) \ +asm("\tmovel sp@+,a4"); \ +asm("\trts"); \ +ADD2LIST(__##name,__FuncTable__,22) + +#define _ADDTABL_END2(name,numargs) \ +asm("\taddqw #4*" #numargs ",sp"); \ +asm("\tmovel sp@+,a4"); \ +asm("\trts"); \ +ADD2LIST(__##name,__FuncTable__,22) + +#define _ADDTABL_ENDN(name,numargs) \ +asm("\taddaw #4*" #numargs ",sp"); \ +asm("\tmovel sp@+,a4"); \ +asm("\trts"); \ +ADD2LIST(__##name,__FuncTable__,22) + +#define ADDTABL_0(name) \ +_ADDTABL_START(name); \ +_ADDTABL_CALL(name); \ +_ADDTABL_END0(name,0) + +#define ADDTABL_1(name,arg1) \ +_ADDTABL_START(name); \ +_ADDTABL_ARG(arg1); \ +_ADDTABL_CALL(name); \ +_ADDTABL_END2(name,1) + +#define ADDTABL_2(name,arg1,arg2) \ +_ADDTABL_START(name); \ +_ADDTABL_ARG(arg2); \ +_ADDTABL_ARG(arg1); \ +_ADDTABL_CALL(name); \ +_ADDTABL_END2(name,2) + +#define ADDTABL_3(name,arg1,arg2,arg3) \ +_ADDTABL_START(name); \ +_ADDTABL_ARG(arg3); \ +_ADDTABL_ARG(arg2); \ +_ADDTABL_ARG(arg1); \ +_ADDTABL_CALL(name); \ +_ADDTABL_ENDN(name,3) + +#define ADDTABL_4(name,arg1,arg2,arg3,arg4) \ +_ADDTABL_START(name); \ +_ADDTABL_ARG(arg4); \ +_ADDTABL_ARG(arg3); \ +_ADDTABL_ARG(arg2); \ +_ADDTABL_ARG(arg1); \ +_ADDTABL_CALL(name); \ +_ADDTABL_ENDN(name,4) + +#define ADDTABL_END() asm(".stabs \"___FuncTable__\",20,0,0,-1") + +#endif diff --git a/libnix/sources/headers/stdio.h b/libnix/sources/headers/stdio.h new file mode 100755 index 0000000..3f2b457 --- /dev/null +++ b/libnix/sources/headers/stdio.h @@ -0,0 +1,116 @@ +#ifndef STDIO_H +#define STDIO_H +#include +#include +#include +#include + +/* Adjusted to be compatible with the bsd headers + * (At least for normal ANSI stuff) + * Member names are not the same, but they need not be :-) + */ + +typedef long fpos_t; + +typedef struct __FILE +{ + unsigned char *p; /* pointer to actual character */ + int incount; /* Bytes left in buffer for reading, writemode: 0 */ + int outcount; /* Space left in buffer for writing + fp->linebufsize, + * readmode: 0 + */ + short flags; /* Some flags: 0x01 line buffered + * 0x02 unbuffered + * 0x04 read mode + * 0x08 write mode + * 0x20 EOF read + * 0x40 error encountered + * 0x80 buffer malloc'ed by library + * 0x200 sprintf/sscanf buffer + */ + short file; /* The filehandle */ + unsigned char *buffer; /* original buffer pointer */ + int bufsize; /* size of the buffer */ + int linebufsize; /* 0 full buffered + * -bufsize line buffered&write mode + * readmode: undefined */ +/* from this point on not binary compatible to bsd headers */ + unsigned char unget[4]; /* ungetc buffer 4 bytes necessary (for -Na*) + * ANSI requires 3 bytes (for -.*), so one more + * doesn't matter + */ + unsigned char *tmpp; /* Stored p if ungetc pending, otherwise NULL */ + int tmpinc; /* Stored incount if ungetc pending, otherwise undefined */ + long tmpdir; /* lock to directory if temporary file */ + char *name; /* filename if temporary file */ +} FILE; + +#ifndef NULL +#define NULL ((void *)0l) +#endif +#define BUFSIZ 1024 +#define EOF (-1) +#define SEEK_SET 0 +#define SEEK_CUR 1 +#define SEEK_END 2 +#define _IOFBF 0 +#define _IOLBF 1 +#define _IONBF 2 + +extern FILE *fopen(const char *filename,const char *mode); +extern FILE *freopen(const char *filename,const char *mode,FILE *stream); +extern int fclose(FILE *stream); +extern int fgetc(FILE *stream); +extern int fputc(int c,FILE *stream); +extern int ungetc(int c,FILE *stream); +extern int sprintf(char *s,const char *format,...); +extern int sscanf(const char *s,const char *format,...); +extern int vprintf(const char *format,va_list args); +extern int vsprintf(char *s,const char *format,va_list args); +extern int vfprintf(FILE *stream,const char *format,va_list args); +extern int vscanf(const char *format,va_list args); +extern int vsscanf(const char *s,const char *format,va_list args); +extern int vfscanf(FILE *stream,const char *format,va_list args); +extern int snprintf(char *s,size_t size,const char *format,...); +extern int vsnprintf(char *s,size_t size,const char *format,va_list args); +extern int fseek(FILE *stream,long int offset,int whence); +extern int fputs(const char *s,FILE *stream); +extern long int ftell(FILE *stream); +extern int setvbuf(FILE *stream,char *buf,int mode,unsigned long size); +extern int fread(void *,unsigned long,unsigned long,FILE *); +extern int fwrite(const void *,unsigned long,unsigned long,FILE *); + +/* More bsd headers compatibility */ + +extern int __swbuf(int c,FILE *stream); +extern int __srget(FILE *stream); +extern FILE **__sF; /* Standard I/O streams */ +#define stdin (__sF[0]) /* Other streams are not in __sF */ +#define stdout (__sF[1]) +#define stderr (__sF[2]) + +/* Be careful: We have side effects and use incount in __srget - + must use comma-operator */ +#define getc(fp) ((fp)->incount--,(fp)->incount>=0?(int)*(fp)->p++:__srget(fp)) +#define putc(c,fp) \ +((fp)->outcount--,(fp)->outcount>=0|| \ +((fp)->outcount>=(fp)->linebufsize&&(char)(c)!='\n')? \ +*(fp)->p++=(c):__swbuf((c),(fp))) +#define ferror(fp) ((fp)->flags&64) +#define feof(fp) ((fp)->flags&32) + +/* own stuff */ +extern struct MinList __filelist; /* List of all fopen'ed files */ +extern unsigned long *__stdfiledes; /* List of Amiga OS filehandles */ +extern struct MinList __memorylist; /* List of memory puddles */ + +extern int __fflush(FILE *stream); /* fflush single file */ +extern void __chkabort(void); /* check for SIGABRT */ + +struct filenode /* objects in __filelist */ +{ + struct MinNode node; + FILE FILE; +}; + +#endif diff --git a/libnix/sources/headers/strsup.h b/libnix/sources/headers/strsup.h new file mode 100755 index 0000000..d581337 --- /dev/null +++ b/libnix/sources/headers/strsup.h @@ -0,0 +1,164 @@ +#ifndef _STRSUP_H +#define _STRSUP_H + +#include + +#ifdef __OPTIMIZE__ + +extern __inline__ void *memcpy(void *s1,const void *s2,size_t n) +{ register char *a6 __asm("a6") = *(char **)4; + register const void *a0 __asm("a0") = s2; + register const void *a1 __asm("a1") = s1; + register size_t d0 __asm("d0") = n; + __asm __volatile ("jsr a6@(-0x270)" + : /* no output */ + : "r" (a6), "r" (a0), "r" (a1), "r" (d0) + : "a0","a1","d0","d1", "memory"); + + return s1; +} + +extern __inline__ void *memmove(void *s1,const void *s2,size_t n) +{ extern void bcopy(); + bcopy(s2,s1,n); return s1; +} + +extern __inline__ void *memset(void *s,int c,size_t n) +{ + if (n) { + unsigned char *p=s; + do;while(*p++=c,--n); + } + return s; +} + +extern __inline__ int memcmp(const void *s1,const void *s2,size_t n) +{ const unsigned char *p1=s1,*p2=s2; + unsigned long r,c; + + if ((r=n)) + do;while(r=*p1++,c=*p2++,!(r-=c) && --n); + return r; +} + +extern __inline__ void *memchr(const void *s,int c,size_t n) +{ + if (n) { + unsigned char *p=(unsigned char *)s; + do { + if (*p++==(unsigned char)c) + return --p; + } while(--n); + } + return (void *)n; +} + +extern __inline__ size_t strlen(const char *string) +{ const char *s=string; + + do;while(*s++); return ~(string-s); +} + +extern __inline__ char *strcpy(char *s1,const char *s2) +{ char *s=s1; +#if 0 + do;while(*s1++=*s2,*s2++!='\0'); +#else + do;while((*s1++=*s2++)); +#endif + return s; +} + +extern __inline__ char *strncpy(char *s1,const char *s2,size_t n) +{ + if (n) { + char *s=s1; + do;while((*s++=*s2++) && --n); + if (n) + while(--n) *s++=0; + } + return s1; +} + +extern __inline__ char *strcat(char *s1,const char *s2) +{ char *s=s1; + + do;while(*s++); --s; do;while((*s++=*s2++)); return s1; +} + +extern __inline__ char *strncat(char *s1,const char *s2,size_t n) +{ + if (n) { + char *s=s1; + do;while(*s++); --s; + for(;;) { + if (!(*s++=*s2++)) + return s1; + if (!--n) { + *s=0; return s1; + } + } + } + return s1; +} + +extern __inline__ int strcmp(const char *s1,const char *s2) +{ unsigned char *p1=(unsigned char *)s1, *p2=(unsigned char *)s2; + unsigned long r,c; + + do;while(r=*p1++,c=*p2++,!(r-=c) && (char)c); return r; +} + +extern __inline__ int strncmp(const char *s1,const char *s2,size_t n) +{ unsigned char *p1=(unsigned char *)s1,*p2=(unsigned char *)s2; + unsigned long r,c; + + if ((r=n)) + do;while(r=*p1++,c=*p2++,!(r-=c) && (char)c && --n); + return r; +} +#if 0 +extern __inline__ char *strchr(const char *s,int c) +{ + while (*s!=(char)c) + if (!*s++) + return (char *)0; + return (char *)s; +} +#endif +extern __inline__ char *strupr(char *s) +{ unsigned char *s1=(unsigned char *)s; + + while(*s1) { + if ((*s1>('a'-1)) && (*s1<('z'+1))) + *s1-='a'-'A'; + s1++; + } + return s; +} + +extern __inline__ char *strlwr(char *s) +{ unsigned char *s1=(unsigned char *)s; + + while(*s1) { + if ((*s1>('A'-1)) && (*s1<('Z'+1))) + *s1+='a'-'A'; + s1++; + } + return s; +} + +extern __inline__ char *stpcpy(char *dst,char *src) +{ + do;while((*dst++=*src++)); return(--dst); +} + +#endif /* __OPTIMIZE__ */ + +static __inline__ size_t strlen_plus_one(const char *string) +{ const char *s=string; + + do;while(*s++); return (s-string); +} + +#endif /* _STRSUP_H */ diff --git a/libnix/sources/history b/libnix/sources/history new file mode 100755 index 0000000..64807f5 --- /dev/null +++ b/libnix/sources/history @@ -0,0 +1,308 @@ +B=Bugfix +S=Specification changed +P=Performance gain +M=Memory gain +F=New Feature + +Start (V0.1) + +B A symbol and it's indirected counterpart cannot be used both - fixed. + +B __stdio.c used the wrong flag for testing if filehandle has to be closed + so the standard filehandle was closed three times - fixed. + +P memchr.c changed - the C code looks not very good, but the assembler + code is very smart now. + +F Half initialized local arrays reference bzero() - added. + +M malloc now rounds even _MSTEP up to full MMU page. + +P strcat(),strncat(),strcpy(),strncpy(),strchr(),strrchr() rewritten in asm. + +B strcmp(),strncmp() work on signed char - fixed. + +P Removed __chkabort() in fgetc() and fputc() - it's not necessary to poll + CTRL-C for EVERY character written. + +B Extraneous semicolon (';') in freopen() deleted. + +M Changed the code for setting buffer flags in setvbuf(). + +B setvbuf() should set the buffer size ;-) - fixed. + +S _main() has the commandline as argument INCLUDING the program's name. + Had to change the interface - easiest way was to rename _main as __submain + and write a new __submain calling _main. Moved the call to open + the shared libraries out of the startups, too. + +S The private library bases now have two '_'. + +B libm.a needs the private library bases, too. + +S Some changes for Gerhard's gerlib: All I/O functions now run over + a unix-alike interface. The standard I/O streams now use fopen. + +F Added setbuffer() to be able to compile gas1.38 . + +F changed 'static char *errorlist[]' to 'char *sys_errlist[]' for better + compatibility. Added 'int sys_nerr' too :-P. + +F Rewrote documentation & some new chapters in texinfo format. + +F Changed the directory structure to the distribution form. + Added a 'distribution' makefile entry. + +V0.2 + +B Adjusted global makefile for auto detach startups. + +F specs file added. + +F The gcc frontend has libgcc.a hardcoded. Added a stub libgcc.a to get + specs file to work. + +B gas writes EOF and expects it to be handled as 0xff - fixed. + +B Symbol redirections didn't work the way I expected - removed most of them. + +B -lm links libm.a BEFORE libnix. Moved some functions. + +B vfscanf() does no longer ungetc EOF + +M Optimized __udivsi3, __umodsi3, __divsi3, __modsi3, div, ldiv. + +F Some functions added to libamiga.a. + +V0.3 + +B strtod() gave a warning - fixed. + +B strftime() didn't count correctly - fixed. + +M Optimized atan2, fmod, strlen. + +B Bug in makefile for the math libraries - fixed. + +F The low level standard-I/O functions are now posix compliant. + +F access(), stricmp(), unlink(), fstat(), bcmp() added. + +V0.4 + +B Fixed bug in fstat(). + +B Bugs in fread() and fwrite() when processing no data at all - fixed. + +P Added an inline version of strlen() in vfprintf, vsscanf, strxfrm, setlocale. + +M Rewrote all stub functions as symbol redirections to a single one. + +F strcasecmp() added. + +S moved __modsi3, __umodsi3 into the div-equivalents. + +B A missing locale.library should not cause a program exit - fixed. + +B asctime used 'c' instead of 'C' - fixed. + +B strftime didn't work correctly on numbers longer than 2 characters - fixed. + +B Some additional work on the low level I/O needed. + +S Did some work on the startups. + +S The auto-detach startups had some holes. I removed them + from distribution until I get a better method :'(. + +V0.5 + +F Added Open("*",MODE_NEWFILE) as a fallback for process->pr_CES. + +F strdup, stricmp, strlower, strnicmp, strupper added. + +(first official release) + +B Fixed a bug in the low-level-I/O cleanup routine. + +B Added more error handling to open(). + +M Changed the kludge in the library startup module. + +F Added optional support for Un*x style pathnames. + +B Bug in the low-level-I/O cleanup function fixed. + +B Yet another bug in strftime() fixed. + +M Optimized the standard I/O initialization. + +S Changed the disk layout for better handling of different library compilations. + +B The glue code generator didn't work correctly on void-'...'-functions - fixed. + +B Bug in freopen when using mode "w" on a already existing file fixed. + +S Cleaned the __initlibraries function up. + +F Hook and boopsi functions added to libamiga.a. + +B The commandline parser overwrote the __commandline variable + (this is not a real bug but a NASTY feature) - fixed. + +F Auto-detach reintegrated (clean this time) as an object module. + +F FastRand and RangeRand added to libamiga.a. + +B LocaleBase was defined twice - fixed. + +B Moved __decimalpoint from libm.a into libnix.a. + +F Added 3.1 system libraries to libstubs.a + +F Added Un*x functions (mkdir,chdir,rmdir,getwd,getcwd,opendir,readdir,closedir) + +S main and _exit implemented with symbol redirection. This gives full C++ support + with libg++.a. + +F Added support for shared amiga-library creation (library and device initcode) + +V0.6 + +F Added a stackswap-module + +S Changed stat() to work silently (now suppresses all *DOS* requesters) + +B Fixed a bug in __swbuf() - overrun buffersize by one character, oops... + +B __chkabort() didn't clear ctrl-c signal - fixed + +S signal handling heavily changed - now more unix-like + +F Added default values to libstubs.a for some by certain modules used variables + (__stack, _procname, __priority) + +S moved redirection of 'main' to '_main' into a separate file (in libnix_main.a) + +B improved precision of vfprintf. + +B fixed returncode of vfscanf on EOF + +F version string added to libnix.a + +V0.7 (second official release) + +B fseek didn't clear the EOF flag. + +S Dropped the ChangeMode call in open(). Now mode "a" files have a shared lock, + but the other method didn't work with all handlers :-(. + +B Made fread() and fwrite() buffered. + +S Got rid of those ARexx-scripts when building the library :-). Now you can + build libnix on a sun using a cross-compiler. + +B Fixed some holes in the commandline parser that could give empty arguments. + +F Prepared startups for the third argument of main(int argc,char *argv[],char *env[]). + It's not supported, but you could now ;-). + +B Fixed a bug in the floating point part of vprintf (introduced with the last + revision :-( ). + +F fileno() and fdtofh() added. + +F Version string added to ALL the modules - let's see if this hack works :-). + +V0.8 (third official release) + +B Fixed the returncode of close(STDIN_FILENO) and errno after lseek(). + +B fflush(NULL) flushed stdout and stderr twice - fixed. + +B Fixed a bug in atan2(). + +F All libnix requesters now check pr_WindowPtr first. + +S Moved __chkabort() one level down into read(), write(), lseek(). + +B Fixed missing terminator in strncat(). + +F Added code to handle stackextension/checking :-). + +S Changed all includes to use proto/ instead of inline/ + +V0.9 + +B ANSI demands flushing of line or unbuffered output files write reading from + line buffered input. + +B Fixed the bug that wrote weird characters for floats on some machines - + the system math libraries don't work correct if you open them in alphabetical + order (like the computer generated libstubs.a did - thanks ls :-( ). + +M Optimized the commandline parsers and shared library opener. + +M Removed some unused prototypes in C-files. + +V1.0 + +B If no characters are read gets() should return NULL. Dropped unnecessary + ferror() call in fgets by the way. + +B strtoul() read characters which were invalid for the current base. + +S switched from fputs() to write(2,..) in raise() + +F addded a bunch of non-ansi function (mktemp,getrusage,etc.) + +F snprintf() and vsnprintf() added. + +F Added CPU check with error requester for the non-68000 versions (changed + startups, too). + +V1.1 +F cache flush function for gcc support added + +B fixed a macro in stabs.h for shared library support + +F replaced asm functions for automatic library with c functions + +F updated support functions for amiga.lib + +F code cleanup + +V1.1a + +B fixed "off-by-one" error of portable strncpy() + +B fixed open() so that it ignores stdio slots now + +V1.1b + +B fixed longjmp() not returning 1 if passed a 0 + +M changed automatic library opening once again ;( + (moved openliberror() function into __initlibraries source) + +P tweaked string functions and removed some asm versions + +P updated headers/strsup.h with new string functions + +F moved all 1.3 compatibility stuff into a separate lib called libnix13.a + (contains integer math functions eg. useful for linking with -nostdlib) + +S added some const qualifiers at several places + +F tweaked libamiga.a functions + +F rewrote libinit.c, libinitr.c and devinit.c (requires ADE/GG GCC 2.7.2.1 or up) + +F added three math functions from vc.lib: frexp.c, ldexp.c and modf.c + +B fixed serious bug in atol() and atoi() + +S added "/WAIT" to default stdiowin options + (suggested by Martin Hauner) + +V1.2 diff --git a/libnix/sources/math/Makefile.in b/libnix/sources/math/Makefile.in new file mode 100644 index 0000000..a1d2653 --- /dev/null +++ b/libnix/sources/math/Makefile.in @@ -0,0 +1,71 @@ +#### Start of system configuration section. #### + +srcdir = @srcdir@ +VPATH = @srcdir@ + +CC = @CC@ +CPP = @CPP@ +AS = as + +RANLIB = @RANLIB@ +AWK = @AWK@ + +#### End system configuration section #### + +ifneq ($(TARGET),clean) +include ../../sources/math/filelist +endif + +CURDIR = $(shell pwd) + +OPTIONS=-I $(srcdir)/../headers -I ../../sources/headers -DFULL_SPECIFIERS $(CFLAGS) + +SOURCEFILES=*/* + +OBJECTS2=$(OBJECTS) \ + ../nix/stdio/printf.o ../nix/stdio/fprintf.o ../nix/stdio/sprintf.o \ + ../nix/stdio/vprintf.o ../nix/stdio/vsprintf.o stdio/vfprintf.o \ + ../nix/stdio/scanf.o ../nix/stdio/fscanf.o ../nix/stdio/sscanf.o \ + ../nix/stdio/vscanf.o ../nix/stdio/vsscanf.o stdio/vfscanf.o + +SUBDIRS2=$(SUBDIRS) ../nix/stdio + +REDEF=-D_DOSBase=___DOSBase \ + -D_UtilityBase=___UtilityBase \ + -D_MathIeeeSingBasBase=___MathIeeeSingBasBase \ + -D_MathIeeeSingTransBase=___MathIeeeSingTransBase \ + -D_MathIeeeDoubBasBase=___MathIeeeDoubBasBase \ + -D_MathIeeeDoubTransBase=___MathIeeeDoubTransBase \ + -D_LocaleBase=___LocaleBase + +%.o: %.c + $(CC) $(OPTIONS) -S $^ -o $*.S 2>&1|tee $*.err + $(CPP) -traditional $(REDEF) $*.S -o $*2.S + $(CC) $(OPTIONS) $*2.S -c -o $*.o + -rm $*.S $*2.S + -if test ! -s $*.err; then rm $*.err; fi + +.PHONY: all clean veryclean + +all: libm.a + +clean: + -rm -rf $(SUBDIRS2) + +veryclean: + -rm -rf * + +$(foreach f,$(SUBDIRS2),$(CURDIR)/$(f)): + mkdir $@ + +libm.a: $(foreach f,$(SUBDIRS2),$(CURDIR)/$(f)) $(OBJECTS2) ../../sources/math/makefile ../../sources/math/filelist + -rm -f $@ + ar -q $@ $(OBJECTS2) + $(RANLIB) $@ + echo "\$$$(V)" >>$@ + +stdio/vfprintf.o: $(srcdir)/../nix/stdio/vfprintf.c + $(CC) $(OPTIONS) $^ -c -o stdio/vfprintf.o + +stdio/vfscanf.o: $(srcdir)/../nix/stdio/vfscanf.c + $(CC) $(OPTIONS) $^ -c -o stdio/vfscanf.o diff --git a/libnix/sources/math/extra/frexp.c b/libnix/sources/math/extra/frexp.c new file mode 100644 index 0000000..3d640c0 --- /dev/null +++ b/libnix/sources/math/extra/frexp.c @@ -0,0 +1,27 @@ +#undef __HAVE_68881__ +#include + +double frexp(double x,int *p) +{ + int neg,j; + j=neg=0; + + if(x<0){ + x=-x; + neg=1; + } + if(x>=1){ + while(x>=1){ + j++; + x/=2; + } + }else if(x<0.5&&x!=0){ + while(x<0.5){ + j--; + x*=2; + } + } + *p = j; + if(neg) x=-x; + return x; +} diff --git a/libnix/sources/math/extra/ldexp.c b/libnix/sources/math/extra/ldexp.c new file mode 100644 index 0000000..481b9d7 --- /dev/null +++ b/libnix/sources/math/extra/ldexp.c @@ -0,0 +1,36 @@ +#undef __HAVE_68881__ +#include + +#define MANT_MASK 0x800FFFFF /* Mantissa extraction mask */ +#define ZPOS_MASK 0x3FF00000 /* Positive # mask for exp = 0 */ +#define ZNEG_MASK 0x3FF00000 /* Negative # mask for exp = 0 */ + +#define EXP_MASK 0x7FF00000 /* Mask for exponent */ +#define EXP_SHIFTS 20 /* Shifts to get into LSB's */ +#define EXP_BIAS 1023 /* Exponent bias */ + + +union dtol +{ + double dval; + int ival[2]; +}; + +double ldexp (double x,int n) +{ + union dtol number; + int *iptr, cn; + + if (x == 0.0) + return (0.0); + else + { + number.dval = x; + iptr = &number.ival[0]; + cn = (((*iptr) & EXP_MASK) >> EXP_SHIFTS) - EXP_BIAS; + *iptr &= ~EXP_MASK; + n += EXP_BIAS; + *iptr |= ((n + cn) << EXP_SHIFTS) & EXP_MASK; + return (number.dval); + } +} diff --git a/libnix/sources/math/extra/modf.c b/libnix/sources/math/extra/modf.c new file mode 100644 index 0000000..c1ce69a --- /dev/null +++ b/libnix/sources/math/extra/modf.c @@ -0,0 +1,13 @@ +#undef __HAVE_68881__ +#include + +double modf(double x,double *p) +{ + if(x<0){ + *p=ceil(x); + return(*p-x); + }else{ + *p=floor(x); + return(x-*p); + } +} diff --git a/libnix/sources/math/extra/rand48.c b/libnix/sources/math/extra/rand48.c new file mode 100755 index 0000000..a159c0b --- /dev/null +++ b/libnix/sources/math/extra/rand48.c @@ -0,0 +1,232 @@ +/* Random number generation using the linear congruential algorithm + X(n+1) = (a * X(n) + c) mod m + with a precision of 48 bits. + + Author: Kriton Kyrimis (kyrimis@theseas.softlab.ece.ntua.gr) + Code status: Public Domain. +*/ + +#include +#include + +/* Parameters for the linear congruential algorithm: + parm[0..2] is the current value of Xn (internal seed, m.s.word last) + parm[3..5] is the value of a (m.s.word last) + parm[6] is the value of c. +*/ +#define X0 0x1234 /* MSB * Initial value for Xn, obtained using seed48() */ +#define X1 0xABCD /* on SunOS 4.1.3 */ +#define X2 0x330E + +#define A0 0x0005 /* MSB * Default value for a, taken from the man page */ +#define A1 0xDEEC +#define A2 0xE66D + +#define C0 0x000B /* Default value for c, taken from the man page */ + +static unsigned short parm[7] = { + X2, X1, X0, + A2, A1, A0, + C0 +}; + +/* To produce a double random number in [0,1) we get a 32-bit unsigned long + random number, convert it to double, and divide it by ULONG_MAX + EPSILON. + (We add the EPSILON to exclude 1.0 from the set of possible results.) + + We derive EPSILON by noting that for a random value of ULONG_MAX, + we want to return the smallest double that is less than 1.0. + Therefore: + + ULONG_MAX + --------------------- = (1.0 - DBL_EPSILON) + (ULONG_MAX + EPSILON) + + (This is probably overkill.) + +*/ + +#define EPSILON (double)ULONG_MAX*(1.0/(1.0-DBL_EPSILON)-1.0) + + +/*--------------------------------------------------------------------------* + * Parameter initialization functions * + *--------------------------------------------------------------------------*/ + +/* This function sets the two m.s.words of the internal seed to the value + supplied by the caller, and the l.s.word of the internal seed to 0x330E. +*/ +void +srand48(long seed) +{ + parm[0] = 0x330E; + parm[1] = ((unsigned long)seed) & 0xFFFF; + parm[2] = ((unsigned long)seed >> 16) & 0xFFFF; + parm[3] = A2; + parm[4] = A1; + parm[5] = A0; + parm[6] = C0; +} + +/* This function sets all three words of the internal seed to the value + supplied by the caller. It returns a pointer to an array containing + a copy of the previous value of the internal seed. +*/ +unsigned short * +seed48(unsigned short *seed) +{ + static unsigned short oldparm[3]; + unsigned short tmpparm[3]; + + /* Can't assign oldparm[] = parm[] directly, because seed[] may be a pointer + to oldparm[], obtained from a previous call to seed48 , in which case + we would destroy the contents of seed[] */ + tmpparm[0] = parm[0]; + tmpparm[1] = parm[1]; + tmpparm[2] = parm[2]; + parm[0] = seed[0]; + parm[1] = seed[1]; + parm[2] = seed[2]; + oldparm[0] = tmpparm[0]; + oldparm[1] = tmpparm[1]; + oldparm[2] = tmpparm[2]; + parm[3] = A2; + parm[4] = A1; + parm[5] = A0; + parm[6] = C0; + + return oldparm; +} + +/* This function sets all seven words of the internal parameters array to the + values supplied by the caller. +*/ +void +lcong48(unsigned short *new_parm) +{ + parm[0] = new_parm[0]; + parm[1] = new_parm[1]; + parm[2] = new_parm[2]; + parm[3] = new_parm[3]; + parm[4] = new_parm[4]; + parm[5] = new_parm[5]; + parm[6] = new_parm[6]; +} + + +/*--------------------------------------------------------------------------* + * Random number generator * + *--------------------------------------------------------------------------*/ + +/* This function implements the linear congruential algorithm. Thanks to + gcc's long long ints, implementing 48-bit arithmetic (actually 64-bit, + truncating the result) is trivial. Limitations of long long int + implementation in (amiga?) gcc 2.7.0, made me use the kludge with the union + to convert from short[3] to long long int. (It's probably faster though!) + + This function takes an array of three shorts (a 48-bit seed, m.s.word + last) and returns a long between -2**31 and 2**31-1, updating the seed + (the result is the two m.s.words of the updated seed). +*/ + +static long +rng(unsigned short *seed) +{ + long long int Xn, Xn1, a, c; + union { + long long int l; + unsigned short s[4]; + } i; + + i.s[0] = 0; + i.s[1] = seed[2]; + i.s[2] = seed[1]; + i.s[3] = seed[0]; + Xn = i.l; + + i.s[0] = 0; + i.s[1] = parm[5]; + i.s[2] = parm[4]; + i.s[3] = parm[3]; + a = i.l; + + c = (long long int)(parm[6]); + + Xn1 = a * Xn + c; + + i.l = Xn1; + seed[0] = i.s[3]; + seed[1] = i.s[2]; + seed[2] = i.s[1]; + + return (long)((((unsigned long)seed[2]) << 16) + seed[1]); +} + + +/*--------------------------------------------------------------------------* + * Interface functions to the random number generator * + *--------------------------------------------------------------------------*/ + +/* This function returns a long between 0 and 2**31-1 by calling rng + with the internal seed, returning the 15 most significant bits of the + result shifted by one position to the right. +*/ +long +lrand48(void) +{ + return (rng(parm) >> 1) & 0x7FFFFFFF; +} + +/* Same as lrand48(), but using an external seed. */ + +long +nrand48(unsigned short seed[3]) +{ + return (rng(seed) >> 1) & 0x7FFFFFFF; +} + +/* This function returns a long between -2**31 and 2**31-1 by calling rng + with the internal seed. +*/ +long +mrand48(void) +{ + return rng(parm); +} + +/* Same as mrand48(), but using an external seed. */ + +long +jrand48(unsigned short seed[3]) +{ + return rng(seed); +} + +/* This function returns a double in the interval [0,1) by calling mrand48() + and dividing the result by ULONG_MAX + EPSILON. */ + +double +drand48(void) +{ + union { + long l; + unsigned long u; + } x; + + x.l = mrand48(); + return (double)x.u / ((double)(ULONG_MAX) + EPSILON); +} + +/* Same as drand48(), but using an external seed. */ + +double +erand48(unsigned short seed[3]) +{ + union { + long l; + unsigned long u; + } x; + + x.l = nrand48(seed); + return (double)x.u / ((double)(ULONG_MAX) + EPSILON); +} diff --git a/libnix/sources/math/stdio/isinf.c b/libnix/sources/math/stdio/isinf.c new file mode 100755 index 0000000..dc6c52c --- /dev/null +++ b/libnix/sources/math/stdio/isinf.c @@ -0,0 +1,5 @@ +int isinf(double a) +{ + unsigned long *b=(unsigned long *)&a; + return (b[0]&0x7ff00000)==0x7ff00000&&!(b[0]&0xfffff)&&!b[1]; +} diff --git a/libnix/sources/math/stdio/isnan.c b/libnix/sources/math/stdio/isnan.c new file mode 100755 index 0000000..a9031dd --- /dev/null +++ b/libnix/sources/math/stdio/isnan.c @@ -0,0 +1,5 @@ +int isnan(double a) +{ + unsigned long *b=(unsigned long *)&a; + return (b[0]&0x7ff00000)==0x7ff00000&&((b[0]&0xfffff)||b[1]); +} diff --git a/libnix/sources/math/stdlib/atof.c b/libnix/sources/math/stdlib/atof.c new file mode 100755 index 0000000..5e9d9d6 --- /dev/null +++ b/libnix/sources/math/stdlib/atof.c @@ -0,0 +1,7 @@ +#include + +double atof(const char *nptr) +{ double a; + sscanf(nptr,"%lf",&a); + return a; +} diff --git a/libnix/sources/math/stdlib/strtod.c b/libnix/sources/math/stdlib/strtod.c new file mode 100755 index 0000000..9e567dd --- /dev/null +++ b/libnix/sources/math/stdlib/strtod.c @@ -0,0 +1,10 @@ +#include + +double strtod(const char *nptr,char **endptr) +{ double a; + unsigned long n=0; + sscanf(nptr,"%lf%ln",&a,&n); + if(endptr) + *endptr=(char *)nptr+n; + return a; +} diff --git a/libnix/sources/math/trans/acos.c b/libnix/sources/math/trans/acos.c new file mode 100755 index 0000000..faab84a --- /dev/null +++ b/libnix/sources/math/trans/acos.c @@ -0,0 +1,4 @@ +#include + +double acos(double x) +{ return IEEEDPAcos(x); } diff --git a/libnix/sources/math/trans/asin.c b/libnix/sources/math/trans/asin.c new file mode 100755 index 0000000..5efb099 --- /dev/null +++ b/libnix/sources/math/trans/asin.c @@ -0,0 +1,4 @@ +#include + +double asin(double x) +{ return IEEEDPAsin(x); } diff --git a/libnix/sources/math/trans/atan.c b/libnix/sources/math/trans/atan.c new file mode 100755 index 0000000..1ca25a0 --- /dev/null +++ b/libnix/sources/math/trans/atan.c @@ -0,0 +1,4 @@ +#include + +double atan(double x) +{ return IEEEDPAtan(x); } diff --git a/libnix/sources/math/trans/atan2.c b/libnix/sources/math/trans/atan2.c new file mode 100755 index 0000000..8414ba0 --- /dev/null +++ b/libnix/sources/math/trans/atan2.c @@ -0,0 +1,12 @@ +#include + +#define PI 3.14159265358979323846 + +static inline double atan(double x) +{ return IEEEDPAtan(x); } + +double atan2(double y,double x) +{ return x>=y?(x>=-y? atan(y/x): -PI/2-atan(x/y)): + (x>=-y? PI/2-atan(x/y):y>=0? PI +atan(y/x): + -PI +atan(y/x)); +} diff --git a/libnix/sources/math/trans/ceil.c b/libnix/sources/math/trans/ceil.c new file mode 100755 index 0000000..78ab7ed --- /dev/null +++ b/libnix/sources/math/trans/ceil.c @@ -0,0 +1,4 @@ +#include + +double ceil(double x) +{ return IEEEDPCeil(x); } diff --git a/libnix/sources/math/trans/cos.c b/libnix/sources/math/trans/cos.c new file mode 100755 index 0000000..b02d2b1 --- /dev/null +++ b/libnix/sources/math/trans/cos.c @@ -0,0 +1,4 @@ +#include + +double cos(double x) +{ return IEEEDPCos(x); } diff --git a/libnix/sources/math/trans/cosh.c b/libnix/sources/math/trans/cosh.c new file mode 100755 index 0000000..d36d4c9 --- /dev/null +++ b/libnix/sources/math/trans/cosh.c @@ -0,0 +1,4 @@ +#include + +double cosh(double x) +{ return IEEEDPCosh(x); } diff --git a/libnix/sources/math/trans/exp.c b/libnix/sources/math/trans/exp.c new file mode 100755 index 0000000..b490ee8 --- /dev/null +++ b/libnix/sources/math/trans/exp.c @@ -0,0 +1,4 @@ +#include + +double exp(double x) +{ return IEEEDPExp(x); } diff --git a/libnix/sources/math/trans/fabs.c b/libnix/sources/math/trans/fabs.c new file mode 100755 index 0000000..38f4a33 --- /dev/null +++ b/libnix/sources/math/trans/fabs.c @@ -0,0 +1,4 @@ +#include + +double fabs(double x) +{ return IEEEDPAbs(x); } diff --git a/libnix/sources/math/trans/floor.c b/libnix/sources/math/trans/floor.c new file mode 100755 index 0000000..dba6ae9 --- /dev/null +++ b/libnix/sources/math/trans/floor.c @@ -0,0 +1,4 @@ +#include + +double floor(double x) +{ return IEEEDPFloor(x); } diff --git a/libnix/sources/math/trans/fmod.c b/libnix/sources/math/trans/fmod.c new file mode 100755 index 0000000..f85e8f9 --- /dev/null +++ b/libnix/sources/math/trans/fmod.c @@ -0,0 +1,16 @@ +#include + +static inline double floor(double x) +{ return IEEEDPFloor(x); } + +static inline double ceil(double x) +{ return IEEEDPCeil(x); } + +double fmod(double x,double y) +{ + double a=x/y; + if(a>=0) + return x-y*floor(a); + else + return x-y*ceil(a); +} diff --git a/libnix/sources/math/trans/log.c b/libnix/sources/math/trans/log.c new file mode 100755 index 0000000..3f2700e --- /dev/null +++ b/libnix/sources/math/trans/log.c @@ -0,0 +1,4 @@ +#include + +double log(double x) +{ return IEEEDPLog(x); } diff --git a/libnix/sources/math/trans/log10.c b/libnix/sources/math/trans/log10.c new file mode 100755 index 0000000..83fa036 --- /dev/null +++ b/libnix/sources/math/trans/log10.c @@ -0,0 +1,4 @@ +#include + +double log10(double x) +{ return IEEEDPLog10(x); } diff --git a/libnix/sources/math/trans/pow.c b/libnix/sources/math/trans/pow.c new file mode 100755 index 0000000..e5dffad --- /dev/null +++ b/libnix/sources/math/trans/pow.c @@ -0,0 +1,4 @@ +#include + +double pow(double x,double y) +{ return IEEEDPPow(y,x); } diff --git a/libnix/sources/math/trans/sin.c b/libnix/sources/math/trans/sin.c new file mode 100755 index 0000000..519f34b --- /dev/null +++ b/libnix/sources/math/trans/sin.c @@ -0,0 +1,4 @@ +#include + +double sin(double x) +{ return IEEEDPSin(x); } diff --git a/libnix/sources/math/trans/sinh.c b/libnix/sources/math/trans/sinh.c new file mode 100755 index 0000000..819a7f8 --- /dev/null +++ b/libnix/sources/math/trans/sinh.c @@ -0,0 +1,4 @@ +#include + +double sinh(double x) +{ return IEEEDPSinh(x); } diff --git a/libnix/sources/math/trans/sqrt.c b/libnix/sources/math/trans/sqrt.c new file mode 100755 index 0000000..657bc20 --- /dev/null +++ b/libnix/sources/math/trans/sqrt.c @@ -0,0 +1,4 @@ +#include + +double sqrt(double x) +{ return IEEEDPSqrt(x); } diff --git a/libnix/sources/math/trans/tan.c b/libnix/sources/math/trans/tan.c new file mode 100755 index 0000000..a60c15b --- /dev/null +++ b/libnix/sources/math/trans/tan.c @@ -0,0 +1,4 @@ +#include + +double tan(double x) +{ return IEEEDPTan(x); } diff --git a/libnix/sources/math/trans/tanh.c b/libnix/sources/math/trans/tanh.c new file mode 100755 index 0000000..753fb55 --- /dev/null +++ b/libnix/sources/math/trans/tanh.c @@ -0,0 +1,4 @@ +#include + +double tanh(double x) +{ return IEEEDPTanh(x); } diff --git a/libnix/sources/misc/Makefile.in b/libnix/sources/misc/Makefile.in new file mode 100644 index 0000000..d4bd924 --- /dev/null +++ b/libnix/sources/misc/Makefile.in @@ -0,0 +1,49 @@ +#### Start of system configuration section. #### + +srcdir = @srcdir@ +VPATH = @srcdir@ + +CC = @CC@ +CPP = @CPP@ +AS = as + +RANLIB = @RANLIB@ +AWK = @AWK@ + +#### End system configuration section #### + +OBJECTS=detach.o swapstack.o + +OPTIONS=-I $(srcdir)/../headers -I../../sources/headers $(CFLAGS) + +vpath %.c $(SOURCEDIR) + +REDEF=-D_DOSBase=___DOSBase \ + -D_UtilityBase=___UtilityBase \ + -D_MathIeeeSingBasBase=___MathIeeeSingBasBase \ + -D_MathIeeeSingTransBase=___MathIeeeSingTransBase \ + -D_MathIeeeDoubBasBase=___MathIeeeDoubBasBase \ + -D_MathIeeeDoubTransBase=___MathIeeeDoubTransBase \ + -D_LocaleBase=___LocaleBase + +#Use private library bases to avoid naming collisions +%.o: %.c + $(CC) $(OPTIONS) -S $^ -o $*.S 2>&1|tee $*.err + $(CPP) -traditional $(REDEF) $*.S -o $*2.S + $(CC) $(OPTIONS) $*2.S -c -o $*.o + -rm $*.S $*2.S + -if test ! -s $*.err; then rm $*.err; fi + echo "\$$$(V)" >>$*.o + +.PHONY: all filelist subdirs clean veryclean + +all: $(OBJECTS) + +filelist: + +subdirs: + +clean: + -rm -f *.o *.err + +veryclean: clean diff --git a/libnix/sources/misc/detach.c b/libnix/sources/misc/detach.c new file mode 100755 index 0000000..94b4034 --- /dev/null +++ b/libnix/sources/misc/detach.c @@ -0,0 +1,86 @@ +#include +#include +#include +#include +#include +#include + +/* Sorry, but the assembler code produced by gcc for this function is too bad. + * This one is much better! + */ +#ifdef CreateNewProcTags +#undef CreateNewProcTags +static APTR createnewproctags(APTR DOSBase,ULONG Tag,...) +{ return CreateNewProc((struct TagItem *)&Tag); } +#define CreateNewProcTags(tag...) createnewproctags(DOSBase,tag) +#endif + +extern struct WBStart *_WBenchMsg; +extern char *__commandline; +extern void *__SaveSP; +extern char __dosname[]; + +extern char *__procname; +extern long __priority; +extern unsigned long __stack; + +/* I must close a library after my child is running - + * and closing a library requires a working dispatcher (IMHO). + * Also semaphores are much smarter ;). Therefore: + */ +static struct SignalSemaphore *sem = NULL; + +void __initdetach(void) +{ struct Library *DOSBase,*SysBase = *(struct Library **)4; + struct SignalSemaphore *sema; + + if (_WBenchMsg) + return; + + if ((sema=sem)) { /* I must be the child process */ + ObtainSemaphore(sema); /* Assert that my parent is already dead */ + ReleaseSemaphore(sema); + FreeMem(sema,sizeof(*sema)); + return; + } + /* I must be the parent */ + if ((sem=sema=(struct SignalSemaphore *)AllocMem(sizeof(*sema),MEMF_PUBLIC|MEMF_CLEAR))) { + + InitSemaphore(sema); + + if ((DOSBase=OpenLibrary(__dosname,37))) { + + struct CommandLineInterface *cli = Cli(); + APTR pr,stack = __SaveSP; + + ObtainSemaphore(sema); /* Assert that my child is suspended until I'm finished */ + + pr = CreateNewProcTags(NP_Seglist,cli->cli_Module, /* child process gets my seglist */ + NP_FreeSeglist,1, /* and must free it */ + NP_Cli,1, /* it must be a CLI process */ + NP_StackSize,__stack, /* it gets a stack */ + NP_Name,(ULONG)__procname, /* a name */ + NP_Priority,__priority, /* a priority */ + NP_Arguments,(ULONG)__commandline,/* and my commandline Arguments */ + TAG_END); + CloseLibrary(DOSBase); + + if (pr) { + + cli->cli_Module = 0; /* I'm no longer owner of this */ + + /* Adjust stack, release semaphore and return 0 in one. + * Maybe the 3 movel are a bit too cautious, but they ARE working + */ + asm("movel %0,sp;movel %1,a6;movel %2,a0;moveql #0,d0;jmp a6@(-570)":: + "r"(stack),"r"(SysBase),"r"(sema):"sp","a6","a0"); + } + + ReleaseSemaphore(sema); /* Again only caution - you never know */ + } + FreeMem(sema,sizeof(*sema)); /* Couldn't start child :( */ + } + exit(20); +} + +ADD2INIT(__initdetach,-70); /* A very high priority */ diff --git a/libnix/sources/misc/swapstack.c b/libnix/sources/misc/swapstack.c new file mode 100755 index 0000000..b2a1424 --- /dev/null +++ b/libnix/sources/misc/swapstack.c @@ -0,0 +1,104 @@ +#include +#include +#include +#include +#include +#include "stabs.h" + +/* + * swapstack.c + * + * A libnix startup module to swap to a new stack if the old one is not + * big enough (minimum value set by the value of the __stack variable). + * + * WARNING! + * Compile with -O3, or your Amiga will explode! + * + * Code derived from a stackswap module by Kriton Kyrimis (kyrimis@theseas.ntua.gr) + * with some changes to work with the libnix startups (MF). + * You use it at your own risk. + * + * Usage: Define some variable 'unsigned long __stack={desired size};' + * somewhere in your code and link with this module. + * The file stabs.h is in the headers directory of the libnix sources. + */ + +extern unsigned long __stack; +void __request(const char *text); + +static struct StackSwapStruct stack; +static char *newstack; + +void __stkinit(long a) +{ APTR SysBase = *(APTR *)4; + register char *sp asm("sp"); + ULONG size,needed=__stack; + struct Process *pr; + char *new; + + asm("":"=r"(sp)); /* touch sp to get compiler happy */ + + /* Determine original stack size */ + + pr=(struct Process *)FindTask(NULL); + + size = (char *)pr->pr_Task.tc_SPUpper - (char *)pr->pr_Task.tc_SPLower; + + if (pr->pr_CLI) { + size = *(ULONG *)pr->pr_ReturnAddr; + } + + if (needed <= size) + return; + + /* Round size to next long word */ + needed = (needed+(sizeof(LONG)-1))&~(sizeof(LONG)-1); + + /* Allocate new stack */ + newstack = new = AllocVec(needed,MEMF_PUBLIC); + if (!new) { + __request("Couldn't allocate new stack!"); + exit(RETURN_FAIL); + } + + /* Build new stack structure */ + size=(char *)&a-sp+2*sizeof(ULONG); + stack.stk_Lower =new; + stack.stk_Upper =(ULONG)(new+=needed); + stack.stk_Pointer=(APTR)(new-=size); + + /* Copy required parts of old stack */ + CopyMem(sp,new,size); + + /* Switch to new stack */ + StackSwap(&stack); +} + +void __stkexit(ULONG a) +{ APTR SysBase = *(APTR *)4; + register char *sp asm("sp"); + ULONG size; + char *new; + + asm("":"=r"(sp)); /* touch sp to get compiler happy */ + + if(!(new=newstack)) + return; + + /* Prepare old stack */ + size=(char *)&a-sp+3*sizeof(ULONG); + stack.stk_Pointer=(APTR)((char *)stack.stk_Pointer-size); + + /* Copy required parts of current stack */ + CopyMem(sp,stack.stk_Pointer,size); + + /* Switch back to old stack */ + StackSwap(&stack); + + /* And clean up */ + FreeVec(new); +} + +/* The same priority as the detach module - you cannot use them both */ +ADD2INIT(__stkinit,-70); +ADD2EXIT(__stkexit,-70); diff --git a/libnix/sources/nix/Makefile.in b/libnix/sources/nix/Makefile.in new file mode 100644 index 0000000..6a3b25c --- /dev/null +++ b/libnix/sources/nix/Makefile.in @@ -0,0 +1,57 @@ +#### Start of system configuration section. #### + +srcdir = @srcdir@ +VPATH = @srcdir@ + +CC = @CC@ +CPP = @CPP@ +AS = as + +RANLIB = @RANLIB@ +AWK = @AWK@ + +#### End system configuration section #### + +ifneq ($(TARGET),clean) +include ../../sources/nix/filelist +endif + +CURDIR = $(shell pwd) + +OPTIONS=-I $(srcdir)/../headers -I ../../sources/headers $(CFLAGS) + +SOURCEFILES=*/* + +REDEF=-D_DOSBase=___DOSBase \ + -D_UtilityBase=___UtilityBase \ + -D_MathIeeeSingBasBase=___MathIeeeSingBasBase \ + -D_MathIeeeSingTransBase=___MathIeeeSingTransBase \ + -D_MathIeeeDoubBasBase=___MathIeeeDoubBasBase \ + -D_MathIeeeDoubTransBase=___MathIeeeDoubTransBase \ + -D_LocaleBase=___LocaleBase + +%.o: %.c + $(CC) $(OPTIONS) -S $^ -o $*.S 2>&1|tee $*.err + $(CPP) -traditional $(REDEF) $*.S -o $*2.S + $(CC) $(OPTIONS) $*2.S -c -o $*.o + -rm $*.S $*2.S + -if test ! -s $*.err; then rm $*.err; fi + +.PHONY: all clean veryclean + +all: libnix.a + +clean: + -rm -rf $(SUBDIRS) + +veryclean: + -rm -rf * + +$(foreach f,$(SUBDIRS),$(CURDIR)/$(f)): + mkdir $@ + +libnix.a: $(foreach f,$(SUBDIRS),$(CURDIR)/$(f)) $(OBJECTS) ../../sources/nix/makefile ../../sources/nix/filelist + -rm -f $@ + ar -q $@ $(OBJECTS) + $(RANLIB) $@ + echo "\$$$(V)" >>$@ diff --git a/libnix/sources/nix/assert/__eprintf.c b/libnix/sources/nix/assert/__eprintf.c new file mode 100755 index 0000000..e215d7b --- /dev/null +++ b/libnix/sources/nix/assert/__eprintf.c @@ -0,0 +1,10 @@ +#include +#include + +void __eprintf(const char *format,...) /* for asserts */ +{ va_list args; + va_start(args,format); + vfprintf(stderr,format,args); + va_end(args); + abort(); +} diff --git a/libnix/sources/nix/ctype/_ctype_.c b/libnix/sources/nix/ctype/_ctype_.c new file mode 100755 index 0000000..d8b0977 --- /dev/null +++ b/libnix/sources/nix/ctype/_ctype_.c @@ -0,0 +1,22 @@ +unsigned char __ctype[]= +{ 0x00, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x88,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10, + 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x10,0x10,0x10,0x10,0x10,0x10, + 0x10,0x41,0x41,0x41,0x41,0x41,0x41,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x10,0x10,0x10,0x10,0x10, + 0x10,0x42,0x42,0x42,0x42,0x42,0x42,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02, + 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x10,0x10,0x10,0x10,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x08,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10, + 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x10,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x02, + 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02, + 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x10,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02, + 0x00,0x00,0x00 +}; + +const unsigned char *_ctype_=__ctype; diff --git a/libnix/sources/nix/ctype/isalnum.c b/libnix/sources/nix/ctype/isalnum.c new file mode 100755 index 0000000..edc7174 --- /dev/null +++ b/libnix/sources/nix/ctype/isalnum.c @@ -0,0 +1,4 @@ +extern char *_ctype_; + +int isalnum(int c) +{ return _ctype_[1+c]&7; } diff --git a/libnix/sources/nix/ctype/isalpha.c b/libnix/sources/nix/ctype/isalpha.c new file mode 100755 index 0000000..b52bf6f --- /dev/null +++ b/libnix/sources/nix/ctype/isalpha.c @@ -0,0 +1,4 @@ +extern char *_ctype_; + +int isalpha(int c) +{ return _ctype_[1+c]&3; } diff --git a/libnix/sources/nix/ctype/iscntrl.c b/libnix/sources/nix/ctype/iscntrl.c new file mode 100755 index 0000000..51051c4 --- /dev/null +++ b/libnix/sources/nix/ctype/iscntrl.c @@ -0,0 +1,4 @@ +extern char *_ctype_; + +int iscntrl(int c) +{ return _ctype_[1+c]&32; } diff --git a/libnix/sources/nix/ctype/isdigit.c b/libnix/sources/nix/ctype/isdigit.c new file mode 100755 index 0000000..e92192e --- /dev/null +++ b/libnix/sources/nix/ctype/isdigit.c @@ -0,0 +1,4 @@ +extern char *_ctype_; + +int isdigit(int c) +{ return _ctype_[1+c]&4; } diff --git a/libnix/sources/nix/ctype/isgraph.c b/libnix/sources/nix/ctype/isgraph.c new file mode 100755 index 0000000..6f9fa7f --- /dev/null +++ b/libnix/sources/nix/ctype/isgraph.c @@ -0,0 +1,4 @@ +extern char *_ctype_; + +int isgraph(int c) +{ return _ctype_[1+c]&23; } diff --git a/libnix/sources/nix/ctype/islower.c b/libnix/sources/nix/ctype/islower.c new file mode 100755 index 0000000..0e937d0 --- /dev/null +++ b/libnix/sources/nix/ctype/islower.c @@ -0,0 +1,4 @@ +extern char *_ctype_; + +int islower(int c) +{ return _ctype_[1+c]&2; } diff --git a/libnix/sources/nix/ctype/isprint.c b/libnix/sources/nix/ctype/isprint.c new file mode 100755 index 0000000..1ab2532 --- /dev/null +++ b/libnix/sources/nix/ctype/isprint.c @@ -0,0 +1,4 @@ +extern char *_ctype_; + +int isprint(int c) +{ return _ctype_[1+c]&151; } diff --git a/libnix/sources/nix/ctype/ispunct.c b/libnix/sources/nix/ctype/ispunct.c new file mode 100755 index 0000000..31facd9 --- /dev/null +++ b/libnix/sources/nix/ctype/ispunct.c @@ -0,0 +1,4 @@ +extern char *_ctype_; + +int ispunct(int c) +{ return _ctype_[1+c]&16; } diff --git a/libnix/sources/nix/ctype/isspace.c b/libnix/sources/nix/ctype/isspace.c new file mode 100755 index 0000000..e2252ae --- /dev/null +++ b/libnix/sources/nix/ctype/isspace.c @@ -0,0 +1,4 @@ +extern char *_ctype_; + +int isspace(int c) +{ return _ctype_[1+c]&8; } diff --git a/libnix/sources/nix/ctype/isupper.c b/libnix/sources/nix/ctype/isupper.c new file mode 100755 index 0000000..1b12699 --- /dev/null +++ b/libnix/sources/nix/ctype/isupper.c @@ -0,0 +1,4 @@ +extern char *_ctype_; + +int isupper(int c) +{ return _ctype_[1+c]&1; } diff --git a/libnix/sources/nix/ctype/isxdigit.c b/libnix/sources/nix/ctype/isxdigit.c new file mode 100755 index 0000000..a777b8d --- /dev/null +++ b/libnix/sources/nix/ctype/isxdigit.c @@ -0,0 +1,4 @@ +extern char *_ctype_; + +int isxdigit(int c) +{ return _ctype_[1+c]&68; } diff --git a/libnix/sources/nix/ctype/tolower.c b/libnix/sources/nix/ctype/tolower.c new file mode 100755 index 0000000..3605077 --- /dev/null +++ b/libnix/sources/nix/ctype/tolower.c @@ -0,0 +1,4 @@ +extern char *_ctype_; + +int tolower(int c) +{ return _ctype_[1+c]&1?c+'a'-'A':c; } diff --git a/libnix/sources/nix/ctype/toupper.c b/libnix/sources/nix/ctype/toupper.c new file mode 100755 index 0000000..b7769d7 --- /dev/null +++ b/libnix/sources/nix/ctype/toupper.c @@ -0,0 +1,4 @@ +extern char *_ctype_; + +int toupper(int c) +{ return _ctype_[1+c]&2?c+'A'-'a':c; } diff --git a/libnix/sources/nix/errno/__seterrno.c b/libnix/sources/nix/errno/__seterrno.c new file mode 100755 index 0000000..b79207c --- /dev/null +++ b/libnix/sources/nix/errno/__seterrno.c @@ -0,0 +1,77 @@ +#include +#include +#include + +/* Table to convert amigados error messages to unix ones */ + +extern int errno; + +static long _errortable[]= +{ + ERROR_NO_FREE_STORE ,ENOMEM, + ERROR_TASK_TABLE_FULL ,EPROCLIM, +/*ERROR_BAD_TEMPLATE + ERROR_BAD_NUMBER + ERROR_REQUIRED_ARG_MISSING + ERROR_KEY_NEEDS_ARG*/ + ERROR_TOO_MANY_ARGS ,E2BIG, +/*ERROR_UNMATCHED_QUOTES*/ + ERROR_LINE_TOO_LONG ,E2BIG, +/*ERROR_FILE_NOT_OBJECT + ERROR_INVALID_RESIDENT_LIBRARY + ERROR_NO_DEFAULT_DIR*/ + ERROR_OBJECT_IN_USE ,ETXTBSY, + ERROR_OBJECT_EXISTS ,EEXIST, + ERROR_DIR_NOT_FOUND ,ENOENT, + ERROR_OBJECT_NOT_FOUND ,ENOENT, + ERROR_BAD_STREAM_NAME ,ENAMETOOLONG, + ERROR_OBJECT_TOO_LARGE ,EFBIG, + ERROR_ACTION_NOT_KNOWN ,ENODEV, +/*ERROR_INVALID_COMPONENT_NAME + ERROR_INVALID_LOCK + ERROR_OBJECT_WRONG_TYPE*/ + ERROR_DISK_NOT_VALIDATED ,EBUSY, + ERROR_DISK_WRITE_PROTECTED ,EROFS, +/*ERROR_RENAME_ACROSS_DEVICES*/ + ERROR_DIRECTORY_NOT_EMPTY ,ENOTEMPTY, + ERROR_TOO_MANY_LEVELS ,ENAMETOOLONG, + ERROR_DEVICE_NOT_MOUNTED ,ENXIO, + ERROR_SEEK_ERROR ,ESPIPE, +/*ERROR_COMMENT_TOO_BIG*/ + ERROR_DISK_FULL ,ENOSPC, + ERROR_DELETE_PROTECTED ,EACCES, + ERROR_WRITE_PROTECTED ,EACCES, + ERROR_READ_PROTECTED ,EACCES, + ERROR_NOT_A_DOS_DISK ,EFTYPE, + ERROR_NO_DISK ,ENXIO, +/*ERROR_NO_MORE_ENTRIES + ERROR_IS_SOFT_LINK + ERROR_OBJECT_LINKED*/ + ERROR_BAD_HUNK ,ENOEXEC, +/*ERROR_NOT_IMPLEMENTED + ERROR_RECORD_NOT_LOCKED + ERROR_LOCK_COLLISION + ERROR_LOCK_TIMEOUT + ERROR_UNLOCK_ERROR + ERROR_BUFFER_OVERFLOW + ERROR_BREAK*/ + ERROR_NOT_EXECUTABLE ,EACCES, + 0 +}; + +void __seterrno(void) +{ + long amigaerror; + long *ptr=_errortable; + amigaerror=IoErr(); + while(*ptr) + { + if(*ptr++==amigaerror) + { + errno=*ptr; + return; + } + ptr++; + } + errno=EPERM; +} diff --git a/libnix/sources/nix/errno/errno.c b/libnix/sources/nix/errno/errno.c new file mode 100755 index 0000000..3c6cdb0 --- /dev/null +++ b/libnix/sources/nix/errno/errno.c @@ -0,0 +1 @@ +int errno=0; diff --git a/libnix/sources/nix/extra/__amigapath.c b/libnix/sources/nix/extra/__amigapath.c new file mode 100755 index 0000000..d2e45d8 --- /dev/null +++ b/libnix/sources/nix/extra/__amigapath.c @@ -0,0 +1,89 @@ +#include +#include +#include +#include + +static int __pathconv; + +/* Convert Un*x style pathnames to Amiga OS ones */ + +char *__amigapath(const char *path) +{ static char *s1=NULL; + char *s2,*s3; + int c; + + if(!__pathconv) + return (char *)path; + + if(s1!=NULL) + free(s1); + + s1=strdup(path); + if(s1==NULL) + { errno=ENOMEM; + return NULL; } + + s3=s2=s1; /* Replace multiple following '/' by single ones */ + do + { if(*s2=='/') + while(s2[1]=='/') + s2++; + *s3++=*s2; + }while(*s2++); + + s3=s2=s1; /* Remove single dots '.' as directory names */ + c=1; + do + { while(c&&s2[0]=='.'&&(s2[1]=='/'||s2[1]=='\0')) + { s2++; + if(*s2=='/') + s2++; + } + *s3++=*s2; + c=0; + if(*s2=='/') + c=1; + }while(*s2++); + + s3=s2=s1; /* Remove double dots '..' as directory names */ + c=1; + do + { if(c&&s2[0]=='.'&&s2[1]=='.') + { if(s2[2]=='/') + s2+=2; + else if(s2[2]=='\0') + { *s3++='/'; + s2+=2; } + } + *s3++=*s2; + c=0; + if(*s2=='/') + c=1; + }while(*s2++); + + if(*s1=='/') /* Convert names beginning with '/' */ + { s3=s2=s1; + s2++; + if(*s2=='/'||*s2=='\0') /* The root directory */ + return "SYS:"; + while(*s2!='/'&&*s2!='\0') + *s3++=*s2++; + *s3++=':'; + if(*s2=='/') + s2++; + do + *s3++=*s2; + while(*s2++); + } + + return s1; +} + +void __initamigapath(void) +{ char *s; + s=getenv("NOIXPATHS"); /* Check explicitly for "1", so we can override it locally */ + if(s&&s[0]=='1'&&s[1]=='\0') /* with 'set NOIXPATHS 0' */ + __pathconv=1; +} + +ADD2INIT(__initamigapath,-10); diff --git a/libnix/sources/nix/extra/__stat.c b/libnix/sources/nix/extra/__stat.c new file mode 100755 index 0000000..06776ec --- /dev/null +++ b/libnix/sources/nix/extra/__stat.c @@ -0,0 +1,33 @@ +#include +#include +#include + +int __stat(struct stat *buf,struct FileInfoBlock *fib) +{ + buf->st_dev=0; + buf->st_ino=fib->fib_DiskKey; + buf->st_mode= + (fib->fib_DirEntryType<0?S_IFREG: + (fib->fib_DirEntryType!=ST_SOFTLINK?S_IFDIR:S_IFLNK))| + (fib->fib_Protection&FIBF_READ?0:S_IRUSR)| + (fib->fib_Protection&FIBF_WRITE?0:S_IWUSR)| + (fib->fib_Protection&FIBF_EXECUTE?0:S_IXUSR)| + (fib->fib_Protection&FIBF_GRP_READ?S_IRGRP:0)| + (fib->fib_Protection&FIBF_GRP_WRITE?S_IWGRP:0)| + (fib->fib_Protection&FIBF_GRP_EXECUTE?S_IXGRP:0)| + (fib->fib_Protection&FIBF_OTR_READ?S_IROTH:0)| + (fib->fib_Protection&FIBF_OTR_WRITE?S_IWOTH:0)| + (fib->fib_Protection&FIBF_OTR_EXECUTE?S_IXOTH:0); + buf->st_nlink=0; + buf->st_uid=fib->fib_OwnerUID; + buf->st_gid=fib->fib_OwnerGID; + buf->st_rdev=0; + buf->st_size=fib->fib_Size; + buf->st_atime=buf->st_mtime=buf->st_ctime= + ((fib->fib_Date.ds_Days+2922)*1440+fib->fib_Date.ds_Minute)*60+ + fib->fib_Date.ds_Tick/TICKS_PER_SECOND; + buf->st_spare1=buf->st_spare2=buf->st_spare3=0; + buf->st_blksize=512; + buf->st_blocks=fib->fib_NumBlocks; + return 0; +} diff --git a/libnix/sources/nix/extra/access.c b/libnix/sources/nix/extra/access.c new file mode 100755 index 0000000..acb2c13 --- /dev/null +++ b/libnix/sources/nix/extra/access.c @@ -0,0 +1,24 @@ +#include +#include +#include +#include + +extern void __seterrno(void); +extern char *__amigapath(const char *path); + +int access (const char *name,int mode) +{ BPTR lock; + +#ifdef IXPATHS + if((name=__amigapath(name))==NULL) + return -1; +#endif + + lock=Lock((char *)name,mode&(O_WRONLY|O_RDWR)?ACCESS_WRITE:ACCESS_READ); + if(lock!=0l) + { UnLock(lock); + return 0; + }else + { __seterrno(); + return -1; } +} diff --git a/libnix/sources/nix/extra/bcmp.c b/libnix/sources/nix/extra/bcmp.c new file mode 100755 index 0000000..3317fbb --- /dev/null +++ b/libnix/sources/nix/extra/bcmp.c @@ -0,0 +1,3 @@ +#include + +ALIAS(bcmp,memcmp); diff --git a/libnix/sources/nix/extra/chdir.c b/libnix/sources/nix/extra/chdir.c new file mode 100755 index 0000000..fc2b14c --- /dev/null +++ b/libnix/sources/nix/extra/chdir.c @@ -0,0 +1,43 @@ +#include +#include +#include +#include + +extern void __seterrno(void); + +static BPTR oldlock; +static int havelock=0; + +int chdir(const char *path) +{ + BPTR fl; + int ret; + + if ((fl=Lock((STRPTR)path,SHARED_LOCK))) + { + UnLock(CurrentDir(fl)); ret=0; + } + else + { + __seterrno(); ret=-1; + } + return ret; +} + +void __initchdir(void) +{ + BPTR fl; + + if (!(fl=Lock("",SHARED_LOCK))) + exit(20); + oldlock=CurrentDir(fl); + havelock=1; +} + +void __exitchdir(void) +{ + if (havelock) UnLock(CurrentDir(oldlock)); +} + +ADD2INIT(__initchdir,-35); +ADD2EXIT(__exitchdir,-35); diff --git a/libnix/sources/nix/extra/chmod.c b/libnix/sources/nix/extra/chmod.c new file mode 100755 index 0000000..fc28af6 --- /dev/null +++ b/libnix/sources/nix/extra/chmod.c @@ -0,0 +1,29 @@ +#include +#include +#include +#include + +extern void __seterrno(void); +extern char *__amigapath(const char *path); + +int chmod(const char *name, mode_t mode) +{ int ret; + +#ifdef IXPATHS + if((name=__amigapath(name))==NULL) + return -1; +#endif + + if ((ret=~(SetProtection((STRPTR)name,((mode&S_IRUSR?0:FIBF_READ)| + (mode&S_IWUSR?0:FIBF_WRITE|FIBF_DELETE)| + (mode&S_IXUSR?0:FIBF_EXECUTE)| + (mode&S_IRGRP?FIBF_GRP_READ:0)| + (mode&S_IWGRP?FIBF_GRP_WRITE|FIBF_GRP_DELETE:0)| + (mode&S_IXGRP?FIBF_GRP_EXECUTE:0)| + (mode&S_IROTH?FIBF_OTR_READ:0)| + (mode&S_IWOTH?FIBF_OTR_WRITE|FIBF_OTR_DELETE:0)| + (mode&S_IXOTH?FIBF_OTR_EXECUTE:0)))))) + __seterrno(); + + return ret; +} diff --git a/libnix/sources/nix/extra/creat.c b/libnix/sources/nix/extra/creat.c new file mode 100755 index 0000000..f8c5181 --- /dev/null +++ b/libnix/sources/nix/extra/creat.c @@ -0,0 +1,8 @@ +#include + +extern void __seterrno(void); + +int creat(const char *path, mode_t mode) +{ + return open(path, O_CREAT | O_TRUNC | O_WRONLY, mode); +} diff --git a/libnix/sources/nix/extra/dirent.c b/libnix/sources/nix/extra/dirent.c new file mode 100755 index 0000000..68f0926 --- /dev/null +++ b/libnix/sources/nix/extra/dirent.c @@ -0,0 +1,82 @@ +#include +#include +#include +#include +#include +#include + +DIR *opendir(const char *dirname) +{ + DIR *dirp; + + if ((dirp=(DIR *)AllocVec(sizeof(DIR),MEMF_PUBLIC)) != NULL) + { + if ((dirp->d_lock=(Lock((STRPTR)dirname,SHARED_LOCK))) != 0ul) + { + dirp->d_count=0; dirp->d_more = DOSTRUE; + + if ((dirp->d_eac=AllocDosObject(DOS_EXALLCONTROL,NULL)) != NULL) + { +#if 0 + dirp->d_eac->eac_LastKey=0; + dirp->d_eac->eac_MatchString=NULL; + dirp->d_eac->eac_MatchFunc=NULL; +#endif + if (Examine(dirp->d_lock,&dirp->d_info)) + { + if (dirp->d_info.fib_EntryType>=0) + return dirp; + } + FreeDosObject(DOS_EXALLCONTROL,dirp->d_eac); + } + UnLock(dirp->d_lock); + } + FreeVec(dirp); dirp=NULL; + } + return dirp; +} + +struct dirent *readdir(DIR *dirp) +{ + struct dirent *result; + + if (dirp->d_count==0 && dirp->d_more!=DOSFALSE) + { + dirp->d_more=ExAll(dirp->d_lock,(APTR)&dirp->d_ead[0],sizeof(dirp->d_ead),ED_NAME,dirp->d_eac); + dirp->current=(struct ExAllData *)&dirp->d_ead[0]; + dirp->d_count=dirp->d_eac->eac_Entries; + } + + result = NULL; + + if (dirp->d_count) + { + dirp->dd_ent.d_fileno = dirp->dd_ent.d_reclen = 1; + strcpy(dirp->dd_ent.d_name,dirp->current->ed_Name); + dirp->dd_ent.d_namlen = strlen(dirp->dd_ent.d_name); + dirp->current=dirp->current->ed_Next; + dirp->d_count--; + result=&dirp->dd_ent; + } + return result; +} + +void rewinddir(DIR *dirp) +{ + if (dirp->d_more!=DOSFALSE) + do + { + dirp->d_more=ExAll(dirp->d_lock,(APTR)&dirp->d_ead[0],sizeof(dirp->d_ead),ED_NAME,dirp->d_eac); + } + while(dirp->d_more!=DOSFALSE); + dirp->d_count=0; dirp->d_more = DOSTRUE; dirp->d_eac->eac_LastKey=0; +} + +int closedir(DIR *dirp) +{ + rewinddir(dirp); + FreeDosObject(DOS_EXALLCONTROL,dirp->d_eac); + UnLock(dirp->d_lock); + FreeVec(dirp); + return 0; +} diff --git a/libnix/sources/nix/extra/dotimer.c b/libnix/sources/nix/extra/dotimer.c new file mode 100755 index 0000000..4a9cc2e --- /dev/null +++ b/libnix/sources/nix/extra/dotimer.c @@ -0,0 +1,35 @@ +#include +#include +#include + +#define NEWLIST(l) ((l)->lh_Head = (struct Node *)&(l)->lh_Tail, \ + (l)->lh_TailPred = (struct Node *)&(l)->lh_Head) + +void dotimer(ULONG unit,ULONG timercmd,struct timeval *t) +{ struct PortIO { + struct timerequest treq; + struct MsgPort port; + } *portio; + + if ((portio=(struct PortIO *)AllocMem(sizeof(*portio),MEMF_CLEAR|MEMF_PUBLIC))) { + portio->port.mp_Node.ln_Type=NT_MSGPORT; + if ((BYTE)(portio->port.mp_SigBit=AllocSignal(-1))>=0) { + portio->port.mp_SigTask=FindTask(NULL); + NEWLIST(&portio->port.mp_MsgList); + portio->treq.tr_node.io_Message.mn_Node.ln_Type=NT_REPLYMSG; + portio->treq.tr_node.io_Message.mn_ReplyPort=&portio->port; + if (!(OpenDevice(TIMERNAME,unit,&portio->treq.tr_node,0))) { + portio->treq.tr_node.io_Command=timercmd; + portio->treq.tr_time.tv_secs =t->tv_secs; + portio->treq.tr_time.tv_micro=t->tv_micro; + if (!DoIO(&portio->treq.tr_node)) { + t->tv_secs =portio->treq.tr_time.tv_secs; + t->tv_micro=portio->treq.tr_time.tv_micro; + } + CloseDevice(&portio->treq.tr_node); + } + FreeSignal(portio->port.mp_SigBit); + } + FreeMem(portio,sizeof(struct PortIO)); + } +} diff --git a/libnix/sources/nix/extra/fdtofh.c b/libnix/sources/nix/extra/fdtofh.c new file mode 100755 index 0000000..37b4e8b --- /dev/null +++ b/libnix/sources/nix/extra/fdtofh.c @@ -0,0 +1,14 @@ +/* + * Get the AmigaDOS FileHandle from the filedescriptor. + * Be careful when mixing both kinds of I/O (flush() between changing). + * + * DICE has such a function SAS has not. + * It's not ANSI but it's encapsulated and may be useful - so why not :-). + * + */ +unsigned long *__stdfiledes; + +unsigned long fdtofh(int filedescriptor) +{ + return __stdfiledes[filedescriptor]; +} diff --git a/libnix/sources/nix/extra/fstat.c b/libnix/sources/nix/extra/fstat.c new file mode 100755 index 0000000..d1d0b6a --- /dev/null +++ b/libnix/sources/nix/extra/fstat.c @@ -0,0 +1,65 @@ +#include +#include +#include +#include +#include + +extern void __seterrno(void); + +extern int __stat(struct stat *buf,struct FileInfoBlock *fib); + +extern unsigned long *__stdfiledes; + +int fstat(int d,struct stat *buf) +{ +#if defined (__GNUC__) + #undef DOS_BASE_NAME + #define DOS_BASE_NAME dosbase + struct DosLibrary *dosbase = DOSBase; +#endif + struct FileInfoBlock *fib; + LONG pos,len; + BPTR fh; + + if (/*dst_mode = S_IFCHR | 0777; + buf->st_nlink = 1; + buf->st_blksize = 512; + /*buf->st_blocks = 0;*/ + + if (((struct FileHandle *)BADDR(fh))->fh_Type != NULL) + { + if (!ExamineFH(fh,fib)) + { + len = 0; pos = Seek(fh,0,OFFSET_END); + if (pos >= 0 && (IoErr() != ERROR_ACTION_NOT_KNOWN)) + len = Seek(fh,pos,OFFSET_BEGINNING); + + fib->fib_DiskKey = (ino_t)~((LONG)fh); + fib->fib_DirEntryType = -1; + fib->fib_Size = len; + fib->fib_Protection = 0xff0; + fib->fib_NumBlocks = ((len + 511) >> 9); + DateStamp(&fib->fib_Date); + } + + __stat(buf,fib); + + Seek(fh,0,OFFSET_CURRENT); + if (IoErr()) + buf->st_mode = ((buf->st_mode & ~S_IFREG) | S_IFCHR); + } + + FreeDosObject(DOS_FIB,fib); return 0; +} diff --git a/libnix/sources/nix/extra/getcwd.c b/libnix/sources/nix/extra/getcwd.c new file mode 100755 index 0000000..cd5b06f --- /dev/null +++ b/libnix/sources/nix/extra/getcwd.c @@ -0,0 +1,20 @@ +#include +#include +#include +#include + +extern void __seterrno(); + +char *getcwd(char *buf,size_t size) +{ + if (buf!=NULL || (buf=(char *)malloc(size))!=NULL) + { + if (GetCurrentDirName(buf,(ULONG)size)==DOSFALSE) + { + __seterrno(); buf=NULL; + } + } + else + errno=ENOMEM; + return buf; +} diff --git a/libnix/sources/nix/extra/getpid.c b/libnix/sources/nix/extra/getpid.c new file mode 100755 index 0000000..ff0de0f --- /dev/null +++ b/libnix/sources/nix/extra/getpid.c @@ -0,0 +1,7 @@ +#include +#include + +pid_t getpid(void) +{ + return (pid_t)FindTask(NULL); +} diff --git a/libnix/sources/nix/extra/getppid.c b/libnix/sources/nix/extra/getppid.c new file mode 100755 index 0000000..7826545 --- /dev/null +++ b/libnix/sources/nix/extra/getppid.c @@ -0,0 +1,6 @@ +#include + +pid_t getppid(void) +{ + return 1; /* init ;-) */ +} diff --git a/libnix/sources/nix/extra/getrusage.c b/libnix/sources/nix/extra/getrusage.c new file mode 100755 index 0000000..f172d61 --- /dev/null +++ b/libnix/sources/nix/extra/getrusage.c @@ -0,0 +1,52 @@ +#include +#include +#include +#include +#include +#include + +extern void timer(long *); + +/* +** store system time at startup. getrusage will return +** (system time - time at startup) as the user time. +*/ + +static long initclock[2]; + +void __inittimer() +{ + timer(initclock); +} + +ADD2INIT(__inittimer,1); + +int getrusage(int who, struct rusage *rusage) +{ + static struct rusage r0 = + { {0, 0}, {0, 0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + long clock[2]; + int status = 0; + + switch(who) { + case RUSAGE_SELF: + timer(clock); + clock[0] -= initclock[0]; + clock[1] -= initclock[1]; + if (clock[1] < 0) { + clock[1] += 1000000; + clock[0] --; + } + memcpy(rusage,&r0,sizeof(struct rusage)); + rusage->ru_utime.tv_sec = clock[0]; + rusage->ru_utime.tv_usec = clock[1]; + break; + case RUSAGE_CHILDREN: + memcpy(rusage,&r0,sizeof(struct rusage)); + break; + default: + errno = EINVAL; + status = -1; + } + return status; +} diff --git a/libnix/sources/nix/extra/getw.c b/libnix/sources/nix/extra/getw.c new file mode 100755 index 0000000..e7933af --- /dev/null +++ b/libnix/sources/nix/extra/getw.c @@ -0,0 +1,14 @@ +/* Read a long word into a file -- returns EOF on error, or when the word + that was read is equal to EOF!!! */ + +#include + +int getw(FILE *f) +{ + int x; + + if (fread((char *)&x, sizeof(x), 1, f) != 1) + return EOF; + else + return x; +} diff --git a/libnix/sources/nix/extra/getwd.c b/libnix/sources/nix/extra/getwd.c new file mode 100755 index 0000000..976528c --- /dev/null +++ b/libnix/sources/nix/extra/getwd.c @@ -0,0 +1,7 @@ +#include +#include + +char *getwd(char *buf) +{ + return getcwd(buf,MAXPATHLEN); +} diff --git a/libnix/sources/nix/extra/mkdir.c b/libnix/sources/nix/extra/mkdir.c new file mode 100755 index 0000000..df88a13 --- /dev/null +++ b/libnix/sources/nix/extra/mkdir.c @@ -0,0 +1,22 @@ +#include +#include +#include +#include + +extern void __seterrno(void); + +int mkdir(const char *name, mode_t mode) +{ + BPTR fl; + int ret; + + if ((fl=CreateDir((STRPTR)name))) + { + UnLock(fl); ret=chmod(name,mode); + } + else + { + __seterrno(); ret=-1; + } + return ret; +} diff --git a/libnix/sources/nix/extra/mktemp.c b/libnix/sources/nix/extra/mktemp.c new file mode 100755 index 0000000..a4703fc --- /dev/null +++ b/libnix/sources/nix/extra/mktemp.c @@ -0,0 +1,25 @@ +#include +#include +#include +#include "strsup.h" + +char *mktemp(char *buf) +{ + long pid = (long)FindTask(0L); + char *c = buf + strlen(buf); + + while (*--c == 'X') { + *c = pid % 10 + '0'; + pid /= 10; + } + c++; + if (*c) { + for(*c='A'; *c <= 'Z'; (*c)++) { + if (access(buf, 0)) { + return buf; + } + } + *c = 0; + } + return buf; +} diff --git a/libnix/sources/nix/extra/putw.c b/libnix/sources/nix/extra/putw.c new file mode 100755 index 0000000..e2c080c --- /dev/null +++ b/libnix/sources/nix/extra/putw.c @@ -0,0 +1,11 @@ +/* Write a long word to a file */ + +#include + +int putw(int w, FILE *f) +{ + if (fwrite((char *)&w, sizeof(w), 1, f) != 1) + return EOF; + else + return 0; +} diff --git a/libnix/sources/nix/extra/rmdir.c b/libnix/sources/nix/extra/rmdir.c new file mode 100755 index 0000000..9645553 --- /dev/null +++ b/libnix/sources/nix/extra/rmdir.c @@ -0,0 +1,3 @@ +#include + +ALIAS(rmdir,remove); diff --git a/libnix/sources/nix/extra/setbuffer.c b/libnix/sources/nix/extra/setbuffer.c new file mode 100755 index 0000000..43e5185 --- /dev/null +++ b/libnix/sources/nix/extra/setbuffer.c @@ -0,0 +1,5 @@ +#include +#include + +int setbuffer(FILE *stream,char *buf,size_t size) +{ return setvbuf(stream,buf,buf!=NULL?_IOFBF:_IONBF,size); } diff --git a/libnix/sources/nix/extra/setlinebuf.c b/libnix/sources/nix/extra/setlinebuf.c new file mode 100755 index 0000000..8396655 --- /dev/null +++ b/libnix/sources/nix/extra/setlinebuf.c @@ -0,0 +1,6 @@ +#include + +int setlinebuf(FILE *f) +{ + return setvbuf(f, NULL, _IOLBF, 0); +} diff --git a/libnix/sources/nix/extra/sleep.c b/libnix/sources/nix/extra/sleep.c new file mode 100755 index 0000000..dea3b28 --- /dev/null +++ b/libnix/sources/nix/extra/sleep.c @@ -0,0 +1,12 @@ +#include + +extern void dotimer(ULONG,ULONG,struct timeval *); + +void sleep(int secs) +{ struct timeval tv; + + if ((int)(tv.tv_secs=secs)>0) + { tv.tv_micro=0; + dotimer(UNIT_VBLANK,TR_ADDREQUEST,&tv); + } +} diff --git a/libnix/sources/nix/extra/stat.c b/libnix/sources/nix/extra/stat.c new file mode 100755 index 0000000..9fe5e3e --- /dev/null +++ b/libnix/sources/nix/extra/stat.c @@ -0,0 +1,48 @@ +#include +#include +#include +#include +#include +#include + +extern int __stat(struct stat *buf,struct FileInfoBlock *fib); +extern void __seterrno(void); +extern char *__amigapath(const char *path); + +int stat(const char *name,struct stat *buf) +{ APTR oldwin,*wptr=&((struct Process *)FindTask(NULL))->pr_WindowPtr; + struct FileInfoBlock *fib; + BPTR lock; + int ret=-1; + +#ifdef IXPATHS + if((name=__amigapath(name))==NULL) + return -1; +#endif + + /* avoid possible dos-requesters ;-( */ + + oldwin=*wptr; *wptr=(APTR)ret; + + if((lock=Lock((STRPTR)name,SHARED_LOCK))!=0) + { + if((fib=(struct FileInfoBlock *)AllocDosObject(DOS_FIB,NULL))!=NULL) + { if(Examine(lock,fib)!=DOSFALSE) + ret=__stat(buf,fib); + else + __seterrno(); + FreeDosObject(DOS_FIB,fib); + } + else + __seterrno(); + UnLock(lock); + } + else + __seterrno(); + + *wptr=oldwin; + + return ret; +} + +ALIAS(lstat,stat); diff --git a/libnix/sources/nix/extra/stpcpy.c b/libnix/sources/nix/extra/stpcpy.c new file mode 100755 index 0000000..299ff30 --- /dev/null +++ b/libnix/sources/nix/extra/stpcpy.c @@ -0,0 +1,4 @@ +char *stpcpy(char *dest,char *source) +{ + while((*dest++=*source++)); return(dest-1); +} diff --git a/libnix/sources/nix/extra/strdup.c b/libnix/sources/nix/extra/strdup.c new file mode 100755 index 0000000..915ca0e --- /dev/null +++ b/libnix/sources/nix/extra/strdup.c @@ -0,0 +1,12 @@ +#include +#include +#include + +char *strdup(const char *s) +{ + char *s1; + + if ((s1=malloc(strlen_plus_one(s)))) + strcpy(s1,s); + return s1; +} diff --git a/libnix/sources/nix/extra/stricmp.c b/libnix/sources/nix/extra/stricmp.c new file mode 100755 index 0000000..87d9880 --- /dev/null +++ b/libnix/sources/nix/extra/stricmp.c @@ -0,0 +1,10 @@ +#include +#include +#include + +int stricmp(const char *s1,const char *s2) +{ + return Stricmp((STRPTR)s1,(STRPTR)s2); +} + +ALIAS(strcasecmp,stricmp); diff --git a/libnix/sources/nix/extra/strlower.c b/libnix/sources/nix/extra/strlower.c new file mode 100755 index 0000000..b7f4de2 --- /dev/null +++ b/libnix/sources/nix/extra/strlower.c @@ -0,0 +1,18 @@ +#include +#include + +char *strlower(char *s) +{ + unsigned char *s1; + + s1=(unsigned char *)s; + while(*s1) + { + if (isupper(*s1)) + *s1+='a'-'A'; + s1++; + } + return s; +} + +ALIAS(strlwr,strlower); diff --git a/libnix/sources/nix/extra/strnicmp.c b/libnix/sources/nix/extra/strnicmp.c new file mode 100755 index 0000000..13f46d4 --- /dev/null +++ b/libnix/sources/nix/extra/strnicmp.c @@ -0,0 +1,11 @@ +#include +#include +#include + +int strnicmp(const char *s1,const char *s2,size_t len) +{ + + return Strnicmp((STRPTR)s1,(STRPTR)s2,(LONG)len); +} + +ALIAS(strncasecmp,strnicmp); diff --git a/libnix/sources/nix/extra/strupper.c b/libnix/sources/nix/extra/strupper.c new file mode 100755 index 0000000..138765e --- /dev/null +++ b/libnix/sources/nix/extra/strupper.c @@ -0,0 +1,18 @@ +#include +#include + +char *strupper(char *s) +{ + unsigned char *s1; + + s1=(unsigned char *)s; + while(*s1) + { + if (islower(*s1)) + *s1-='a'-'A'; + s1++; + } + return s; +} + +ALIAS(strupr,strupper); diff --git a/libnix/sources/nix/extra/timer.c b/libnix/sources/nix/extra/timer.c new file mode 100755 index 0000000..c01b2e1 --- /dev/null +++ b/libnix/sources/nix/extra/timer.c @@ -0,0 +1,8 @@ +#include + +extern void dotimer(ULONG,ULONG,struct timeval *); + +void timer(long clock[2]) +{ + dotimer(UNIT_VBLANK,TR_GETSYSTIME,(struct timeval *)&clock[0]); +} diff --git a/libnix/sources/nix/extra/times.c b/libnix/sources/nix/extra/times.c new file mode 100755 index 0000000..54ca8be --- /dev/null +++ b/libnix/sources/nix/extra/times.c @@ -0,0 +1,38 @@ +#include +#include +#include +#include +#include + +clock_t times(struct tms *tp) +{ + struct rusage r1, r2; + clock_t tim; + int status; + + status = getrusage(RUSAGE_SELF, &r1); + if (status != 0) { + return status; + } + status = getrusage(RUSAGE_CHILDREN, &r2); + if (status != 0) { + return status; + } + + tim = time(0L); + if (errno != 0) { + return tim; + } + + tp->tms_utime = r1.ru_utime.tv_sec * CLK_TCK + + (r1.ru_utime.tv_usec * CLK_TCK) /1000000; + tp->tms_cutime = 0; + tp->tms_stime = r1.ru_stime.tv_sec * CLK_TCK + + (r1.ru_stime.tv_usec * CLK_TCK) / 1000000; + tp->tms_cstime = 0; + /* The value we are supposed to return does not fit in 32 bits. + Still, it is useful if you are interested in time differences + in CLK_TCKths of a second. + */ + return tim * CLK_TCK; +} diff --git a/libnix/sources/nix/extra/unlink.c b/libnix/sources/nix/extra/unlink.c new file mode 100755 index 0000000..fc0877a --- /dev/null +++ b/libnix/sources/nix/extra/unlink.c @@ -0,0 +1,3 @@ +#include + +ALIAS(unlink,remove); diff --git a/libnix/sources/nix/extra/usleep.c b/libnix/sources/nix/extra/usleep.c new file mode 100755 index 0000000..d52facb --- /dev/null +++ b/libnix/sources/nix/extra/usleep.c @@ -0,0 +1,13 @@ +#include +#include + +extern void dotimer(ULONG,ULONG,struct timeval *); + +void usleep(unsigned int tim) +{ struct timeval tv; + + tv.tv_secs = tim / 1000000; + tv.tv_micro = tim % 1000000; + + dotimer(UNIT_VBLANK,TR_ADDREQUEST,&tv); +} diff --git a/libnix/sources/nix/extra/utime.c b/libnix/sources/nix/extra/utime.c new file mode 100755 index 0000000..5c5d45c --- /dev/null +++ b/libnix/sources/nix/extra/utime.c @@ -0,0 +1,17 @@ +#include +#include + +int utime(const char *file, const struct utimbuf *timep) +{ + struct timeval times[2],*t=NULL; + + if (timep != NULL) + { + t=×[0]; + t[0].tv_sec = timep->actime; + t[0].tv_usec = 0; + t[1].tv_sec = timep->modtime; + t[1].tv_usec = 0; + } + return utimes(file, t); +} diff --git a/libnix/sources/nix/extra/utimes.c b/libnix/sources/nix/extra/utimes.c new file mode 100755 index 0000000..5d7d51b --- /dev/null +++ b/libnix/sources/nix/extra/utimes.c @@ -0,0 +1,50 @@ +#include +#include +#include +#include +#include +#include + +#define MAX(x,y) (((x) > (y)) ? (x) : (y)) + +#define SECSPERDAY (24L * 60L * 60L) + +int utimes(const char *file, const struct timeval *times) +{ + struct timeval modtime; + struct DateStamp d; + time_t t; + + if (times) { + modtime = times[1]; + if (modtime.tv_usec > 1000000) { + modtime.tv_sec += (modtime.tv_usec / 1000000); + modtime.tv_usec %= 1000000; + } + t = modtime.tv_sec; +#if 0 + extern long timezone; +#endif + t -= (2922L * SECSPERDAY); /* Datestamps start from Jan 1, 1978, unix + time from Jan 1, 1970, i.e., 2922 days + earlier! */ +#if 0 + t -= timezone; /* Adjust for local time */ +#endif + d.ds_Days = t / SECSPERDAY; + t %= SECSPERDAY; + d.ds_Minute = t / 60L; + t %= 60L; + d.ds_Tick = t * 50 + (modtime.tv_usec / 20000); + }else{ + DateStamp(&d); + } + + if (SetFileDate((STRPTR)file, &d)) { + errno = 0; + return 0; + }else{ + errno = ENOENT; + return -1; + } +} diff --git a/libnix/sources/nix/locale/__decimalpoint.c b/libnix/sources/nix/locale/__decimalpoint.c new file mode 100755 index 0000000..caedfc1 --- /dev/null +++ b/libnix/sources/nix/locale/__decimalpoint.c @@ -0,0 +1 @@ +unsigned char *__decimalpoint="."; diff --git a/libnix/sources/nix/locale/__lconv.c b/libnix/sources/nix/locale/__lconv.c new file mode 100755 index 0000000..df6f724 --- /dev/null +++ b/libnix/sources/nix/locale/__lconv.c @@ -0,0 +1,3 @@ +#include + +struct lconv __lconv; diff --git a/libnix/sources/nix/locale/__localevec.c b/libnix/sources/nix/locale/__localevec.c new file mode 100755 index 0000000..4936f5e --- /dev/null +++ b/libnix/sources/nix/locale/__localevec.c @@ -0,0 +1,14 @@ +#include + +/* This is the vector of Locales for the different locale types. + * Since the default locale is not NULL, NULL means "C" locale. + * This is the default if locale.library could not be opened + * or setlocale is never referenced. + */ + +struct Locale *__localevec[5]= +{ NULL,NULL,NULL,NULL,NULL }; + +/* If you need __localevec you need LocaleBase and vice versa. + */ +struct Library *LocaleBase=NULL; diff --git a/libnix/sources/nix/locale/localeconv.c b/libnix/sources/nix/locale/localeconv.c new file mode 100755 index 0000000..d2194bd --- /dev/null +++ b/libnix/sources/nix/locale/localeconv.c @@ -0,0 +1,6 @@ +#include + +extern struct lconv __lconv; + +struct lconv *localeconv(void) +{ return &__lconv; } diff --git a/libnix/sources/nix/locale/setlocale.c b/libnix/sources/nix/locale/setlocale.c new file mode 100755 index 0000000..fe4bd0c --- /dev/null +++ b/libnix/sources/nix/locale/setlocale.c @@ -0,0 +1,194 @@ +#include +#include +#include +#include +#include +#ifdef __GNUC__ /* This is very sad :-( */ +#undef BITSPERBYTE +#undef MAXINT +#undef MININT +#endif +#include +#include +#include +#include +#include + +extern struct LocaleBase *LocaleBase; +extern char __localename[]; +extern struct Locale *__localevec[]; + +/* for LC_CTYPE */ +extern const unsigned char __ctype[]; +extern const unsigned char *_ctype_; +static unsigned char *ctype; + +/* for LC_NUMERIC */ +extern unsigned char *__decimalpoint; + +/* for LC_TIME */ +extern long __gmtoffset; +extern int __dstflag; + +extern struct lconv __lconv; + +char *setlocale(int category,const char *name) +{ static char *string=NULL; + size_t i,a,b; + struct Locale *vec[5]; + unsigned char *s1,*s2,c; + + if(string!=NULL) /* Free string if possible */ + { free(string); + string=NULL; } + + if(category<0||category>5) + return NULL; + + if(category==LC_ALL) + { a=0; + b=4; } + else + a=b=category-1; + + if(name==NULL) /* return name of current locale */ + { size_t s=0; + for(i=a;i<=b;i++) + if(__localevec[i]!=NULL) + s+=strlen(__localevec[i]->loc_LocaleName); + else + s++; /* "C" locale */ + + if((string=malloc(s+b-a+1))==NULL) + return NULL; + + string[0]='\0'; + for(i=a;i<=b;i++) + { if(__localevec[i]!=NULL) + strcat(string,__localevec[i]->loc_LocaleName); + else + strcat(string,"C"); + if(i!=b) + strcat(string,"\n"); + } + return string; + } + + if((string=malloc(strlen_plus_one(name)))==NULL) /* gets freed next time */ + return NULL; + strcpy(string,name); + + s1=s2=string; + for(i=a;i<=b;i++) + { while(*s2!='\0'&&*s2!='\n') + s2++; + c=*s2; + *s2='\0'; + if(LocaleBase==NULL||(s1[0]=='C'&&s1[1]=='\0')) /* This is the only place */ + vec[i]=NULL; /* LocaleBase gets tested for NULL */ + else + if((vec[i]=OpenLocale(s1[0]=='\0'?NULL:s1))==NULL) + { for(;i-->a;) + CloseLocale(vec[i]); + return NULL; } + *s2=c; + if(c=='\0') + s2=string; + s1=s2; + } + + for(i=a;i<=b;i++) + { if(__localevec[i]!=NULL) + CloseLocale(__localevec[i]); + __localevec[i]=vec[i]; + } + + if(__localevec[LC_CTYPE-1]!=NULL) + { struct Locale *locale=__localevec[LC_CTYPE-1]; + ctype[0]=0; + for(i=0;i<256;i++) + ctype[i+1]=((IsPrint(locale,i)&&!IsGraph(locale,i))?128:0)| + (IsXDigit(locale,i)?64:0)|(IsCntrl(locale,i)?32:0)| + (IsPunct(locale,i)?16:0)|(IsSpace(locale,i)?8:0)| + (IsDigit(locale,i)?4:0)|(IsLower(locale,i)?2:0)| + (IsUpper(locale,i)?1:0); + _ctype_=ctype; + }else + _ctype_=__ctype; + + if(__localevec[LC_MONETARY-1]!=NULL) + { struct Locale *locale=__localevec[LC_MONETARY-1]; + __lconv.int_curr_symbol =locale->loc_MonIntCS; + __lconv.currency_symbol =locale->loc_MonCS; + __lconv.mon_decimal_point=locale->loc_MonDecimalPoint; + __lconv.mon_thousands_sep=locale->loc_MonGroupSeparator; + __lconv.mon_grouping =locale->loc_MonFracGrouping; + __lconv.positive_sign =locale->loc_MonPositiveSign; + __lconv.negative_sign =locale->loc_MonNegativeSign; + __lconv.int_frac_digits =locale->loc_MonIntFracDigits; + __lconv.frac_digits =locale->loc_MonFracDigits; + __lconv.p_cs_precedes =locale->loc_MonPositiveCSPos; + __lconv.p_sep_by_space =locale->loc_MonPositiveSpaceSep; + __lconv.p_sign_posn =locale->loc_MonPositiveSignPos; + __lconv.n_cs_precedes =locale->loc_MonNegativeCSPos; + __lconv.n_sep_by_space =locale->loc_MonNegativeSpaceSep; + __lconv.n_sign_posn =locale->loc_MonNegativeSignPos; + }else + { __lconv.int_curr_symbol =""; + __lconv.currency_symbol =""; + __lconv.mon_decimal_point=""; + __lconv.mon_thousands_sep=""; + __lconv.mon_grouping =""; + __lconv.positive_sign =""; + __lconv.negative_sign =""; + __lconv.int_frac_digits =CHAR_MAX; + __lconv.frac_digits =CHAR_MAX; + __lconv.p_cs_precedes =CHAR_MAX; + __lconv.p_sep_by_space =CHAR_MAX; + __lconv.p_sign_posn =CHAR_MAX; + __lconv.n_cs_precedes =CHAR_MAX; + __lconv.n_sep_by_space =CHAR_MAX; + __lconv.n_sign_posn =CHAR_MAX; + } + + if(__localevec[LC_NUMERIC-1]!=NULL) + { struct Locale *locale=__localevec[LC_NUMERIC-1]; + __lconv.decimal_point=locale->loc_DecimalPoint; + __lconv.thousands_sep=locale->loc_GroupSeparator; + }else + { __lconv.decimal_point="."; + __lconv.thousands_sep=""; + } + __decimalpoint=__lconv.decimal_point; + + if(__localevec[LC_TIME-1]!=NULL) + __gmtoffset=__localevec[LC_TIME-1]->loc_GMTOffset; + else + __gmtoffset=0; + + return (char *)name; +} + +void __initlocale(void) +{ if ((ctype=malloc(257))!=NULL) + { + LocaleBase=(struct LocaleBase *)OpenLibrary(__localename,0); /* Don't give up if this failes */ + + if (setlocale(LC_ALL,"")!=NULL) /* Set the default locale */ + return; + } + exit(20); +} + +void __exitlocale(void) +{ int i; + for(i=0;i<5;i++) + if(__localevec[i]!=NULL) + CloseLocale(__localevec[i]); + + if(LocaleBase!=NULL) + CloseLibrary((struct Library *)LocaleBase); +} + +ADD2INIT(__initlocale,-10); +ADD2EXIT(__exitlocale,-10); diff --git a/libnix/sources/nix/math/__adddf3.c b/libnix/sources/nix/math/__adddf3.c new file mode 100755 index 0000000..1b369b1 --- /dev/null +++ b/libnix/sources/nix/math/__adddf3.c @@ -0,0 +1,4 @@ +#include + +double __adddf3(double x,double y) +{ return IEEEDPAdd(x,y); } diff --git a/libnix/sources/nix/math/__addsf3.c b/libnix/sources/nix/math/__addsf3.c new file mode 100755 index 0000000..f94c19d --- /dev/null +++ b/libnix/sources/nix/math/__addsf3.c @@ -0,0 +1,4 @@ +#include + +float __addsf3(float x,float y) +{ return IEEESPAdd(x,y); } diff --git a/libnix/sources/nix/math/__divdf3.c b/libnix/sources/nix/math/__divdf3.c new file mode 100755 index 0000000..e29131f --- /dev/null +++ b/libnix/sources/nix/math/__divdf3.c @@ -0,0 +1,4 @@ +#include + +double __divdf3(double x,double y) +{ return IEEEDPDiv(x,y); } diff --git a/libnix/sources/nix/math/__divsf3.c b/libnix/sources/nix/math/__divsf3.c new file mode 100755 index 0000000..23a62de --- /dev/null +++ b/libnix/sources/nix/math/__divsf3.c @@ -0,0 +1,4 @@ +#include + +float __divsf3(float x,float y) +{ return IEEESPDiv(x,y); } diff --git a/libnix/sources/nix/math/__divsi3.c b/libnix/sources/nix/math/__divsi3.c new file mode 100755 index 0000000..c5ae764 --- /dev/null +++ b/libnix/sources/nix/math/__divsi3.c @@ -0,0 +1,23 @@ +#include + +asm(" + .globl _div + .globl _ldiv + .globl ___modsi3 + .globl ___divsi3 + +| D1.L = D0.L % D1.L signed + +___modsi3: moveml sp@(4:W),d0/d1 + jbsr ___divsi4 + movel d1,d0 + rts + +| D0.L = D0.L / D1.L signed + +_div: +_ldiv: +___divsi3: moveml sp@(4:W),d0/d1 +___divsi4: movel "A4(_UtilityBase)",a0 + jmp a0@(-150:W) +"); diff --git a/libnix/sources/nix/math/__eqdf2.c b/libnix/sources/nix/math/__eqdf2.c new file mode 100755 index 0000000..aa37e76 --- /dev/null +++ b/libnix/sources/nix/math/__eqdf2.c @@ -0,0 +1,11 @@ +#include +#include + +signed long __eqdf2(double x,double y) +{ return IEEEDPCmp(x,y); } + +ALIAS(__gedf2,__eqdf2); +ALIAS(__nedf2,__eqdf2); +ALIAS(__gtdf2,__eqdf2); +ALIAS(__ltdf2,__eqdf2); +ALIAS(__ledf2,__eqdf2); diff --git a/libnix/sources/nix/math/__eqsf2.c b/libnix/sources/nix/math/__eqsf2.c new file mode 100755 index 0000000..b5af8ec --- /dev/null +++ b/libnix/sources/nix/math/__eqsf2.c @@ -0,0 +1,11 @@ +#include +#include + +signed long __eqsf2(float x,float y) +{ return IEEESPCmp(x,y); } + +ALIAS(__gesf2,__eqsf2); +ALIAS(__nesf2,__eqsf2); +ALIAS(__gtsf2,__eqsf2); +ALIAS(__ltsf2,__eqsf2); +ALIAS(__lesf2,__eqsf2); diff --git a/libnix/sources/nix/math/__extendsfdf2.c b/libnix/sources/nix/math/__extendsfdf2.c new file mode 100755 index 0000000..61c017f --- /dev/null +++ b/libnix/sources/nix/math/__extendsfdf2.c @@ -0,0 +1,4 @@ +#include + +double __extendsfdf2(float x) +{ return IEEEDPFieee(x); } diff --git a/libnix/sources/nix/math/__fixdfsi.c b/libnix/sources/nix/math/__fixdfsi.c new file mode 100755 index 0000000..03d5010 --- /dev/null +++ b/libnix/sources/nix/math/__fixdfsi.c @@ -0,0 +1,4 @@ +#include + +signed long __fixdfsi(double x) +{ return IEEEDPFix(x); } diff --git a/libnix/sources/nix/math/__fixsfsi.c b/libnix/sources/nix/math/__fixsfsi.c new file mode 100755 index 0000000..b0c9f95 --- /dev/null +++ b/libnix/sources/nix/math/__fixsfsi.c @@ -0,0 +1,4 @@ +#include + +signed long __fixsfsi(float x) +{ return IEEESPFix(x); } diff --git a/libnix/sources/nix/math/__fixunsdfsi.c b/libnix/sources/nix/math/__fixunsdfsi.c new file mode 100755 index 0000000..4c9897d --- /dev/null +++ b/libnix/sources/nix/math/__fixunsdfsi.c @@ -0,0 +1,7 @@ +unsigned long __fixunsdfsi(double x) +{ if(x<0) + return 0; + if(x>=0x80000000u) + return (signed long)(x-0x80000000u)+0x80000000u; + return (signed long)x; +} diff --git a/libnix/sources/nix/math/__fixunssfsi.c b/libnix/sources/nix/math/__fixunssfsi.c new file mode 100755 index 0000000..18c3085 --- /dev/null +++ b/libnix/sources/nix/math/__fixunssfsi.c @@ -0,0 +1,7 @@ +unsigned long __fixunssfsi(float x) +{ if(x<0) + return 0; + if(x>=0x80000000u) + return (signed long)(x-0x80000000u)+0x80000000u; + return (signed long)x; +} diff --git a/libnix/sources/nix/math/__floatsidf.c b/libnix/sources/nix/math/__floatsidf.c new file mode 100755 index 0000000..603a3f2 --- /dev/null +++ b/libnix/sources/nix/math/__floatsidf.c @@ -0,0 +1,4 @@ +#include + +double __floatsidf(signed long x) +{ return IEEEDPFlt(x); } diff --git a/libnix/sources/nix/math/__floatsisf.c b/libnix/sources/nix/math/__floatsisf.c new file mode 100755 index 0000000..fc30bfb --- /dev/null +++ b/libnix/sources/nix/math/__floatsisf.c @@ -0,0 +1,4 @@ +#include + +float __floatsisf(signed long x) +{ return IEEESPFlt(x); } diff --git a/libnix/sources/nix/math/__muldf3.c b/libnix/sources/nix/math/__muldf3.c new file mode 100755 index 0000000..2755613 --- /dev/null +++ b/libnix/sources/nix/math/__muldf3.c @@ -0,0 +1,4 @@ +#include + +double __muldf3(double x,double y) +{ return IEEEDPMul(x,y); } diff --git a/libnix/sources/nix/math/__mulsf3.c b/libnix/sources/nix/math/__mulsf3.c new file mode 100755 index 0000000..a461e1c --- /dev/null +++ b/libnix/sources/nix/math/__mulsf3.c @@ -0,0 +1,4 @@ +#include + +float __mulsf3(float x,float y) +{ return IEEESPMul(x,y); } diff --git a/libnix/sources/nix/math/__mulsi3.c b/libnix/sources/nix/math/__mulsi3.c new file mode 100755 index 0000000..f870c89 --- /dev/null +++ b/libnix/sources/nix/math/__mulsi3.c @@ -0,0 +1,11 @@ +#include + +asm(" + .globl ___mulsi3 + +| D0 = D0 * D1 + +___mulsi3: moveml sp@(4),d0/d1 + movel "A4(_UtilityBase)",a0 + jmp a0@(-138:W) +"); diff --git a/libnix/sources/nix/math/__negdf2.c b/libnix/sources/nix/math/__negdf2.c new file mode 100755 index 0000000..fcca055 --- /dev/null +++ b/libnix/sources/nix/math/__negdf2.c @@ -0,0 +1,4 @@ +#include + +double __negdf2(double x) +{ return IEEEDPNeg(x); } diff --git a/libnix/sources/nix/math/__negsf2.c b/libnix/sources/nix/math/__negsf2.c new file mode 100755 index 0000000..48ddd6d --- /dev/null +++ b/libnix/sources/nix/math/__negsf2.c @@ -0,0 +1,4 @@ +#include + +float __negsf2(float x) +{ return IEEESPNeg(x); } diff --git a/libnix/sources/nix/math/__subdf3.c b/libnix/sources/nix/math/__subdf3.c new file mode 100755 index 0000000..abe69f2 --- /dev/null +++ b/libnix/sources/nix/math/__subdf3.c @@ -0,0 +1,4 @@ +#include + +double __subdf3(double x,double y) +{ return IEEEDPSub(x,y); } diff --git a/libnix/sources/nix/math/__subsf3.c b/libnix/sources/nix/math/__subsf3.c new file mode 100755 index 0000000..546491e --- /dev/null +++ b/libnix/sources/nix/math/__subsf3.c @@ -0,0 +1,4 @@ +#include + +float __subsf3(float x,float y) +{ return IEEESPSub(x,y); } diff --git a/libnix/sources/nix/math/__truncdfsf2.c b/libnix/sources/nix/math/__truncdfsf2.c new file mode 100755 index 0000000..a9d9988 --- /dev/null +++ b/libnix/sources/nix/math/__truncdfsf2.c @@ -0,0 +1,4 @@ +#include + +float __truncdfsf2(double x) +{ return IEEEDPTieee(x); } diff --git a/libnix/sources/nix/math/__udivsi3.c b/libnix/sources/nix/math/__udivsi3.c new file mode 100755 index 0000000..1220933 --- /dev/null +++ b/libnix/sources/nix/math/__udivsi3.c @@ -0,0 +1,19 @@ +#include + +asm(" + .globl ___umodsi3 + .globl ___udivsi3 + +| D1.L = D0.L % D1.L unsigned + +___umodsi3: moveml sp@(4:W),d0/d1 + jbsr ___udivsi4 + movel d1,d0 + rts + +| D0.L = D0.L / D1.L unsigned + +___udivsi3: moveml sp@(4:W),d0/d1 +___udivsi4: movel "A4(_UtilityBase)",a0 + jmp a0@(-156:W) +"); diff --git a/libnix/sources/nix/misc/__request.c b/libnix/sources/nix/misc/__request.c new file mode 100755 index 0000000..23f7f0b --- /dev/null +++ b/libnix/sources/nix/misc/__request.c @@ -0,0 +1,51 @@ +#include + +asm(" + .data + .even + +body: .byte 0,0,0,0 + .word 15,5 + .long 0,0,0 + +ok: .byte 0,0,0,0 + .word 6,3 + .long 0,oktext,0 + + .text +oktext: .byte 79,107,0 + + .even + .globl ___request +___request: + moveml #0x3832,sp@- + movel 4:W,a6 + subal a1,a1 + jsr a6@(-0x126) | FindTask(a1:nam) + movel d0,a1 + moveq #-1,d1 + cmpl a1@(0xb8:W),d1 + jeq l_fail | Dont put requesters up + lea "A4(___intuitionname)",a1 + moveq #0,d0 + jsr a6@(-0x228) | OpenLibrary(a1:nam,d0:ver) + movel d0,d4 + jeq l_fail + lea "A4(ok)",a3 + lea "A4(body)",a1 + subl a2,a2 + movel sp@(28),a1@(12:W) + subl a0,a0 + moveq #0,d0 + moveq #0,d1 + moveq #(640>>4),d2 + lslw #4,d2 + moveq #72,d3 + exg d4,a6 + jsr a6@(-0x15c) | AutoRequest(a0,a1,a2,a3,d0,d1,d2,d3) + movel a6,a1 + movel d4,a6 + jsr a6@(-0x19e) | CloseLibrary(a1:lib) +l_fail: moveml sp@+,#0x4c1c + rts +"); diff --git a/libnix/sources/nix/misc/bcopy.c b/libnix/sources/nix/misc/bcopy.c new file mode 100755 index 0000000..3141922 --- /dev/null +++ b/libnix/sources/nix/misc/bcopy.c @@ -0,0 +1,36 @@ +#include + +/* This is a _fast_ block move routine */ + +void bcopy(const void *s1,void *s2,size_t n) +{ size_t m; + if(!n) + return; + if(s2 + +void bzero(void *b,size_t len) +{ size_t n; + if((unsigned long)b&1) + { *((char *)b)++=0; + len--; } + n=len/sizeof(long); + len-=n*sizeof(long); + while(n--) + *((long *)b)++=0; + while(len--) + *((char *)b)++=0; +} diff --git a/libnix/sources/nix/setjmp/longjmp.c b/libnix/sources/nix/setjmp/longjmp.c new file mode 100755 index 0000000..89d93e7 --- /dev/null +++ b/libnix/sources/nix/setjmp/longjmp.c @@ -0,0 +1,16 @@ +asm(" + .text + .even + .globl _longjmp + +_longjmp: + addql #4,sp | returns to another address + movel sp@+,a0 | get address of jmp_buf + movel sp@+,d0 | get returncode + jne l0 | != 0 -> ok + moveql #1,d0 +l0: movel a0@(48:W),sp | restore sp + movel a0@+,sp@ | set returnaddress + moveml a0@,d2-d7/a2-a6 | restore all registers except scratch and sp + rts +"); diff --git a/libnix/sources/nix/setjmp/setjmp.c b/libnix/sources/nix/setjmp/setjmp.c new file mode 100755 index 0000000..c6eba67 --- /dev/null +++ b/libnix/sources/nix/setjmp/setjmp.c @@ -0,0 +1,12 @@ +asm(" + .text + .even + .globl _setjmp + +_setjmp: + movel sp@(4),a0 | get address of jmp_buf + movel sp@,a0@+ | store returnaddress + moveml d2-d7/a2-a6/sp,a0@ | store all registers except scratch + moveql #0,d0 | return 0 + rts +"); diff --git a/libnix/sources/nix/signal/__chkabort.c b/libnix/sources/nix/signal/__chkabort.c new file mode 100755 index 0000000..c8046bf --- /dev/null +++ b/libnix/sources/nix/signal/__chkabort.c @@ -0,0 +1,9 @@ +#include +#include +#include + +void __chkabort(void) +{ + if (SetSignal(0L,SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) + raise(SIGINT); +} diff --git a/libnix/sources/nix/signal/__signalfunc.c b/libnix/sources/nix/signal/__signalfunc.c new file mode 100755 index 0000000..9474b9d --- /dev/null +++ b/libnix/sources/nix/signal/__signalfunc.c @@ -0,0 +1,4 @@ +#include + +void (*__signalfunc[6])(int)={ NULL }; /* array of signalhandlers */ +int __signalpending=0,__signalmask=0; diff --git a/libnix/sources/nix/signal/raise.c b/libnix/sources/nix/signal/raise.c new file mode 100755 index 0000000..eef9b5d --- /dev/null +++ b/libnix/sources/nix/signal/raise.c @@ -0,0 +1,39 @@ +#include +#include + +extern void (*__signalfunc[])(int); +extern int __signalmask,__signalpending; + +#define wlen(s) s,sizeof(s)-1 + +int raise(int sig) +{ int ret=-1; + + if (!(sig<1||sig>6)) + { + int *mask=&__signalmask,*pending=&__signalpending; + + *pending|=1<<(sig-1); + while(!(*mask&(1<<(sig-1)))&& + (*pending&(1<<(sig-1)))) + { + *pending&=~(1<<(sig-1)); + if(__signalfunc[sig-1]!=SIG_IGN) + { + int oldmask=*mask; + *mask|=1<<(sig-1); + if(__signalfunc[sig-1]==SIG_DFL) + { + if(sig==SIGINT) + { + write(2,wlen("***Break\n")); exit(20); + } + }else + (*__signalfunc[sig-1])(sig); + *mask=oldmask; + } + } + ret=0; + } + return ret; +} diff --git a/libnix/sources/nix/signal/signal.c b/libnix/sources/nix/signal/signal.c new file mode 100755 index 0000000..34c3d4e --- /dev/null +++ b/libnix/sources/nix/signal/signal.c @@ -0,0 +1,17 @@ +#include + +extern void (*__signalfunc[])(int); +extern int __signalmask,__signalpending; + +void (*signal(int sig,void (*func)(int)))(int) +{ + void (*oldfunc)(int); + if(sig<1||sig>6) + return SIG_ERR; + oldfunc=__signalfunc[sig-1]; + __signalfunc[sig-1]=func; + __signalmask&=~(1<<(sig-1)); + if(__signalpending&(1<<(sig-1))) + raise(sig); + return oldfunc; +} diff --git a/libnix/sources/nix/stdio/__fflush.c b/libnix/sources/nix/stdio/__fflush.c new file mode 100755 index 0000000..083ef2d --- /dev/null +++ b/libnix/sources/nix/stdio/__fflush.c @@ -0,0 +1,31 @@ +#include +#include +#include + +int __fflush(FILE *stream) /* fflush exactly one file */ +{ + long size,subsize; + unsigned char *subbuf; + if(stream->flags&0x40) /* Error on stream */ + { errno=EPERM; + return EOF; } + if(stream->flags&8) /* Works only on output streams */ + { + size=stream->p-stream->buffer; /* calculate size */ + subbuf=stream->buffer; + while(size) + { + if((subsize=write(stream->file,subbuf,size))<0) + { + stream->flags|=64; /* error flag */ + return EOF; + } + size-=subsize; + subbuf+=subsize; + } + stream->flags&=~8; /* unset write state */ + stream->outcount=0; + stream->linebufsize=0; + } /* Nothing to be done for input streams */ + return 0; +} diff --git a/libnix/sources/nix/stdio/__srget.c b/libnix/sources/nix/stdio/__srget.c new file mode 100755 index 0000000..f260471 --- /dev/null +++ b/libnix/sources/nix/stdio/__srget.c @@ -0,0 +1,52 @@ +#include +#include +#include + +int __srget(FILE *stream) /* Get next input block */ +{ + if(stream->flags&96) /* Error on stream / EOF */ + { + stream->incount=0; + errno=EPERM; + return EOF; + } + if(stream->flags&8) + { + if(__fflush(stream)) + return EOF; + }else if(stream->tmpp!=NULL) /* File is in ungetc mode */ + { + stream->p=stream->tmpp; + stream->incount=stream->tmpinc; + stream->tmpp=NULL; + if(--stream->incount>=0) + return *stream->p++; + } + if(stream->flags&0x200) /* Is a sscanf buffer */ + return EOF; + if(stream->flags&3) /* Before reading from line- or unbuffered input file */ + { /* fflush all line buffered output files (ANSI) */ + struct filenode *fp=(struct filenode *)__filelist.mlh_Head; + while(fp->node.mln_Succ) + { + if((fp->FILE.flags&9)==9) + __fflush(&fp->FILE); /* Don't return EOF if this fails */ + fp=(struct filenode *)fp->node.mln_Succ; + } + } + stream->flags|=4; + stream->incount=read(stream->file,stream->buffer,stream->bufsize); + if(stream->incount==0) /* EOF found */ + { + stream->flags|=32; + return EOF; + }else if(stream->incount<0) /* Error */ + { + stream->incount=0; + stream->flags|=64; + return EOF; + } + stream->incount--; + stream->p=stream->buffer; + return *stream->p++; +} diff --git a/libnix/sources/nix/stdio/__stdio.c b/libnix/sources/nix/stdio/__stdio.c new file mode 100755 index 0000000..7a9aafe --- /dev/null +++ b/libnix/sources/nix/stdio/__stdio.c @@ -0,0 +1,19 @@ +#include +#include + +static FILE *__files[3]; + +FILE **__sF=__files; /* stdin, stdout, stderr */ + +void __initstdfio(void) +{ FILE **f=__sF; + + if((*f++=fopen((char *)1,NULL))!=NULL) + if((*f++=fopen((char *)2,NULL))!=NULL) + if((*f=fopen((char *)3,NULL))!=NULL) + return; + exit(20); +} + +/* Call our private constructor */ +ADD2INIT(__initstdfio,-10); diff --git a/libnix/sources/nix/stdio/__swbuf.c b/libnix/sources/nix/stdio/__swbuf.c new file mode 100755 index 0000000..081fe19 --- /dev/null +++ b/libnix/sources/nix/stdio/__swbuf.c @@ -0,0 +1,33 @@ +#include +#include + +int __swbuf(int c,FILE *stream) /* Get next output block */ +{ + int out,lbs; + if(stream->flags&0x240) /* sprintf buffer | error on stream */ + { stream->outcount=0; + errno=EPERM; + return EOF; + }else if(stream->flags&4) + { + stream->incount=0; /* throw away input buffer */ + stream->tmpp=NULL; + stream->flags&=~4; + } + lbs=stream->flags&_IOLBF?-stream->bufsize:0; + out=(stream->flags&_IONBF?0:stream->bufsize-1)+lbs; + if(!(stream->flags&8)) /* File wasn't in write mode */ + { stream->p=stream->buffer; /* set buffer */ + stream->outcount=--out; /* and buffercount */ + stream->flags|=8; } /* and write mode */ + *stream->p++=c; /* put this character */ + if(stream->outcount<0&&(stream->outcountp=stream->buffer; /* Set new buffer */ + } + stream->linebufsize=lbs; + stream->outcount=out; + stream->flags|=8; + return c; +} diff --git a/libnix/sources/nix/stdio/clearerr.c b/libnix/sources/nix/stdio/clearerr.c new file mode 100755 index 0000000..958bae0 --- /dev/null +++ b/libnix/sources/nix/stdio/clearerr.c @@ -0,0 +1,4 @@ +#include + +void clearerr(FILE *stream) +{ stream->flags&=~96; } diff --git a/libnix/sources/nix/stdio/feof.c b/libnix/sources/nix/stdio/feof.c new file mode 100755 index 0000000..13d592f --- /dev/null +++ b/libnix/sources/nix/stdio/feof.c @@ -0,0 +1,8 @@ +#include + +#ifdef feof +#undef feof +#endif + +int feof(FILE *stream) +{ return (stream->flags&32)!=0; } diff --git a/libnix/sources/nix/stdio/ferror.c b/libnix/sources/nix/stdio/ferror.c new file mode 100755 index 0000000..46a21f3 --- /dev/null +++ b/libnix/sources/nix/stdio/ferror.c @@ -0,0 +1,8 @@ +#include + +#ifdef ferror +#undef ferror +#endif + +int ferror(FILE *stream) +{ return (stream->flags&64)!=0; } diff --git a/libnix/sources/nix/stdio/fflush.c b/libnix/sources/nix/stdio/fflush.c new file mode 100755 index 0000000..94e97b6 --- /dev/null +++ b/libnix/sources/nix/stdio/fflush.c @@ -0,0 +1,18 @@ +#include +#include +#include + +int fflush(FILE *stream) /* fflush one or all files */ +{ + int retval; + struct MinNode *node,*nextnode; + if(stream!=NULL) + return __fflush(stream); + retval=0; + node=__filelist.mlh_Head; + while((nextnode=node->mln_Succ)!=NULL) + { if(__fflush(&((struct filenode *)node)->FILE)) + retval=EOF; + node=nextnode; } + return retval; +} diff --git a/libnix/sources/nix/stdio/fgetc.c b/libnix/sources/nix/stdio/fgetc.c new file mode 100755 index 0000000..a3ad043 --- /dev/null +++ b/libnix/sources/nix/stdio/fgetc.c @@ -0,0 +1,4 @@ +#include + +int fgetc(FILE *stream) +{ return getc(stream); } diff --git a/libnix/sources/nix/stdio/fgetpos.c b/libnix/sources/nix/stdio/fgetpos.c new file mode 100755 index 0000000..a7f4051 --- /dev/null +++ b/libnix/sources/nix/stdio/fgetpos.c @@ -0,0 +1,4 @@ +#include + +int fsetpos(FILE *stream,fpos_t *pos) +{ return fseek(stream,*pos,SEEK_SET); } diff --git a/libnix/sources/nix/stdio/fgets.c b/libnix/sources/nix/stdio/fgets.c new file mode 100755 index 0000000..7db7502 --- /dev/null +++ b/libnix/sources/nix/stdio/fgets.c @@ -0,0 +1,22 @@ +#include + +char *fgets(char *s,int n,FILE *stream) +{ + int c; + char *s2=s; + while(--n) + { + c=fgetc(stream); + if(c==EOF) + { + if(s2==s) + return NULL; + break; + } + *s2++=c; + if(c=='\n') + break; + } + *s2++='\0'; + return s; +} diff --git a/libnix/sources/nix/stdio/fileno.c b/libnix/sources/nix/stdio/fileno.c new file mode 100755 index 0000000..e470ba8 --- /dev/null +++ b/libnix/sources/nix/stdio/fileno.c @@ -0,0 +1,6 @@ +#include + +int fileno(FILE *file) +{ + return file->file; +} diff --git a/libnix/sources/nix/stdio/fopen.c b/libnix/sources/nix/stdio/fopen.c new file mode 100755 index 0000000..bb5b48a --- /dev/null +++ b/libnix/sources/nix/stdio/fopen.c @@ -0,0 +1,70 @@ +#include +#include /* If you use normal file I/O, + the memory functions don't count that much on memory */ +#include +#include +#include +#include +#include +#include + +struct MinList __filelist= /* list of open files (fflush() needs also access) */ +{ + (struct MinNode *)&__filelist.mlh_Tail, + NULL, + (struct MinNode *)&__filelist.mlh_Head +}; + +FILE *fopen(const char *filename,const char *mode) +{ + struct filenode *node; + if((node=(struct filenode *)calloc(1,sizeof(struct filenode)))!=NULL) + { + if((node->FILE.buffer=(char *)malloc(BUFSIZ))!=NULL) + { + node->FILE.bufsize=BUFSIZ; + node->FILE.flags|=0x80; /* Buffer is malloc'ed */ + if(freopen(filename,mode,&node->FILE)!=NULL) + { AddHead((struct List *)&__filelist,(struct Node *)&node->node); + return &node->FILE; } + free(node->FILE.buffer); + } + else + errno=ENOMEM; + free(node); + } + else + errno=ENOMEM; + return NULL; +} + +int fclose(FILE *stream) +{ + int retval=0; + struct filenode *node; + if(stream==NULL) + { +#ifdef DEBUG_LIB + FATALERROR("NULL pointer fclose'd\n"); +#endif + return EOF; + } + retval=freopen(NULL,NULL,stream)==NULL?EOF:0; + if(stream->flags&0x80) /* Free buffer if necessary */ + { free(stream->buffer); + stream->buffer=NULL; } + node=(struct filenode *)((struct MinNode *)stream-1); + Remove((struct Node *)&node->node); + free(node); + return retval; +} + +void __exitstdfio(void) +{ + struct MinNode *node; + while((node=__filelist.mlh_Head)->mln_Succ!=NULL) + fclose(&((struct filenode *)node)->FILE); +} + +/* Call our private destructor at cleanup */ +ADD2EXIT(__exitstdfio,-20); diff --git a/libnix/sources/nix/stdio/fprintf.c b/libnix/sources/nix/stdio/fprintf.c new file mode 100755 index 0000000..1d93b7a --- /dev/null +++ b/libnix/sources/nix/stdio/fprintf.c @@ -0,0 +1,11 @@ +#include +#include + +int fprintf(FILE *stream,const char *format,...) +{ int retval; + va_list args; + va_start(args,format); + retval=vfprintf(stream,format,args); + va_end(args); + return retval; +} diff --git a/libnix/sources/nix/stdio/fputc.c b/libnix/sources/nix/stdio/fputc.c new file mode 100755 index 0000000..f3a620e --- /dev/null +++ b/libnix/sources/nix/stdio/fputc.c @@ -0,0 +1,4 @@ +#include + +int fputc(int c,FILE *stream) +{ return putc(c,stream); } diff --git a/libnix/sources/nix/stdio/fputs.c b/libnix/sources/nix/stdio/fputs.c new file mode 100755 index 0000000..6d1a4aa --- /dev/null +++ b/libnix/sources/nix/stdio/fputs.c @@ -0,0 +1,9 @@ +#include + +int fputs(const char *s,FILE *stream) +{ + while(*s) + if(fputc(*s++,stream)==EOF) + return EOF; + return 0; +} diff --git a/libnix/sources/nix/stdio/fread.c b/libnix/sources/nix/stdio/fread.c new file mode 100755 index 0000000..b3a061d --- /dev/null +++ b/libnix/sources/nix/stdio/fread.c @@ -0,0 +1,33 @@ +#include +#include +#include +#include + +int fread(void *ptr,size_t size,size_t nmemb,FILE *stream) +{ + signed long subsize; + unsigned long total; + unsigned char *b=(unsigned char *)ptr; + if(!(total=size*nmemb)) /* Just in case size==0 */ + return total; + do + { + if(stream->incount>0) + { + subsize=total>stream->incount?stream->incount:total; + memcpy(b,stream->p,subsize); + stream->p+=subsize; + stream->incount-=subsize; + b+=subsize; + total-=subsize; + }else + { + int c; + if((c=__srget(stream))==EOF) + break; + *b++=c; + total--; + } + }while(total); + return (b-(unsigned char *)ptr)/size; +} diff --git a/libnix/sources/nix/stdio/freopen.c b/libnix/sources/nix/stdio/freopen.c new file mode 100755 index 0000000..bd30b4a --- /dev/null +++ b/libnix/sources/nix/stdio/freopen.c @@ -0,0 +1,83 @@ +#include +#include +#include +#include +#include +#include +#include + +extern void __seterrno(void); + +FILE *freopen(const char *filename,const char *mode,FILE *stream) +{ int error; + error=__fflush(stream); + if(stream->file>2) + { close(stream->file); + if(stream->name!=NULL) /* file is temporary */ + { BPTR cd; + cd=CurrentDir(stream->tmpdir); /* cd t: */ + if(!DeleteFile(stream->name)) /* delete file */ + { __seterrno(); + error=1; } + free(stream->name); /* free filename */ + stream->name=NULL; + UnLock(CurrentDir(cd)); /* cd back, unlock t: */ + } + stream->file=0l; + } + if(error) + return NULL; + + if(filename!=NULL) + { long file; + long flags=O_RDONLY; + int append=0,plus=1; + if(mode!=NULL) + { switch(mode[0]) + { + case 'r': + break; + case 'w': + flags=O_WRONLY|O_CREAT|O_TRUNC; + break; + case 'a': + flags=O_WRONLY|O_CREAT; + append=1; + break; + default: + return NULL; + } + if(mode[1]=='b') + plus=2; + switch(mode[plus]) + { + case '+': + flags=(flags&~O_ACCMODE)|O_RDWR; + if(mode[plus+1]) + return NULL; + break; + case '\0': + break; + default: + return NULL; + } + } + + if((long)filename<4) + file=(long)filename-1; + else + if((file=open(filename,flags,0777))<0) + return NULL; + + if(append&&lseek(file,0,SEEK_END)<0) + return NULL; + + stream->flags&=~0x6f; /* clear a lot of flags */ + if(isatty(file)) + stream->flags|=1; /* set linebuffered flag */ + + stream->file=file; + } + + return stream; +} diff --git a/libnix/sources/nix/stdio/fscanf.c b/libnix/sources/nix/stdio/fscanf.c new file mode 100755 index 0000000..904e5b5 --- /dev/null +++ b/libnix/sources/nix/stdio/fscanf.c @@ -0,0 +1,11 @@ +#include +#include + +int fscanf(FILE *stream,const char *format,...) +{ int retval; + va_list args; + va_start(args,format); + retval=vfscanf(stream,format,args); + va_end(args); + return retval; +} diff --git a/libnix/sources/nix/stdio/fseek.c b/libnix/sources/nix/stdio/fseek.c new file mode 100755 index 0000000..fbdf85c --- /dev/null +++ b/libnix/sources/nix/stdio/fseek.c @@ -0,0 +1,24 @@ +#include +#include +#include + +int fseek(FILE *stream,long int offset,int whence) +{ + if(stream->flags&64) /* Error on stream */ + { errno=EPERM; + return EOF; } + if(stream->flags&8) + if(__fflush(stream)) + return EOF; + if(whence==SEEK_CUR) + offset-=stream->incount+(stream->tmpp!=NULL?stream->tmpinc:0); + stream->incount=0; + stream->tmpp=NULL; + stream->flags&=~36; + if(lseek(stream->file,offset,whence)==EOF) + { + stream->flags|=64; + return EOF; + } + return 0; +} diff --git a/libnix/sources/nix/stdio/fsetpos.c b/libnix/sources/nix/stdio/fsetpos.c new file mode 100755 index 0000000..ddbfb44 --- /dev/null +++ b/libnix/sources/nix/stdio/fsetpos.c @@ -0,0 +1,5 @@ +#include + +int fgetpos(FILE *stream,fpos_t *pos) +{ *pos=ftell(stream); + return 0; } diff --git a/libnix/sources/nix/stdio/ftell.c b/libnix/sources/nix/stdio/ftell.c new file mode 100755 index 0000000..61ef6b2 --- /dev/null +++ b/libnix/sources/nix/stdio/ftell.c @@ -0,0 +1,19 @@ +#include +#include +#include + +long ftell(FILE *stream) +{ + long pos; + if(stream->flags&64) /* Error on stream */ + { errno=EPERM; + return EOF; } + if((pos=lseek(stream->file,0,SEEK_CUR))==EOF) + { stream->flags|=64; + return pos; } + if(stream->flags&4) + pos-=stream->incount+(stream->tmpp!=NULL?stream->tmpinc:0); + else if(stream->flags&8) + pos+=stream->p-stream->buffer; + return pos; +} diff --git a/libnix/sources/nix/stdio/fwrite.c b/libnix/sources/nix/stdio/fwrite.c new file mode 100755 index 0000000..4aae63c --- /dev/null +++ b/libnix/sources/nix/stdio/fwrite.c @@ -0,0 +1,33 @@ +#include +#include +#include +#include + +int fwrite(const void *ptr,size_t size,size_t nmemb,FILE *stream) +{ + signed long subsize; + unsigned long total; + unsigned char *b=(unsigned char *)ptr; + if(!(total=size*nmemb)) /* Just in case size==0 */ + return total; + do + { + if(stream->outcount>0) + { + subsize=total>stream->outcount?stream->outcount:total; + memcpy(stream->p,b,subsize); + stream->p+=subsize; + stream->outcount-=subsize; + b+=subsize; + total-=subsize; + }else + { + int c; + c=*b++; + if(putc(c,stream)==EOF) + break; + total--; + } + }while(total); + return (b-(unsigned char *)ptr)/size; +} diff --git a/libnix/sources/nix/stdio/gets.c b/libnix/sources/nix/stdio/gets.c new file mode 100755 index 0000000..e6d95b8 --- /dev/null +++ b/libnix/sources/nix/stdio/gets.c @@ -0,0 +1,22 @@ +#include + +char *gets(char *s) +{ + int c; + char *s2=s; + for(;;) + { + c=fgetc(stdin); + if(c==EOF) + { + if(s2==s) + return NULL; + break; + } + if(c=='\n') + break; + *s2++=c; + } + *s2++='\0'; + return s; +} diff --git a/libnix/sources/nix/stdio/mblen.c b/libnix/sources/nix/stdio/mblen.c new file mode 100755 index 0000000..eb4af6f --- /dev/null +++ b/libnix/sources/nix/stdio/mblen.c @@ -0,0 +1,12 @@ +#include + +/* Sorry, the Amiga OS locale currently doesn't support + * character sets other than ECMA Latin 1, so this is + * just a "C" locale function + */ +int mblen(const char *s,size_t n) +{ size_t l=0; + while(n--&&*s++) + l++; + return sizeof(wchar_t)*(l+1); /* 1 for the NUL character */ +} diff --git a/libnix/sources/nix/stdio/mbstowcs.c b/libnix/sources/nix/stdio/mbstowcs.c new file mode 100755 index 0000000..e1929be --- /dev/null +++ b/libnix/sources/nix/stdio/mbstowcs.c @@ -0,0 +1,14 @@ +#include + +/* Sorry, the Amiga OS locale currently doesn't support + * character sets other than ECMA Latin 1, so this is + * just a "C" locale function + */ +size_t mbstowcs(wchar_t *wc,const char *s,size_t n) +{ size_t l=0; + while(n--&&*s) + { *wc++=*s++; + l++; } + *wc++='\0'; + return l; +} diff --git a/libnix/sources/nix/stdio/mbtowc.c b/libnix/sources/nix/stdio/mbtowc.c new file mode 100755 index 0000000..e3c5ac8 --- /dev/null +++ b/libnix/sources/nix/stdio/mbtowc.c @@ -0,0 +1,12 @@ +#include + +/* Sorry, the Amiga OS locale currently doesn't support + * character sets other than ECMA Latin 1, so this is + * just a "C" locale function + */ +int mbtowc(wchar_t *wc,const char *s,size_t n) +{ if(n&&s) + { *wc=*s; + return sizeof(wchar_t); } + return 0; +} diff --git a/libnix/sources/nix/stdio/open.c b/libnix/sources/nix/stdio/open.c new file mode 100755 index 0000000..7eac724 --- /dev/null +++ b/libnix/sources/nix/stdio/open.c @@ -0,0 +1,138 @@ +#include +#include +#include +#include +#include +#include +#undef LONGBITS +#undef BITSPERBYTE +#undef MAXINT +#undef MININT +#include +#define DEVICES_TIMER_H +#include +#include +#include +#include + +extern void __seterrno(void); +extern char *__amigapath(const char *path); +extern struct WBStartup *_WBenchMsg; + +unsigned long *__stdfiledes; +static unsigned long stdfilesize=3; +static long stderrdes=0; /* The normal Amiga shell sets no process->pr_CES stream - + * we use Open("*",MODE_NEWFILE) in this case + */ + +void __initstdio(void) +{ unsigned long *sfd; + + if((sfd=__stdfiledes=(unsigned long *)malloc(3*sizeof(unsigned long)))==NULL) + exit(20); + sfd[STDIN_FILENO ]=Input(); + sfd[STDOUT_FILENO]=Output(); + if(!(sfd[STDERR_FILENO]=((struct Process *)FindTask(NULL))->pr_CES)) + if(_WBenchMsg!=NULL||!(sfd[STDERR_FILENO]=stderrdes=Open("*",MODE_OLDFILE))) + sfd[STDERR_FILENO]=sfd[STDOUT_FILENO]; +} + +/* Call our private constructor */ +ADD2INIT(__initstdio,-30); + +void __exitstdio(void) +{ long file,*sfd; + int i,max; + + for(sfd=&__stdfiledes[3],max=stdfilesize,i=3;iSHRT_MAX) + { errno=EMFILE; + return -1; } + + if(file==max) + { if((sfd=realloc(sfd,(file+1)*sizeof(unsigned long)))==NULL) + { errno=ENOMEM; + return -1; } + __stdfiledes=sfd; + stdfilesize++; + } + + if((sfd[file]=Open((char *)path,flags&O_TRUNC?MODE_NEWFILE: + flags&(O_WRONLY|O_RDWR)?MODE_READWRITE:MODE_OLDFILE))) + return file; + __seterrno(); + return EOF; +} + +int close(int d) +{ + int ret=0; + if(d>2) + { + if(!Close(__stdfiledes[d])) + { ret=EOF; + __seterrno(); } + __stdfiledes[d]=0; + } + return ret; +} + +off_t lseek(int d,off_t offset,int whence) +{ + long r,file=__stdfiledes[d]; + __chkabort(); + r=Seek(file,offset,whence==SEEK_SET?OFFSET_BEGINNING: + whence==SEEK_END?OFFSET_END:OFFSET_CURRENT); + if(r!=EOF) + r=Seek(file,0,OFFSET_CURRENT); + if(r==EOF) + __seterrno(); + return r; +} + +ssize_t read(int d,void *buf,size_t nbytes) +{ + long r; + __chkabort(); + r=Read(__stdfiledes[d],buf,nbytes); + if(r==EOF) + __seterrno(); + return r; +} + +ssize_t write(int d,const void *buf,size_t nbytes) +{ + long r; + __chkabort(); + r=Write(__stdfiledes[d],(char *)buf,nbytes); + if(r==EOF) + __seterrno(); + return r; +} + +int isatty(int d) +{ return IsInteractive(__stdfiledes[d]); } diff --git a/libnix/sources/nix/stdio/perror.c b/libnix/sources/nix/stdio/perror.c new file mode 100755 index 0000000..a22cc8f --- /dev/null +++ b/libnix/sources/nix/stdio/perror.c @@ -0,0 +1,13 @@ +#include +#include +#include + +void perror(const char *string) +{ int err=errno; + if(string!=NULL) + { fputs(string,stderr); + fputc(':',stderr); + fputc(' ',stderr); } + fputs(strerror(err),stderr); + fputc('\n',stderr); +} diff --git a/libnix/sources/nix/stdio/printf.c b/libnix/sources/nix/stdio/printf.c new file mode 100755 index 0000000..aac8cb2 --- /dev/null +++ b/libnix/sources/nix/stdio/printf.c @@ -0,0 +1,11 @@ +#include +#include + +int printf(const char *format,...) +{ int retval; + va_list args; + va_start(args,format); + retval=vprintf(format,args); + va_end(args); + return retval; +} diff --git a/libnix/sources/nix/stdio/puts.c b/libnix/sources/nix/stdio/puts.c new file mode 100755 index 0000000..479e984 --- /dev/null +++ b/libnix/sources/nix/stdio/puts.c @@ -0,0 +1,11 @@ +#include + +int puts(const char *s) +{ + while(*s) + if(fputc(*s++,stdout)==EOF) + return EOF; + if(fputc('\n',stdout)==EOF) + return EOF; + return 0; +} diff --git a/libnix/sources/nix/stdio/remove.c b/libnix/sources/nix/stdio/remove.c new file mode 100755 index 0000000..6e57a24 --- /dev/null +++ b/libnix/sources/nix/stdio/remove.c @@ -0,0 +1,21 @@ +#include +#include +#include +#include + +extern void __seterrno(void); +extern char *__amigapath(const char *path); + +int remove(const char *filename) +{ +#ifdef IXPATHS + if((filename=__amigapath(filename))==NULL) + return -1; +#endif + + if(DeleteFile((char *)filename)) + return 0; + else + { __seterrno(); + return -1; } +} diff --git a/libnix/sources/nix/stdio/rename.c b/libnix/sources/nix/stdio/rename.c new file mode 100755 index 0000000..c73d216 --- /dev/null +++ b/libnix/sources/nix/stdio/rename.c @@ -0,0 +1,33 @@ +#include +#include +#include +#include + +extern void __seterrno(void); +extern char *__amigapath(const char *path); + +int rename(const char *old,const char *new) +{ int ret=-1; + +#ifdef IXPATHS + if((old=__amigapath(old))!=NULL) + { + if((old=strdup(old))!=NULL) + { + if((new=__amigapath(new))!=NULL) + { +#endif + if(Rename((char *)old,(char *)new)) + ret=0; + else + __seterrno(); + +#ifdef IXPATHS + } + free(old); + } + } +#endif + + return ret; +} diff --git a/libnix/sources/nix/stdio/rewind.c b/libnix/sources/nix/stdio/rewind.c new file mode 100755 index 0000000..19b4787 --- /dev/null +++ b/libnix/sources/nix/stdio/rewind.c @@ -0,0 +1,4 @@ +#include + +void rewind(FILE *stream) +{ fseek(stream,0,SEEK_SET); } diff --git a/libnix/sources/nix/stdio/scanf.c b/libnix/sources/nix/stdio/scanf.c new file mode 100755 index 0000000..c707ef3 --- /dev/null +++ b/libnix/sources/nix/stdio/scanf.c @@ -0,0 +1,11 @@ +#include +#include + +int scanf(const char *format,...) +{ int retval; + va_list args; + va_start(args,format); + retval=vscanf(format,args); + va_end(args); + return retval; +} diff --git a/libnix/sources/nix/stdio/setbuf.c b/libnix/sources/nix/stdio/setbuf.c new file mode 100755 index 0000000..2837ac8 --- /dev/null +++ b/libnix/sources/nix/stdio/setbuf.c @@ -0,0 +1,4 @@ +#include + +int setbuf(FILE *stream,char *buf) +{ return setvbuf(stream,buf,buf!=NULL?_IOFBF:_IONBF,BUFSIZ); } diff --git a/libnix/sources/nix/stdio/setvbuf.c b/libnix/sources/nix/stdio/setvbuf.c new file mode 100755 index 0000000..093786d --- /dev/null +++ b/libnix/sources/nix/stdio/setvbuf.c @@ -0,0 +1,29 @@ +#include +#include +#include + +int setvbuf(FILE *stream,char *buf,int mode,size_t size) +{ stream->flags&=~3; + stream->flags|=mode==_IOLBF?1:(mode==_IONBF?2:0); + if(size!=stream->bufsize||buf!=(char *)stream->buffer) + { if(__fflush(stream)) + return -1; + stream->incount=0; + stream->tmpp=0; + stream->flags&=~4; + mode=(buf==NULL); + if(mode) + if((buf=malloc(size))==NULL) + { errno=ENOMEM; + return -1; } + if(stream->flags&0x80) + free(stream->buffer); + if(mode) + stream->flags|=0x80; + else + stream->flags&=~0x80; + stream->buffer=buf; + stream->bufsize=size; + } /* Need not adjust outcount, since setvbuf affects only the NEXT full buffer */ + return 0; +} diff --git a/libnix/sources/nix/stdio/sprintf.c b/libnix/sources/nix/stdio/sprintf.c new file mode 100755 index 0000000..30d7721 --- /dev/null +++ b/libnix/sources/nix/stdio/sprintf.c @@ -0,0 +1,11 @@ +#include +#include + +int sprintf(char *s,const char *format,...) +{ int retval; + va_list args; + va_start(args,format); + retval=vsprintf(s,format,args); + va_end(args); + return retval; +} diff --git a/libnix/sources/nix/stdio/sscanf.c b/libnix/sources/nix/stdio/sscanf.c new file mode 100755 index 0000000..eac7313 --- /dev/null +++ b/libnix/sources/nix/stdio/sscanf.c @@ -0,0 +1,11 @@ +#include +#include + +int sscanf(const char *s,const char *format,...) +{ int retval; + va_list args; + va_start(args,format); + retval=vsscanf(s,format,args); + va_end(args); + return retval; +} diff --git a/libnix/sources/nix/stdio/tmpfile.c b/libnix/sources/nix/stdio/tmpfile.c new file mode 100755 index 0000000..6301c37 --- /dev/null +++ b/libnix/sources/nix/stdio/tmpfile.c @@ -0,0 +1,34 @@ +#include +#include +#include +#include +#include + +FILE *tmpfile(void) +{ char *name; + FILE *file; + BPTR dirlock,filelock,cd; + static unsigned long filecount=0; + name=malloc(32); /* buffer for filename */ + if(name!=NULL) + { dirlock=Lock("T:",ACCESS_READ); /* lock T: directory */ + if(dirlock!=0) + { cd=CurrentDir(dirlock); /* cd T: */ + do /* generate a filename that doesn't exist */ + { sprintf(name,"tempfile_1_%p_%lu",FindTask(NULL),filecount++); + filelock=Lock(name,ACCESS_WRITE); + if(filelock!=0) + UnLock(filelock); + }while(filelock!=0||IoErr()==ERROR_OBJECT_IN_USE); + file=fopen(name,"wb+"); + CurrentDir(cd); + if(file!=NULL) + { file->tmpdir=dirlock; + file->name=name; + return file; } + UnLock(dirlock); + } + free(name); + } + return NULL; +} diff --git a/libnix/sources/nix/stdio/tmpnam.c b/libnix/sources/nix/stdio/tmpnam.c new file mode 100755 index 0000000..26ef3d9 --- /dev/null +++ b/libnix/sources/nix/stdio/tmpnam.c @@ -0,0 +1,21 @@ +#include +#include +#include +#include +#include + +static char namebuffer[34]; + +char *tmpnam(char *s) +{ BPTR filelock; + static unsigned long filecount=0; + if(s==NULL) + s=namebuffer; + do /* generate a filename that doesn't exist */ + { sprintf(s,"T:tempfile_2_%p_%lu",FindTask(NULL),filecount++); + filelock=Lock(s,ACCESS_WRITE); + if(filelock!=0) + UnLock(filelock); + }while(filelock!=0||IoErr()==ERROR_OBJECT_IN_USE); + return s; +} diff --git a/libnix/sources/nix/stdio/ungetc.c b/libnix/sources/nix/stdio/ungetc.c new file mode 100755 index 0000000..0897c00 --- /dev/null +++ b/libnix/sources/nix/stdio/ungetc.c @@ -0,0 +1,32 @@ +#include +#include + +int ungetc(int c,FILE *stream) +{ + if(c==EOF) + return EOF; + if(stream->flags&64) /* Error on stream */ + { errno=EPERM; + return EOF; } + if(stream->flags&8) /* File is in write mode */ + if(__fflush(stream)) /* write buffer */ + return EOF; + if(stream->tmpp==NULL) + { if(stream->flags&4) /* File is in read mode */ + { stream->tmpp=stream->p; /* store actual position */ + stream->tmpinc=stream->incount; + stream->p=&stream->unget[4]; /* and use other buffer */ + stream->incount=0; + }else /* File is in indeterminated state */ + { stream->tmpp=(unsigned char *)2; /* Dummy */ + stream->tmpinc=0; + stream->p=&stream->unget[4]; /* use other buffer */ + stream->incount=0; + stream->flags|=4; + } + } + if(stream->incount==4) /* ungetc buffer overflow */ + return EOF; + stream->incount++; + return *--stream->p=c; +} diff --git a/libnix/sources/nix/stdio/vfprintf.c b/libnix/sources/nix/stdio/vfprintf.c new file mode 100755 index 0000000..d35aa5b --- /dev/null +++ b/libnix/sources/nix/stdio/vfprintf.c @@ -0,0 +1,378 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* a little macro to make life easier */ + +#define OUT(c) do \ + { if(fputc((c),stream)==EOF) \ + return outcount; \ + outcount++; \ + }while(0) + +#define MINFLOATSIZE (DBL_DIG+1) /* Why not 1 more - it's 97% reliable */ +#define MININTSIZE (sizeof(unsigned long)*CHAR_BIT/3+1) +#define MINPOINTSIZE (sizeof(void *)*CHAR_BIT/4+1) +#define REQUIREDBUFFER (MININTSIZE>MINPOINTSIZE? \ + (MININTSIZE>MINFLOATSIZE?MININTSIZE:MINFLOATSIZE): \ + (MINPOINTSIZE>MINFLOATSIZE?MINPOINTSIZE:MINFLOATSIZE)) + +#define ALTERNATEFLAG 1 /* '#' is set */ +#define ZEROPADFLAG 2 /* '0' is set */ +#define LALIGNFLAG 4 /* '-' is set */ +#define BLANKFLAG 8 /* ' ' is set */ +#define SIGNFLAG 16 /* '+' is set */ + +extern unsigned char *__decimalpoint; + +int vfprintf(FILE *stream,const char *format,va_list args) +{ + size_t outcount=0; + + while(*format) + { + if(*format=='%') + { + static const char flagc[]= + { '#','0','-',' ','+' }; + static const char lowertabel[]= + { '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' }; + static const char uppertabel[]= + { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' }; + size_t width=0,preci=ULONG_MAX,flags=0; /* Specifications */ + char type,subtype='i'; + char buffer1[2]; /* Signs and that like */ + char buffer[REQUIREDBUFFER]; /* The body */ + char *buffer2=buffer; /* So we can set this to any other strings */ + size_t size1=0,size2=0; /* How many chars in buffer? */ + const char *ptr=format+1; /* pointer to format string */ + size_t i,pad; /* Some temporary variables */ + + do /* read flags */ + for(i=0;i=0) + preci=a; + }else + { preci=0; + while(isdigit(*ptr)) + preci=preci*10+(*ptr++-'0'); + } + } + + if(*ptr=='h'||*ptr=='l'||*ptr=='L') + subtype=*ptr++; + + type=*ptr++; + + switch(type) + { case 'd': + case 'i': + case 'o': + case 'p': + case 'u': + case 'x': + case 'X': + { unsigned long v; + const char *tabel; + int base; + + if(type=='p') + { subtype='l'; /* This is written as %#lx */ + type='x'; + flags|=ALTERNATEFLAG; } + + if(type=='d'||type=='i') /* These are signed */ + { signed long v2; + if(subtype=='l') + v2=va_arg(args,signed long); + else + v2=va_arg(args,signed int); + if(v2<0) + { buffer1[size1++]='-'; + v=-v2; + }else + { if(flags&SIGNFLAG) + buffer1[size1++]='+'; + else if(flags&BLANKFLAG) + buffer1[size1++]=' '; + v=v2; } + }else /* These are unsigned */ + { if(subtype=='l') + v=va_arg(args,unsigned long); + else + v=va_arg(args,unsigned int); + if(flags&ALTERNATEFLAG) + { if(type=='o'&&(preci||v)) + buffer1[size1++]='0'; + if((type=='x'||type=='X')&&v) + { buffer1[size1++]='0'; + buffer1[size1++]=type; } + } + } + + buffer2=&buffer[sizeof(buffer)]; /* Calculate body string */ + base=type=='x'||type=='X'?16:(type=='o'?8:10); + tabel=type!='X'?lowertabel:uppertabel; + do + { *--buffer2=tabel[v%base]; + v=v/base; + size2++; + }while(v); + if(preci==ULONG_MAX) /* default */ + preci=0; + else + flags&=~ZEROPADFLAG; + break; + } + case 'c': + if(subtype=='l') + *buffer2=va_arg(args,long); + else + *buffer2=va_arg(args,int); + size2=1; + preci=0; + break; + case 's': + buffer2=va_arg(args,char *); + size2=strlen(buffer2); + size2=size2<=preci?size2:preci; + preci=0; + break; +#ifdef FULL_SPECIFIERS + case 'f': + case 'e': + case 'E': + case 'g': + case 'G': + { double v; + char killzeros=0,sign=0; /* some flags */ + int ex1,ex2; /* Some temporary variables */ + size_t size,dnum,dreq; + char *udstr=NULL; + + v=va_arg(args,double); + + if(isinf(v)) + { if(v>0) + udstr="+inf"; + else + udstr="-inf"; + }else if(isnan(v)) + udstr="NaN"; + + if(udstr!=NULL) + { size2=strlen(udstr); + preci=0; + buffer2=udstr; + break; } + + if(preci==ULONG_MAX) /* old default */ + preci=6; /* new default */ + + if(v<0.0) + { sign='-'; + v=-v; + }else + { if(flags&SIGNFLAG) + sign='+'; + else if(flags&BLANKFLAG) + sign=' '; + } + + ex1=0; + if(v!=0.0) + { ex1=log10(v); + if(v<1.0) + v=v*pow(10,- --ex1); /* Caution: (int)log10(.5)!=-1 */ + else + v=v/pow(10,ex1); + if(v<1.0) /* adjust if we are too low (log10(.1)=-.999999999) */ + { v*=10.0; /* luckily this cannot happen with FLT_MAX and FLT_MIN */ + ex1--; } /* The case too high (log(10.)=.999999999) is done later */ + } + + ex2=preci; + if(type=='f') + ex2+=ex1; + if(tolower(type)=='g') + ex2--; + v+=.5/pow(10,ex2=10.0) /* Adjusts log10(10.)=.999999999 too */ + { v/=10.0; + ex1++; } + + if(tolower(type)=='g') /* This changes to one of the other types */ + { if(ex1<(signed long)preci&&ex1>=-4) + { type='f'; + preci-=ex1; + }else + type=type=='g'?'e':'E'; + preci--; + if(!(flags&ALTERNATEFLAG)) + killzeros=1; /* set flag to kill trailing zeros */ + } + + dreq=preci+1; /* Calculate number of decimal places required */ + if(type=='f') + dreq+=ex1; /* even more before the decimal point */ + + dnum=0; + while(dnumdnum||buffer[dreq]=='0')) + preci--; + + if(type=='f')/* Calculate actual size of string (without sign) */ + { size=preci+1; /* numbers after decimal point + 1 before */ + if(ex1>0) + size+=ex1; /* numbers >= 10 */ + if(preci||flags&ALTERNATEFLAG) + size++; /* 1 for decimal point */ + }else + { size=preci+5; /* 1 for the number before the decimal point, and 4 for the exponent */ + if(preci||flags&ALTERNATEFLAG) + size++; + if(ex1>99||ex1<-99) + size++; /* exponent needs an extra decimal place */ + } + + pad=size+(sign!=0); + pad=pad>=width?0:width-pad; + + if(sign&&flags&ZEROPADFLAG) + OUT(sign); + + if(!(flags&LALIGNFLAG)) + for(i=0;i=0) + { OUT(dreq99) + OUT(ex1/100+'0'); + OUT(ex1/10%10+'0'); + OUT(ex1%10+'0'); + } + + if(flags&LALIGNFLAG) + for(i=0;i=preci?size2:preci); /* Calculate the number of characters */ + pad=pad>=width?0:width-pad; /* and the number of resulting pad bytes */ + + if(flags&ZEROPADFLAG) /* print sign and that like */ + for(i=0;i +#include +#include +#include +#include +#include + +/* some macros to cut this short + * NEXT(c); read next character + * PREV(c); ungetc a character + * VAL(a) leads to 1 if a is true and valid + */ +#define NEXT(c) ((c)=fgetc(stream),size++,incount++) +#define PREV(c) do{if((c)!=EOF)ungetc((c),stream);size--;incount--;}while(0) +#define VAL(a) ((a)&&size<=width) + +extern unsigned char *__decimalpoint; + +#ifdef FULL_SPECIFIERS +static const unsigned char undef[3][sizeof(double)]= /* Undefined numeric values, IEEE */ +{ { 0x7f,0xf0,0x00,0x00,0x00,0x00,0x00,0x00 }, /* +inf */ + { 0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00 }, /* -inf */ + { 0x7f,0xf1,0x00,0x00,0x00,0x00,0x00,0x00 } /* NaN */ +}; +#endif + +int vfscanf(FILE *stream,const char *format,va_list args) +{ + size_t blocks=0,incount=0; + int c=0; + + while(*format) + { + size_t size=0; + + if(*format=='%') + { + size_t width=ULONG_MAX; + char type,subtype='i',ignore=0; + const unsigned char *ptr=format+1; + size_t i; + + if(isdigit(*ptr)) + { width=0; + while(isdigit(*ptr)) + width=width*10+(*ptr++-'0'); } + + while(*ptr=='h'||*ptr=='l'||*ptr=='L'||*ptr=='*') + { if(*ptr=='*') + ignore=1; + else + subtype=*ptr; + ptr++; + } + + type=*ptr++; + + if(type&&type!='%'&&type!='c'&&type!='n'&&type!='[') + { do /* ignore leading whitespace characters */ + NEXT(c); + while(isspace(c)); + size=1; } /* The first non-whitespace character is already read */ + + switch(type) + { case 'c': + { unsigned char *bp; + + if(width==ULONG_MAX) /* Default */ + width=1; + + if(!ignore) + bp=va_arg(args,char *); + else + bp=NULL; /* Just to get the compiler happy */ + + NEXT(c); /* 'c' did not skip whitespace */ + while(VAL(c!=EOF)) + { if(!ignore) + *bp++=c; + NEXT(c); + } + PREV(c); + + if(!ignore&&size) + blocks++; + break; + } + case '[': + { unsigned char *bp; + unsigned char tab[32],a,b; + char circflag=0; + + if(*ptr=='^') + { circflag=1; + ptr++; } + for(i=0;i malformatted */ + { PREV(c); + c=__decimalpoint[0]; } + } + + if(min&&size==2) /* No number read till now -> malformatted */ + { PREV(c); + c=min; } + if(size==1) + break; + + if(VAL(tolower(c)=='e')) + { int d; + NEXT(d); + if(VAL(d=='-'||d=='+')) + { mine=d; + NEXT(d); } + + if(VAL(isdigit(d))) + { do + { ex=ex*10+(d-'0'); + NEXT(d); + }while(VAL(isdigit(d)&&ex<100)); + c=d; + }else + { PREV(d); + if(mine) + PREV(mine); + } + } + PREV(c); + + if(mine=='-') + v=v/pow(10.0,ex); + else + v=v*pow(10.0,ex); + + if(min=='-') + v=-v; + + }while(0); + + if(!ignore&&size) + { switch(subtype) + { case 'l': + case 'L': + *va_arg(args,double *)=v; + break; + case 'i': + *va_arg(args,float *)=v; + break; + } + blocks++; + } + break; + } +#endif + case '%': + NEXT(c); + if(c!='%') + PREV(c); /* unget non-'%' character */ + break; + case 'n': + if(!ignore) + *va_arg(args,int *)=incount; + size=1; /* fake a valid argument */ + blocks++; + break; + default: + { unsigned long v=0; + int base; + int min=0; + + if(!type) + ptr--; /* unparse NUL character */ + + if(type=='p') + { subtype='l'; /* This is the same as %lx */ + type='x'; } + + if(VAL((c=='-'&&type!='u')||c=='+')) + { min=c; + NEXT(c); } + + if(type=='i') /* which one to use ? */ + { if(VAL(c=='0')) /* Could be octal or sedecimal */ + { int d; + NEXT(d); /* Get a look at next character */ + if(VAL(tolower(d)=='x')) + { int e; + NEXT(e); /* And the next */ + if(VAL(isxdigit(c))) + type='x'; /* Is a valid x number with '0x?' */ + PREV(e); + }else + type='o'; + PREV(d); + }else if(VAL(!isdigit(c)&&isxdigit(c))) + type='x'; /* Is a valid x number without '0x' */ + } + + while(type=='x'&&VAL(c=='0')) /* sedecimal */ + { int d; + NEXT(d); + if(VAL(tolower(d)=='x')) + { int e; + NEXT(e); + if(VAL(isxdigit(e))) + { c=e; + break; } /* Used while just to do this ;-) */ + PREV(e); + } + PREV(d); + break; /* Need no loop */ + } + + base=type=='x'||type=='X'?16:(type=='o'?8:10); + while(VAL(isxdigit(c)&&(base!=10||isdigit(c))&&(base!=8||c<='7'))) + { v=v*base+(isdigit(c)?c-'0':0)+(isupper(c)?c-'A'+10:0)+(islower(c)?c-'a'+10:0); + NEXT(c); + } + + if(min&&size==2) /* If there is no valid character after sign, unget last */ + { PREV(c); + c=min; } + + PREV(c); + + if(ignore||!size) + break; + + if(type=='u') + switch(subtype) + { case 'l': + case 'L': + *va_arg(args,unsigned long *)=v; + break; + case 'i': + *va_arg(args,unsigned int *)=v; + break; + case 'h': + *va_arg(args,unsigned short *)=v; + break; + } + else + { signed long v2; + if(min=='-') + v2=-v; + else + v2=v; + switch(subtype) + { case 'l': + case 'L': + *va_arg(args,signed long *)=v2; + break; + case 'i': + *va_arg(args,signed int *)=v2; + break; + case 'h': + *va_arg(args,signed short *)=v2; + break; + } + } + blocks++; + break; + } + } + format=ptr; + }else + { if(isspace(*format)) + { do + NEXT(c); + while(isspace(c)); + PREV(c); + size=1; } + else + { NEXT(c); + if(c!=*format) + PREV(c); } + format++; + } + if(!size) + break; + } + + if(c==EOF&&!blocks) + return c; + else + return blocks; +} diff --git a/libnix/sources/nix/stdio/vprintf.c b/libnix/sources/nix/stdio/vprintf.c new file mode 100755 index 0000000..80259d6 --- /dev/null +++ b/libnix/sources/nix/stdio/vprintf.c @@ -0,0 +1,5 @@ +#include +#include + +int vprintf(const char *format,va_list args) +{ return vfprintf(stdout,format,args); } diff --git a/libnix/sources/nix/stdio/vscanf.c b/libnix/sources/nix/stdio/vscanf.c new file mode 100755 index 0000000..c2c94d8 --- /dev/null +++ b/libnix/sources/nix/stdio/vscanf.c @@ -0,0 +1,5 @@ +#include +#include + +int vscanf(const char *format,va_list args) +{ return vfscanf(stdin,format,args); } diff --git a/libnix/sources/nix/stdio/vsprintf.c b/libnix/sources/nix/stdio/vsprintf.c new file mode 100755 index 0000000..93781f7 --- /dev/null +++ b/libnix/sources/nix/stdio/vsprintf.c @@ -0,0 +1,17 @@ +#include +#include +#include + +int vsprintf(char *s,const char *format,va_list args) +{ + int retval; + FILE buffer; + buffer.p=s; + buffer.incount=0; + buffer.outcount=INT_MAX; + buffer.flags=0x208; + buffer.linebufsize=0; + retval=vfprintf(&buffer,format,args); + fputc('\0',&buffer); + return retval; +} diff --git a/libnix/sources/nix/stdio/vsscanf.c b/libnix/sources/nix/stdio/vsscanf.c new file mode 100755 index 0000000..103a1f5 --- /dev/null +++ b/libnix/sources/nix/stdio/vsscanf.c @@ -0,0 +1,15 @@ +#include +#include +#include +#include + +int vsscanf(const char *s,const char *format,va_list args) +{ + FILE buffer; + buffer.p=(char *)s; + buffer.flags=0x204; + buffer.incount=strlen(s); + buffer.outcount=0; + buffer.tmpp=NULL; + return vfscanf(&buffer,format,args); +} diff --git a/libnix/sources/nix/stdio/wcstombs.c b/libnix/sources/nix/stdio/wcstombs.c new file mode 100755 index 0000000..0f906b1 --- /dev/null +++ b/libnix/sources/nix/stdio/wcstombs.c @@ -0,0 +1,14 @@ +#include + +/* Sorry, the Amiga OS locale currently doesn't support + * character sets other than ECMA Latin 1, so this is + * just a "C" locale function + */ +size_t wcstombs(char *s,const wchar_t *wc,size_t n) +{ size_t l=0; + while(n--&&*wc) + { *s++=*wc++; + l++; } + *s++='\0'; + return l; +} diff --git a/libnix/sources/nix/stdio/wctomb.c b/libnix/sources/nix/stdio/wctomb.c new file mode 100755 index 0000000..510b390 --- /dev/null +++ b/libnix/sources/nix/stdio/wctomb.c @@ -0,0 +1,11 @@ +#include + +/* Sorry, the Amiga OS locale currently doesn't support + * character sets other than ECMA Latin 1, so this is + * just a "C" locale function + */ +int wctomb(char *s,wchar_t wc) +{ if(s) + *s=wc; + return 1; +} diff --git a/libnix/sources/nix/stdlib/_MSTEP.c b/libnix/sources/nix/stdlib/_MSTEP.c new file mode 100755 index 0000000..0066d3e --- /dev/null +++ b/libnix/sources/nix/stdlib/_MSTEP.c @@ -0,0 +1,5 @@ +#include + +ULONG _MSTEP=16384; + +/* suggestion of Gerhard Müller to be more SAS alike */ diff --git a/libnix/sources/nix/stdlib/abort.c b/libnix/sources/nix/stdlib/abort.c new file mode 100755 index 0000000..2132459 --- /dev/null +++ b/libnix/sources/nix/stdlib/abort.c @@ -0,0 +1,10 @@ +#include +#include +#include + +void abort(void) +{ + raise(SIGABRT); + fputs("Program aborted\n",stderr); + exit(20); +} diff --git a/libnix/sources/nix/stdlib/abs.c b/libnix/sources/nix/stdlib/abs.c new file mode 100755 index 0000000..8de7c26 --- /dev/null +++ b/libnix/sources/nix/stdlib/abs.c @@ -0,0 +1,2 @@ +int abs(int j) +{ return j>=0?j:-j; } diff --git a/libnix/sources/nix/stdlib/atexit.c b/libnix/sources/nix/stdlib/atexit.c new file mode 100755 index 0000000..c1f3f4b --- /dev/null +++ b/libnix/sources/nix/stdlib/atexit.c @@ -0,0 +1,35 @@ +#include +#include +#include +#include + +struct atexitnode +{ + struct atexitnode *next; + void (*func)(void); +}; + +static struct atexitnode *__funclist=NULL; /* List of functions to call at exit */ + +int atexit(void (*func)(void)) +{ + struct atexitnode *node; + if((node=(struct atexitnode *)malloc(sizeof(struct atexitnode)))==NULL) + { errno=ENOMEM; + return -1; } + else + { node->next=__funclist; + node->func=func; + __funclist=node; + return 0; } +} + +void __exitatexit(void) +{ + struct atexitnode *thisf=__funclist; + while(thisf!=NULL) + { (*thisf->func)(); + thisf=thisf->next; } +} + +ADD2EXIT(__exitatexit,0); diff --git a/libnix/sources/nix/stdlib/atoi.c b/libnix/sources/nix/stdlib/atoi.c new file mode 100755 index 0000000..a4fddd2 --- /dev/null +++ b/libnix/sources/nix/stdlib/atoi.c @@ -0,0 +1,5 @@ +#include +#include + +int atoi(const char *nptr) +{ return strtol(nptr,NULL,10); } diff --git a/libnix/sources/nix/stdlib/atol.c b/libnix/sources/nix/stdlib/atol.c new file mode 100755 index 0000000..0d7c364 --- /dev/null +++ b/libnix/sources/nix/stdlib/atol.c @@ -0,0 +1,5 @@ +#include +#include + +long atol(const char *nptr) +{ return strtol(nptr,NULL,10); } diff --git a/libnix/sources/nix/stdlib/bsearch.c b/libnix/sources/nix/stdlib/bsearch.c new file mode 100755 index 0000000..8752ed0 --- /dev/null +++ b/libnix/sources/nix/stdlib/bsearch.c @@ -0,0 +1,27 @@ +#include +#include + +/* sample compar function: int cmp(void *a,void *b){ return *(int *)a-*(int *)b; } */ + +void *bsearch +(const void *key,const void *base,size_t nmemb,size_t size, + int (*compar)(const void *,const void *)) +{ char *base2=(char *)base; + size_t a=0; + size_t b=nmemb; + size_t c; + int d; + if(nmemb!=0) + for(;;) + { c=(a+b)/2; + if((d=(*compar)(key,&base2[size*c]))==0) + return &base2[size*c]; + if(c==a) + break; + if(d<0) + b=c; + else + a=c; + } + return NULL; +} diff --git a/libnix/sources/nix/stdlib/calloc.c b/libnix/sources/nix/stdlib/calloc.c new file mode 100755 index 0000000..75c1b58 --- /dev/null +++ b/libnix/sources/nix/stdlib/calloc.c @@ -0,0 +1,18 @@ +#include +#include + +void *calloc(unsigned long nmemb,unsigned long size) +{ + unsigned long l; + unsigned long *a; + void *b; + l=(nmemb*size+(sizeof(unsigned long)-1))&~(sizeof(unsigned long)-1); + a=(unsigned long *)(b=malloc(l)); + if(b!=NULL) + { + do + *a++=0; + while((l-=sizeof(unsigned long))!=0); + } + return b; +} diff --git a/libnix/sources/nix/stdlib/free.c b/libnix/sources/nix/stdlib/free.c new file mode 100755 index 0000000..8eca237 --- /dev/null +++ b/libnix/sources/nix/stdlib/free.c @@ -0,0 +1,48 @@ +#include +#include +#include +#include +#include +#include +#include + +extern struct MinList __memorylist; + +void free(void *ptr) +{ + struct MemHeader *a; + + if(ptr==NULL) /* What does that mean ????? */ + { +#ifdef DEBUG_LIB + FATALERROR("NULL pointer free'd\n"); +#endif + return; + } + + a=(struct MemHeader *)__memorylist.mlh_Head; + for(;;) + { + if(((struct MinNode *)a)->mln_Succ==NULL) /* Is not in list ????? */ + { +#ifdef DEBUG_LIB + FATALERROR("Fake memory free'd\n"); +#endif + return; + } + + if(ptr>=a->mh_Lower&&ptrmh_Upper) /* Entry found */ + break; + + a=(struct MemHeader *)((struct MinNode *)a)->mln_Succ; + } + +#ifdef DEBUG_LIB + memset(ptr,0xcc,((ULONG *)ptr)[-1]); /* Destroy contents */ +#endif + + Deallocate(a,(ULONG *)ptr-1,((ULONG *)ptr)[-1]); + if(a->mh_Free==(char *)a->mh_Upper-(char *)a->mh_Lower) /* All free ? */ + { Remove(&a->mh_Node); + FreeMem(a,(char *)a->mh_Upper-(char *)a); } +} diff --git a/libnix/sources/nix/stdlib/getenv.c b/libnix/sources/nix/stdlib/getenv.c new file mode 100755 index 0000000..207c4f8 --- /dev/null +++ b/libnix/sources/nix/stdlib/getenv.c @@ -0,0 +1,22 @@ +#include +#include +#include +#include + +char *getenv(const char *name) +{ static char *var=NULL; + size_t len,i=0; + do + { i+=256; + if(var!=NULL) /* free old buffer */ + free(var); + var=malloc(i); /* and get a new one */ + if(var==NULL) /* Oh, dear */ + return NULL; + len=GetVar((char *)name,var,i,GVF_BINARY_VAR)+1; + }while(len>=i); /* just to be sure we got everything, we _require_ 1 unused byte */ + if(len==0) /* Variable doesn't exist */ + return NULL; + else + return var; +} diff --git a/libnix/sources/nix/stdlib/labs.c b/libnix/sources/nix/stdlib/labs.c new file mode 100755 index 0000000..1bb61f0 --- /dev/null +++ b/libnix/sources/nix/stdlib/labs.c @@ -0,0 +1,2 @@ +long labs(long j) +{ return j>=0?j:-j; } diff --git a/libnix/sources/nix/stdlib/malloc.c b/libnix/sources/nix/stdlib/malloc.c new file mode 100755 index 0000000..7ee2a2d --- /dev/null +++ b/libnix/sources/nix/stdlib/malloc.c @@ -0,0 +1,63 @@ +/* 10-Apr-94 bug fix M. Fleischer + * 11-Apr-94 bug fix & readjastment G. Nikl + * 14-Apr-94 readjustment M. Fleischer + * 24-Apr-94 cleanup for malloc changed + */ + +#include +#include +#include +#include +#include +#include + +extern ULONG _MSTEP; + +struct MinList __memorylist= /* memorylist (empty): free needs also access */ +{ + (struct MinNode *)&__memorylist.mlh_Tail, + NULL, + (struct MinNode *)&__memorylist.mlh_Head +}; + +void *malloc(unsigned long size) +{ + struct MinNode *node=__memorylist.mlh_Head; + struct MemHeader *b; + ULONG size2,*a; + + size+=sizeof(ULONG); + while(node->mln_Succ) /* yet some memory in my list ? */ + { + if((a=Allocate((struct MemHeader *)node,size))!=NULL) + { + *a++=size; + return a; + } + node=node->mln_Succ; + } + size2=sizeof(struct MemHeader)+sizeof(ULONG)+size; /* Total memory needed */ + if(size2<=_MSTEP) + size2=_MSTEP; /* Allocate a _MSTEP bytes large block if possible */ + size2=(size2+4095)&~4095; /* Blow up to full MMU Page */ + if((b=(struct MemHeader *)AllocMem(size2,MEMF_ANY))!=NULL) + { + b->mh_Lower=b->mh_First=(struct MemChunk *)(b+1); + b->mh_First->mc_Next=NULL; + b->mh_Free=b->mh_First->mc_Bytes=size2-sizeof(struct MemHeader); + b->mh_Upper=(char *)b+size2; + AddHead((struct List *)&__memorylist,&b->mh_Node); + a=Allocate(b,size); /* It has to work this time */ + *a++=size; + return a; + } + return NULL; +} + +void __exitmalloc(void) +{ struct MemHeader *a; + while((a=(struct MemHeader *)RemHead((struct List *)&__memorylist))!=NULL) + FreeMem(a,(char *)a->mh_Upper-(char *)a); /* free all memory */ +} + +ADD2EXIT(__exitmalloc,-50); diff --git a/libnix/sources/nix/stdlib/qsort.c b/libnix/sources/nix/stdlib/qsort.c new file mode 100755 index 0000000..b87bc42 --- /dev/null +++ b/libnix/sources/nix/stdlib/qsort.c @@ -0,0 +1,54 @@ +#include +#include + +/* sample compar function: int cmp(void *a,void *b){ return *(int *)a-*(int *)b; } */ + +/* This qsort function does a little trick: + * To reduce stackspace it iterates the larger interval instead of doing + * the recursion on both intervals. + * So stackspace is limited to 32*stack_for_1_iteration = + * 32*4*(4 arguments+1 returnaddress+11 stored registers) = 2048 Bytes, + * which is small enough for everybodys use. + * (And this is the worst case if you own 4GB and sort an array of chars.) + * Sparing the function calling overhead does improve performance, too. + */ + +void qsort +(void *base,size_t nmemb,size_t size,int (*compar)(const void *,const void *)) +{ char *base2=(char *)base; + char tmp; + size_t i,a,b,c; + while(nmemb>1) + { a=0; + b=nmemb-1; + c=(a+b)/2; /* Middle element */ + for(;;) + { while((*compar)(&base2[size*c],&base2[size*a])>0) + a++; /* Look for one >= middle */ + while((*compar)(&base2[size*c],&base2[size*b])<0) + b--; /* Look for one <= middle */ + if(a>=b) + break; /* We found no pair */ + for(i=0;i + +static unsigned int a=1; + +int rand(void) +{ return (a=a*1103515245+12345)%RAND_MAX; } + +void srand(unsigned int seed) +{ a=seed; } diff --git a/libnix/sources/nix/stdlib/realloc.c b/libnix/sources/nix/stdlib/realloc.c new file mode 100755 index 0000000..cdbb4df --- /dev/null +++ b/libnix/sources/nix/stdlib/realloc.c @@ -0,0 +1,22 @@ +#include +#include + +void *realloc(void *ptr,unsigned long size) +{ + void *a; + unsigned long l; + if(size) + a=malloc(size); + else + a=NULL; + if(ptr!=NULL) + { if(a!=NULL) + { l=((ULONG *)ptr)[-1]-sizeof(ULONG); + l=l +#include +#include +#include +#include + +signed long strtol(const char *nptr,char **endptr,int base) +{ const char *p=nptr; + char *q; + unsigned long r; + while(isspace(*p)) + p++; + r=strtoul(p,&q,base); + if(endptr!=NULL) + { if(q==p) + *endptr=(char *)nptr; + else + *endptr=q; + } + if(*p=='-') + { if((signed long)r>0) + { errno=ERANGE; + return LONG_MIN; } + else + return r; + }else + { if((signed long)r<0) + { errno=ERANGE; + return LONG_MAX; } + else + return r; + } +} diff --git a/libnix/sources/nix/stdlib/strtoul.c b/libnix/sources/nix/stdlib/strtoul.c new file mode 100755 index 0000000..d152959 --- /dev/null +++ b/libnix/sources/nix/stdlib/strtoul.c @@ -0,0 +1,55 @@ +#include +#include +#include +#include +#include + +unsigned long strtoul(const char *nptr,char **endptr,int base) +{ const char *p=nptr,*q; + char c=0; + unsigned long r=0; + if(base<0||base==1||base>36) + { if(endptr!=NULL) + *endptr=(char *)nptr; + return 0; + } + while(isspace(*p)) + p++; + if(*p=='-'||*p=='+') + c=*p++; + if(base==0) + { if(p[0]=='0') + { if(tolower(p[1])=='x'&&isxdigit(p[2])) + { p+=2; + base=16; } + else + base=8; + }else + base=10; + } + q=p; + for(;;) + { int a; + if(!isalnum(*q)) + break; + a=isdigit(*q)?*q-'0':tolower(*q)-('a'-10); + if(a>=base) + break; + if(r>(ULONG_MAX-a)/base||r*base>ULONG_MAX-a) + { errno=ERANGE; /* overflow */ + r=ULONG_MAX; } + else + r=r*base+a; + q++; + } + if(q==p) /* Not a single number read */ + { if(endptr!=NULL) + *endptr=(char *)nptr; + return 0; + } + if(c=='-') + r=-r; + if(endptr!=NULL) + *endptr=(char *)q; + return r; +} diff --git a/libnix/sources/nix/stdlib/system.c b/libnix/sources/nix/stdlib/system.c new file mode 100755 index 0000000..31a5171 --- /dev/null +++ b/libnix/sources/nix/stdlib/system.c @@ -0,0 +1,13 @@ +#include +#include +#include + +static struct TagItem list[]={ { TAG_END,0 } }; /* No Tags */ + +int system(const char *string) +{ + if(string==NULL) + return 1; + else + return SystemTagList((char *)string,list); +} diff --git a/libnix/sources/nix/string/memchr.c b/libnix/sources/nix/string/memchr.c new file mode 100755 index 0000000..d9b369d --- /dev/null +++ b/libnix/sources/nix/string/memchr.c @@ -0,0 +1,13 @@ +#include + +void *memchr(const void *s,int c,size_t n) +{ + if (n) { + unsigned char *p=(unsigned char *)s; + do { + if (*p++==(unsigned char)c) + return --p; + } while (--n); + } + return (void *)n; +} diff --git a/libnix/sources/nix/string/memcmp.c b/libnix/sources/nix/string/memcmp.c new file mode 100755 index 0000000..83f64f7 --- /dev/null +++ b/libnix/sources/nix/string/memcmp.c @@ -0,0 +1,10 @@ +#include + +int memcmp(const void *s1,const void *s2,size_t n) +{ const unsigned char *p1=s1,*p2=s2; + unsigned long r,c; + + if ((r=n)) + do;while(r=*p1++,c=*p2++,!(r-=c) && --n); + return r; +} diff --git a/libnix/sources/nix/string/memcpy.c b/libnix/sources/nix/string/memcpy.c new file mode 100755 index 0000000..9f61567 --- /dev/null +++ b/libnix/sources/nix/string/memcpy.c @@ -0,0 +1,7 @@ +#include +#include + +void *memcpy(void *s1,const void *s2,size_t n) +{ + CopyMem((APTR)s2,s1,n); return s1; +} diff --git a/libnix/sources/nix/string/memmove.c b/libnix/sources/nix/string/memmove.c new file mode 100755 index 0000000..313d6e3 --- /dev/null +++ b/libnix/sources/nix/string/memmove.c @@ -0,0 +1,8 @@ +#include + +extern void bcopy(const void *s1,void *s2,size_t n); + +void *memmove(void *s1,const void *s2,size_t n) +{ + bcopy(s2,s1,n); return s1; +} diff --git a/libnix/sources/nix/string/memset.c b/libnix/sources/nix/string/memset.c new file mode 100755 index 0000000..0bf120c --- /dev/null +++ b/libnix/sources/nix/string/memset.c @@ -0,0 +1,10 @@ +#include + +void *memset(void *s,int c,size_t n) +{ + if (n) { + unsigned char *p=s; + do;while(*p++=c,--n); + } + return s; +} diff --git a/libnix/sources/nix/string/strcat.c b/libnix/sources/nix/string/strcat.c new file mode 100755 index 0000000..89128dd --- /dev/null +++ b/libnix/sources/nix/string/strcat.c @@ -0,0 +1,26 @@ +#ifndef mc68000 + +#include + +char *strcat(char *s1,const char *s2) +{ char *s=s1; + + do;while(*s++); --s; do;while((*s++=*s2++)); return s1; +} + +#else + +asm(" + .globl _strcat +_strcat: + movml sp@(4:W),d0/a0 + movel d0,a1 +L2: tstb a1@+ + jne L2 + subql #1,a1 +L1: moveb a0@+,a1@+ + jne L1 + rts +"); + +#endif diff --git a/libnix/sources/nix/string/strchr.c b/libnix/sources/nix/string/strchr.c new file mode 100755 index 0000000..7bf18e3 --- /dev/null +++ b/libnix/sources/nix/string/strchr.c @@ -0,0 +1,12 @@ +#include +#include + +char *strchr(const char *s,int c) +{ + while (*s!=(char)c) + if (!*s++) + { s = (char *)0; break; } + return (char *)s; +} + +ALIAS(index,strchr); diff --git a/libnix/sources/nix/string/strcmp.c b/libnix/sources/nix/string/strcmp.c new file mode 100755 index 0000000..08f4a8a --- /dev/null +++ b/libnix/sources/nix/string/strcmp.c @@ -0,0 +1,8 @@ +#include + +int strcmp(const char *s1,const char *s2) +{ unsigned char *p1=(unsigned char *)s1, *p2=(unsigned char *)s2; + unsigned long r,c; + + do;while(r=*p1++,c=*p2++,!(r-=c) && (char)c); return r; +} diff --git a/libnix/sources/nix/string/strcoll.c b/libnix/sources/nix/string/strcoll.c new file mode 100755 index 0000000..1349ef7 --- /dev/null +++ b/libnix/sources/nix/string/strcoll.c @@ -0,0 +1,15 @@ +#include +#include +#include +#include +#include +#include + +extern struct Locale *__localevec[]; + +int strcoll(const char *s1,const char *s2) +{ if (!__localevec[LC_COLLATE-1]) + return strcmp(s1,s2); + else + return StrnCmp(__localevec[LC_COLLATE-1],(char *)s1,(char *)s2,LONG_MAX,SC_COLLATE1); +} diff --git a/libnix/sources/nix/string/strcpy.c b/libnix/sources/nix/string/strcpy.c new file mode 100755 index 0000000..56508b0 --- /dev/null +++ b/libnix/sources/nix/string/strcpy.c @@ -0,0 +1,27 @@ +#ifndef mc68000 + +#include + +char *strcpy(char *s1,const char *s2) +{ char *s=s1; +#if 0 + do;while(*s1++=*s2,*s2++!='\0'); +#else + do;while((*s1++=*s2++)); +#endif + return s; +} + +#else + +asm(" + .globl _strcpy +_strcpy: + moveml sp@(4:W),d0/a0 + movel d0,a1 +L1: moveb a0@+,a1@+ + jne L1 + rts +"); + +#endif diff --git a/libnix/sources/nix/string/strcspn.c b/libnix/sources/nix/string/strcspn.c new file mode 100755 index 0000000..01f5fbe --- /dev/null +++ b/libnix/sources/nix/string/strcspn.c @@ -0,0 +1,13 @@ +#include + +size_t strcspn(const char *s1,const char *s2) +{ unsigned char *c2,*c1=(unsigned char *)s1; + size_t i; + for(i=0;;i++) { + c2=(unsigned char *)s2; + do + if(c1[i]==*c2) + return i; + while(*c2++!='\0'); + } +} diff --git a/libnix/sources/nix/string/strerror.c b/libnix/sources/nix/string/strerror.c new file mode 100755 index 0000000..246bb7c --- /dev/null +++ b/libnix/sources/nix/string/strerror.c @@ -0,0 +1,90 @@ +char *sys_errlist[] = { + "Undefined error", + "Operation not permitted", + "No such file or directory", + "No such process", + "Interrupted system call", + "Input/output error", + "Device not configured", + "Argument list too long", + "Exec format error", + "Bad file descriptor", + "No child processes", + "Resource deadlock avoided", + "Cannot allocate memory", + "Permission denied", + "Bad address", + "Block device required", + "Device busy", + "File exists", + "Cross-device link", + "Operation not supported by device", + "Not a directory", + "Is a directory", + "Invalid argument", + "Too many open files in system", + "Too many open files", + "Inappropriate ioctl for device", + "Text file busy", + "File too large", + "No space left on device", + "Illegal seek", + "Read-only file system", + "Too many links", + "Broken pipe", + "Numerical argument out of domain", + "Result too large", + "Resource temporarily unavailable", + "Operation now in progress", + "Operation already in progress", + "Socket operation on non-socket", + "Destination address required", + "Message too long", + "Protocol wrong type for socket", + "Protocol not available", + "Protocol not supported", + "Socket type not supported", + "Operation not supported", + "Protocol family not supported", + "Address family not supported by protocol family", + "Address already in use", + "Can't assign requested address", + "Network is down", + "Network is unreachable", + "Network dropped connection on reset", + "Software caused connection abort", + "Connection reset by peer", + "No buffer space available", + "Socket is already connected", + "Socket is not connected", + "Can't send after socket shutdown", + "Too many references: can't splice", + "Connection timed out", + "Connection refused", + "Too many levels of symbolic links", + "File name too long", + "Host is down", + "No route to host", + "Directory not empty", + "Too many processes", + "Too many users", + "Disc quota exceeded", + "Stale NFS file handle", + "Too many levels of remote in path", + "RPC struct is bad", + "RPC version wrong", + "RPC prog. not avail", + "Program version wrong", + "Bad procedure for program", + "No locks available", + "Function not implemented", + "Inappropriate file type or format" +}; + +int sys_nerr=sizeof(sys_errlist)/sizeof(sys_errlist[0]); + +char *strerror(int errno) +{ if(errno<0||errno>=sys_nerr) + errno=0; + return sys_errlist[errno]; +} diff --git a/libnix/sources/nix/string/strlen.c b/libnix/sources/nix/string/strlen.c new file mode 100755 index 0000000..6f4ce5a --- /dev/null +++ b/libnix/sources/nix/string/strlen.c @@ -0,0 +1,7 @@ +#include + +size_t strlen(const char *string) +{ const char *s=string; + + do;while(*s++); return ~(string-s); +} diff --git a/libnix/sources/nix/string/strncat.c b/libnix/sources/nix/string/strncat.c new file mode 100755 index 0000000..50b1d8a --- /dev/null +++ b/libnix/sources/nix/string/strncat.c @@ -0,0 +1,41 @@ +#ifndef mc68000 + +#include + +char *strncat(char *s1,const char *s2,size_t n) +{ + if (n) { + char *s=s1; + do;while(*s++); --s; + for(;;) { + if (!(*s++=*s2++)) + break; + if (!--n) { + *s=0; break; + } + } + } + return s1; +} + +#else + +asm(" + .globl _strncat +_strncat: + moveml sp@(4:W),d0/a0 + movel d0,a1 + movel sp@(12),d1 + jeq L1 +L3: tstb a1@+ + jne L3 + subql #1,a1 +L2: moveb a0@+,a1@+ + jeq L1 + subql #1,d1 + jne L2 + clrb a1@ +L1: rts +"); + +#endif diff --git a/libnix/sources/nix/string/strncmp.c b/libnix/sources/nix/string/strncmp.c new file mode 100755 index 0000000..9f985dc --- /dev/null +++ b/libnix/sources/nix/string/strncmp.c @@ -0,0 +1,10 @@ +#include + +int strncmp(const char *s1,const char *s2,size_t n) +{ unsigned char *p1=(unsigned char *)s1,*p2=(unsigned char *)s2; + unsigned long r,c; + + if ((r=n)) + do;while(r=*p1++,c=*p2++,!(r-=c) && (char)c && --n); + return r; +} diff --git a/libnix/sources/nix/string/strncpy.c b/libnix/sources/nix/string/strncpy.c new file mode 100755 index 0000000..1c1c3f5 --- /dev/null +++ b/libnix/sources/nix/string/strncpy.c @@ -0,0 +1,35 @@ +#ifndef mc68000 + +#include + +char *strncpy(char *s1,const char *s2,size_t n) +{ + if (n) { + char *s=s1; + do;while((*s++=*s2++) && --n); + if (n) + while(--n) *s++=0; + } + return s1; +} + +#else + +asm(" + .globl _strncpy +_strncpy: + moveml sp@(4:W),d0/a0 + movel d0,a1 + movel sp@(12:W),d1 +L4: subql #1,d1 + bcs L1 + moveb a0@+,a1@+ + bne L4 + .word 0x0c40 +L3: clrb a1@+ + subql #1,d1 + bcc L3 +L1: rts +"); + +#endif diff --git a/libnix/sources/nix/string/strpbrk.c b/libnix/sources/nix/string/strpbrk.c new file mode 100755 index 0000000..e5586ac --- /dev/null +++ b/libnix/sources/nix/string/strpbrk.c @@ -0,0 +1,14 @@ +#include + +char *strpbrk(const char *s1,const char *s2) +{ unsigned char *c1=(unsigned char *)s1; + unsigned char *c2; + while(*c1!='\0') + { c2=(unsigned char *)s2; + while(*c2!='\0') + if(*c1==*c2++) + return (char *)c1; + c1++; + } + return (char *)0; +} diff --git a/libnix/sources/nix/string/strrchr.c b/libnix/sources/nix/string/strrchr.c new file mode 100755 index 0000000..f17ce87 --- /dev/null +++ b/libnix/sources/nix/string/strrchr.c @@ -0,0 +1,13 @@ +#include +#include + +char *strrchr(const char *s,int c) +{ char *c1=(char *)0; + do + if (*s==(char)c) + c1=(char *)s; + while(*s++); + return c1; +} + +ALIAS(rindex,strrchr); diff --git a/libnix/sources/nix/string/strspn.c b/libnix/sources/nix/string/strspn.c new file mode 100755 index 0000000..4e13e51 --- /dev/null +++ b/libnix/sources/nix/string/strspn.c @@ -0,0 +1,14 @@ +#include + +size_t strspn(const char *s1,const char *s2) +{ size_t i; + unsigned char *c1=(unsigned char *)s1; + unsigned char *c2; + for(i=0;;i++) + { c2=(unsigned char *)s2; + while(*c2!='\0'&&c1[i]!=*c2) + c2++; + if(*c2=='\0') + return i; + } +} diff --git a/libnix/sources/nix/string/strstr.c b/libnix/sources/nix/string/strstr.c new file mode 100755 index 0000000..947352a --- /dev/null +++ b/libnix/sources/nix/string/strstr.c @@ -0,0 +1,15 @@ +#include + +char *strstr(const char *s1,const char *s2) +{ const char *c1,*c2; + + do { + c1 = s1; c2 = s2; + while(*c1 && *c1==*c2) { + c1++; c2++; + } + if (!*c2) + return (char *)s1; + } while(*s1++); + return (char *)0; +} diff --git a/libnix/sources/nix/string/strtok.c b/libnix/sources/nix/string/strtok.c new file mode 100755 index 0000000..64a7dd2 --- /dev/null +++ b/libnix/sources/nix/string/strtok.c @@ -0,0 +1,17 @@ +#include + +char *strtok(char *s1,const char *s2) +{ static char *t; + if(s1) + t=s1; + else + s1=t; + s1+=strspn(s1,s2); + if(*s1=='\0') + return (char *)0; + t=s1; + t+=strcspn(s1,s2); + if(*t!='\0') + *t++='\0'; + return s1; +} diff --git a/libnix/sources/nix/string/strxfrm.c b/libnix/sources/nix/string/strxfrm.c new file mode 100755 index 0000000..9a9b3d5 --- /dev/null +++ b/libnix/sources/nix/string/strxfrm.c @@ -0,0 +1,14 @@ +#include +#include +#include +#include +#include + +extern struct Locale *__localevec[]; + +size_t strxfrm(char *buffer,const char *s,size_t n) +{ if (!__localevec[LC_COLLATE-1]) + { strncpy(buffer,s,n); return strlen(s); } + else + return StrConvert(__localevec[LC_COLLATE-1],(char *)s,buffer,n,SC_COLLATE1); +} diff --git a/libnix/sources/nix/time/__gmtoffset.c b/libnix/sources/nix/time/__gmtoffset.c new file mode 100755 index 0000000..c9b29b3 --- /dev/null +++ b/libnix/sources/nix/time/__gmtoffset.c @@ -0,0 +1,5 @@ +/* Greenwich mean time offset and daylight savings time flag + */ + +long __gmtoffset=0; +int __dstflag=0; diff --git a/libnix/sources/nix/time/asctime.c b/libnix/sources/nix/time/asctime.c new file mode 100755 index 0000000..d7cd8fb --- /dev/null +++ b/libnix/sources/nix/time/asctime.c @@ -0,0 +1,11 @@ +#include + +static char buffer[26]; + +char *asctime(const struct tm *t) +{ strftime(buffer,sizeof(buffer),"%C\n",t); + return buffer; +} + +char *ctime(const time_t *t) +{ return asctime(localtime(t)); } diff --git a/libnix/sources/nix/time/clock.c b/libnix/sources/nix/time/clock.c new file mode 100755 index 0000000..82cc1b7 --- /dev/null +++ b/libnix/sources/nix/time/clock.c @@ -0,0 +1,27 @@ +#include +#include +#ifdef __GNUC__ /* This is very sad :-( */ +#undef BITSPERBYTE +#undef MAXINT +#undef MININT +#endif +#include +#include +#include + +static struct DateStamp ds; + +int __initclock(void) +{ DateStamp(&ds); + return 0; +} + +ADD2INIT(__initclock,-10); + +clock_t clock(void) +{ struct DateStamp ds2; + DateStamp(&ds2); + return (((ds2.ds_Days-ds.ds_Days)*(24*60)+ + ds2.ds_Minute-ds.ds_Minute)*(60*TICKS_PER_SECOND)+ + ds2.ds_Tick-ds.ds_Tick)*CLK_TCK/TICKS_PER_SECOND; +} diff --git a/libnix/sources/nix/time/difftime.c b/libnix/sources/nix/time/difftime.c new file mode 100755 index 0000000..680c3f9 --- /dev/null +++ b/libnix/sources/nix/time/difftime.c @@ -0,0 +1,4 @@ +#include + +double difftime(time_t a,time_t b) +{ return a-b; } diff --git a/libnix/sources/nix/time/gmtime.c b/libnix/sources/nix/time/gmtime.c new file mode 100755 index 0000000..c7922e2 --- /dev/null +++ b/libnix/sources/nix/time/gmtime.c @@ -0,0 +1,74 @@ +#include + +/* Rules for leap-years: + * 1. every 4th year is a leap year + * 2. every 100th year is none + * 3. every 400th is one + * 4. 1900 was none, 2000 is one + */ + +extern int __dstflag; + +static char monthtable[]= +{ 31,29,31,30,31,30,31,31,30,31,30 }; + +struct tm *gmtime(const time_t *t) +{ + static struct tm utim; + signed long tim; + int leapday=0,leapyear=0,i; + tim=*t; + utim.tm_sec=tim%60; + tim/=60; + utim.tm_min=tim%60; + tim/=60; + utim.tm_hour=tim%24; + tim=tim/24+719162; + utim.tm_wday=(tim+1)%7; + utim.tm_year=tim/146097*400-1899; + tim%=146097; + if(tim>=145731) + { leapyear++; /* The day is in one of the 400th */ + if(tim==146096) + { tim--; /* Be careful: The last of the 4 centuries is 1 day longer */ + leapday++; } + } + utim.tm_year+=tim/36524*100; + tim%=36524; + if(tim>=36159) + leapyear--; /* The day is in one of the 100th */ + utim.tm_year+=tim/1461*4; + tim%=1461; + if(tim>=1095) + { leapyear++; /* The day is in one of the 4th */ + if(tim==1460) + { tim--; /* Be careful: The 4th year is 1 day longer */ + leapday++; } + } + utim.tm_year+=tim/365; + tim=tim%365+leapday; + utim.tm_yday=tim; + if(!leapyear&&tim>=31+28) + tim++; /* add 1 for 29-Feb if no leap year */ + for(i=0;i<11;i++) + if(tim + +extern long __gmtoffset; + +struct tm *localtime(const time_t *t) +{ time_t ti=*t; + ti-=__gmtoffset*60; + return gmtime(&ti); +} diff --git a/libnix/sources/nix/time/mktime.c b/libnix/sources/nix/time/mktime.c new file mode 100755 index 0000000..0c1337a --- /dev/null +++ b/libnix/sources/nix/time/mktime.c @@ -0,0 +1,32 @@ +#include + +static char monthtable[]= +{ 31,29,31,30,31,30,31,31,30,31,30 }; + +time_t mktime(struct tm *t) +{ + time_t tim,year; + int leapyear=0,i; + year=t->tm_year+1899; /* years from year 1 */ + tim=year/400*146097; + year%=400; + if(year==399) + leapyear++; + tim+=year/100*36524; + year%=100; + if(year==99) + leapyear--; + tim+=year/4*1461; + year%=4; + if(year==3) + leapyear++; + tim+=year*365-719162+t->tm_mday; + for(i=0;itm_mon;i++) + tim+=monthtable[i]; + if(!leapyear&&t->tm_mon>1) /* Sub 1 if no leap year */ + tim--; /* tim contains now the number of days since 1.1.1970 */ + tim=((tim*24+t->tm_hour)*60+t->tm_min)*60+t->tm_sec; + return tim; +} + +/* See gmtime.c for more details on the magic numbers :-) */ diff --git a/libnix/sources/nix/time/strftime.c b/libnix/sources/nix/time/strftime.c new file mode 100755 index 0000000..51c5c1f --- /dev/null +++ b/libnix/sources/nix/time/strftime.c @@ -0,0 +1,129 @@ +#include +#include +#include +#include + +#define ADDS(st) tmp=strftime(s,maxsize-size,(st),timeptr);break; + +#define ADDN(a,b) tmp=strfnumb(s,maxsize-size,(a),(b));break; + +#define STOR(c) if(++size<=maxsize)*s++=(c); + +#define STR(a) \ +(__localevec[LC_TIME-1]==NULL?strings[(a)-1]:GetLocaleStr(__localevec[LC_TIME-1],(a))) + +extern struct Locale *__localevec[]; + +/* All calendar strings */ +static const unsigned char *const strings[]= +{ "Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday", + "Sun","Mon","Tue","Wed","Thu","Fri","Sat", + "January","February","March","April","May","June", + "July","August","September","October","November","December", + "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec", + "","","AM","PM" }; + +static size_t strfnumb(char *s,size_t maxsize,signed int places,size_t value) +{ size_t size=0; + if(places>1) + size=strfnumb(s,maxsize,places-1,value/10); + else if(value>=10) + size=strfnumb(s,maxsize,places+1,value/10); + else + while ((places++<-1) && (++size<=maxsize)) s[size-1]=' '; + if(++size<=maxsize) + s[size-1]=(value%10+'0'); + return size; +} + +size_t strftime(char *s,size_t maxsize,const char *format,const struct tm *timeptr) +{ size_t size=0,tmp; + while(*format) + { if(*format=='%') + { tmp=0; + switch(*++format) + { case 'a': + ADDS(STR(ABDAY_1+timeptr->tm_wday)); + case 'b': + case 'h': + ADDS(STR(ABMON_1+timeptr->tm_mon)); + case 'c': + ADDS("%m/%d/%y"); + case 'd': + ADDN(2,timeptr->tm_mday); + case 'e': + ADDN(-2,timeptr->tm_mday); + case 'j': + ADDN(3,timeptr->tm_yday+1); + case 'k': + ADDN(-2,timeptr->tm_hour); + case 'l': + ADDN(-2,timeptr->tm_hour%12+(timeptr->tm_hour%12==0)*12); + case 'm': + ADDN(2,timeptr->tm_mon+1); + case 'p': + ADDS(STR(AM_STR+(timeptr->tm_hour>=12))); + case 'r': + ADDS("%I:%M:%S %p"); + case 'w': + ADDN(1,timeptr->tm_wday); + case 'x': + ADDS("%m/%d/%y %H:%M:%S"); + case 'y': + ADDN(2,timeptr->tm_year%100); + case 'A': + ADDS(STR(DAY_1+timeptr->tm_wday)); + case 'B': + ADDS(STR(MON_1+timeptr->tm_mon)); + case 'C': + ADDS("%a %b %e %H:%M:%S %Y"); + case 'D': + ADDS("%m/%d/%y"); + case 'H': + ADDN(2,timeptr->tm_hour); + case 'I': + ADDN(2,timeptr->tm_hour%12+(timeptr->tm_hour%12==0)*12); + case 'M': + ADDN(2,timeptr->tm_min); + case 'R': + ADDS("%H:%M"); + case 'S': + ADDN(2,timeptr->tm_sec); + case 'T': + case 'X': + ADDS("%H:%M:%S"); + case 'U': + ADDN(2,(timeptr->tm_yday+7-timeptr->tm_wday)/7); + case 'W': + ADDN(2,(timeptr->tm_yday+7-(6+timeptr->tm_wday)%7)/7); + case 'Y': + ADDN(4,timeptr->tm_year+1900); + case 't': + STOR('\t'); + break; + case 'n': + STOR('\n'); + break; + case '%': + STOR('%'); + break; + case '\0': + format--; + break; + } + size+=tmp; + s+=tmp; + } + else + STOR(*format); + format++; + } + STOR('\0'); + if(size>maxsize) + { s-=size; + if(maxsize) /* Don't know if this is necessary, therefore it's here ;-) */ + s[maxsize-1]='\0'; + size=1; + } + return size-1; +} diff --git a/libnix/sources/nix/time/time.c b/libnix/sources/nix/time/time.c new file mode 100755 index 0000000..fbe1d93 --- /dev/null +++ b/libnix/sources/nix/time/time.c @@ -0,0 +1,22 @@ +#include +#include +#include + +extern long __gmtoffset; + +time_t time(time_t *tloc) +{ struct DateStamp t; + time_t ti; + DateStamp(&t); /* Get timestamp */ + ti=((t.ds_Days+2922)*1440+t.ds_Minute+__gmtoffset)*60+ + t.ds_Tick/TICKS_PER_SECOND; + if(tloc!=NULL) + *tloc=ti; + return ti; +} + +/* + * 2922 is the number of days between 1.1.1970 and 1.1.1978 (2 leap years and 6 normal) + * 1440 is the number of minutes per day + * 60 is the number of seconds per minute + */ diff --git a/libnix/sources/nix13/Makefile.in b/libnix/sources/nix13/Makefile.in new file mode 100644 index 0000000..a18047f --- /dev/null +++ b/libnix/sources/nix13/Makefile.in @@ -0,0 +1,57 @@ +#### Start of system configuration section. #### + +srcdir = @srcdir@ +VPATH = @srcdir@ + +CC = @CC@ +CPP = @CPP@ +AS = as + +RANLIB = @RANLIB@ +AWK = @AWK@ + +#### End system configuration section #### + +ifneq ($(TARGET),clean) +include ../../sources/nix13/filelist +endif + +CURDIR = $(shell pwd) + +OPTIONS=-I $(srcdir)/../headers -I ../../sources/headers $(CFLAGS) -msmall-code + +SOURCEFILES=*/* + +REDEF=-D_DOSBase=___DOSBase \ + -D_UtilityBase=___UtilityBase \ + -D_MathIeeeSingBasBase=___MathIeeeSingBasBase \ + -D_MathIeeeSingTransBase=___MathIeeeSingTransBase \ + -D_MathIeeeDoubBasBase=___MathIeeeDoubBasBase \ + -D_MathIeeeDoubTransBase=___MathIeeeDoubTransBase \ + -D_LocaleBase=___LocaleBase + +%.o: %.c + $(CC) $(OPTIONS) -S $^ -o $*.S 2>&1|tee $*.err + $(CPP) -traditional $(REDEF) $*.S -o $*2.S + $(CC) $(OPTIONS) $*2.S -c -o $*.o + -rm $*.S $*2.S + -if test ! -s $*.err; then rm $*.err; fi + +.PHONY: all clean veryclean + +all: libnix13.a + +clean: + -rm -rf $(SUBDIRS) + +veryclean: + -rm -rf * + +$(foreach f,$(SUBDIRS),$(CURDIR)/$(f)): + mkdir $@ + +libnix13.a: $(foreach f,$(SUBDIRS),$(CURDIR)/$(f)) $(OBJECTS) ../../sources/nix13/makefile ../../sources/nix13/filelist + -rm -f $@ + ar -q $@ $(OBJECTS) + $(RANLIB) $@ + echo "\$$$(V)" >>$@ diff --git a/libnix/sources/nix13/extra/stricmp.c b/libnix/sources/nix13/extra/stricmp.c new file mode 100644 index 0000000..00a9e63 --- /dev/null +++ b/libnix/sources/nix13/extra/stricmp.c @@ -0,0 +1,24 @@ +#include +#include +#include + +int stricmp(const char *s1,const char *s2) +{ unsigned char c1,c2; + int r; + + for(;;) { + c1=*s1++; + if (isupper(c1)) + c1+='a'-'A'; + c2=*s2; + if (isupper(c2)) + c2+='a'-'A'; + if ((r=(char)c1-(char)c2)!=0) + break; + if (!*s2++) + break; + } + return r; +} + +ALIAS(strcasecmp,stricmp); diff --git a/libnix/sources/nix13/extra/strnicmp.c b/libnix/sources/nix13/extra/strnicmp.c new file mode 100644 index 0000000..3d71a38 --- /dev/null +++ b/libnix/sources/nix13/extra/strnicmp.c @@ -0,0 +1,27 @@ +#include +#include +#include + +int strnicmp(const char *s1,const char *s2,size_t len) +{ unsigned char c1,c2; + int r; + + if ((r=(int)len)) + for(;;) { + c1=*s1++; + if (isupper(c1)) + c1+='a'-'A'; + c2=*s2; + if (isupper(c2)) + c2+='a'-'A'; + if ((r=(char)c1-(char)c2)!=0) + break; + if (!*s2++) + break; + if (!--len) + break; + } + return r; +} + +ALIAS(strncasecmp,strnicmp); diff --git a/libnix/sources/nix13/math/__divsi3.c b/libnix/sources/nix13/math/__divsi3.c new file mode 100644 index 0000000..5798a37 --- /dev/null +++ b/libnix/sources/nix13/math/__divsi3.c @@ -0,0 +1,41 @@ +asm(" + .globl _div + .globl _ldiv + .globl ___modsi3 + .globl ___divsi3 + +| D1.L = D0.L % D1.L signed + +___modsi3: moveml sp@(4:W),d0/d1 + jbsr ___divsi4 + movel d1,d0 + rts + +| D0.L = D0.L / D1.L signed + +_div: +_ldiv: +___divsi3: moveml sp@(4:W),d0/d1 +___divsi4: movel d3,sp@- + movel d2,sp@- + moveq #0,d2 + tstl d0 + bpls LC5 + negl d0 + addql #1,d2 +LC5: movel d2,d3 + tstl d1 + bpls LC4 + negl d1 + eoriw #1,d3 +LC4: jbsr ___udivsi4 +LC3: tstw d2 + beqs LC2 + negl d0 +LC2: tstw d3 + beqs LC1 + negl d1 +LC1: movel sp@+,d2 + movel sp@+,d3 + rts +"); diff --git a/libnix/sources/nix13/math/__mulsi3.c b/libnix/sources/nix13/math/__mulsi3.c new file mode 100644 index 0000000..a91186d --- /dev/null +++ b/libnix/sources/nix13/math/__mulsi3.c @@ -0,0 +1,25 @@ +asm(" + .globl ___mulsi3 + +| D0 = D0 * D1 + +___mulsi3: moveml sp@(4),d0/d1 + movel d3,sp@- + movel d2,sp@- + movew d1,d2 + mulu d0,d2 + movel d1,d3 + swap d3 + mulu d0,d3 + swap d3 + clrw d3 + addl d3,d2 + swap d0 + mulu d1,d0 + swap d0 + clrw d0 + addl d2,d0 + movel sp@+,d2 + movel sp@+,d3 + rts +"); diff --git a/libnix/sources/nix13/math/__udivsi3.c b/libnix/sources/nix13/math/__udivsi3.c new file mode 100644 index 0000000..7a41031 --- /dev/null +++ b/libnix/sources/nix13/math/__udivsi3.c @@ -0,0 +1,50 @@ +asm(" + .globl ___umodsi3 + .globl ___udivsi3 + .globl ___udivsi4 + +| D1.L = D0.L % D1.L unsigned + +___umodsi3: moveml sp@(4:W),d0/d1 + jbsr ___udivsi4 + movel d1,d0 + rts + +| D0.L = D0.L / D1.L unsigned + +___udivsi3: moveml sp@(4:W),d0/d1 +___udivsi4: movel d3,sp@- + movel d2,sp@- + movel d1,d3 + swap d1 + tstw d1 + bnes LC4 + movew d0,d2 + clrw d0 + swap d0 + divu d3,d0 + movel d0,d1 + swap d0 + movew d2,d1 + divu d3,d1 + movew d1,d0 + clrw d1 + swap d1 + jra LC1 +LC4: movel d0,d1 + swap d0 + clrw d0 + clrw d1 + swap d1 + moveq #16-1,d2 +LC3: addl d0,d0 + addxl d1,d1 + cmpl d1,d3 + bhis LC2 + subl d3,d1 + addqw #1,d0 +LC2: dbra d2,LC3 +LC1: movel sp@+,d2 + movel sp@+,d3 + rts +"); diff --git a/libnix/sources/nix_main/Makefile.in b/libnix/sources/nix_main/Makefile.in new file mode 100644 index 0000000..a4870b4 --- /dev/null +++ b/libnix/sources/nix_main/Makefile.in @@ -0,0 +1,53 @@ +#### Start of system configuration section. #### + +srcdir = @srcdir@ +VPATH = @srcdir@ + +CC = @CC@ +CPP = @CPP@ +AS = as + +RANLIB = @RANLIB@ +AWK = @AWK@ + +#### End system configuration section #### + +OBJECTS=__nocommandline.o _main.o + +OPTIONS=-I $(srcdir)/../headers -I../../sources/headers $(CFLAGS) + +REDEF=-D_DOSBase=___DOSBase \ + -D_UtilityBase=___UtilityBase \ + -D_MathIeeeSingBasBase=___MathIeeeSingBasBase \ + -D_MathIeeeSingTransBase=___MathIeeeSingTransBase \ + -D_MathIeeeDoubBasBase=___MathIeeeDoubBasBase \ + -D_MathIeeeDoubTransBase=___MathIeeeDoubTransBase \ + -D_LocaleBase=___LocaleBase + +#Use private library bases to avoid naming collisions +%.o: %.c + $(CC) $(OPTIONS) -S $^ -o $*.S 2>&1|tee $*.err + $(CPP) -traditional $(REDEF) $*.S -o $*2.S + $(CC) $(OPTIONS) $*2.S -c -o $*.o + -rm $*.S $*2.S + -if test ! -s $*.err; then rm $*.err; fi + +.PHONY: all filelist subdirs clean veryclean + +all: libnix_main.a + +filelist: + +subdirs: + +clean: + -rm -f *.o *.err + +veryclean: clean + -rm -f libnix_main.a + +libnix_main.a: $(OBJECTS) ../../sources/nix_main/makefile + -rm -f $@ + ar -q $@ $(OBJECTS) + $(RANLIB) $@ + echo "\$$$(V)" >>$@ diff --git a/libnix/sources/nix_main/__nocommandline.c b/libnix/sources/nix_main/__nocommandline.c new file mode 100755 index 0000000..148dc23 --- /dev/null +++ b/libnix/sources/nix_main/__nocommandline.c @@ -0,0 +1,58 @@ +/* + * This is a different calling convention for main (actually its _main): + * + * int main(char *commandline); + * void exit(int returncode); + * + */ +#include +#include +#include +#include +#include +#include +#include + +extern char *__argc; /* Defined in startup */ +extern char *__commandline; +extern unsigned long __commandlen; +extern struct WBStartup *_WBenchMsg; + +/* This guarantees that this module gets linked in. + If you replace this by an own reference called + __nocommandline you get no commandline arguments */ +ALIAS(__nocommandline,__initcommandline); + +void __initcommandline(void) +{ if(_WBenchMsg==NULL) + { unsigned long len,i; + char *a; + + for(len=__commandlen,i=256;;i+=256) /* try in steps of 256 bytes */ + { if(!(__argc=a=(char *)AllocVec(i+len+4,MEMF_ANY))) + exit(20); + GetProgramName(a+1,i); /* Who am I ? */ + if(IoErr()!=ERROR_LINE_TOO_LONG) + break; + FreeVec(a); + } + *a++='\"'; + while(*a++) + ; + a[-1]='\"'; + *a++=' '; + a[len]=0; + CopyMem(__commandline,a,len); + } +} + +void __exitcommandline(void) +{ char **ac; + + if(*(ac=&__argc)!=NULL) + FreeVec(*ac); +} + +/* Add these two functions to the lists */ +ADD2INIT(__initcommandline,-40); +ADD2EXIT(__exitcommandline,-40); diff --git a/libnix/sources/nix_main/_main.c b/libnix/sources/nix_main/_main.c new file mode 100755 index 0000000..1a9e515 --- /dev/null +++ b/libnix/sources/nix_main/_main.c @@ -0,0 +1,4 @@ +#include + +/* main is now called _main! */ +ALIAS(main,_main); diff --git a/libnix/sources/nixmain/Makefile.in b/libnix/sources/nixmain/Makefile.in new file mode 100644 index 0000000..255768f --- /dev/null +++ b/libnix/sources/nixmain/Makefile.in @@ -0,0 +1,53 @@ +#### Start of system configuration section. #### + +srcdir = @srcdir@ +VPATH = @srcdir@ + +CC = @CC@ +CPP = @CPP@ +AS = as + +RANLIB = @RANLIB@ +AWK = @AWK@ + +#### End system configuration section #### + +OBJECTS=__nocommandline.o __stdiowin.o + +OPTIONS=-I $(srcdir)/../headers -I../../sources/headers $(CFLAGS) + +REDEF=-D_DOSBase=___DOSBase \ + -D_UtilityBase=___UtilityBase \ + -D_MathIeeeSingBasBase=___MathIeeeSingBasBase \ + -D_MathIeeeSingTransBase=___MathIeeeSingTransBase \ + -D_MathIeeeDoubBasBase=___MathIeeeDoubBasBase \ + -D_MathIeeeDoubTransBase=___MathIeeeDoubTransBase \ + -D_LocaleBase=___LocaleBase + +#Use private library bases to avoid naming collisions +%.o: %.c + $(CC) $(OPTIONS) -S $^ -o $*.S 2>&1|tee $*.err + $(CPP) -traditional $(REDEF) $*.S -o $*2.S + $(CC) $(OPTIONS) $*2.S -c -o $*.o + -rm $*.S $*2.S + -if test ! -s $*.err; then rm $*.err; fi + +.PHONY: all filelist subdirs clean veryclean + +all: libnixmain.a + +subdirs: + +filelist: + +clean: + -rm -f *.o *.err + +veryclean: clean + -rm -f libnixmain.a + +libnixmain.a: $(OBJECTS) ../../sources/nixmain/makefile + -rm -f $@ + ar -q $@ $(OBJECTS) + $(RANLIB) $@ + echo "\$$$(V)" >>$@ diff --git a/libnix/sources/nixmain/__nocommandline.c b/libnix/sources/nixmain/__nocommandline.c new file mode 100755 index 0000000..bbb8e1c --- /dev/null +++ b/libnix/sources/nixmain/__nocommandline.c @@ -0,0 +1,143 @@ +#include +#include +#include +#include +#include +#include +#include + +extern int __argc; /* Defined in startup */ +extern char **__argv; +extern char *__commandline; +extern unsigned long __commandlen; +extern struct WBStartup *_WBenchMsg; + +extern char __stdiowin[]; + +static char *cline=NULL; /* Copy of commandline */ +static BPTR cd=0l; /* Lock for Current Directory */ +static BPTR window=0l; /* CLI-window for start from workbench */ + +/* This guarantees that this module gets linked in. + If you replace this by an own reference called + __nocommandline you get no commandline arguments */ +ALIAS(__nocommandline,__initcommandline); + +void __initcommandline(void) +{ + struct WBStartup *wbs=_WBenchMsg; + + if(wbs!=NULL) + { if(__stdiowin[0]) + { BPTR win; + + if((window=win=Open(__stdiowin,MODE_OLDFILE))==0l) + exit(RETURN_FAIL); + SelectInput(win); + SelectOutput(win); + } + if(wbs->sm_ArgList!=NULL) /* cd to icon */ + cd=CurrentDir(DupLock(wbs->sm_ArgList->wa_Lock)); + + __argc=0; + __argv=(char **)wbs; + }else + { + char **av,*a,*cl=__commandline; + size_t i=__commandlen; + int ac; + + if(!(cline=(char *)AllocVec(i+1,MEMF_ANY))) /* get buffer */ + exit(RETURN_FAIL); + + for(a=cline,ac=1;;) /* and parse commandline */ + { + while(i&&(*cl==' '||*cl=='\t'||*cl=='\n')) + { cl++; + i--; } + if(!i) + break; + if(*cl=='\"') + { + cl++; + i--; + while(i) + { + if(*cl=='\"') + { + cl++; + i--; + break; + } + if(*cl=='*') + { + cl++; + i--; + if(!i) + break; + } + *a++=*cl++; + i--; + } + } + else + while(i&&(*cl!=' '&&*cl!='\t'&&*cl!='\n')) + { *a++=*cl++; + i--; } + *a++='\0'; + ac++; + } + /* NULL Terminated */ + if(!(__argv=av=(char **)AllocVec(((__argc=ac)+1)*sizeof(char *),MEMF_ANY|MEMF_CLEAR))) + exit(RETURN_FAIL); + + for(a=cline,i=1;ism_ArgList!=NULL) /* set original lock */ + UnLock(CurrentDir(cd)); + }else + { char *cl=cline; + + if(cl!=NULL) + { char **av=__argv; + + if(av!=NULL) + { + if(*av!=NULL) + FreeVec(*av); + FreeVec(av); + } + FreeVec(cl); + } + } +} + +/* Add these two functions to the lists */ +ADD2INIT(__initcommandline,-40); +ADD2EXIT(__exitcommandline,-40); diff --git a/libnix/sources/nixmain/__stdiowin.c b/libnix/sources/nixmain/__stdiowin.c new file mode 100755 index 0000000..6365b8b --- /dev/null +++ b/libnix/sources/nixmain/__stdiowin.c @@ -0,0 +1,3 @@ +/* Replace this with your own if you want */ + +char __stdiowin[]="CON://///AUTO/CLOSE/WAIT"; diff --git a/libnix/sources/stack/Makefile.in b/libnix/sources/stack/Makefile.in new file mode 100644 index 0000000..7b13e5a --- /dev/null +++ b/libnix/sources/stack/Makefile.in @@ -0,0 +1,46 @@ +#### Start of system configuration section. #### + +srcdir = @srcdir@ +VPATH = @srcdir@ + +CC = @CC@ +CPP = @CPP@ +AS = as + +RANLIB = @RANLIB@ +AWK = @AWK@ + +#### End system configuration section #### + +ifneq ($(TARGET),clean) +include ../../sources/stack/filelist +endif + +OPTIONS=-I $(srcdir)/../headers -I../../sources/headers $(CFLAGS) + +SOURCEFILES=*.c + +REDEF=-D_DOSBase=___DOSBase + +%.o: %.c + $(CC) $(OPTIONS) -S $^ -o $*.S 2>&1|tee $*.err + $(CPP) -traditional $(REDEF) $*.S -o $*2.S + $(CC) $(OPTIONS) $*2.S -c -o $*.o + -rm $*.S $*2.S + -if test ! -s $*.err; then rm $*.err; fi + +.PHONY: all clean veryclean + +all: libstack.a + +clean: + -rm -rf *.o + +veryclean: + -rm -rf * + +libstack.a: $(OBJECTS) ../../sources/stack/makefile ../../sources/stack/filelist + -rm -f $@ + ar -q $@ $(OBJECTS) + $(RANLIB) $@ + echo "\$$$(V)" >>$@ diff --git a/libnix/sources/stack/init_stk.c b/libnix/sources/stack/init_stk.c new file mode 100755 index 0000000..63c1f2e --- /dev/null +++ b/libnix/sources/stack/init_stk.c @@ -0,0 +1,34 @@ +#include +#include +#include + +extern ULONG __stk_safezone; + +APTR *__stackborders,__stk_limit; + +/* + * This way to find the bottom of the current stackframe + * is the way descibed in the amiga-guru-book. + * + * Note that it's of no use to check if the actual parameters are set + * correctly (disabling stackextension if not) because a program will + * crash anyway in that case (if you check against the wrong border or + * not at all). + * But with wrong parameters you can probably raise a stackextend too + * soon - thus gaining *correct* (for following stackextends) stackbounds + * at the cost of only some memory. + */ + +void __init_stk(void) +{ + struct Process *me = (struct Process *)FindTask(NULL); + UBYTE *sl; + + __stackborders = (APTR *)(sl = (UBYTE *)&me->pr_Task.tc_SPLower); + if (me->pr_CLI) + sl = /*sizeof(ULONG)+*/ (UBYTE *)me->pr_ReturnAddr - *(ULONG *)me->pr_ReturnAddr; + /*^^^^^^^^^^^^^^ need not be that precise */ + __stk_limit = (sl += __stk_safezone); +} + +ADD2INIT(__init_stk,-50); diff --git a/libnix/sources/stack/link_a5_0_f.c b/libnix/sources/stack/link_a5_0_f.c new file mode 100755 index 0000000..3882157 --- /dev/null +++ b/libnix/sources/stack/link_a5_0_f.c @@ -0,0 +1,27 @@ +#include + +asm(" + .text + .even + .globl ___link_a5_0_f + .globl ___sub_0_sp_f + +___link_a5_0_f: + movel sp@+,a0 + cmpl "A4(___stk_limit)",sp + jcc l0 + jbsr l2 +l0: link a5,#0:W + jmp a0@ + +___sub_0_sp_f: + movel sp@+,a0 + cmpl "A4(___stk_limit)",sp + jcc l1 + jbsr l2 +l1: jmp a0@ + +l2: moveq #0,d0 + moveq #0,d1 + jra ___stkext_f +"); diff --git a/libnix/sources/stack/link_a5_d0_f.c b/libnix/sources/stack/link_a5_d0_f.c new file mode 100755 index 0000000..9e2ed12 --- /dev/null +++ b/libnix/sources/stack/link_a5_d0_f.c @@ -0,0 +1,32 @@ +#include + +asm(" + .text + .even + .globl ___link_a5_d0_f + .globl ___sub_d0_sp_f + +___link_a5_d0_f: + movel sp@+,a0 + movel sp,d1 + subl d0,d1 + cmpl "A4(___stk_limit)",d1 + jcc l0 + jbsr l2 +l0: link a5,#0:W + subl d0,sp + jmp a0@ + +___sub_d0_sp_f: + movel sp@+,a0 + movel sp,d1 + subl d0,d1 + cmpl "A4(___stk_limit)",d1 + jcc l1 + jbsr l2 +l1: subl d0,sp + jmp a0@ + +l2: moveq #0,d1 + jra ___stkext_f +"); diff --git a/libnix/sources/stack/longjmp.c b/libnix/sources/stack/longjmp.c new file mode 100755 index 0000000..d3f656d --- /dev/null +++ b/libnix/sources/stack/longjmp.c @@ -0,0 +1,18 @@ +asm(" + .text + .even + .globl _longjmp + +_longjmp: + addql #4,sp | returns to another address + movel sp@+,a0 | get address of jmp_buf + movel sp@+,d2 | get returncode + movel a0@(48:W),d0 + jbsr ___stkrst | restore sp + movel d2,d0 + jne l0 | != 0 -> ok + moveql #1,d0 +l0: movel a0@+,sp@ | set returnaddress + moveml a0@,#0x7cfc | restore all registers except scratch and sp + rts +"); diff --git a/libnix/sources/stack/stk_argbytes.c b/libnix/sources/stack/stk_argbytes.c new file mode 100755 index 0000000..0222f89 --- /dev/null +++ b/libnix/sources/stack/stk_argbytes.c @@ -0,0 +1 @@ +unsigned long __stk_argbytes=256; diff --git a/libnix/sources/stack/stk_minframe.c b/libnix/sources/stack/stk_minframe.c new file mode 100755 index 0000000..bb22e10 --- /dev/null +++ b/libnix/sources/stack/stk_minframe.c @@ -0,0 +1 @@ +unsigned long __stk_minframe=32768; diff --git a/libnix/sources/stack/stk_safezone.c b/libnix/sources/stack/stk_safezone.c new file mode 100755 index 0000000..942948e --- /dev/null +++ b/libnix/sources/stack/stk_safezone.c @@ -0,0 +1 @@ +unsigned long __stk_safezone=2048; diff --git a/libnix/sources/stack/stkchk_d0.c b/libnix/sources/stack/stkchk_d0.c new file mode 100755 index 0000000..05241aa --- /dev/null +++ b/libnix/sources/stack/stkchk_d0.c @@ -0,0 +1,22 @@ +#include + +asm(" + .text + .even + .globl ___stkchk_d0 + .globl ___stkchk_0 + +___stkchk_d0: + negl d0 + addl sp,d0 + cmpl "A4(___stk_limit)",d0 + jcs L0 + rts + +___stkchk_0: + cmpl "A4(___stk_limit)",sp + jcs L0 + rts + +L0: jra ___stkovf +"); diff --git a/libnix/sources/stack/stkext.c b/libnix/sources/stack/stkext.c new file mode 100755 index 0000000..8952046 --- /dev/null +++ b/libnix/sources/stack/stkext.c @@ -0,0 +1,139 @@ +#include +#include + +asm(" + .text + .even + .globl ___stkext_f + .globl ___stkext + .globl ___exit_stk + .globl ___stk_free + +___stkext_f: + movel a0,sp@- + movel sp,a0 | memorize sp + moveml #0xc062,sp@- | preserves all registers + movel sp,a2 | memorize sp + addl #28:W,d1 | Used by this function itself + movel "A4(___stackborders)",a1| get upper border of stack in a1 + movel a1@(4:W),a1 + tstl "A4(___used_stack)" + bne l0 + movel "A4(___SaveSP)",a1 +l0: jbsr ___stkext | change to a stackframe with d0 bytes + movel "A4(___used_stack)",a6 | fix stored sp + addl d1,a6@(12:W) + movel a2,d0 | calculate number of bytes to copy + addl "A4(___stk_argbytes)",d0| to new stackframe in d0 + addl d1,d0 + cmpl a1,d0 | never copy over the bottom of the stack + jls l1 + movel a1,d0 +l1: subl a0,d0 | copy + subl d0,sp + movel sp,a1 + movel "A4(_SysBase)",a6 + jsr a6@(-0x270) | CopyMem(src:a0,dst:a1,siz:d0) + movel a2,a0 + moveml a0@+,#0x4603 + movel sp,a0 | Prepare cleanup + addl d1,a0 + movel #___stkrst_f,a0@(8:W) + movel sp@+,a0 + rts + +___stkext: + movel a0,sp@- + moveml #0xf072,sp@- | preserves all registers + movel "A4(___stk_safezone)",d3 + lea "A4(___stk_limit)",a2 + lea "A4(___used_stack)",a3 + addql #4,a3 + movel "A4(_SysBase)",a6 + movel d0,d2 + addl d3,d2 + addl "A4(___stk_argbytes)",d2| required stack + movel a3@,d0 | Look for a spare stackframe + jeq l4 +l3: movel d0,a0 + movel a0@,a3@ | Remove spare stackframe from list + movel a0@(8:W),d0 | Test spare stackframe + subl a0@(4:W),d0 + cmpl d0,d2 + jls l7 + moveq #20,d1 | Not big enough + addl d1,d0 + movel a0,a1 + jsr a6@(-0xd2) | FreeMem(mem:a1,siz:d0) + movel a3@,d0 + jne l3 +l4: moveq #20,d0 + addl d0,d2 | no more stackframes - allocate a new one + movel "A4(___stk_minframe)",d0 + cmpl d0,d2 + jge l5 + movel d0,d2 +l5: movel d2,d0 + moveql #1,d1 | MEMF_PUBLIC + jsr a6@(-0xc6) | AllocMem(siz:d0,typ:d1) + movel d0,a0 + movel a0,d0 + jne l6 + jbsr ___stkovf | allocation failed +l6: moveq #20,d0 + addl a0,d0 + movel d0,a0@(4:W) + addl a0,d2 | prepare new frame for use + movel d2,a0@(8:W) +l7: movel a3@-,a0@ | Add it to the used list + movel a0,a3@ + addql #4,a0 + movel a2@,a0@(12:W) + movel a0@,a2@ | Prepare ___top_of_stackframe variable + addl d3,a2@ + lea a0@(4:W),a2 + movel a2@+,a2@ | Prepare target sp + jsr a6@(-0x2dc) | StackSwap(sss:a0) + moveq #40,d0 + movel a2@,a0 + addl d0,a2@ | Fix stored sp + moveml a0@+,#0x4e0f + movel a0@(4:W),sp@- | prepare returnaddress + movel a0@,a0 + rts + +___exit_stk: + tstl "A4(___used_stack)" + jeq ___stk_free + lea sp@(12:W),a0 + movel "A4(___SaveSP)",d0 | Go back to first stackframe + jbsr ___stkrst + movel a0@,sp@- | restore argument of exit() + movel a0@-,sp@- | returnaddress for exit() + movel a0@-,sp@- | returnaddress for callfuncs() + movel a0@-,sp@- | our returnaddress +| jbsr ___stk_free +| rts + +___stk_free: + movel a2,sp@- + movel a6,sp@- | Free all unused stackframes + movel "A4(_SysBase)",a6 + lea "A4(___used_stack)",a2 + addql #4,a2 + movel a2@,d0 | Remove spare stackframe from list + jeq l9 +l8: movel d0,a1 + movel a1@,a2@ + moveq #20,d0 + addl a1@(8:W),d0 | Calculate size + subl a1@(4:W),d0 + jsr a6@(-0xd2) | FreeMem(mem:a1,siz:d0) + movel a2@,d0 + jne l8 +l9: movel sp@+,a6 + movel sp@+,a2 + rts +"); + +ADD2EXIT(__exit_stk,-50); diff --git a/libnix/sources/stack/stkovf.c b/libnix/sources/stack/stkovf.c new file mode 100755 index 0000000..8150fc9 --- /dev/null +++ b/libnix/sources/stack/stkovf.c @@ -0,0 +1,11 @@ +#include + +asm(" + .text + .even + .globl ___stkovf + +___stkovf: + clrl "A4(___stk_limit)" | generate no more stackoverflows + jra __XCOVF +"); diff --git a/libnix/sources/stack/stkrst.c b/libnix/sources/stack/stkrst.c new file mode 100755 index 0000000..efc168b --- /dev/null +++ b/libnix/sources/stack/stkrst.c @@ -0,0 +1,68 @@ +#include + +asm(" +| the stack consists of a single linked linear list like this: +| +| struct stack +| { struct stack *next; points to the next underlying structure +| struct StackSwapStruct sss; holds previous stackframe when used, +| itself when unused, the current stackborders +| are in the task structure ;-) +| APTR top_of_stackframe; } previous variable value +| Note: stack->sss.stk_Lower is not reliable +| +| For better performance stackframes are cached in a 'unused' list when +| not in use. (AllocMem() is really a performance killer). +| + +| +| Caution: +| Race condition ahead! exec might preempt our task at any time storing +| the current register set on top of the free stack. NEVER set a sp higher +| than the location of important data. +| + .comm ___used_stack,8 | pointer to used stackframes, + | pointer to unused stackframes + .text + .even + .globl ___stkrst + +___stkrst: + exg d0,a3 | better use an address register + movel a2,sp@- + moveml d0/d1/a0/a1/a5/a6,sp@- + movel sp,a2 + lea "A4(___used_stack)",a5 + tstl a5@ + jeq l0 | No previous stackframe +l2: movel "A4(___stackborders)",a0 + cmpl a0@,a3 + jcs l1 + cmpl a0@(4:W),a3 + jle l0 | Stackpointer points to current frame +l1: movel "A4(_SysBase)",a6 | Go to previous stack + movel a5,a1 + movel a1@,a0 + movel a0@,a1@+ + movel a1@,a0@ + movel a0,a1@ + addql #4,a0 + movel a0@(12:W),"A4(___stk_limit)" + jsr a6@(-0x2dc) | StackSwap(sss:a0) + tstl a5@ + jne l2 +l0: moveml a2@+,d0/d1/a0/a1/a5/a6 | Restore registers + movel a2@(4:W),sp@- | preserve returnaddress on current stackframe + movel a2@,a2 | be careful to not clobber any registers now + cmpl sp,a3 | Depending on whether sp moves up or down + jls l3 | use one of two possible routines + movel sp@,a3@- | moves up (pop): copy returnaddress first + movel a3,sp | then set sp + jra l4 +l3: exg a3,sp | moves down (push): set sp first + movel a3@,sp@- | then copy returnaddress + movel sp,a3 +l4: exg d0,a3 | move back + addql #4,d0 | compensate for returnaddress + rts +"); diff --git a/libnix/sources/stack/stkrst_f.c b/libnix/sources/stack/stkrst_f.c new file mode 100755 index 0000000..e2527c0 --- /dev/null +++ b/libnix/sources/stack/stkrst_f.c @@ -0,0 +1,24 @@ +#include + +asm(" + .text + .even + .globl ___stkrst_f + +___stkrst_f: + movel a2,sp@- + moveml #0xc0c2,sp@- | Preserve all registers + movel sp,a2 + lea "A4(___used_stack)",a1 | Move current stackframe to the spares list + movel a1@,a0 + movel a0@,a1@+ + movel a1@,a0@ + movel a0,a1@ + addql #4,a0 | Return to old stackframe + movel a0@(12:W),"A4(___stk_limit)" + movel "A4(_SysBase)",a6 + jsr a6@(-0x2dc) | StackSwap(sss:a0) + moveml a2@+,#0x4303 + movel a2@,a2 + rts +"); diff --git a/libnix/sources/stack/sub_d0_sp.c b/libnix/sources/stack/sub_d0_sp.c new file mode 100755 index 0000000..75fbed3 --- /dev/null +++ b/libnix/sources/stack/sub_d0_sp.c @@ -0,0 +1,29 @@ +#include +#include + +asm(" + .text + .even + .globl ___sub_d0_sp + .globl ___unlk_a5_rts + +___sub_d0_sp: + movel sp@+,a0 + movel sp,d1 + subl d0,d1 + cmpl "A4(___stk_limit)",d1 + jcc l0 + jbsr ___stkext +l0: subl d0,sp + jmp a0@ + +___unlk_a5_rts: + movel d0,a0 + movel a5,d0 + jbsr ___stkrst + movel a0,d0 + movel sp@+,a5 + rts +"); + +ALIAS(__move_d0_sp,__stkrst); diff --git a/libnix/sources/stack/xcovf.c b/libnix/sources/stack/xcovf.c new file mode 100755 index 0000000..a1bd1e7 --- /dev/null +++ b/libnix/sources/stack/xcovf.c @@ -0,0 +1,10 @@ +#include +#include + +void __request(const char *text); + +void _XCOVF(void) /* stack overflow handler */ +{ + __request("Stack overflow"); + exit(RETURN_FAIL); +} diff --git a/libnix/sources/startup/Makefile.in b/libnix/sources/startup/Makefile.in new file mode 100644 index 0000000..7ff6cbb --- /dev/null +++ b/libnix/sources/startup/Makefile.in @@ -0,0 +1,55 @@ +# make startup-files +# 13-Apr-94 G. Nikl +# 14-Apr-94 M. Fleischer clean+veryclean added + +#### Start of system configuration section. #### + +srcdir = @srcdir@ +VPATH = @srcdir@ + +CC = @CC@ +CPP = @CPP@ +AS = as + +RANLIB = @RANLIB@ +AWK = @AWK@ + +#### End system configuration section #### + +OPTIONS=-I $(srcdir)/../headers -I ../../sources/headers -O -fomit-frame-pointer + +%.o: %.c + $(CC) $(OPTIONS) -c $^ 2>&1|tee $*.err + -if test ! -s $*.err; then rm $*.err; fi + echo "\$$$(V)" >>$@ + +.PHONY: all filelist subdirs clean veryclean + +all: nrcrt0.o nbcrt0.o ncrt0.o libinit.o libinitr.o#devinit.o + +subdirs: + +filelist: + +clean: + +veryclean: + -rm *.o + +# baserelative resident startup-code + +nrcrt0.o: nrcrt0.S + $(CC) -c $^ + echo "\$$$(V)" >>$@ + +# baserelative startup code + +nbcrt0.o: nbcrt0.S + $(CC) -c $^ + echo "\$$$(V)" >>$@ + +# normal (=large) startup code + +ncrt0.o: ncrt0.S + $(CC) -c $^ + echo "\$$$(V)" >>$@ diff --git a/libnix/sources/startup/devinit.c b/libnix/sources/startup/devinit.c new file mode 100755 index 0000000..aa98d4c --- /dev/null +++ b/libnix/sources/startup/devinit.c @@ -0,0 +1,314 @@ +/******************************************************************************/ +/* */ +/* this works with gcc too and makes life easier */ +/* */ +/******************************************************************************/ + +#define _USEOLDEXEC_ + +/******************************************************************************/ +/* */ +/* includes */ +/* */ +/******************************************************************************/ + +#include +#include +#include +#include "libinit.h" +#include "stabs.h" + +/******************************************************************************/ +/* */ +/* *** FIRST *** function - prevents a crash when called from CLI! */ +/* */ +/******************************************************************************/ + +int safefail() +{ + return -1; +} + +/******************************************************************************/ +/* */ +/* imports */ +/* */ +/******************************************************************************/ + +extern const UWORD DevVersion; +extern const UWORD DevRevision; + +extern const BYTE DevName[]; +extern const BYTE DevIdString[]; + +extern APTR __FuncTable__[]; + +extern int __UserDevInit(_DEV *); +extern int __UserDevOpen(struct IORequest *,ULONG,ULONG); +extern VOID __UserDevClose(); +extern VOID __UserDevCleanUp(); + +/******************************************************************************/ +/* */ +/* resident structure */ +/* */ +/******************************************************************************/ + +const APTR InitTab[4]; + +static const struct Resident RomTag = { + RTC_MATCHWORD, + (struct Resident *)&RomTag, + (APTR)((&RomTag)+1), + RTF_AUTOINIT, + 0, + NT_DEVICE, + 0, + (BYTE *)DevName, + (BYTE *)DevIdString, + (APTR)&InitTab +}; + +/******************************************************************************/ +/* */ +/* autoinit table for use with initial MakeLibrary() */ +/* */ +/******************************************************************************/ + +const APTR InitTab[4] = { + (APTR)sizeof(_DEV), + (APTR)&__FuncTable__[1], + 0, + (APTR)DevInit +}; + +/******************************************************************************/ +/* */ +/* support function(s) to be inlined */ +/* */ +/******************************************************************************/ + +static inline APTR __GetDataSeg() +{ + APTR res; + asm ("lea ___a4_init,%0" : "=a" (res)); + return res; +} + +static inline ULONG __BSize() +{ + ULONG res; + asm ("movel #___bss_size,%0" : "=d" (res)); + return res; +} + +static inline ULONG *__GetBssStart() +{ + ULONG *res; + asm ("lea __edata,%0" : "=a" (res)); + return res; +} + +/******************************************************************************/ +/* */ +/* initialization function called by MakeLibrary() */ +/* */ +/******************************************************************************/ + +struct Library *DevInit() +{ + register APTR DataSeg asm("a4"); + register APTR SegList asm("a0"); + register struct Library *dev asm("d0"); + _DEV *Device = (_DEV *)dev; + ULONG size,result; + + /* init library base */ + + Device->DevNode.lib_Node.ln_Type = NT_DEVICE; + Device->DevNode.lib_Node.ln_Name = (UBYTE *)DevName; + Device->DevNode.lib_Flags = LIBF_CHANGED | LIBF_SUMUSED; + Device->DevNode.lib_Version = (UWORD)DevVersion; + Device->DevNode.lib_Revision = (UWORD)DevRevision; + Device->DevNode.lib_IdString = (UBYTE *)DevIdString; + Device->SegList = SegList; + Device->DataSeg = __GetDataSeg(); + + /* clear the bss part */ + + if ((size=__BSize())) + { + ULONG *p=__GetBssStart(); + + do + { + *p++=0; + } + while((size-=sizeof(ULONG))); + } + + DataSeg=Device->DataSeg; asm volatile ("" : /**/ : "r" (DataSeg)); + + /* now call user-init */ + + result=__UserDevInit(Device); + + /* all ok? */ + + if (result!=0) + Device=NULL; + + /* this will be added to SysBase->DevList or NULL (init error) */ + + return (struct Library *)Device; +} + +/******************************************************************************/ +/* */ +/* DevOpen() will be called for every OpenDevice() */ +/* */ +/* !!! CAUTION: This function runs in a forbidden state !!! */ +/* */ +/******************************************************************************/ + +VOID DevOpen() +{ + register struct Library *dev asm("a6"); + register struct IORequest *iorq asm("a1"); + register ULONG flags asm("d1"); + register ULONG unit asm("d0"); + register APTR DataSeg asm("a4"); + int result; + + /* any memory allocation can cause a call of THIS device expunge vector. + if OpenCnt is zero the library might go away ... so fake a user :-) */ + + dev->lib_OpenCnt++; + + DataSeg=((_DEV *)dev)->DataSeg; asm volatile ("" : /**/ : "r" (DataSeg)); + + /* call user-open */ + + result=__UserDevOpen(iorq,unit,flags); + + if (result==0) + { + /* clear delayed expunge flag */ + + dev->lib_Flags &= ~LIBF_DELEXP; + + /* one new user */ + + dev->lib_OpenCnt++; + } + + /* end of expunge protection */ + + --dev->lib_OpenCnt; + + /* exec returns io_error later */ +} + +/******************************************************************************/ +/* */ +/* DevClose() will be called for every CloseDevice() */ +/* */ +/* !!! CAUTION: This function runs in a forbidden state !!! */ +/* */ +/******************************************************************************/ + +APTR DevClose() +{ + register struct Library *dev asm("a6"); + register struct IORequest *iorq asm("a1"); + register APTR DataSeg asm("a4"); + APTR SegList=0; + + DataSeg=((_DEV *)dev)->DataSeg; asm volatile ("" : /**/ : "r" (DataSeg)); + + __UserDevClose(iorq); + + /* one less user */ + + if (--dev->lib_OpenCnt==0 && (dev->lib_Flags&LIBF_DELEXP)) + SegList=DevExpunge(); + + /* SegList or NULL (still in use) */ + + return SegList; +} + +/******************************************************************************/ +/* */ +/* remove device from memory if possible */ +/* */ +/* !!! CAUTION: This function runs in a forbidden state !!! */ +/* */ +/******************************************************************************/ + +APTR DevExpunge() +{ + register struct Library *dev asm("a6"); + register APTR DataSeg asm("a4"); + _DEV *Device = (_DEV *)dev; + APTR SegList=0; + + /* set delayed expunge flag */ + + Device->DevNode.lib_Flags |= LIBF_DELEXP; + + /* still in use? */ + + if (Device->DevNode.lib_OpenCnt == 0) + { + ULONG NegSize; + + /* return the seglist for UnLoadSeg() */ + + SegList = Device->SegList; + + /* remove device from SysBase->DevList */ + + Remove((struct Node *)Device); + + DataSeg=Device->DataSeg; asm volatile ("" : /**/ : "r" (DataSeg)); + + /* now call user-exit */ + + __UserDevCleanup(); + + /* free device */ + + NegSize = Device->DevNode.lib_NegSize; + FreeMem((APTR)((UBYTE *)Device-(UBYTE *)NegSize),NegSize+Device->DevNode.lib_PosSize); + } + return SegList; +} + +/******************************************************************************/ +/* */ +/* a do nothing stub (required!) */ +/* */ +/******************************************************************************/ + +APTR DevExtFunc() +{ + return 0; +} + +/******************************************************************************/ +/* */ +/* add these functions to 'funclist' */ +/* */ +/******************************************************************************/ + +ADD2LIST(DevOpen,__FuncTable__,22); +ADD2LIST(DevClose,__FuncTable__,22); +ADD2LIST(DevExpunge,__FuncTable__,22); +ADD2LIST(DevExtFunc,__FuncTable__,22); + +/******************************************************************************/ +/* */ +/* end of devinit.c */ +/* */ +/******************************************************************************/ diff --git a/libnix/sources/startup/libinit.c b/libnix/sources/startup/libinit.c new file mode 100755 index 0000000..b6261e3 --- /dev/null +++ b/libnix/sources/startup/libinit.c @@ -0,0 +1,240 @@ +/******************************************************************************/ +/* */ +/* our include */ +/* */ +/******************************************************************************/ + +#include "libinit.h" + +/******************************************************************************/ +/* */ +/* *** FIRST *** function - prevents a crash when called from CLI! */ +/* */ +/******************************************************************************/ + +LONG safefail(VOID) +{ + return -1; +} + +/******************************************************************************/ +/* */ +/* a do nothing stub (required!) */ +/* */ +/******************************************************************************/ + +LONG +LibExtFunc(VOID) +{ + return 0; +} + +/******************************************************************************/ +/* */ +/* remove library from memory if possible */ +/* */ +/* !!! CAUTION: This function runs in a forbidden state !!! */ +/* */ +/******************************************************************************/ + +LONG +LibExpunge(REG(a6,struct LibBase *lib)) +{ + LONG SegList = 0; + + /* set delayed expunge flag */ + + lib->LibNode.lib_Flags |= LIBF_DELEXP; + + /* still in use? */ + + if (!lib->LibNode.lib_OpenCnt) { + + APTR SysBase = lib->SysBase; + + /* remove library from SysBase->LibList */ + + Remove((struct Node *)lib); + + /* now call user-exit */ + + __UserLibCleanup(lib->DataSeg); + + /* return the seglist for UnLoadSeg() */ + + SegList = lib->SegList; + + /* free library */ + + FreeMem((UBYTE *)lib-lib->LibNode.lib_NegSize,lib->LibNode.lib_NegSize+lib->LibNode.lib_PosSize); + } + + return SegList; +} + +/******************************************************************************/ +/* */ +/* LibClose() will be called for every CloseLibrary() */ +/* */ +/* !!! CAUTION: This function runs in a forbidden state !!! */ +/* */ +/******************************************************************************/ + +LONG +LibClose(REG(a6,struct LibBase *lib)) +{ + LONG SegList = 0; + + /* one less user */ + + if (!--lib->LibNode.lib_OpenCnt && (lib->LibNode.lib_Flags & LIBF_DELEXP)) + SegList = LibExpunge(lib); + + /* SegList or NULL (still in use) */ + + return SegList; +} + +/******************************************************************************/ +/* */ +/* LibOpen() will be called for every OpenLibrary() */ +/* */ +/* !!! CAUTION: This function runs in a forbidden state !!! */ +/* */ +/******************************************************************************/ + +APTR +LibOpen(REG(a6,struct LibBase *lib)) +{ + /* clear delayed expunge flag */ + + lib->LibNode.lib_Flags &= ~LIBF_DELEXP; + + /* one new user */ + + lib->LibNode.lib_OpenCnt++; + + /* return basePtr */ + + return lib; +} + +/******************************************************************************/ +/* */ +/* initialization function called by MakeLibrary() */ +/* */ +/******************************************************************************/ + +static __inline APTR __GetDataSeg(void) +{ APTR res; + + __asm("lea ___a4_init,%0" : "=a" (res)); return res; +} + +static __inline ULONG __BSize(void) +{ ULONG res; + + __asm("movel #___bss_size,%0" : "=d" (res)); return res; +} + +static __inline APTR __GetBssStart(void) +{ APTR res; + + __asm("lea __edata,%0" : "=a" (res)); return res; +} + +APTR +LibInit(REG(a0,LONG SegList),REG(d0,struct LibBase *lib),REG(a6,struct Library *SysBase)) +{ ULONG size; + + /* set up header data */ + + lib->LibNode.lib_Node.ln_Type = NT_LIBRARY; + lib->LibNode.lib_Node.ln_Name = (char *)LibName; + lib->LibNode.lib_Flags = LIBF_CHANGED | LIBF_SUMUSED; + lib->LibNode.lib_Version = (UWORD)LibVersion; + lib->LibNode.lib_Revision = (UWORD)LibRevision; + lib->LibNode.lib_IdString = (char *)LibIdString; + + /* setup private data */ + + lib->SegList = SegList; + lib->SysBase = SysBase; + +#if 1 + + lib->DataSeg = __GetDataSeg(); + + /* clear the bss part */ + + if ((size=__BSize())) { + + ULONG *p = __GetBssStart(); + + do { + *p++ = 0; + } while ((size-=sizeof(*p))); + } + +#endif + + /* now call user-init */ + + if (!__UserLibInit(&lib->LibNode,lib->DataSeg)) { + FreeMem((UBYTE *)lib-lib->LibNode.lib_NegSize,lib->LibNode.lib_NegSize+lib->LibNode.lib_PosSize); + lib = NULL; + } + + /* this will be added to SysBase->LibList or NULL (init error) */ + + return lib; +} + +/******************************************************************************/ +/* */ +/* autoinit table for use with initial MakeLibrary() */ +/* */ +/******************************************************************************/ + +static const APTR InitTab[] = { + (APTR)sizeof(struct LibBase), + (APTR)&__FuncTable__[1], + (APTR)NULL, + (APTR)&LibInit +}; + +/******************************************************************************/ +/* */ +/* resident structure */ +/* */ +/******************************************************************************/ + +static const struct Resident RomTag = { + RTC_MATCHWORD, + (struct Resident *)&RomTag, + (struct Resident *)&RomTag+1, + RTF_AUTOINIT, + 0, + NT_LIBRARY, + 0, + (char *)LibName, + (char *)LibIdString, + (APTR)&InitTab +}; + +/******************************************************************************/ +/* */ +/* add these functions to 'funclist' */ +/* */ +/******************************************************************************/ + +ADD2LIST(LibOpen,__FuncTable__,22); +ADD2LIST(LibClose,__FuncTable__,22); +ADD2LIST(LibExpunge,__FuncTable__,22); +ADD2LIST(LibExtFunc,__FuncTable__,22); + +/******************************************************************************/ +/* */ +/* end of libinit.c */ +/* */ +/******************************************************************************/ diff --git a/libnix/sources/startup/libinitr.c b/libnix/sources/startup/libinitr.c new file mode 100755 index 0000000..36aa330 --- /dev/null +++ b/libnix/sources/startup/libinitr.c @@ -0,0 +1,283 @@ +/******************************************************************************/ +/* */ +/* our include */ +/* */ +/******************************************************************************/ + +#define EXTENDED /* multibase library */ +#include "libinit.h" + +/******************************************************************************/ +/* */ +/* *** FIRST *** function - prevents a crash when called from CLI! */ +/* */ +/******************************************************************************/ + +LONG safefail(VOID) +{ + return -1; +} + +/******************************************************************************/ +/* */ +/* a do nothing stub (required!) */ +/* */ +/******************************************************************************/ + +LONG +LibExtFunc(VOID) +{ + return 0; +} + +/******************************************************************************/ +/* */ +/* remove library from memory if possible */ +/* */ +/* !!! CAUTION: This function runs in a forbidden state !!! */ +/* */ +/******************************************************************************/ + +LONG +LibExpunge(REG(a6,struct LibBase *lib)) +{ + LONG SegList = 0; + + /* get 'real' base */ + + lib = lib->Parent; + + /* set delayed expunge flag */ + + lib->LibNode.lib_Flags |= LIBF_DELEXP; + + /* still in use? */ + + if (!lib->LibNode.lib_OpenCnt) { + + APTR SysBase = lib->SysBase; + + /* remove library from SysBase->LibList */ + + Remove((struct Node *)lib); + + /* return the seglist for UnLoadSeg() */ + + SegList = lib->SegList; + + /* free library */ + + FreeMem((UBYTE *)lib-lib->LibNode.lib_NegSize,lib->LibNode.lib_NegSize+lib->LibNode.lib_PosSize); + } + + return SegList; +} + +/******************************************************************************/ +/* */ +/* LibClose() will be called for every CloseLibrary() */ +/* */ +/* !!! CAUTION: This function runs in a forbidden state !!! */ +/* */ +/******************************************************************************/ + +LONG +LibClose(REG(a6,struct LibBase *lib)) +{ + APTR SysBase = lib->SysBase; + LONG SegList = 0; + + if (!--lib->Parent->LibNode.lib_OpenCnt && (lib->LibNode.lib_Flags & LIBF_DELEXP)) + SegList = LibExpunge(lib); + + /* call user-exit */ + + __UserLibCleanup(lib->DataSeg); + + /* free library */ + + FreeMem((UBYTE *)lib-lib->LibNode.lib_NegSize,lib->LibNode.lib_NegSize+lib->LibNode.lib_PosSize); + + /* SegList or NULL (still in use) */ + + return SegList; +} + +/******************************************************************************/ +/* */ +/* LibOpen() will be called for every OpenLibrary() */ +/* */ +/* !!! CAUTION: This function runs in a forbidden state !!! */ +/* */ +/******************************************************************************/ + +static __inline ULONG __DSize(void) +{ ULONG res; + + __asm("movel #___data_size,%0" : "=d" (res)); return res; +} + +APTR +LibOpen(REG(a6,struct LibBase *lib)) +{ + APTR dataseg, SysBase = lib->SysBase; + struct LibBase *child; + + /* any memory allocation can cause a call of THIS library expunge vector. + if OpenCnt is zero the library might go away ... So fake a user :-) */ + + lib->LibNode.lib_OpenCnt++; + + /* create new library base */ + + if ((child=(struct LibBase *)MakeLibrary(&__FuncTable__[1],NULL,(ULONG (*)())LibInit,sizeof(*lib)+lib->DataSize,0))) { + + LONG *relocs,numrel; + + /* one user */ + + child->LibNode.lib_OpenCnt++; + + /* copy dataseg */ + + CopyMem(child->DataSeg,dataseg=(UBYTE *)child+sizeof(*lib),__DSize()); + + /* relocate */ + + relocs = __datadata_relocs; + if ((numrel=*relocs++)) { + LONG dist = (LONG)child->DataSeg - (LONG)dataseg; + + do { + *(LONG *)((LONG)dataseg + *relocs++) -= dist; + } while (--numrel); + } + child->DataSeg = (dataseg=(UBYTE *)dataseg+0x7ffe); + + /* our 'real' parent */ + + child->Parent = lib; + + /* assume user-init won't fail */ + + lib->LibNode.lib_Flags &= LIBF_DELEXP; + lib->LibNode.lib_OpenCnt++; + + /* now call user-init */ + + if (!__UserLibInit(&child->LibNode,dataseg)) { + FreeMem((UBYTE *)child-child->LibNode.lib_NegSize,child->LibNode.lib_NegSize+sizeof(*child)+child->DataSize); + --lib->LibNode.lib_OpenCnt; + child = NULL; + } + } + + /* end of expunge protection */ + + --lib->LibNode.lib_OpenCnt; + + return child; +} + +/******************************************************************************/ +/* */ +/* initialization function called by MakeLibrary() */ +/* */ +/******************************************************************************/ + +static __inline APTR __GetDataSeg(void) +{ APTR res; + + __asm("lea ___a4_init-0x7ffe,%0" : "=a" (res)); return res; +} + +static __inline ULONG __GetDBSize(void) +{ ULONG res; + + __asm("movel #___data_size,%0; addl #___bss_size,%0" : "=d" (res)); return res; +} + +APTR +LibInit(REG(a0,LONG SegList),REG(d0,struct LibBase *lib),REG(a6,struct Library *SysBase)) +{ + /* set up header data */ + + lib->LibNode.lib_Node.ln_Type = NT_LIBRARY; + lib->LibNode.lib_Node.ln_Name = (char *)LibName; + lib->LibNode.lib_Flags = LIBF_CHANGED | LIBF_SUMUSED; + lib->LibNode.lib_Version = (UWORD)LibVersion; + lib->LibNode.lib_Revision = (UWORD)LibRevision; + lib->LibNode.lib_IdString = (char *)LibIdString; + + /* setup private data */ + + lib->SegList = SegList; + lib->SysBase = SysBase; + lib->DataSeg = __GetDataSeg(); + lib->DataSize = __GetDBSize(); + lib->Parent = lib; + + /* this will be added to SysBase->LibList */ + + return lib; +} +/******************************************************************************/ +/* */ +/* autoinit table for use with initial MakeLibrary() */ +/* */ +/******************************************************************************/ + +static const APTR InitTab[] = { + (APTR)sizeof(struct LibBase), + (APTR)&__LibTable__[1], + (APTR)NULL, + (APTR)&LibInit +}; + +/******************************************************************************/ +/* */ +/* resident structure */ +/* */ +/******************************************************************************/ + +static const struct Resident RomTag = { + RTC_MATCHWORD, + (struct Resident *)&RomTag, + (struct Resident *)&RomTag+1, + RTF_AUTOINIT, + 0, + NT_LIBRARY, + 0, + (char *)LibName, + (char *)LibIdString, + (APTR)&InitTab +}; + +/******************************************************************************/ +/* */ +/* add these functions to 'liblist' */ +/* */ +/******************************************************************************/ + +ADD2LIST(LibOpen, __LibTable__,22); +ADD2LIST(LibExtFunc,__LibTable__,22); +ADD2LIST(LibExpunge,__LibTable__,22); +ADD2LIST(LibExtFunc,__LibTable__,22); +asm(".stabs \"___LibTable__\",20,0,0,-1"); + +/******************************************************************************/ +/* */ +/* add these functions to 'funclist' */ +/* */ +/******************************************************************************/ + +ADD2LIST(LibExtFunc,__FuncTable__,22); +ADD2LIST(LibClose, __FuncTable__,22); +ADD2LIST(LibExpunge,__FuncTable__,22); +ADD2LIST(LibExtFunc,__FuncTable__,22); + +/******************************************************************************/ +/* */ +/* end of libinitr.c */ +/* */ +/******************************************************************************/ diff --git a/libnix/sources/startup/nbcrt0.S b/libnix/sources/startup/nbcrt0.S new file mode 100755 index 0000000..fc9fd95 --- /dev/null +++ b/libnix/sources/startup/nbcrt0.S @@ -0,0 +1,142 @@ +| baserelative startup code for gcc v2.3.3+ +| (c) by M.Fleischer and G.Nikl Wed Apr 13 17:45 1994 +| No bugs known + +| some specific defines + +_LVOForbid = -132 +_LVOFindTask = -294 +_LVOGetMsg = -372 +_LVOReplyMsg = -378 +_LVOWaitPort = -384 + +pr_MsgPort = 92 +pr_CLI = 172 + +| public symbols + + .globl __exit + .globl _geta4 + + .text + +| first entry - init some vars, check for cli or wb start + +start: movel #___bss_size,d1 + jbsr _geta4 + beqs nobss + lea a4@(__edata:W),a1 +clrbss: clrl a1@+ + subql #4,d1 + bnes clrbss + +nobss: movel a0,a4@(___commandline:W) + movel d0,a4@(___commandlen:W) + + movel sp,a4@(___SaveSP:W) + movel 4:W,a6 + movel a6,a4@(_SysBase:W) + + subal a1,a1 + jsr a6@(_LVOFindTask:W) + movel d0,a3 + tstl a3@(pr_CLI:W) + bne fromCLI + +| wb start - get wbmsg + +fromWB: lea a3@(pr_MsgPort:W),a0 + jsr a6@(_LVOWaitPort:W) + lea a3@(pr_MsgPort:W),a0 + jsr a6@(_LVOGetMsg:W) + movel d0,a4@(__WBenchMsg:W) + +| execute all init functions then call main + +fromCLI: lea a4@(___INIT_LIST__:W),a2 + addqw #4,a2 + moveql #-1,d2 + jbsr callfuncs + + movel a4@(___env:W),sp@- + movel a4@(___argv:W),sp@- + movel a4@(___argc:W),sp@- + jbsr _main + movel d0,sp@(4:W) + +| exit() entry - execute all exit functions, reply wbmsg + +__exit: lea a4@(___EXIT_LIST__:W),a2 + addqw #4,a2 + moveql #0,d2 + jbsr callfuncs + + movel a4@(_SysBase:W),a6 + + movel a4@(__WBenchMsg:W),d2 + beq todos + jsr a6@(_LVOForbid:W) + movel d2,a1 + jsr a6@(_LVOReplyMsg:W) + +| leave - get return val, restore stackptr + +todos: movel sp@(4:W),d0 + movel a4@(___SaveSP:W),sp + rts + +| call all functions in the NULL terminated list pointed to by a2 +| d2 ascending or descending priority mode + +callfuncs: lea a4@(cleanupflag:W),a5 + movel a2,a3 + moveql #0,d3 + jra oldpri +stabloop: movel a3@+,d4 + movel a5@,d5 + cmpl d4,d5 + jne notnow + movel d0,a0 + jsr a0@ +notnow: eorl d2,d4 + eorl d2,d5 + cmpl d5,d4 + jcc oldpri + cmpl d3,d4 + jls oldpri + movel d4,d3 +oldpri: movel a3@+,d0 + jne stabloop + eorl d2,d3 + movel d3,a5@ + cmpl d2,d3 + jne callfuncs + rts + +| get baseptr + +_geta4: lea ___a4_init,a4 + rts + +| redirection of _exit + + .stabs "_exit",11,0,0,0 + .stabs "__exit",1,0,0,0 + +| data area + + .data + + .long ___nocommandline + .long ___initlibraries + .long ___cpucheck + +.comm _SysBase,4 +.comm ___SaveSP,4 +.comm __WBenchMsg,4 +.comm ___commandline,4 +.comm ___commandlen,4 +.comm ___argc,4 +.comm ___argv,4 +.comm ___env,4 +.lcomm cleanupflag,4 diff --git a/libnix/sources/startup/ncrt0.S b/libnix/sources/startup/ncrt0.S new file mode 100755 index 0000000..773c035 --- /dev/null +++ b/libnix/sources/startup/ncrt0.S @@ -0,0 +1,131 @@ +| not baserelative startup code for gcc v2.3.3+ +| (c) by M.Fleischer and G.Nikl Wed Apr 13 17:44 1994 +| No bugs known + +| some specific defines + +_LVOForbid = -132 +_LVOFindTask = -294 +_LVOGetMsg = -372 +_LVOReplyMsg = -378 +_LVOWaitPort = -384 + +pr_MsgPort = 92 +pr_CLI = 172 + +| public symbols + + .globl __exit + .globl _geta4 + + .text + +| first entry - init some vars, check for cli or wb start + +start: movel a0,___commandline + movel d0,___commandlen + + movel sp,___SaveSP + movel 4:W,a6 + movel a6,_SysBase + + subal a1,a1 + jsr a6@(_LVOFindTask:W) + movel d0,a3 + tstl a3@(pr_CLI:W) + bne fromCLI + +| wb start - get wbmsg + +fromWB: lea a3@(pr_MsgPort:W),a0 + jsr a6@(_LVOWaitPort:W) + lea a3@(pr_MsgPort:W),a0 + jsr a6@(_LVOGetMsg:W) + movel d0,__WBenchMsg + +| execute all init functions then call main + +fromCLI: lea ___INIT_LIST__+4,a2 + moveql #-1,d2 + jbsr callfuncs + + movel ___env,sp@- + movel ___argv,sp@- + movel ___argc,sp@- + jbsr _main + movel d0,sp@(4:W) + +| exit() entry - execute all exit functions, reply wbmsg + +__exit: lea ___EXIT_LIST__+4,a2 + moveql #0,d2 + jbsr callfuncs + + movel _SysBase,a6 + + movel __WBenchMsg,d2 + beq todos + jsr a6@(_LVOForbid:W) + movel d2,a1 + jsr a6@(_LVOReplyMsg:W) + +| leave - get return val, restore stackptr + +todos: movel sp@(4:W),d0 + movel ___SaveSP,sp + rts + +| call all functions in the NULL terminated list pointed to by a2 +| d2 ascending or descending priority mode + +callfuncs: lea cleanupflag,a5 + movel a2,a3 + moveql #0,d3 + jra oldpri +stabloop: movel a3@+,d4 + movel a5@,d5 + cmpl d4,d5 + jne notnow + movel d0,a0 + jsr a0@ +notnow: eorl d2,d4 + eorl d2,d5 + cmpl d5,d4 + jcc oldpri + cmpl d3,d4 + jls oldpri + movel d4,d3 +oldpri: movel a3@+,d0 + jne stabloop + eorl d2,d3 + movel d3,a5@ + cmpl d2,d3 + jne callfuncs + +| geta4() doesnīt do anything, but enables you to use +| one source for both code models + +_geta4: rts + +| redirection of _exit + + .stabs "_exit",11,0,0,0 + .stabs "__exit",1,0,0,0 + +| data area + + .data + + .long ___nocommandline + .long ___initlibraries + .long ___cpucheck + +.comm _SysBase,4 +.comm ___SaveSP,4 +.comm __WBenchMsg,4 +.comm ___commandline,4 +.comm ___commandlen,4 +.comm ___argc,4 +.comm ___argv,4 +.comm ___env,4 +.lcomm cleanupflag,4 diff --git a/libnix/sources/startup/nrcrt0.S b/libnix/sources/startup/nrcrt0.S new file mode 100755 index 0000000..7a95bcb --- /dev/null +++ b/libnix/sources/startup/nrcrt0.S @@ -0,0 +1,182 @@ +| residentable baserelative startup code for gcc v2.3.3+ +| (c) by M.Fleischer and G.Nikl Wed Apr 13 17:46 1994 +| No bugs known +| +| Problem: geta4() +| I really donīt know how to implement it with multiple starts +| +| You should use the non-resident startup-code if you need it ! + +| some specific defines + +_LVOForbid = -132 +_LVOAllocMem = -198 +_LVOFindTask = -294 +_LVOFreeMem = -210 +_LVOGetMsg = -372 +_LVOReplyMsg = -378 +_LVOWaitPort = -384 +_LVOCopyMemQuick = -630 + +pr_MsgPort = 92 +pr_CLI = 172 + +ERROR_NO_FREE_STORE = 103 + +| public symbols + + .globl __exit + + .text + +| first entry - check for cli or wb start + +start: movel a0,d3 + movel d0,d4 + + movel 4:W,a6 + + subal a1,a1 + jsr a6@(_LVOFindTask:W) + movel d0,a3 + tstl a3@(pr_CLI:W) + subal a2,a2 + bne fromCLI + +| wb start - get our message + +fromWB: lea a3@(pr_MsgPort:W),a0 + jsr a6@(_LVOWaitPort:W) + lea a3@(pr_MsgPort:W),a0 + jsr a6@(_LVOGetMsg:W) + movel d0,a2 + +| resident setup - allocate memory and relocate + +fromCLI: movql #ERROR_NO_FREE_STORE,d7 + movel #___data_size,d5 + movel #___bss_size,d2 + addl d5,d2 + movel d2,d0 + movql #1,d1 + swap d1 + jsr a6@(_LVOAllocMem:W) + movel d0,a4 + movel a4,d0 + beq cleanup + lea ___a4_init-0x7ffe,a5 + movel d5,d0 + movel a5,a0 + movel a4,a1 + jsr a6@(_LVOCopyMemQuick:W) + lea ___datadata_relocs,a0 + movel a0@+,d0 + beq no_reloc + movel a5,d1 + subl a4,d1 +do_reloc: movel a0@+,a1 + subl d1,a4@(a1:l) + subql #1,d0 + bne do_reloc +no_reloc: lea a4@(0x7ffe:W),a4 + + movel sp,a4@(___SaveSP:W) + movel a6,a4@(_SysBase:W) + movel a2,a4@(__WBenchMsg:W) + movel d3,a4@(___commandline:W) + movel d4,a4@(___commandlen:W) + movel d2,a4@(___MemLen:W) + +| call main() - push args onto stack + + lea a4@(___INIT_LIST__:W),a2 + addqw #4,a2 + moveql #-1,d2 + jbsr callfuncs + + movel a4@(___env:W),sp@- + movel a4@(___argv:W),sp@- + movel a4@(___argc:W),sp@- + jbsr _main + movel d0,sp@(4:W) + +| exit() entry - get return val, restore stackptr + +__exit: lea a4@(___EXIT_LIST__:W),a2 + addqw #4,a2 + moveql #0,d2 + jbsr callfuncs + + movel sp@(4:W),d7 + movel a4@(___SaveSP:W),sp + +| prepare cleanup - setup regs, free resident memory + + movel a4@(_SysBase:W),a6 + + movel a4@(__WBenchMsg:W),a2 + movel a4@(___MemLen:W),d0 + lea a4@(-0x7ffe:W),a1 + jsr a6@(_LVOFreeMem:W) + +| cleanup - reply wbmsg and exit + +cleanup: movel a2,d0 + beqs todos + jsr a6@(_LVOForbid:W) + movel a2,a1 + jsr a6@(_LVOReplyMsg:W) +todos: movel d7,d0 + rts + +| call all functions in the NULL terminated list pointed to by a2 +| d2 ascending or descending priority mode + +callfuncs: lea a4@(cleanupflag:W),a5 + movel a2,a3 + moveql #0,d3 + jra oldpri +stabloop: movel a3@+,d4 + movel a5@,d5 + cmpl d4,d5 + jne notnow + movel d0,a0 + jsr a0@ +notnow: eorl d2,d4 + eorl d2,d5 + cmpl d5,d4 + jcc oldpri + cmpl d3,d4 + jls oldpri + movel d4,d3 +oldpri: movel a3@+,d0 + jne stabloop + eorl d2,d3 + movel d3,a5@ + cmpl d2,d3 + jne callfuncs + rts + +| redirection of _exit + + .stabs "_exit",11,0,0,0 + .stabs "__exit",1,0,0,0 + +| data area + + .data + + .long ___nocommandline + .long ___initlibraries + .long ___cpucheck + +.comm _SysBase,4 +.comm ___SaveSP,4 +.comm __WBenchMsg,4 +.comm ___commandline,4 +.comm ___commandlen,4 +.comm ___MemLen,4 +.comm ___argc,4 +.comm ___argv,4 +.comm ___env,4 +.lcomm cleanupflag,4 diff --git a/libnix/sources/stubs/Makefile.in b/libnix/sources/stubs/Makefile.in new file mode 100644 index 0000000..06e62ab --- /dev/null +++ b/libnix/sources/stubs/Makefile.in @@ -0,0 +1,48 @@ +#### Start of system configuration section. #### + +srcdir = @srcdir@ +VPATH = @srcdir@ + +CC = @CC@ +CPP = @CPP@ +AS = as + +RANLIB = @RANLIB@ +AWK = @AWK@ + +#### End system configuration section #### + +ifneq ($(TARGET),clean) +include ../../sources/stubs/filelist +endif + +CURDIR = $(shell pwd) + +OPTIONS=-I $(srcdir)/../headers -I ../../sources/headers $(CFLAGS) + +OBJECTS2=$(OBJECTS) ../nix/misc/__request.o + +SUBDIRS2=$(SUBDIRS) ../nix/misc + +%.o: %.c + $(CC) $(OPTIONS) -c $^ -o $@ 2>&1|tee $*.err + -if test ! -s $*.err; then rm $*.err; fi + +.PHONY: all clean veryclean + +all: libstubs.a + +clean: + rm -rf $(SUBDIRS) + +veryclean: + rm -rf * + +$(foreach f,$(SUBDIRS2),$(CURDIR)/$(f)): + mkdir $@ + +libstubs.a: $(foreach f,$(SUBDIRS2),$(CURDIR)/$(f)) $(OBJECTS2) ../../sources/stubs/makefile ../../sources/stubs/filelist + rm -f $@ + ar -q $@ $(OBJECTS2) + $(RANLIB) $@ + echo "\$$$(V)" >>$@ diff --git a/libnix/sources/stubs/library.list b/libnix/sources/stubs/library.list new file mode 100755 index 0000000..330df89 --- /dev/null +++ b/libnix/sources/stubs/library.list @@ -0,0 +1,29 @@ +AmigaGuideBase amigaguide.library +AslBase asl.library +BulletBase bullet.library +CxBase commodities.library +DataTypesBase datatypes.library +DiskfontBase diskfont.library +DOSBase dos.library +ExpansionBase expansion.library +GadToolsBase gadtools.library +GfxBase graphics.library +IconBase icon.library +IFFParseBase iffparse.library +IntuitionBase intuition.library +KeymapBase keymap.library +LayersBase layers.library +LocaleBase locale.library +LowLevelBase lowlevel.library +MathBase mathffp.library +MathIeeeDoubBasBase mathieeedoubbas.library +MathIeeeDoubTransBase mathieeedoubtrans.library +MathIeeeSingBasBase mathieeesingbas.library +MathIeeeSingTransBase mathieeesingtrans.library +MathTransBase mathtrans.library +NVBase nonvolatile.library +RealTimeBase realtime.library +RexxSysBase rexxsyslib.library +TranslatorBase translator.library +UtilityBase utility.library +WorkbenchBase workbench.library diff --git a/libnix/sources/stubs/misc/__DOSBase.c b/libnix/sources/stubs/misc/__DOSBase.c new file mode 100755 index 0000000..0c1643c --- /dev/null +++ b/libnix/sources/stubs/misc/__DOSBase.c @@ -0,0 +1,4 @@ +#include +extern char __dosname[]; +void *__DOSBase[2]={ 0l,__dosname }; +ADD2LIB(__DOSBase); diff --git a/libnix/sources/stubs/misc/__MathIeeeDoubBasBase.c b/libnix/sources/stubs/misc/__MathIeeeDoubBasBase.c new file mode 100755 index 0000000..b17ebbc --- /dev/null +++ b/libnix/sources/stubs/misc/__MathIeeeDoubBasBase.c @@ -0,0 +1,4 @@ +#include +extern char __mathieeedoubbasname[]; +void *__MathIeeeDoubBasBase[2]={ 0l,__mathieeedoubbasname }; +ADD2LIB(__MathIeeeDoubBasBase); diff --git a/libnix/sources/stubs/misc/__MathIeeeDoubTransBase.c b/libnix/sources/stubs/misc/__MathIeeeDoubTransBase.c new file mode 100755 index 0000000..c892566 --- /dev/null +++ b/libnix/sources/stubs/misc/__MathIeeeDoubTransBase.c @@ -0,0 +1,4 @@ +#include +extern char __mathieeedoubtransname[]; +void *__MathIeeeDoubTransBase[2]={ 0l,__mathieeedoubtransname }; +ADD2LIB(__MathIeeeDoubTransBase); diff --git a/libnix/sources/stubs/misc/__MathIeeeSingBasBase.c b/libnix/sources/stubs/misc/__MathIeeeSingBasBase.c new file mode 100755 index 0000000..c19c1f6 --- /dev/null +++ b/libnix/sources/stubs/misc/__MathIeeeSingBasBase.c @@ -0,0 +1,4 @@ +#include +extern char __mathieeesingbasname[]; +void *__MathIeeeSingBasBase[2]={ 0l,__mathieeesingbasname }; +ADD2LIB(__MathIeeeSingBasBase); diff --git a/libnix/sources/stubs/misc/__MathIeeeSingTransBase.c b/libnix/sources/stubs/misc/__MathIeeeSingTransBase.c new file mode 100755 index 0000000..5e5dc4a --- /dev/null +++ b/libnix/sources/stubs/misc/__MathIeeeSingTransBase.c @@ -0,0 +1,4 @@ +#include +extern char __mathieeesingtransname[]; +void *__MathIeeeSingTransBase[2]={ 0l,__mathieeesingtransname }; +ADD2LIB(__MathIeeeSingTransBase); diff --git a/libnix/sources/stubs/misc/__UtilityBase.c b/libnix/sources/stubs/misc/__UtilityBase.c new file mode 100755 index 0000000..77e50e7 --- /dev/null +++ b/libnix/sources/stubs/misc/__UtilityBase.c @@ -0,0 +1,4 @@ +#include +extern char __utilityname[]; +void *__UtilityBase[2]={ 0l,__utilityname }; +ADD2LIB(__UtilityBase); diff --git a/libnix/sources/stubs/misc/__cpucheck.c b/libnix/sources/stubs/misc/__cpucheck.c new file mode 100755 index 0000000..07ae453 --- /dev/null +++ b/libnix/sources/stubs/misc/__cpucheck.c @@ -0,0 +1,52 @@ +#include +#include + +#if defined(mc68020) || defined(__HAVE_68881__) + +#ifdef mc68020 +static const char errtext1[]="Need a 68020 or higher CPU"; +#endif + +#ifdef __HAVE_68881__ +static const char errtext2[]="Need some FPU to run"; +#endif + +asm(" + .text + .even + + .globl ___cpucheck +___cpucheck: + movel "A4(_SysBase)",a1 + movew a1@(0x128:W),d0 +" +#ifdef mc68020 +" + lea _errtext1,a0 + btst #1,d0 + jeq error +" +#endif +#ifdef __HAVE_68881__ +" + lea _errtext2,a0 + btst #4,d0 + jeq error +" +#endif +" + rts +error: + movel a0,sp@- + jsr ___request | jbsr translates to jra which doesn't work on 68000 + pea 20:W + jsr _exit | dito +"); + +ADD2INIT(__cpucheck,-80); /* Highest priority */ + +#else + +int __cpucheck; + +#endif diff --git a/libnix/sources/stubs/misc/__flush_cache.c b/libnix/sources/stubs/misc/__flush_cache.c new file mode 100644 index 0000000..cb7bd6d --- /dev/null +++ b/libnix/sources/stubs/misc/__flush_cache.c @@ -0,0 +1,7 @@ +#include +#include + +void __flush_cache(APTR adr, ULONG len) +{ + CacheClearE(adr, len, CACRF_ClearD | CACRF_ClearI); +} diff --git a/libnix/sources/stubs/misc/__initlibraries.c b/libnix/sources/stubs/misc/__initlibraries.c new file mode 100755 index 0000000..f34c16b --- /dev/null +++ b/libnix/sources/stubs/misc/__initlibraries.c @@ -0,0 +1,55 @@ +#include +#include + +extern struct lib /* These are the elements pointed to by __LIB_LIST__ */ +{ struct Library *base; + char *name; +} *__LIB_LIST__[]; + +extern ULONG __oslibversion; +extern void __request(const char *text); +extern void exit(int returncode); + +static void __openliberror(ULONG, char *,...) __attribute__ ((noreturn)); + +static void __openliberror(ULONG version, char *name,...) +{ static const ULONG tricky=0x16c04e75; /* move.b d0,(a3)+ ; rts */ + char buf[60]; + + RawDoFmt("Need version %.10ld of %.32s",(APTR)&version,(void (*)())&tricky,buf); + __request(buf); + exit(20); +} + +void __initlibraries(void) +{ + ULONG version=__oslibversion; + struct lib **list=__LIB_LIST__; + ULONG numbases=(ULONG)*list++; + + if(numbases) + do { + struct lib *l=*list++; + if((l->base=OpenLibrary(l->name,version))==NULL) + __openliberror(version,l->name); + } while(--numbases); +} + +void __exitlibraries(void) +{ + struct lib **list=__LIB_LIST__; + ULONG numbases=(ULONG)*list++; + + if(numbases) + do { + struct lib *l=*list++; + struct Library *lb=l->base; + if(lb!=NULL) { + /* l->base=NULL; */ + CloseLibrary(lb); + } + } while(--numbases); +} + +ADD2INIT(__initlibraries,-60); +ADD2EXIT(__exitlibraries,-60); diff --git a/libnix/sources/stubs/stubs/__exit_list__.c b/libnix/sources/stubs/stubs/__exit_list__.c new file mode 100755 index 0000000..4d74729 --- /dev/null +++ b/libnix/sources/stubs/stubs/__exit_list__.c @@ -0,0 +1 @@ +void *__EXIT_LIST__[2]={ 0,0 }; diff --git a/libnix/sources/stubs/stubs/__init_list__.c b/libnix/sources/stubs/stubs/__init_list__.c new file mode 100755 index 0000000..d8246fa --- /dev/null +++ b/libnix/sources/stubs/stubs/__init_list__.c @@ -0,0 +1 @@ +void *__INIT_LIST__[2]={ 0,0 }; diff --git a/libnix/sources/stubs/stubs/__lib_list__.c b/libnix/sources/stubs/stubs/__lib_list__.c new file mode 100755 index 0000000..61cce34 --- /dev/null +++ b/libnix/sources/stubs/stubs/__lib_list__.c @@ -0,0 +1 @@ +void *__LIB_LIST__[2]={ 0,0 }; diff --git a/libnix/sources/stubs/stubs/__main.c b/libnix/sources/stubs/stubs/__main.c new file mode 100755 index 0000000..e708b25 --- /dev/null +++ b/libnix/sources/stubs/stubs/__main.c @@ -0,0 +1 @@ +int __main(void) { return 0; } diff --git a/libnix/sources/stubs/stubs/__oslibversion.c b/libnix/sources/stubs/stubs/__oslibversion.c new file mode 100755 index 0000000..3186483 --- /dev/null +++ b/libnix/sources/stubs/stubs/__oslibversion.c @@ -0,0 +1,2 @@ +#include +ULONG __oslibversion=37; diff --git a/libnix/sources/stubs/stubs/__priority.c b/libnix/sources/stubs/stubs/__priority.c new file mode 100755 index 0000000..ff9daa5 --- /dev/null +++ b/libnix/sources/stubs/stubs/__priority.c @@ -0,0 +1 @@ +long __priority=0; diff --git a/libnix/sources/stubs/stubs/__procname.c b/libnix/sources/stubs/stubs/__procname.c new file mode 100755 index 0000000..3dfc07c --- /dev/null +++ b/libnix/sources/stubs/stubs/__procname.c @@ -0,0 +1 @@ +char *__procname="Background process"; diff --git a/libnix/sources/stubs/stubs/__stack.c b/libnix/sources/stubs/stubs/__stack.c new file mode 100755 index 0000000..1725075 --- /dev/null +++ b/libnix/sources/stubs/stubs/__stack.c @@ -0,0 +1 @@ +unsigned long __stack=4000;