Improve documentation

The Cosmo API documentation page is pretty good now
https://justine.lol/cosmopolitan/documentation.html
This commit is contained in:
Justine Tunney 2020-12-27 07:02:35 -08:00
parent 13437dd19b
commit 1bc3a25505
367 changed files with 2542 additions and 26178 deletions

View file

@ -1,26 +0,0 @@
AVIR License Agreement
The MIT License (MIT)
AVIR Copyright (c) 2015-2019 Aleksey Vaneev
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Please credit the author of this library in your documentation in the
following way: "AVIR image resizing algorithm designed by Aleksey Vaneev"

View file

@ -1,5 +0,0 @@
commit 7dd9515ef6aed6fb6d565ee12754703bdc46b3b0
Author: Aleksey Vaneev <aleksey.vaneev@gmail.com>
Date: Mon Jul 29 07:43:23 2019 +0300
Version 2.4 release.

View file

@ -1,367 +0,0 @@
# AVIR #
## Introduction ##
Keywords: image resize, image resizer, image resizing, image scaling,
image scaler, image resize c++, image resizer c++
Please consider supporting the author on [Patreon](https://www.patreon.com/aleksey_vaneev).
Me, Aleksey Vaneev, is happy to offer you an open source image resizing /
scaling library which has reached a production level of quality, and is
ready to be incorporated into any project. This library features routines
for both down- and upsizing of 8- and 16-bit, 1 to 4-channel images. Image
resizing routines were implemented in multi-platform C++ code, and have a
high level of optimality. Beside resizing, this library offers a sub-pixel
shift operation. Built-in sRGB gamma correction is available.
The resizing algorithm at first produces 2X upsized image (relative to the
source image size, or relative to the destination image size if downsizing is
performed) and then performs interpolation using a bank of sinc function-based
fractional delay filters. At the last stage a correction filter is applied
which fixes smoothing introduced at previous steps.
The resizing algorithm was designed to provide the best visual quality. The
author even believes this algorithm provides the "ultimate" level of
quality (for an orthogonal resizing) which cannot be increased further: no
math exists to provide a better frequency response, better anti-aliasing
quality and at the same time having less ringing artifacts: these are 3
elements that define any resizing algorithm's quality; in AVIR practice these
elements have a high correlation to each other, so they can be represented by
a single parameter (AVIR offers several parameter sets with varying quality).
Algorithm's time performance turned out to be very good as well (for the
"ultimate" image quality).
An important element utilized by this algorithm is the so called Peaked Cosine
window function, which is applied over sinc function in all filters. Please
consult the documentation for more details.
Note that since AVIR implements orthogonal resizing, it may exhibit diagonal
aliasing artifacts. These artifacts are usually suppressed by EWA or radial
filtering techniques. EWA-like technique is not implemented in AVIR, because
it requires considerably more computing resources and may produce a blurred
image.
As a bonus, a faster `LANCIR` image resizing algorithm is also offered as a
part of this library. But the main focus of this documentation is the original
AVIR image resizing algorithm.
AVIR does not offer affine and non-linear image transformations "out of the
box". Since upsizing is a relatively fast operation in AVIR (required time
scales linearly with the output image area), affine and non-linear
transformations can be implemented in steps: 4- to 8-times upsizing,
transformation via bilinear interpolation, downsizing (linear proportional
affine transformations can probably skip the downsizing step). This should not
compromise the transformation quality much as bilinear interpolation's
problems will mostly reside in spectral area without useful signal, with a
maximum of 0.7 dB high-frequency attenuation for 4-times upsizing, and 0.17 dB
attenuation for 8-times upsizing. This approach is probably as time efficient
as performing a high-quality transform over the input image directly (the only
serious drawback is the increased memory requirement). Note that affine
transformations that change image proportions should first apply proportion
change during upsizing.
*AVIR is devoted to women. Your digital photos can look good at any size!*
## Requirements ##
C++ compiler and system with efficient "float" floating point (24-bit
mantissa) type support. This library can also internally use the "double" and
SIMD floating point types during resizing if needed. This library does not
have dependencies beside the standard C library.
## Links ##
* [Documentation](https://www.voxengo.com/public/avir/Documentation/)
## Usage Information ##
The image resizer is represented by the `avir::CImageResizer<>` class, which
is a single front-end class for the whole library. Basically, you do not need
to use nor understand any other classes beside this class.
The code of the library resides in the "avir" C++ namespace, effectively
isolating it from all other code. The code is thread-safe. You need just
a single resizer object per running application, at any time, even when
resizing images concurrently.
To resize images in your application, simply add 3 lines of code:
#include "avir.h"
avir :: CImageResizer<> ImageResizer( 8 );
ImageResizer.resizeImage( InBuf, 640, 480, 0, OutBuf, 1024, 768, 3, 0 );
(multi-threaded operation requires additional coding, see the documentation)
For low-ringing performance:
avir :: CImageResizer<> ImageResizer( 8, 0, avir :: CImageResizerParamsLR() );
To use the built-in gamma correction, an object of the
`avir::CImageResizerVars` class with its variable `UseSRGBGamma` set to "true"
should be supplied to the `resizeImage()` function. Note that the gamma
correction is applied to all channels (e.g. alpha-channel) in the current
implementation.
avir :: CImageResizerVars Vars;
Vars.UseSRGBGamma = true;
Dithering (error-diffusion dither which is perceptually good) can be enabled
this way:
typedef avir :: fpclass_def< float, float,
avir :: CImageResizerDithererErrdINL< float > > fpclass_dith;
avir :: CImageResizer< fpclass_dith > ImageResizer( 8 );
The library is able to process images of any bit depth: this includes 8-bit,
16-bit, float and double types. Larger integer and signed integer types are
not supported. Supported source and destination image sizes are only limited
by the available system memory.
The code of this library was commented in the [Doxygen](http://www.doxygen.org/)
style. To generate the documentation locally you may run the
`doxygen ./other/avirdoxy.txt` command from the library's directory. Note that
the code was suitably documented allowing you to make modifications, and to
gain full understanding of the algorithm.
Preliminary tests show that this library (compiled with Intel C++ Compiler
18.2 with AVX2 instructions enabled, without explicit SIMD resizing code) can
resize 8-bit RGB 5184x3456 (17.9 Mpixel) 3-channel image down to 1920x1280
(2.5 Mpixel) image in 245 milliseconds, utilizing a single thread, on Intel
Core i7-7700K processor-based system without overclocking. This scales down to
74 milliseconds if 8 threads are utilized.
Multi-threaded operation is not provided by this library "out of the box".
The multi-threaded (horizontally-threaded) infrastructure is available, but
requires additional system-specific interfacing code for engagement.
## SIMD Usage Information ##
This library is capable of using SIMD floating point types for internal
variables. This means that up to 4 color channels can be processed in
parallel. Since the default interleaved processing algorithm itself remains
non-SIMD, the use of SIMD internal types is not practical for 1- and 2-channel
image resizing (due to overhead). SIMD internal type can be used this way:
#include "avir_float4_sse.h"
avir :: CImageResizer< avir :: fpclass_float4 > ImageResizer( 8 );
For 1-channel and 2-channel image resizing when AVX instructions are allowed
it may be reasonable to utilize de-interleaved SIMD processing algorithm.
While it gives no performance benefit if the "float4" SSE processing type is
used, it offers some performance boost if the "float8" AVX processing type is
used (given dithering is not performed, or otherwise performance is reduced at
the dithering stage since recursive dithering cannot be parallelized). The
internal type remains non-SIMD "float". De-interleaved algorithm can be used
this way:
#include "avir_float8_avx.h"
avir :: CImageResizer< avir :: fpclass_float8_dil > ImageResizer( 8 );
It's important to note that on the latest Intel processors (i7-7700K and
probably later) the use of the aforementioned SIMD-specific resizing code may
not be justifiable, or may be even counter-productive due to many factors:
memory bandwidth bottleneck, increased efficiency of processor's circuitry
utilization and out-of-order execution, automatic SIMD optimizations performed
by the compiler. This is at least true when compiling 64-bit code with Intel
C++ Compiler 18.2 with /QxSSE4.2, or especially with the /QxCORE-AVX2 option.
SSE-specific resizing code may still be a little bit more efficient for
4-channel image resizing.
## Notes ##
This library was tested for compatibility with [GNU C++](http://gcc.gnu.org/),
[Microsoft Visual C++](http://www.microsoft.com/visualstudio/eng/products/visual-studio-express-products)
and [Intel C++](http://software.intel.com/en-us/c-compilers) compilers, on 32-
and 64-bit Windows, macOS and CentOS Linux. The code was also tested with
Dr.Memory/Win32 for the absence of uninitialized or unaddressable memory
accesses.
All code is fully "inline", without the need to compile any source files. The
memory footprint of the library itself is very modest, except that the size of
the temporary image buffers depends on the input and output image sizes, and
is proportionally large.
The "heart" of resizing algorithm's quality resides in the parameters defined
via the `avir::CImageResizerParams` structure. While the default set of
parameters that offers a good quality was already provided, there is
(probably) still a place for improvement exists, and the default parameters
may change in a future update. If you need to recall an exact set of
parameters, simply save them locally for a later use.
When the algorithm is run with no resizing applied (k=1), the result of
resizing will not be an exact, but a very close copy of the source image. The
reason for such inexactness is that the image is always low-pass filtered at
first to reduce aliasing during subsequent resizing, and at last filtered by a
correction filter. Such approach allows algorithm to maintain a stable level
of quality regardless of the resizing "k" factor used.
This library includes a binary command line tool "imageresize" for major
desktop platforms. This tool was designed to be used as a demonstration of
library's performance, and as a reference, it is multi-threaded (the `-t`
switch can be used to control the number of threads utilized). This tool uses
plain "float" processing (no explicit SIMD) and relies on automatic compiler
optimization (with Win64 binary being the "main" binary as it was compiled
with the best ICC optimization options for the time being). This tool uses the
following libraries:
* turbojpeg Copyright (c) 2009-2013 D. R. Commander
* libpng Copyright (c) 1998-2013 Glenn Randers-Pehrson
* zlib Copyright (c) 1995-2013 Jean-loup Gailly and Mark Adler
Note that you can enable gamma-correction with the `-g` switch. However,
sometimes gamma-correction produces "greenish/reddish/bluish haze" since
low-amplitude oscillations produced by resizing at object boundaries are
amplified by gamma correction. This can also have an effect of reduced
contrast.
## Interpolation Discussion ##
The use of certain low-pass filters and 2X upsampling in this library is
hardly debatable, because they are needed to attain a certain anti-aliasing
effect and keep ringing artifacts low. But the use of sinc function-based
interpolation filter that is 18 taps-long (may be higher, up to 36 taps in
practice) can be questioned, because even in 0th order case such
interpolation filter requires 18 multiply-add operations. Comparatively, an
optimal Hermite or cubic interpolation spline requires 8 multiply and 11 add
operations.
One of the reasons 18-tap filter is preferred, is because due to memory
bandwidth limitations using a lower-order filter does not provide any
significant performance increase (e.g. 14-tap filter is less than 5% more
efficient overall). At the same time, in comparison to cubic spline, 18-tap
filter embeds a low-pass filter that rejects signal above 0.5\*pi (provides
additional anti-aliasing filtering), and this filter has a consistent shape at
all fractional offsets. Splines have a varying low-pass filter shape at
different fractional offsets (e.g. no low-pass filtering at 0.0 offset,
and maximal low-pass filtering at 0.5 offset). 18-tap filter also offers a
superior stop-band attenuation which almost guarantees absence of artifacts if
the image is considerably sharpened afterwards.
## Why 2X upsizing in AVIR? ##
Classic approaches to image resizing do not perform an additional 2X upsizing.
So, why such upsizing is needed at all in AVIR? Indeed, image resizing can be
implemented using a single interpolation filter which is applied to the source
image directly. However, such approach has limitations:
First of all, speaking about non-2X-upsized resizing, during upsizing the
interpolation filter has to be tuned to a frequency close to pi (Nyquist) in
order to reduce high-frequency smoothing: this reduces the space left for
filter optimization. Beside that, during downsizing, a filter that performs
well and predictable when tuned to frequencies close to the Nyquist frequency,
may become distorted in its spectral shape when it is tuned to lower
frequencies. That is why it is usually a good idea to have filter's stop-band
begin below Nyquist so that the transition band's shape remains stable at any
lower-frequency setting. At the same time, this requirement complicates a
further corrective filtering, because correction filter may become too steep
at the point where the stop-band begins.
Secondly, speaking about non-2X-upsized resizing, filter has to be very short
(with a base length of 5-7 taps, further multiplied by the resizing factor) or
otherwise the ringing artifacts will be very strong: it is a general rule that
the steeper the filter is around signal frequencies being removed the higher
the ringing artifacts are. That is why it is preferred to move steep
transitions into the spectral area with a quieter signal. A short filter also
means it cannot provide a strong "beyond-Nyquist" stop-band attenuation, so an
interpolated image will look a bit edgy or not very clean due to stop-band
artifacts.
To sum up, only additional controlled 2X upsizing provides enough spectral
space to design interpolation filter without visible ringing artifacts yet
providing a strong stop-band attenuation and stable spectral characteristics
(good at any resizing "k" factor). Moreover, 2X upsizing becomes very
important in maintaining a good resizing quality when downsizing and upsizing
by small "k" factors, in the range 0.5 to 2: resizing approaches that do not
perform 2X upsizing usually cannot design a good interpolation filter for such
factors just because there is not enough spectral space available.
## Why Peaked Cosine in AVIR? ##
First of all, AVIR is a general solution to image resizing problem. That is
why it should not be directly compared to "spline interpolation" or "Lanczos
resampling", because the latter two are only means to design interpolation
filters, and they can be implemented in a variety of ways, even in sub-optimal
ways. Secondly, with only a minimal effort AVIR can be changed to use any
existing interpolation formula and any window function, but this is just not
needed.
An effort was made to compare Peaked Cosine to Lanczos window function, and
here is the author's opinion. Peaked Cosine has two degrees of freedom whereas
Lanczos has one degree of freedom. While both functions can be used with
acceptable results, Peaked Cosine window function used in automatic parameter
optimization really pushes the limits of frequency response linearity,
anti-aliasing strength (stop-band attenuation) and low-ringing performance
which Lanczos cannot usually achieve. This is true at least when using a
general-purpose downhill simplex optimization method. Lanczos window has good
(but not better) characteristics in several special cases (certain "k"
factors) which makes it of limited use in a general solution such as AVIR.
Among other window functions (Kaiser, Gaussian, Cauchy, Poisson, generalized
cosine windows) there are no better candidates as well. It looks like Peaked
Cosine function's scalability (it retains stable, almost continously-variable
spectral characteristics at any window parameter values), and its ability to
create "desirable" pass-band ripple in the frequency response near the cutoff
point contribute to its better overall quality. Somehow Peaked Cosine window
function optimization manages to converge to reasonable states in most cases
(that is why AVIR library comes with a set of equally robust, but distinctive
parameter sets) whereas all other window functions tend to produce
unpredictable optimization results.
The only disadvantage of Peaked Cosine window function is that usable filters
windowed by this function tend to be longer than "usual" (with Kaiser window
being the "golden standard" for filter length per decibel of stop-band
attenuation). This is a price that should be paid for stable spectral
characteristics.
## LANCIR ##
As a part of AVIR library, the `CLancIR` class is also offered which is an
optimal implementation of *Lanczos* image resizing filter. This class has a
similar programmatic interface to AVIR, but it is not thread-safe: each
executing thread should have its own `CLancIR` object. This class was designed
for cases of batch processing of same-sized frames like in video encoding.
LANCIR offers up to 200% faster image resizing in comparison to AVIR. The
quality difference is, however, debatable. Note that while LANCIR can take
8- and 16-bit and float image buffers, its precision is limited to 8-bit
resizing.
LANCIR should be seen as a bonus and as some kind of quality comparison.
LANCIR uses Lanczos filter "a" parameter equal to 3 which is similar to AVIR's
default setting.
## Change log ##
Version 2.4:
* Removed outdated `_mm_reset()` function calls from the SIMD code.
* Changed `float4 round()` to use SSE2 rounding features, avoiding use of
64-bit registers.
Version 2.3:
* Implemented CLancIR image resizing algorithm.
* Fixed a minor image offset on image upsizing.
Version 2.2:
* Released AVIR under a permissive MIT license agreement.
Version 2.1:
* Fixed error-diffusion dither problems introduced in the previous version.
* Added the `-1` switch to the `imageresize` to enable 1-bit output for
dither's quality evaluation (use together with the `-d` switch).
* Added the `--algparams=` switch to the `imageresize` to control resizing
quality (replaces the `--low-ring` switch).
* Added `avir :: CImageResizerParamsULR` parameter set for lowest-ringing
performance possible (not considerably different to
`avir :: CImageResizerParamsLR`, but a bit lower ringing).
Version 2.0:
* Minor inner loop optimizations.
* Lifted the supported image size constraint by switching buffer addressing to
`size_t` from `int`, now image size is limited by the available system memory.
* Added several useful switches to the `imageresize` utility.
* Now `imageresize` does not apply gamma-correction by default.
* Fixed scaling of bit depth-reduction operation.
* Improved error-diffusion dither's signal-to-noise ratio.
* Compiled binaries with AVX2 instruction set (SSE4 for macOS).
## Users ##
This library is used by:
* [Contaware.com](http://www.contaware.com/)
Please drop me a note at aleksey.vaneev@gmail.com and I will include a link to
your software product to the list of users. This list is important at
maintaining confidence in this library among the interested parties.

17065
third_party/avir/avir.h vendored

File diff suppressed because it is too large Load diff

View file

@ -1,71 +0,0 @@
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
PKGS += THIRD_PARTY_AVIR
THIRD_PARTY_AVIR_ARTIFACTS += THIRD_PARTY_AVIR_A
THIRD_PARTY_AVIR = $(THIRD_PARTY_AVIR_A_DEPS) $(THIRD_PARTY_AVIR_A)
THIRD_PARTY_AVIR_A = o/$(MODE)/third_party/avir/avir.a
THIRD_PARTY_AVIR_A_CHECKS = $(THIRD_PARTY_AVIR_A).pkg
THIRD_PARTY_AVIR_A_FILES := $(wildcard third_party/avir/*)
THIRD_PARTY_AVIR_A_SRCS_S = $(filter %.S,$(THIRD_PARTY_AVIR_A_FILES))
THIRD_PARTY_AVIR_A_SRCS_C = $(filter %.c,$(THIRD_PARTY_AVIR_A_FILES))
THIRD_PARTY_AVIR_A_SRCS_X = $(filter %.cc,$(THIRD_PARTY_AVIR_A_FILES))
THIRD_PARTY_AVIR_A_HDRS = \
$(filter %.h,$(THIRD_PARTY_AVIR_A_FILES)) \
$(filter %.hpp,$(THIRD_PARTY_AVIR_A_FILES))
THIRD_PARTY_AVIR_A_SRCS = \
$(THIRD_PARTY_AVIR_A_SRCS_S) \
$(THIRD_PARTY_AVIR_A_SRCS_C) \
$(THIRD_PARTY_AVIR_A_SRCS_X)
THIRD_PARTY_AVIR_A_OBJS = \
$(THIRD_PARTY_AVIR_A_SRCS:%=o/$(MODE)/%.zip.o) \
$(THIRD_PARTY_AVIR_A_SRCS_S:%.S=o/$(MODE)/%.o) \
$(THIRD_PARTY_AVIR_A_SRCS_C:%.c=o/$(MODE)/%.o) \
$(THIRD_PARTY_AVIR_A_SRCS_X:%.cc=o/$(MODE)/%.o)
THIRD_PARTY_AVIR_A_DIRECTDEPS = \
DSP_CORE \
LIBC_NEXGEN32E \
LIBC_BITS \
LIBC_MEM \
LIBC_CALLS \
LIBC_STUBS \
LIBC_SYSV \
LIBC_FMT \
LIBC_UNICODE \
LIBC_LOG \
LIBC_TINYMATH
$(THIRD_PARTY_AVIR_A).pkg: \
$(THIRD_PARTY_AVIR_A_OBJS) \
$(foreach x,$(THIRD_PARTY_AVIR_A_DIRECTDEPS),$($(x)_A).pkg)
$(THIRD_PARTY_AVIR_A): \
third_party/avir/ \
$(THIRD_PARTY_AVIR_A).pkg \
$(THIRD_PARTY_AVIR_A_OBJS)
#o/$(MODE)/third_party/avir/lanczos1b.o: \
CXX = clang++-10
o/$(MODE)/third_party/avir/lanczos1b.o \
o/$(MODE)/third_party/avir/lanczos.o: \
OVERRIDE_CXXFLAGS += \
$(MATHEMATICAL)
THIRD_PARTY_AVIR_A_DEPS := \
$(call uniq,$(foreach x,$(THIRD_PARTY_AVIR_A_DIRECTDEPS),$($(x))))
THIRD_PARTY_AVIR_LIBS = $(foreach x,$(THIRD_PARTY_AVIR_ARTIFACTS),$($(x)))
THIRD_PARTY_AVIR_SRCS = $(foreach x,$(THIRD_PARTY_AVIR_ARTIFACTS),$($(x)_SRCS))
THIRD_PARTY_AVIR_HDRS = $(foreach x,$(THIRD_PARTY_AVIR_ARTIFACTS),$($(x)_HDRS))
THIRD_PARTY_AVIR_CHECKS = $(foreach x,$(THIRD_PARTY_AVIR_ARTIFACTS),$($(x)_CHECKS))
THIRD_PARTY_AVIR_OBJS = $(foreach x,$(THIRD_PARTY_AVIR_ARTIFACTS),$($(x)_OBJS))
THIRD_PARTY_AVIR_TESTS = $(foreach x,$(THIRD_PARTY_AVIR_ARTIFACTS),$($(x)_TESTS))
.PHONY: o/$(MODE)/third_party/avir
o/$(MODE)/third_party/avir: $(THIRD_PARTY_AVIR_A_CHECKS)

View file

@ -1,17 +0,0 @@
#ifndef COSMOPOLITAN_THIRD_PARTY_AVIR_AVIR1_H_
#define COSMOPOLITAN_THIRD_PARTY_AVIR_AVIR1_H_
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
struct avir1 {
void *p;
};
void avir1init(struct avir1 *);
void avir1free(struct avir1 *);
void avir1(struct avir1 *, size_t, size_t, void *, size_t, size_t, size_t,
size_t, const void *, size_t);
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_THIRD_PARTY_AVIR_AVIR1_H_ */

File diff suppressed because it is too large Load diff

View file

@ -1,324 +0,0 @@
/* clang-format off */
//$ nobt
//$ nocpp
/**
* @file avir_float4_sse.h
*
* @brief Inclusion file for the "float4" type.
*
* This file includes the "float4" SSE-based type used for SIMD variable
* storage and processing.
*
* AVIR Copyright (c) 2015-2019 Aleksey Vaneev
*/
#ifndef AVIR_FLOAT4_SSE_INCLUDED
#define AVIR_FLOAT4_SSE_INCLUDED
#include "third_party/avir/avir.h"
#include "libc/bits/mmintrin.internal.h"
#include "libc/bits/xmmintrin.internal.h"
#include "libc/bits/xmmintrin.internal.h"
#include "libc/bits/xmmintrin.internal.h"
#include "libc/bits/emmintrin.internal.h"
namespace avir {
/**
* @brief SIMD packed 4-float type.
*
* This class implements a packed 4-float type that can be used to perform
* parallel computation using SIMD instructions on SSE-enabled processors.
* This class can be used as the "fptype" argument of the avir::fpclass_def
* class.
*/
class float4
{
public:
float4()
{
}
float4( const float4& s )
: value( s.value )
{
}
float4( const __m128 s )
: value( s )
{
}
float4( const float s )
: value( _mm_set1_ps( s ))
{
}
float4& operator = ( const float4& s )
{
value = s.value;
return( *this );
}
float4& operator = ( const __m128 s )
{
value = s;
return( *this );
}
float4& operator = ( const float s )
{
value = _mm_set1_ps( s );
return( *this );
}
operator float () const
{
return( _mm_cvtss_f32( value ));
}
/**
* @param p Pointer to memory from where the value should be loaded,
* should be 16-byte aligned.
* @return float4 value loaded from the specified memory location.
*/
static float4 load( const float* const p )
{
return( _mm_load_ps( p ));
}
/**
* @param p Pointer to memory from where the value should be loaded,
* may have any alignment.
* @return float4 value loaded from the specified memory location.
*/
static float4 loadu( const float* const p )
{
return( _mm_loadu_ps( p ));
}
/**
* @param p Pointer to memory from where the value should be loaded,
* may have any alignment.
* @param lim The maximum number of elements to load, >0.
* @return float4 value loaded from the specified memory location, with
* elements beyond "lim" set to 0.
*/
static float4 loadu( const float* const p, int lim )
{
if( lim > 2 )
{
if( lim > 3 )
{
return( _mm_loadu_ps( p ));
}
else
{
return( _mm_set_ps( 0.0f, p[ 2 ], p[ 1 ], p[ 0 ]));
}
}
else
{
if( lim == 2 )
{
return( _mm_set_ps( 0.0f, 0.0f, p[ 1 ], p[ 0 ]));
}
else
{
return( _mm_load_ss( p ));
}
}
}
/**
* Function stores *this value to the specified memory location.
*
* @param[out] p Output memory location, should be 16-byte aligned.
*/
void store( float* const p ) const
{
_mm_store_ps( p, value );
}
/**
* Function stores *this value to the specified memory location.
*
* @param[out] p Output memory location, may have any alignment.
*/
void storeu( float* const p ) const
{
_mm_storeu_ps( p, value );
}
/**
* Function stores "lim" lower elements of *this value to the specified
* memory location.
*
* @param[out] p Output memory location, may have any alignment.
* @param lim The number of lower elements to store, >0.
*/
void storeu( float* const p, int lim ) const
{
if( lim > 2 )
{
if( lim > 3 )
{
_mm_storeu_ps( p, value );
}
else
{
_mm_storel_pi( (__m64*) p, value );
_mm_store_ss( p + 2, _mm_movehl_ps( value, value ));
}
}
else
{
if( lim == 2 )
{
_mm_storel_pi( (__m64*) p, value );
}
else
{
_mm_store_ss( p, value );
}
}
}
float4& operator += ( const float4& s )
{
value = _mm_add_ps( value, s.value );
return( *this );
}
float4& operator -= ( const float4& s )
{
value = _mm_sub_ps( value, s.value );
return( *this );
}
float4& operator *= ( const float4& s )
{
value = _mm_mul_ps( value, s.value );
return( *this );
}
float4& operator /= ( const float4& s )
{
value = _mm_div_ps( value, s.value );
return( *this );
}
float4 operator + ( const float4& s ) const
{
return( _mm_add_ps( value, s.value ));
}
float4 operator - ( const float4& s ) const
{
return( _mm_sub_ps( value, s.value ));
}
float4 operator * ( const float4& s ) const
{
return( _mm_mul_ps( value, s.value ));
}
float4 operator / ( const float4& s ) const
{
return( _mm_div_ps( value, s.value ));
}
/**
* @return Horizontal sum of elements.
*/
float hadd() const
{
const __m128 v = _mm_add_ps( value, _mm_movehl_ps( value, value ));
const __m128 res = _mm_add_ss( v, _mm_shuffle_ps( v, v, 1 ));
return( _mm_cvtss_f32( res ));
}
/**
* Function performs in-place addition of a value located in memory and
* the specified value.
*
* @param p Pointer to value where addition happens. May be unaligned.
* @param v Value to add.
*/
static void addu( float* const p, const float4& v )
{
( loadu( p ) + v ).storeu( p );
}
/**
* Function performs in-place addition of a value located in memory and
* the specified value. Limited to the specfied number of elements.
*
* @param p Pointer to value where addition happens. May be unaligned.
* @param v Value to add.
* @param lim The element number limit, >0.
*/
static void addu( float* const p, const float4& v, const int lim )
{
( loadu( p, lim ) + v ).storeu( p, lim );
}
__m128 value; ///< Packed value of 4 floats.
///<
};
/**
* SIMD rounding function, exact result.
*
* @param v Value to round.
* @return Rounded SIMD value.
*/
inline float4 round( const float4& v )
{
unsigned int prevrm = _MM_GET_ROUNDING_MODE();
_MM_SET_ROUNDING_MODE( _MM_ROUND_NEAREST );
const __m128 res = _mm_cvtepi32_ps( _mm_cvtps_epi32( v.value ));
_MM_SET_ROUNDING_MODE( prevrm );
return( res );
}
/**
* SIMD function "clamps" (clips) the specified packed values so that they are
* not lesser than "minv", and not greater than "maxv".
*
* @param Value Value to clamp.
* @param minv Minimal allowed value.
* @param maxv Maximal allowed value.
* @return The clamped value.
*/
inline float4 clamp( const float4& Value, const float4& minv,
const float4& maxv )
{
return( _mm_min_ps( _mm_max_ps( Value.value, minv.value ), maxv.value ));
}
typedef fpclass_def< avir :: float4, float > fpclass_float4; ///<
///< Class that can be used as the "fpclass" template parameter of the
///< avir::CImageResizer class to perform calculation using default
///< interleaved algorithm, using SIMD float4 type.
///<
} // namespace avir
#endif // AVIR_FLOAT4_SSE_INCLUDED

View file

@ -1,365 +0,0 @@
/* clang-format off */
//$ nobt
//$ nocpp
/**
* @file avir_float8_avx.h
*
* @brief Inclusion file for the "float8" type.
*
* This file includes the "float8" AVX-based type used for SIMD variable
* storage and processing.
*
* AVIR Copyright (c) 2015-2019 Aleksey Vaneev
*/
#ifndef AVIR_FLOAT8_AVX_INCLUDED
#define AVIR_FLOAT8_AVX_INCLUDED
#include "libc/bits/mmintrin.internal.h"
#include "libc/bits/avxintrin.internal.h"
#include "libc/bits/smmintrin.internal.h"
#include "libc/bits/pmmintrin.internal.h"
#include "libc/bits/avx2intrin.internal.h"
#include "libc/bits/xmmintrin.internal.h"
#include "third_party/avir/avir_dil.h"
namespace avir {
/**
* @brief SIMD packed 8-float type.
*
* This class implements a packed 8-float type that can be used to perform
* parallel computation using SIMD instructions on AVX-enabled processors.
* This class can be used as the "fptype" argument of the avir::fpclass_def
* or avir::fpclass_def_dil class.
*/
class float8
{
public:
float8()
{
}
float8( const float8& s )
: value( s.value )
{
}
float8( const __m256 s )
: value( s )
{
}
float8( const float s )
: value( _mm256_set1_ps( s ))
{
}
float8& operator = ( const float8& s )
{
value = s.value;
return( *this );
}
float8& operator = ( const __m256 s )
{
value = s;
return( *this );
}
float8& operator = ( const float s )
{
value = _mm256_set1_ps( s );
return( *this );
}
operator float () const
{
return( _mm_cvtss_f32( _mm256_extractf128_ps( value, 0 )));
}
/**
* @param p Pointer to memory from where the value should be loaded,
* should be 32-byte aligned.
* @return float8 value loaded from the specified memory location.
*/
static float8 load( const float* const p )
{
return( _mm256_load_ps( p ));
}
/**
* @param p Pointer to memory from where the value should be loaded,
* may have any alignment.
* @return float8 value loaded from the specified memory location.
*/
static float8 loadu( const float* const p )
{
return( _mm256_loadu_ps( p ));
}
/**
* @param p Pointer to memory from where the value should be loaded,
* may have any alignment.
* @param lim The maximum number of elements to load, >0.
* @return float8 value loaded from the specified memory location, with
* elements beyond "lim" set to 0.
*/
static float8 loadu( const float* const p, const int lim )
{
__m128 lo;
__m128 hi;
if( lim > 4 )
{
lo = _mm_loadu_ps( p );
hi = loadu4( p + 4, lim - 4 );
}
else
{
lo = loadu4( p, lim );
hi = _mm_setzero_ps();
}
return( _mm256_insertf128_ps( _mm256_castps128_ps256( lo ), hi, 1 ));
}
/**
* Function stores *this value to the specified memory location.
*
* @param[out] p Output memory location, should be 32-byte aligned.
*/
void store( float* const p ) const
{
_mm256_store_ps( p, value );
}
/**
* Function stores *this value to the specified memory location.
*
* @param[out] p Output memory location, may have any alignment.
*/
void storeu( float* const p ) const
{
_mm256_storeu_ps( p, value );
}
/**
* Function stores "lim" lower elements of *this value to the specified
* memory location.
*
* @param[out] p Output memory location, may have any alignment.
* @param lim The number of lower elements to store, >0.
*/
void storeu( float* p, int lim ) const
{
__m128 v;
if( lim > 4 )
{
_mm_storeu_ps( p, _mm256_extractf128_ps( value, 0 ));
v = _mm256_extractf128_ps( value, 1 );
p += 4;
lim -= 4;
}
else
{
v = _mm256_extractf128_ps( value, 0 );
}
if( lim > 2 )
{
if( lim > 3 )
{
_mm_storeu_ps( p, v );
}
else
{
_mm_storel_pi( (__m64*) p, v );
_mm_store_ss( p + 2, _mm_movehl_ps( v, v ));
}
}
else
{
if( lim == 2 )
{
_mm_storel_pi( (__m64*) p, v );
}
else
{
_mm_store_ss( p, v );
}
}
}
float8& operator += ( const float8& s )
{
value = _mm256_add_ps( value, s.value );
return( *this );
}
float8& operator -= ( const float8& s )
{
value = _mm256_sub_ps( value, s.value );
return( *this );
}
float8& operator *= ( const float8& s )
{
value = _mm256_mul_ps( value, s.value );
return( *this );
}
float8& operator /= ( const float8& s )
{
value = _mm256_div_ps( value, s.value );
return( *this );
}
float8 operator + ( const float8& s ) const
{
return( _mm256_add_ps( value, s.value ));
}
float8 operator - ( const float8& s ) const
{
return( _mm256_sub_ps( value, s.value ));
}
float8 operator * ( const float8& s ) const
{
return( _mm256_mul_ps( value, s.value ));
}
float8 operator / ( const float8& s ) const
{
return( _mm256_div_ps( value, s.value ));
}
/**
* @return Horizontal sum of elements.
*/
float hadd() const
{
__m128 v = _mm_add_ps( _mm256_extractf128_ps( value, 0 ),
_mm256_extractf128_ps( value, 1 ));
v = _mm_hadd_ps( v, v );
v = _mm_hadd_ps( v, v );
return( _mm_cvtss_f32( v ));
}
/**
* Function performs in-place addition of a value located in memory and
* the specified value.
*
* @param p Pointer to value where addition happens. May be unaligned.
* @param v Value to add.
*/
static void addu( float* const p, const float8& v )
{
( loadu( p ) + v ).storeu( p );
}
/**
* Function performs in-place addition of a value located in memory and
* the specified value. Limited to the specfied number of elements.
*
* @param p Pointer to value where addition happens. May be unaligned.
* @param v Value to add.
* @param lim The element number limit, >0.
*/
static void addu( float* const p, const float8& v, const int lim )
{
( loadu( p, lim ) + v ).storeu( p, lim );
}
__m256 value; ///< Packed value of 8 floats.
///<
private:
/**
* @param p Pointer to memory from where the value should be loaded,
* may have any alignment.
* @param lim The maximum number of elements to load, >0.
* @return __m128 value loaded from the specified memory location, with
* elements beyond "lim" set to 0.
*/
static __m128 loadu4( const float* const p, const int lim )
{
if( lim > 2 )
{
if( lim > 3 )
{
return( _mm_loadu_ps( p ));
}
else
{
return( _mm_set_ps( 0.0f, p[ 2 ], p[ 1 ], p[ 0 ]));
}
}
else
{
if( lim == 2 )
{
return( _mm_set_ps( 0.0f, 0.0f, p[ 1 ], p[ 0 ]));
}
else
{
return( _mm_load_ss( p ));
}
}
}
};
/**
* SIMD rounding function, exact result.
*
* @param v Value to round.
* @return Rounded SIMD value.
*/
inline float8 round( const float8& v )
{
return( _mm256_round_ps( v.value,
( _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC )));
}
/**
* SIMD function "clamps" (clips) the specified packed values so that they are
* not lesser than "minv", and not greater than "maxv".
*
* @param Value Value to clamp.
* @param minv Minimal allowed value.
* @param maxv Maximal allowed value.
* @return The clamped value.
*/
inline float8 clamp( const float8& Value, const float8& minv,
const float8& maxv )
{
return( _mm256_min_ps( _mm256_max_ps( Value.value, minv.value ),
maxv.value ));
}
typedef fpclass_def_dil< float, avir :: float8 > fpclass_float8_dil; ///<
///< Class that can be used as the "fpclass" template parameter of the
///< avir::CImageResizer class to perform calculation using
///< de-interleaved SIMD algorithm, using SIMD float8 type.
///<
} // namespace avir
#endif // AVIR_FLOAT8_AVX_INCLUDED

File diff suppressed because it is too large Load diff

View file

@ -1,40 +0,0 @@
/*-*-mode:c++;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8-*-│
vi: set net ft=c++ ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/limits.h"
#include "libc/log/check.h"
#include "libc/log/log.h"
#include "third_party/avir/lanczos.h"
namespace {
#include "third_party/avir/lancir.h"
} // namespace
/**
* Does Lanczos interpolation.
* @note computers w/o AVX2+FMA need to call BilinearScale()
*/
void lanczos(unsigned dyn, unsigned dxn, void *restrict dst, unsigned syn,
unsigned sxn, const void *restrict src, unsigned sw) {
avir::CLancIR lanczos;
DCHECK_ALIGNED(64, dst);
DCHECK_ALIGNED(64, src);
LOGF("%10s%5zux×%-5zu→%5zu×%-5zu", "lanczos", sxn, syn, dxn, dyn);
lanczos.resizeImage((const float *)src, sxn, syn, sw, (float *)dst, dxn, dyn,
4);
}

View file

@ -1,13 +0,0 @@
#ifndef COSMOPOLITAN_THIRD_PARTY_AVIR_LANCZOS_H_
#define COSMOPOLITAN_THIRD_PARTY_AVIR_LANCZOS_H_
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
void lanczos(unsigned, unsigned, void *, unsigned, unsigned, const void *,
unsigned);
void lanczos3(unsigned, unsigned, void *, unsigned, unsigned, const void *,
unsigned);
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_THIRD_PARTY_AVIR_LANCZOS_H_ */

View file

@ -1,77 +0,0 @@
/*-*-mode:c++;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8-*-│
vi: set net ft=c++ ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/bits/xmmintrin.internal.h"
#include "libc/limits.h"
#include "libc/log/log.h"
#include "libc/runtime/runtime.h"
#include "third_party/avir/lanczos1.h"
namespace {
#include "third_party/avir/lanczos1.hpp"
} // namespace
void lanczos1init(struct lanczos1 *resizer) {
lanczos1free(resizer);
resizer->p = new Lanczos1Impl;
}
void lanczos1free(struct lanczos1 *resizer) {
Lanczos1Impl *impl;
if (!resizer->p) return;
impl = (Lanczos1Impl *)resizer->p;
delete impl;
resizer->p = nullptr;
}
/**
* Resizes image plane w/ Lanczos interpolation, e.g.
*
* struct lanczos1 scaler = {0};
* lanczos1init(&scaler);
* lanczos1(&scaler, ...);
* lanczos1free(&scaler);
*
* @param dyn is destination height
* @param dxn is destination width
* @param dst is destination unsigned char array
* @param dstsize is number of bytes in dst
* @param syn is source height
* @param sxn is source width
* @param ssw is number of unsigned chars per scanline in src
* @param src is source unsigned char array
* @param srcsize is number of bytes in src
*/
void lanczos1(struct lanczos1 *resizer, size_t dyn, size_t dxn, void *dst,
size_t dstsize, size_t syn, size_t sxn, size_t ssw,
const void *src, size_t srcsize) {
Lanczos1Impl *impl;
unsigned int roundhouse;
LOGF("%10s%5zux×%-5zu→%5zu×%-5zu", "lanczos1", sxn, syn, dxn, dyn);
CHECK_LE(dstsize, INT_MAX);
CHECK_LE(srcsize, INT_MAX);
CHECK_LE(sizeof(unsigned char) * 1 * dyn * dxn, dstsize);
CHECK_LE(sizeof(unsigned char) * 1 * syn * sxn, srcsize);
CHECK_LE(sizeof(unsigned char) * syn * ssw, srcsize);
roundhouse = _MM_GET_ROUNDING_MODE();
_MM_SET_ROUNDING_MODE(_MM_ROUND_NEAREST);
impl = (Lanczos1Impl *)resizer->p;
impl->lanczos.resizeImage((const unsigned char *)src, sxn, syn, ssw,
(unsigned char *)dst, dxn, dyn, 1);
_MM_SET_ROUNDING_MODE(roundhouse);
}

View file

@ -1,18 +0,0 @@
#ifndef COSMOPOLITAN_THIRD_PARTY_AVIR_LANCZOS1_H_
#define COSMOPOLITAN_THIRD_PARTY_AVIR_LANCZOS1_H_
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
struct lanczos1 {
void *p;
};
void lanczos1init(struct lanczos1 *self);
void lanczos1free(struct lanczos1 *self);
void lanczos1(struct lanczos1 *self, size_t dyn, size_t dxn, void *dst,
size_t dstsize, size_t syn, size_t sxn, size_t ssw,
const void *src, size_t srcsize) paramsnonnull();
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_THIRD_PARTY_AVIR_LANCZOS1_H_ */

View file

@ -1,11 +0,0 @@
#ifndef COSMOPOLITAN_THIRD_PARTY_AVIR_LANCZOS1_HPP_
#define COSMOPOLITAN_THIRD_PARTY_AVIR_LANCZOS1_HPP_
#include "third_party/avir/lancir.h"
struct Lanczos1Impl {
Lanczos1Impl() : lanczos{} {
}
avir::CLancIR lanczos;
};
#endif /* COSMOPOLITAN_THIRD_PARTY_AVIR_LANCZOS1_HPP_ */

View file

@ -1,31 +0,0 @@
/*-*-mode:c++;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8-*-│
vi: set net ft=c++ ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/bits/bits.h"
#include "third_party/avir/lanczos1b.h"
namespace {
#include "third_party/avir/lancir.h"
} // namespace
void lanczos1b(size_t dyn, size_t dxn, unsigned char *restrict dst, size_t syn,
size_t sxn, const unsigned char *restrict src) {
avir::CLancIR lanczos;
LOGF("%10s%5zux×%-5zu→%5zu×%-5zu", "lanczos1b", sxn, syn, dxn, dyn);
lanczos.resizeImage(src, sxn, syn, roundup2pow(sxn) * 4, dst, dxn, dyn, 4);
}

View file

@ -1,11 +0,0 @@
#ifndef COSMOPOLITAN_THIRD_PARTY_AVIR_LANCZOS1B_H_
#define COSMOPOLITAN_THIRD_PARTY_AVIR_LANCZOS1B_H_
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
void lanczos1b(size_t dyn, size_t dxn, unsigned char *restrict dst, size_t syn,
size_t sxn, const unsigned char *restrict src);
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_THIRD_PARTY_AVIR_LANCZOS1B_H_ */

View file

@ -1,63 +0,0 @@
/*-*-mode:c++;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8-*-│
vi: set net ft=c++ ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/bits/xmmintrin.internal.h"
#include "libc/runtime/runtime.h"
#include "third_party/avir/lanczos1f.h"
namespace {
#include "third_party/avir/lanczos1f.hpp"
} // namespace
void lanczos1finit(struct lanczos1f *resizer) {
lanczos1ffree(resizer);
resizer->p = new Lanczos1fImpl;
}
void lanczos1ffree(struct lanczos1f *resizer) {
Lanczos1fImpl *impl;
if (!resizer->p) return;
impl = (Lanczos1fImpl *)resizer->p;
delete impl;
resizer->p = nullptr;
}
/**
* Resizes image plane w/ Lanczos interpolation, e.g.
*
* struct lanczos1f scaler = {0};
* lanczos1finit(&scaler);
* lanczos1f(&scaler, ...);
* lanczos1ffree(&scaler);
*
* @param dyn is destination height
* @param dxn is destination width
* @param dst is destination unsigned char array
* @param syn is source height
* @param sxn is source width
* @param ssw is number of unsigned chars per scanline in src
* @param src is source unsigned char array
*/
void lanczos1f(struct lanczos1f *resizer, size_t dyn, size_t dxn, void *dst,
size_t syn, size_t sxn, size_t ssw, const void *src, double ky0,
double kx0, double oy, double ox) {
Lanczos1fImpl *impl;
impl = (Lanczos1fImpl *)resizer->p;
impl->lanczos.resizeImage((const float *)src, sxn, syn, ssw, (float *)dst,
dxn, dyn, 1, kx0, ky0, ox, oy);
}

View file

@ -1,18 +0,0 @@
#ifndef COSMOPOLITAN_THIRD_PARTY_AVIR_LANCZOS1F_H_
#define COSMOPOLITAN_THIRD_PARTY_AVIR_LANCZOS1F_H_
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
struct lanczos1f {
void *p;
};
void lanczos1finit(struct lanczos1f *);
void lanczos1ffree(struct lanczos1f *);
void lanczos1f(struct lanczos1f *, size_t, size_t, void *, size_t, size_t,
size_t, const void *, double, double, double, double)
paramsnonnull();
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_THIRD_PARTY_AVIR_LANCZOS1F_H_ */

View file

@ -1,11 +0,0 @@
#ifndef COSMOPOLITAN_THIRD_PARTY_AVIR_LANCZOS1F_HPP_
#define COSMOPOLITAN_THIRD_PARTY_AVIR_LANCZOS1F_HPP_
#include "third_party/avir/lancir.h"
struct Lanczos1fImpl {
Lanczos1fImpl() : lanczos{} {
}
avir::CLancIR lanczos;
};
#endif /* COSMOPOLITAN_THIRD_PARTY_AVIR_LANCZOS1F_HPP_ */

View file

@ -1,30 +0,0 @@
/*-*-mode:c++;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8-*-│
vi: set net ft=c++ ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "third_party/avir/lanczos.h"
namespace {
#include "third_party/avir/lancir.h"
}
void lanczos3(unsigned dyn, unsigned dxn, void *dst, unsigned syn, unsigned sxn,
const void *src, unsigned sw) {
avir::CLancIR lanczos;
lanczos.resizeImage((const float *)src, sxn, syn, sw, (float *)dst, dxn, dyn,
3, -1, -2);
}

View file

@ -1,11 +0,0 @@
#ifndef COSMOPOLITAN_THIRD_PARTY_AVIR_NOTICE_H_
#define COSMOPOLITAN_THIRD_PARTY_AVIR_NOTICE_H_
#if !(__ASSEMBLER__ + __LINKER__ + 0)
asm(".ident\t\"\\n\\n\
AVIR (MIT License)\\n\
Copyright 2015-2019 Aleksey Vaneev\"");
asm(".include \"libc/disclaimer.inc\"");
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_THIRD_PARTY_AVIR_NOTICE_H_ */

View file

@ -1,48 +0,0 @@
/*-*-mode:c++;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8-*-│
vi: set net ft=c++ ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "third_party/avir/resize.h"
namespace {
#include "third_party/avir/avir_float4_sse.h"
} // namespace
struct ResizerImpl {
ResizerImpl() : resizer{8, 8, avir::CImageResizerParamsULR()} {}
avir::CImageResizer<avir::fpclass_float4> resizer;
};
void NewResizer(Resizer *resizer, int aResBitDepth, int aSrcBitDepth) {
FreeResizer(resizer);
resizer->p = new ResizerImpl();
}
void FreeResizer(Resizer *resizer) {
if (!resizer->p) return;
delete (ResizerImpl *)resizer->p;
resizer->p = nullptr;
}
void ResizeImage(Resizer *resizer, float *Dest, int DestHeight, int DestWidth,
const float *Src, int SrcHeight, int SrcWidth) {
ResizerImpl *impl = (ResizerImpl *)resizer->p;
int SrcScanLineSize = 0;
double ResizingStep = 0;
impl->resizer.resizeImage(Src, SrcWidth, SrcHeight, SrcScanLineSize, Dest,
DestWidth, DestHeight, 4, ResizingStep);
}

View file

@ -1,17 +0,0 @@
#ifndef COSMOPOLITAN_THIRD_PARTY_AVIR_RESIZE_H_
#define COSMOPOLITAN_THIRD_PARTY_AVIR_RESIZE_H_
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
struct Resizer {
void *p;
};
void FreeResizer(struct Resizer *) paramsnonnull();
void NewResizer(struct Resizer *, int, int) paramsnonnull();
void ResizeImage(struct Resizer *, float *, int, int, const float *, int, int)
paramsnonnull();
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_THIRD_PARTY_AVIR_RESIZE_H_ */

View file

@ -2707,15 +2707,6 @@ static noinline void OpFpu1(struct As *a, int op, int reg) {
OpFpu1Impl(a, op, reg);
}
static void OnFucomi(struct As *a, struct Slice s) {
int reg, rm;
rm = !IsPunct(a, a->i, ';') ? GetRegisterRm(a) : 1;
reg = !IsPunct(a, a->i, ';') ? GetRegisterReg(a) : 0;
if (reg & 7) Fail(a, "bad register");
EmitByte(a, 0xDB);
EmitByte(a, 0350 | rm & 7);
}
static void OnFxch(struct As *a, struct Slice s) {
int rm;
rm = !IsPunct(a, a->i, ';') ? GetRegisterRm(a) : 1;
@ -2731,6 +2722,18 @@ static void OnBswap(struct As *a, struct Slice s) {
EmitByte(a, 0310 | srm & 7);
}
static noinline void OpFcomImpl(struct As *a, int op) {
int reg, rm;
rm = !IsPunct(a, a->i, ';') ? GetRegisterRm(a) : 1;
reg = !IsPunct(a, a->i, ';') ? GetRegisterReg(a) : 0;
if (reg & 7) Fail(a, "bad register");
EmitVarword(a, op | rm & 7);
}
static noinline void OpFcom(struct As *a, int op) {
OpFcomImpl(a, op);
}
// clang-format off
static void OnAdc(struct As *a, struct Slice s) { OpAlu(a, s, 2); }
static void OnAdd(struct As *a, struct Slice s) { OpAlu(a, s, 0); }
@ -2803,13 +2806,22 @@ static void OnDivps(struct As *a, struct Slice s) { OpSse(a, 0x0F5E); }
static void OnDivsd(struct As *a, struct Slice s) { OpSse(a, 0xF20F5E); }
static void OnDivss(struct As *a, struct Slice s) { OpSse(a, 0xF30F5E); }
static void OnDppd(struct As *a, struct Slice s) { OpSse(a, 0x660F3A41); }
static void OnFabs(struct As *a, struct Slice s) { EmitVarword(a, 0xd9e1); }
static void OnFabs(struct As *a, struct Slice s) { EmitVarword(a, 0xD9E1); }
static void OnFaddl(struct As *a, struct Slice s) { OpFpu1(a, 0xDC, 0); }
static void OnFaddp(struct As *a, struct Slice s) { EmitVarword(a, 0xdec1); }
static void OnFaddp(struct As *a, struct Slice s) { EmitVarword(a, 0xDEC1); }
static void OnFadds(struct As *a, struct Slice s) { OpFpu1(a, 0xD8, 0); }
static void OnFchs(struct As *a, struct Slice s) { EmitVarword(a, 0xd9e0); }
static void OnFcomip(struct As *a, struct Slice s) { EmitVarword(a, 0xdff1); }
static void OnFdivrp(struct As *a, struct Slice s) { EmitVarword(a, 0xdef9); }
static void OnFchs(struct As *a, struct Slice s) { EmitVarword(a, 0xD9E0); }
static void OnFcmovb(struct As *a, struct Slice s) { OpFcom(a, 0xDAC0); }
static void OnFcmovbe(struct As *a, struct Slice s) { OpFcom(a, 0xDAD0); }
static void OnFcmove(struct As *a, struct Slice s) { OpFcom(a, 0xDAC8); }
static void OnFcmovnb(struct As *a, struct Slice s) { OpFcom(a, 0xDBC0); }
static void OnFcmovnbe(struct As *a, struct Slice s) { OpFcom(a, 0xDBD0); }
static void OnFcmovne(struct As *a, struct Slice s) { OpFcom(a, 0xDBC8); }
static void OnFcmovnu(struct As *a, struct Slice s) { OpFcom(a, 0xDBD8); }
static void OnFcmovu(struct As *a, struct Slice s) { OpFcom(a, 0xDAD8); }
static void OnFcomi(struct As *a, struct Slice s) { OpFcom(a, 0xDBF0); }
static void OnFcomip(struct As *a, struct Slice s) { OpFcom(a, 0xDFF0); }
static void OnFdivrp(struct As *a, struct Slice s) { EmitVarword(a, 0xDEF9); }
static void OnFildl(struct As *a, struct Slice s) { OpFpu1(a, 0xDB, 0); }
static void OnFildll(struct As *a, struct Slice s) { OpFpu1(a, 0xDF, 5); }
static void OnFildq(struct As *a, struct Slice s) { OpFpu1(a, 0xDF, 5); }
@ -2837,9 +2849,11 @@ static void OnFstps(struct As *a, struct Slice s) { OpFpu1(a, 0xD9, 3); }
static void OnFstpt(struct As *a, struct Slice s) { OpFpu1(a, 0xDB, 7); }
static void OnFsubrp(struct As *a, struct Slice s) { EmitVarword(a, 0xDEE9); }
static void OnFtst(struct As *a, struct Slice s) { EmitVarword(a, 0xD9E4); }
static void OnFucomip(struct As *a, struct Slice s) { EmitVarword(a, 0xDFE9); }
static void OnFucomi(struct As *a, struct Slice s) { OpFcom(a, 0xDBE8); }
static void OnFucomip(struct As *a, struct Slice s) { OpFcom(a, 0xDFE8); }
static void OnFwait(struct As *a, struct Slice s) { EmitByte(a, 0x9B); }
static void OnFxam(struct As *a, struct Slice s) { EmitVarword(a, 0xd9e5); }
static void OnFxam(struct As *a, struct Slice s) { EmitVarword(a, 0xD9E5); }
static void OnFxtract(struct As *a, struct Slice s) { EmitVarword(a, 0xD9F4); }
static void OnHaddpd(struct As *a, struct Slice s) { OpSse(a, 0x660F7C); }
static void OnHaddps(struct As *a, struct Slice s) { OpSse(a, 0xF20F7C); }
static void OnHlt(struct As *a, struct Slice s) { EmitByte(a, 0xF4); }
@ -3211,6 +3225,15 @@ static const struct Directive8 {
{"faddp", OnFaddp}, //
{"fadds", OnFadds}, //
{"fchs", OnFchs}, //
{"fcmovb", OnFcmovb}, //
{"fcmovbe", OnFcmovbe}, //
{"fcmove", OnFcmove}, //
{"fcmovnb", OnFcmovnb}, //
{"fcmovnbe", OnFcmovnbe}, //
{"fcmovne", OnFcmovne}, //
{"fcmovnu", OnFcmovnu}, //
{"fcmovu", OnFcmovu}, //
{"fcomi", OnFcomi}, //
{"fcomip", OnFcomip}, //
{"fdivrp", OnFdivrp}, //
{"fildl", OnFildl}, //
@ -3246,6 +3269,7 @@ static const struct Directive8 {
{"fwait", OnFwait}, //
{"fxam", OnFxam}, //
{"fxch", OnFxch}, //
{"fxtract", OnFxtract}, //
{"haddpd", OnHaddpd}, //
{"haddps", OnHaddps}, //
{"hlt", OnHlt}, //

View file

@ -1,3 +1,5 @@
#include "libc/calls/struct/siginfo.h"
#include "libc/calls/ucontext.h"
#include "third_party/chibicc/chibicc.h"
asm(".ident\t\"\\n\\n\
@ -381,10 +383,9 @@ static bool run_subprocess(char **argv) {
for (int i = 1; argv[i]; i++) fprintf(stderr, " %s", argv[i]);
fprintf(stderr, "\n");
}
if (fork() == 0) {
if (!vfork()) {
// Child process. Run a new command.
execvp(argv[0], argv);
fprintf(stderr, "exec failed: %s: %s\n", argv[0], strerror(errno));
_exit(1);
}
// Wait for the child process to finish.
@ -503,7 +504,7 @@ static Token *append_tokens(Token *tok1, Token *tok2) {
return tok1;
}
static FileType get_file_type(char *filename) {
static FileType get_file_type(const char *filename) {
if (opt_x != FILE_NONE) return opt_x;
if (endswith(filename, ".a")) return FILE_AR;
if (endswith(filename, ".o")) return FILE_OBJ;
@ -514,7 +515,13 @@ static FileType get_file_type(char *filename) {
}
static void cc1(void) {
FileType ft;
Token *tok = NULL;
ft = get_file_type(base_file);
if (opt_J && (ft == FILE_ASM || ft == FILE_ASM_CPP)) {
output_javadown_asm(output_file, base_file);
return;
}
// Process -include option
for (int i = 0; i < opt_include.len; i++) {
char *incl = opt_include.data[i];
@ -538,7 +545,7 @@ static void cc1(void) {
if (opt_M) return;
}
// If -E is given, print out preprocessed C code as a result.
if (opt_E || get_file_type(base_file) == FILE_ASM_CPP) {
if (opt_E || ft == FILE_ASM_CPP) {
print_tokens(tok);
return;
}
@ -605,8 +612,13 @@ static void run_linker(StringArray *inputs, char *output) {
handle_exit(run_subprocess(arr.data));
}
static void OnCtrlC(int sig, siginfo_t *si, ucontext_t *ctx) {
exit(1);
}
int chibicc(int argc, char **argv) {
showcrashreports();
sigaction(SIGINT, &(struct sigaction){.sa_sigaction = OnCtrlC}, NULL);
atexit(cleanup);
init_macros();
parse_args(argc, argv);
@ -649,6 +661,18 @@ int chibicc(int argc, char **argv) {
strarray_push(&ld_args, input);
continue;
}
// Dox
if (opt_J) {
if (opt_c) {
handle_exit(run_cc1(argc, argv, input, output));
} else {
char *tmp = create_tmpfile();
if (run_cc1(argc, argv, input, tmp)) {
strarray_push(&dox_args, tmp);
}
}
continue;
}
// Handle .s
if (type == FILE_ASM) {
if (!opt_S) {
@ -657,6 +681,11 @@ int chibicc(int argc, char **argv) {
continue;
}
assert(type == FILE_C || type == FILE_ASM_CPP);
// Just print ast.
if (opt_A) {
handle_exit(run_cc1(argc, argv, input, NULL));
continue;
}
// Just preprocess
if (opt_E || opt_M) {
handle_exit(run_cc1(argc, argv, input, NULL));
@ -674,14 +703,6 @@ int chibicc(int argc, char **argv) {
assemble(tmp, output);
continue;
}
// Dox
if (opt_J) {
char *tmp = create_tmpfile();
if (run_cc1(argc, argv, input, tmp)) {
strarray_push(&dox_args, tmp);
}
continue;
}
// Compile, assemble and link
char *tmp1 = create_tmpfile();
char *tmp2 = create_tmpfile();

View file

@ -272,6 +272,7 @@ struct Obj {
bool is_destructor;
bool is_constructor;
bool is_ms_abi; /* TODO */
bool is_no_instrument_function;
bool is_force_align_arg_pointer;
bool is_no_caller_saved_registers;
int stack_size;
@ -616,10 +617,16 @@ Obj *alloc_obj(void);
Type *alloc_type(void);
//
// javadown.c
// dox1.c
//
void output_javadown(const char *, Obj *);
void output_javadown_asm(const char *, const char *);
//
// dox2.c
//
void drop_dox(const StringArray *, const char *);
COSMOPOLITAN_C_END_

View file

@ -116,15 +116,6 @@ o/$(MODE)/third_party/chibicc/as.com.dbg: \
$(THIRD_PARTY_CHIBICC_A).pkg
@$(APELINK)
o/$(MODE)/third_party/chibicc/hello.com.dbg: \
$(THIRD_PARTY_CHIBICC_A_DEPS) \
$(THIRD_PARTY_CHIBICC_A) \
$(APE) \
$(CRT) \
o/$(MODE)/third_party/chibicc/hello.chibicc.o \
$(THIRD_PARTY_CHIBICC_A).pkg
@$(APELINK)
o/$(MODE)/third_party/chibicc/chibicc.o: \
CPPFLAGS += $(THIRD_PARTY_CHIBICC_DEFINES)

View file

@ -973,6 +973,12 @@ static bool gen_builtin_funcall(Node *node, const char *name) {
pop("%rax");
return true;
}
} else if (!strcmp(name, "logbl")) {
gen_expr(node->args);
emitlin("\
\tfxtract\n\
\tfstp\t%st");
return true;
} else if (!strcmp(name, "isgreater")) {
gen_comis(node, "comisd", 1, 0, "a");
return true;
@ -1010,17 +1016,17 @@ static bool gen_builtin_funcall(Node *node, const char *name) {
\tflds\t(%rsp)\n\
\tpop\t%rax");
return true;
} else if (!strcmp(name, "inff")) {
} else if (!strcmp(name, "inff") || !strcmp(name, "huge_valf")) {
emitlin("\
\tmov\t$0x7f800000,%eax\n\
\tmovd\t%eax,%xmm0");
return true;
} else if (!strcmp(name, "inf")) {
} else if (!strcmp(name, "inf") || !strcmp(name, "huge_val")) {
emitlin("\
\tmov\t$0x7ff0000000000000,%rax\n\
\tmovq\t%rax,%xmm0");
return true;
} else if (!strcmp(name, "infl")) {
} else if (!strcmp(name, "infl") || !strcmp(name, "huge_vall")) {
emitlin("\
\tpush\t$0x7f800000\n\
\tflds\t(%rsp)\n\
@ -2304,6 +2310,42 @@ static void store_gp(int r, int offset, int sz) {
}
}
static void emit_function_hook(void) {
if (opt_nop_mcount) {
print_profiling_nop();
} else if (opt_fentry) {
emitlin("\tcall\t__fentry__@gotpcrel(%rip)");
} else if (opt_pg) {
emitlin("\tcall\tmcount@gotpcrel(%rip)");
} else {
print_profiling_nop();
}
}
static void save_caller_saved_registers(void) {
emitlin("\
\tpush\t%rdi\n\
\tpush\t%rsi\n\
\tpush\t%rdx\n\
\tpush\t%rcx\n\
\tpush\t%r8\n\
\tpush\t%r9\n\
\tpush\t%r10\n\
\tpush\t%r11");
}
static void restore_caller_saved_registers(void) {
emitlin("\
\tpop\t%r11\n\
\tpop\t%r10\n\
\tpop\t%r9\n\
\tpop\t%r8\n\
\tpop\t%rcx\n\
\tpop\t%rdx\n\
\tpop\t%rsi\n\
\tpop\t%rdi");
}
static void emit_text(Obj *prog) {
for (Obj *fn = prog; fn; fn = fn->next) {
if (!fn->is_function || !fn->is_definition) continue;
@ -2327,14 +2369,8 @@ static void emit_text(Obj *prog) {
// Prologue
emitlin("\tpush\t%rbp");
emitlin("\tmov\t%rsp,%rbp");
if (opt_nop_mcount) {
print_profiling_nop();
} else if (opt_fentry) {
emitlin("\tcall\t__fentry__@gotpcrel(%rip)");
} else if (opt_pg) {
emitlin("\tcall\tmcount@gotpcrel(%rip)");
} else {
print_profiling_nop();
if (!fn->is_no_instrument_function) {
emit_function_hook();
}
println("\tsub\t$%d,%%rsp", fn->stack_size);
println("\tmov\t%%rsp,%d(%%rbp)", fn->alloca_bottom->offset);
@ -2410,15 +2446,7 @@ static void emit_text(Obj *prog) {
emitlin("\tand\t$-16,%rsp");
}
if (fn->is_no_caller_saved_registers) {
emitlin("\
\tpush\t%rdi\n\
\tpush\t%rsi\n\
\tpush\t%rdx\n\
\tpush\t%rcx\n\
\tpush\t%r8\n\
\tpush\t%r9\n\
\tpush\t%r10\n\
\tpush\t%r11");
save_caller_saved_registers();
}
// Emit code
gen_stmt(fn->body);
@ -2436,15 +2464,7 @@ static void emit_text(Obj *prog) {
emitlin("\tud2");
} else {
if (fn->is_no_caller_saved_registers) {
emitlin("\
\tpop\t%r11\n\
\tpop\t%r10\n\
\tpop\t%r9\n\
\tpop\t%r8\n\
\tpop\t%rcx\n\
\tpop\t%rdx\n\
\tpop\t%rsi\n\
\tpop\t%rdi");
restore_caller_saved_registers();
}
emitlin("\tleave");
emitlin("\tret");

View file

@ -17,7 +17,11 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/runtime/gc.h"
#include "libc/sysv/consts/map.h"
#include "libc/sysv/consts/o.h"
#include "libc/sysv/consts/prot.h"
#include "third_party/chibicc/chibicc.h"
#include "tool/build/lib/asmdown.h"
#define APPEND(L) L.p = realloc(L.p, ++L.n * sizeof(*L.p))
@ -101,30 +105,34 @@ static char *DescribeType(struct Type *ty) {
return DescribeScalar(ty, "double");
case TY_LDOUBLE:
return DescribeScalar(ty, "long double");
case TY_FUNC:
return xasprintf("%s(*)()", gc(DescribeType(ty->return_ty)));
case TY_PTR:
return xasprintf("%s*", gc(DescribeType(ty->base)));
if (ty->base->kind == TY_FUNC) {
return DescribeType(ty->base);
} else {
return xasprintf("%s*", gc(DescribeType(ty->base)));
}
case TY_ARRAY:
return xasprintf("%s[%d]", gc(DescribeType(ty->base)), ty->array_len);
case TY_ENUM:
if (ty->name_pos) {
return xasprintf("enum %.*s", ty->name_pos->len, ty->name_pos->loc);
if (ty->name) {
return xasprintf("enum %.*s", ty->name->len, ty->name->loc);
} else {
return strdup("ANONYMOUS-ENUM");
}
case TY_STRUCT:
if (ty->name_pos) {
return xasprintf("struct %.*s", ty->name_pos->len, ty->name_pos->loc);
if (ty->name) {
return xasprintf("struct %.*s", ty->name->len, ty->name->loc);
} else {
return strdup("ANONYMOUS-STRUCT");
}
case TY_UNION:
if (ty->name_pos) {
return xasprintf("union %.*s", ty->name_pos->len, ty->name_pos->loc);
if (ty->name) {
return xasprintf("union %.*s", ty->name->len, ty->name->loc);
} else {
return strdup("ANONYMOUS-UNION");
}
case TY_FUNC:
return xasprintf("%s(*)()", gc(DescribeType(ty->return_ty)));
default:
return "UNKNOWN";
}
@ -136,6 +144,12 @@ static int CountParams(Obj *params) {
return n;
}
static int CountMacroParams(struct MacroParam *params) {
int n;
for (n = 0; params; params = params->next) ++n;
return n;
}
static const char *GetFileName(Obj *obj) {
if (obj->javadown && obj->javadown->file) return obj->javadown->file->name;
if (obj->tok && obj->tok->file) return obj->tok->file->name;
@ -155,7 +169,9 @@ static void SerializeDox(struct DoxWriter *dox, Obj *prog) {
MacroParam *mparam;
SerializeInt(&dox->buf, dox->objects.n);
for (i = 0; i < dox->objects.n; ++i) {
s = DescribeType(dox->objects.p[i]->ty);
s = DescribeType(dox->objects.p[i]->is_function
? dox->objects.p[i]->ty->return_ty
: dox->objects.p[i]->ty);
SerializeStr(&dox->buf, s);
free(s);
SerializeStr(&dox->buf, dox->objects.p[i]->name);
@ -170,7 +186,10 @@ static void SerializeDox(struct DoxWriter *dox, Obj *prog) {
SerializeInt(&dox->buf, dox->objects.p[i]->is_force_align_arg_pointer);
SerializeInt(&dox->buf, dox->objects.p[i]->is_no_caller_saved_registers);
SerializeStr(&dox->buf, dox->objects.p[i]->visibility);
SerializeJavadown(&dox->buf, dox->objects.p[i]->javadown->javadown);
SerializeInt(&dox->buf, !!dox->objects.p[i]->javadown);
if (dox->objects.p[i]->javadown) {
SerializeJavadown(&dox->buf, dox->objects.p[i]->javadown->javadown);
}
SerializeInt(&dox->buf, CountParams(dox->objects.p[i]->params));
for (param = dox->objects.p[i]->params; param; param = param->next) {
s = DescribeType(param->ty);
@ -184,22 +203,93 @@ static void SerializeDox(struct DoxWriter *dox, Obj *prog) {
SerializeStr(&dox->buf, dox->macros.p[i]->name);
SerializeStr(&dox->buf, dox->macros.p[i]->javadown->file->name);
SerializeInt(&dox->buf, dox->macros.p[i]->javadown->line_no);
SerializeJavadown(&dox->buf, dox->macros.p[i]->javadown->javadown);
SerializeInt(&dox->buf, dox->macros.p[i]->is_objlike);
SerializeStr(&dox->buf, dox->macros.p[i]->va_args_name);
SerializeInt(&dox->buf, !!dox->macros.p[i]->javadown);
if (dox->macros.p[i]->javadown) {
SerializeJavadown(&dox->buf, dox->macros.p[i]->javadown->javadown);
}
SerializeInt(&dox->buf, CountMacroParams(dox->macros.p[i]->params));
for (mparam = dox->macros.p[i]->params; mparam; mparam = mparam->next) {
SerializeStr(&dox->buf, mparam->name);
}
}
SerializeInt(&dox->buf, 31337);
}
static int IsJavadownParam(struct JavadownTag *jt) {
return !strcmp(jt->tag, "param") && strchr(jt->text, ' ');
}
static char *ExtractJavadownParamName(const char *text) {
char *space;
space = strchr(text, ' ');
return strndup(text, space - text);
}
static int CountJavadownParams(struct Javadown *jd) {
int i, n;
for (n = i = 0; i < jd->tags.n; ++i) {
if (IsJavadownParam(jd->tags.p + i)) {
++n;
}
}
return n;
}
static void SerializeAsmdown(struct DoxWriter *dox, struct Asmdown *ad,
const char *filename) {
char *s;
int i, j;
SerializeInt(&dox->buf, ad->symbols.n);
for (i = 0; i < ad->symbols.n; ++i) {
SerializeStr(&dox->buf, ""); // type
SerializeStr(&dox->buf, ad->symbols.p[i].name);
SerializeStr(&dox->buf, filename);
SerializeInt(&dox->buf, ad->symbols.p[i].line);
SerializeInt(&dox->buf, true); // TODO: is_function
SerializeInt(&dox->buf, false); // TODO: is_weak
SerializeInt(&dox->buf, false); // is_inline
SerializeInt(&dox->buf, false); // is_noreturn
SerializeInt(&dox->buf, false); // is_destructor
SerializeInt(&dox->buf, false); // is_constructor
SerializeInt(&dox->buf, false); // is_force_align_arg_pointer
SerializeInt(&dox->buf, false); // is_no_caller_saved_registers
SerializeStr(&dox->buf, ""); // TODO: visibility
SerializeInt(&dox->buf, true); // has_javadown
SerializeJavadown(&dox->buf, ad->symbols.p[i].javadown);
SerializeInt(&dox->buf, CountJavadownParams(ad->symbols.p[i].javadown));
for (j = 0; j < ad->symbols.p[i].javadown->tags.n; ++j) {
if (IsJavadownParam(ad->symbols.p[i].javadown->tags.p + j)) {
SerializeStr(&dox->buf, ""); // type
s = ExtractJavadownParamName(ad->symbols.p[i].javadown->tags.p[j].text);
SerializeStr(&dox->buf, s); // name
free(s);
}
}
}
SerializeInt(&dox->buf, 0); // macros
SerializeInt(&dox->buf, 31337);
}
static void LoadPublicDefinitions(struct DoxWriter *dox, Obj *prog) {
int i;
Obj *obj;
Macro *macro;
for (obj = prog; obj; obj = obj->next) {
if (!obj->javadown) {
if (*obj->name == '_') continue;
if (strchr(obj->name, '$')) continue;
if (startswith(obj->name, "__gdtoa_")) continue;
if (obj->visibility && !strcmp(obj->visibility, "hidden")) continue;
if (!obj->is_definition && (!obj->is_function || !obj->params ||
!obj->params->name || !*obj->params->name)) {
continue;
}
}
if (obj->is_static) continue;
if (*obj->name == '_') continue;
if (!obj->javadown) continue;
if (obj->is_string_literal) continue;
if (obj->visibility && !strcmp(obj->visibility, "hidden")) continue;
if (strchr(obj->name, '$')) continue;
if (obj->section && startswith(obj->section, ".init_array")) continue;
APPEND(dox->objects);
dox->objects.p[dox->objects.n - 1] = obj;
}
@ -209,8 +299,8 @@ static void LoadPublicDefinitions(struct DoxWriter *dox, Obj *prog) {
macro = macros.buckets[i].val;
if (!macro->javadown) continue;
if (!macro->javadown->javadown) continue;
if (*macro->name == '_') continue;
if (strchr(macro->name, '$')) continue;
/* if (*macro->name == '_') continue; */
/* if (strchr(macro->name, '$')) continue; */
APPEND(dox->macros);
dox->macros.p[dox->macros.n - 1] = macro;
}
@ -237,7 +327,7 @@ static void WriteDox(struct DoxWriter *dox, const char *path) {
}
/**
* Emits documentation datum for compilation unit just parsed.
* Emits documentation data for compilation unit just parsed.
*/
void output_javadown(const char *path, Obj *prog) {
struct DoxWriter *dox = NewDoxWriter();
@ -246,3 +336,30 @@ void output_javadown(const char *path, Obj *prog) {
WriteDox(dox, path);
FreeDoxWriter(dox);
}
/**
* Emits documentation data for assembly source file.
*/
void output_javadown_asm(const char *path, const char *source) {
int fd;
void *map;
struct stat st;
struct Asmdown *ad;
struct DoxWriter *dox;
CHECK_NE(-1, (fd = open(source, O_RDONLY)));
CHECK_NE(-1, fstat(fd, &st));
if (st.st_size) {
CHECK_NE(MAP_FAILED,
(map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0)));
ad = ParseAsmdown(map, st.st_size);
munmap(map, st.st_size);
} else {
ad = ParseAsmdown("", 0);
}
close(fd);
dox = NewDoxWriter();
SerializeAsmdown(dox, ad, source);
WriteDox(dox, path);
FreeDoxWriter(dox);
FreeAsmdown(ad);
}

View file

@ -65,10 +65,34 @@ struct Dox {
} params;
} * p;
} objects;
struct {
struct DoxMacros {
size_t n;
int *p;
} objectindex;
struct DoxMacro {
bool ignore;
char *name;
char *path;
int line;
bool is_objlike;
char *va_args_name;
struct Javadown *javadown;
struct DoxMacroParams {
size_t n;
struct DoxMacroParam {
char *name;
} * p;
} params;
} * p;
} macros;
struct DoxIndex {
size_t n;
struct DoxIndexEntry {
enum DoxIndexType {
kObject,
kMacro,
} t;
int i;
} * p;
} index;
};
static unsigned Hash(const void *p, unsigned long n) {
@ -93,6 +117,8 @@ static void FreeDox(struct Dox *dox) {
free(dox->names.p);
free(dox->freelist.p);
free(dox->objects.p);
free(dox->macros.p);
free(dox->index.p);
free(dox);
}
}
@ -124,18 +150,23 @@ static char *DeserializeStr(struct Dox *dox) {
static struct Javadown *DeserializeJavadown(struct Dox *dox) {
int i;
bool present;
struct Javadown *jd;
jd = FreeLater(dox, calloc(1, sizeof(struct Javadown)));
jd->isfileoverview = DeserializeInt(dox);
jd->title = DeserializeStr(dox);
jd->text = DeserializeStr(dox);
jd->tags.n = DeserializeInt(dox);
jd->tags.p = FreeLater(dox, malloc(jd->tags.n * sizeof(*jd->tags.p)));
for (i = 0; i < jd->tags.n; ++i) {
jd->tags.p[i].tag = DeserializeStr(dox);
jd->tags.p[i].text = DeserializeStr(dox);
if (DeserializeInt(dox)) {
jd = FreeLater(dox, calloc(1, sizeof(struct Javadown)));
jd->isfileoverview = DeserializeInt(dox);
jd->title = DeserializeStr(dox);
jd->text = DeserializeStr(dox);
jd->tags.n = DeserializeInt(dox);
jd->tags.p = FreeLater(dox, malloc(jd->tags.n * sizeof(*jd->tags.p)));
for (i = 0; i < jd->tags.n; ++i) {
jd->tags.p[i].tag = DeserializeStr(dox);
jd->tags.p[i].text = DeserializeStr(dox);
}
return jd;
} else {
return NULL;
}
return jd;
}
static void DeserializeObject(struct Dox *dox, struct DoxObject *o) {
@ -163,6 +194,22 @@ static void DeserializeObject(struct Dox *dox, struct DoxObject *o) {
}
}
static void DeserializeMacro(struct Dox *dox, struct DoxMacro *m) {
int i;
m->ignore = false;
m->name = DeserializeStr(dox);
m->path = DeserializeStr(dox);
m->line = DeserializeInt(dox);
m->is_objlike = DeserializeInt(dox);
m->va_args_name = DeserializeStr(dox);
m->javadown = DeserializeJavadown(dox);
m->params.n = DeserializeInt(dox);
m->params.p = FreeLater(dox, malloc(m->params.n * sizeof(*m->params.p)));
for (i = 0; i < m->params.n; ++i) {
m->params.p[i].name = DeserializeStr(dox);
}
}
static void DeserializeDox(struct Dox *dox) {
int i, j, n;
i = dox->objects.n;
@ -172,7 +219,16 @@ static void DeserializeDox(struct Dox *dox) {
for (j = 0; j < n; ++j) {
DeserializeObject(dox, dox->objects.p + i + j);
}
i = dox->macros.n;
dox->objects.n += n;
n = DeserializeInt(dox);
dox->macros.p =
realloc(dox->macros.p, (dox->macros.n + n) * sizeof(*dox->macros.p));
for (j = 0; j < n; ++j) {
DeserializeMacro(dox, dox->macros.p + i + j);
}
dox->macros.n += n;
CHECK_EQ(31337, DeserializeInt(dox));
}
static void ReadDox(struct Dox *dox, const StringArray *files) {
@ -210,43 +266,66 @@ static bool AddSet(struct Set *set, char *s) {
}
}
static int CompareObjectNames(const void *a, const void *b, void *arg) {
int *i1, *i2;
static int CompareDoxIndexEntry(const void *p1, const void *p2, void *arg) {
struct Dox *dox;
i1 = a, i2 = b, dox = arg;
return strcmp(dox->objects.p[*i1].name, dox->objects.p[*i2].name);
const char *s1, *s2;
struct DoxIndexEntry *a, *b;
dox = arg, a = p1, b = p2;
s1 = a->t == kObject ? dox->objects.p[a->i].name : dox->macros.p[a->i].name;
s2 = b->t == kObject ? dox->objects.p[b->i].name : dox->macros.p[b->i].name;
while (*s1 == '_') ++s1;
while (*s2 == '_') ++s2;
return strcasecmp(s1, s2);
}
static void IndexDox(struct Dox *dox) {
size_t i, j, n;
dox->names.n = roundup2pow(dox->objects.n) << 1;
dox->names.n = roundup2pow(dox->objects.n + dox->macros.n) << 1;
dox->names.p = calloc(dox->names.n, sizeof(*dox->names.p));
for (n = i = 0; i < dox->objects.n; ++i) {
n = 0;
for (i = 0; i < dox->objects.n; ++i) {
if (AddSet(&dox->names, dox->objects.p[i].name)) {
++n;
} else {
dox->objects.p[i].ignore = true;
}
}
dox->objectindex.n = n;
dox->objectindex.p = malloc(n * sizeof(*dox->objectindex.p));
for (j = i = 0; i < dox->objects.n; ++i) {
if (dox->objects.p[i].ignore) continue;
dox->objectindex.p[j++] = i;
for (i = 0; i < dox->macros.n; ++i) {
if (AddSet(&dox->names, dox->macros.p[i].name)) {
++n;
} else {
dox->macros.p[i].ignore = true;
}
}
qsort_r(dox->objectindex.p, dox->objectindex.n, sizeof(*dox->objectindex.p),
CompareObjectNames, dox);
dox->index.n = n;
dox->index.p = malloc(n * sizeof(*dox->index.p));
j = 0;
for (i = 0; i < dox->objects.n; ++i) {
if (dox->objects.p[i].ignore) continue;
dox->index.p[j].t = kObject;
dox->index.p[j].i = i;
++j;
}
for (i = 0; i < dox->macros.n; ++i) {
if (dox->macros.p[i].ignore) continue;
dox->index.p[j].t = kMacro;
dox->index.p[j].i = i;
++j;
}
CHECK_EQ(n, j);
qsort_r(dox->index.p, dox->index.n, sizeof(*dox->index.p),
CompareDoxIndexEntry, dox);
}
static void PrintText(FILE *f, const char *s) {
int c;
bool bol, pre;
for (pre = false, bol = true;;) {
bool bol, pre, ul0, ul2, bt1, bt2;
for (bt1 = bt2 = ul2 = ul0 = pre = false, bol = true;;) {
switch ((c = *s++)) {
case '\0':
if (pre) {
fprintf(f, "</pre>");
}
if (bt1 || bt2) fprintf(f, "</code>");
if (pre) fprintf(f, "</pre>");
if (ul0 || ul2) fprintf(f, "</ul>");
return;
case '&':
fprintf(f, "&amp;");
@ -268,25 +347,79 @@ static void PrintText(FILE *f, const char *s) {
fprintf(f, "&apos;");
bol = false;
break;
case '\n':
if (!pre && *s == '\n') {
case '`':
if (!pre && !bt1 && !bt2 && *s != '`') {
fprintf(f, "<code>");
bt1 = true;
} else if (!pre && !bt1 && !bt2 && *s == '`') {
fprintf(f, "<code>");
bt2 = true;
++s;
} else if (bt1) {
fprintf(f, "</code>");
bt1 = false;
} else if (bt2 && *s == '`') {
fprintf(f, "</code>");
bt2 = false;
++s;
} else {
fprintf(f, "`");
}
bol = false;
break;
case '\n':
if (!pre && !ul0 && !ul2 && *s == '\n') {
fprintf(f, "\n<p>");
} else if (pre &&
bol = true;
} else if (pre && s[0] != '\n' &&
(s[0] != ' ' || s[1] != ' ' || s[2] != ' ' || s[3] != ' ')) {
fprintf(f, "</pre>\n");
pre = false;
bol = true;
} else if (ul0 && s[0] == '-' && s[1] == ' ') {
fprintf(f, "\n<li>");
s += 2;
bol = false;
} else if (ul2 && s[0] == ' ' && s[1] == ' ' && s[2] == '-' &&
s[3] == ' ') {
fprintf(f, "\n<li>");
s += 4;
bol = false;
} else if (ul0 && s[0] != '\n' && (s[0] != ' ' || s[1] != ' ')) {
fprintf(f, "\n</ul>\n");
bol = true;
ul0 = false;
} else if (ul2 && s[0] != '\n' &&
(s[0] != ' ' || s[1] != ' ' || s[2] != ' ' || s[3] != ' ')) {
fprintf(f, "\n</ul>\n");
bol = true;
ul2 = false;
} else {
fprintf(f, "\n");
bol = true;
}
bol = true;
break;
case '-':
if (bol && !ul0 && !ul2 && s[0] == ' ') {
ul0 = true;
fprintf(f, "<ul><li>");
} else {
fprintf(f, "-");
}
bol = false;
break;
case ' ':
if (bol && !pre && s[0] == ' ' && s[1] == ' ' && s[2] == ' ') {
pre = true;
fprintf(f, "<pre>");
fprintf(f, "<pre> ");
} else if (bol && !ul0 && !ul2 && s[0] == ' ' && s[1] == '-' &&
s[2] == ' ') {
ul2 = true;
fprintf(f, "<ul><li>");
s += 3;
} else {
fprintf(f, " ");
}
fprintf(f, " ");
bol = false;
break;
default:
@ -297,83 +430,364 @@ static void PrintText(FILE *f, const char *s) {
}
}
static bool HasTag(struct Javadown *jd, const char *tag) {
int k;
if (jd) {
for (k = 0; k < jd->tags.n; ++k) {
if (!strcmp(jd->tags.p[k].tag, tag)) {
return true;
}
}
}
return false;
}
static bool IsNoReturn(struct DoxObject *o) {
return o->is_noreturn || HasTag(o->javadown, "noreturn");
}
static void PrintDox(struct Dox *dox, FILE *f) {
int i, j, k;
char *prefix;
bool was_outputted;
struct DoxMacro *m;
struct DoxObject *o;
// header
fprintf(f, "\
<!doctype html>\n\
<html lang=\"en\">\n\
<meta charset=\"utf-8\">\n\
<script async src=\"https://www.googletagmanager.com/gtag/js?id=UA-43182592-5\"></script>\n\
<script>window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-43182592-5');</script>\n\
<title>Cosmopolitan C Library</title>\n\
<meta name=\"viewport\" content=\"width=1024\">\n\
<link rel=\"canonical\" href=\"https://justine.lol/cosmopolitan/documentation.html\">\n\
<link rel=\"stylesheet\" href=\"https://fonts.googleapis.com/css2?family=Roboto&display=swap\">\n\
<link rel=\"stylesheet\" href=\"style.css\">\n\
<style>\n\
.indent {\n\
padding-left: 1em;\n\
}\n\
.nav {\n\
margin-bottom: 0;\n\
}\n\
.toc a {\n\
text-decoration: none;\n\
}\n\
h3 a {\n\
color: inherit;\n\
text-decoration: none;\n\
}\n\
pre {\n\
margin-left: 0;\n\
padding: 12px;\n\
background: #f6f6f6;\n\
width: 100%;\n\
overflow-x: auto;\n\
border-radius: 5px;\n\
}\n\
code {\n\
padding: 2px 4px;\n\
background: #e4e6e8;\n\
border-radius: 3px;\n\
}\n\
hr {\n\
height: 1px;\n\
margin-bottom: 16px;\n\
color: #d6d9dc;\n\
background: #d6d9dc;\n\
border: 0;\n\
}\n\
.category {\n\
font-weight: bold;\n\
}\n\
.tagname {\n\
font-size: 12pt;\n\
font-weight: bold;\n\
}\n\
.tag {\n\
margin-top: .5em;\n\
}\n\
.tag dl {\n\
margin-top: .5em;\n\
margin-bottom: .5em;\n\
margin-left: 1em;\n\
}\n\
</style>\n\
\n\
<table width=\"100%%\"><tr><td width=\"33%%\" valign=\"top\">\n\
<p class=\"toc\">\n\
<header>\n\
<img width=\"196\" height=\"105\" src=\"//storage.googleapis.com/justine/cosmopolitan/cosmopolitan.png\" alt=\"honeybadger\">\n\
<h1>cosmopolitan libc</h1>\n\
<span>build-once run-anywhere c without devops</span>\n\
</header>\n\
\n\
<nav class=\"nav\">\n\
<ul>\n\
<li><a href=\"index.html\">Intro</a>\n\
<li><a href=\"download.html\">Download</a>\n\
<li><a class=\"active\" href=\"documentation.html\">Documentation</a>\n\
<li><a href=\"sources.html\">Sources</a>\n\
<li><a href=\"https://github.com/jart/cosmopolitan\">GitHub</a>\n\
<li><a href=\"license.html\">License</a>\n\
<li class=\"right\"><a href=\"../index.html\">» jart's web page</a>\n\
</ul>\n\
</nav>\n\
\n\
<table class=\"dox\" width=\"960\">\n\
<tr>\n\
<td width=\"320\" valign=\"top\" class=\"toc\">\n\
");
for (i = 0; i < dox->objectindex.n; ++i) {
o = dox->objects.p + dox->objectindex.p[i];
if (o->ignore || !o->is_function) continue;
/* // lefthand index: objects */
/* fprintf(f, "<p><span class=\"category\">macro objects</span>\n"); */
/* fprintf(f, "<p>\n"); */
/* for (i = 0; i < dox->index.n; ++i) { */
/* if (dox->index.p[i].t != kMacro) continue; */
/* m = dox->macros.p + dox->index.p[i].i; */
/* if (m->ignore) continue; */
/* if (!m->is_objlike) continue; */
/* fprintf(f, "<a href=\"#%s\">%s</a><br>\n", m->name, m->name); */
/* } */
/* // lefthand index: functions */
/* fprintf(f, "<p><span class=\"category\">macro functions</span>\n"); */
/* fprintf(f, "<p>\n"); */
/* for (i = 0; i < dox->index.n; ++i) { */
/* if (dox->index.p[i].t != kMacro) continue; */
/* m = dox->macros.p + dox->index.p[i].i; */
/* if (m->ignore) continue; */
/* if (m->is_objlike) continue; */
/* fprintf(f, "<a href=\"#%s\">%s</a><br>\n", m->name, m->name); */
/* } */
// lefthand index: objects
fprintf(f, "<p><span class=\"category\">objects</span>\n");
fprintf(f, "<p>\n");
for (i = 0; i < dox->index.n; ++i) {
if (dox->index.p[i].t != kObject) continue;
o = dox->objects.p + dox->index.p[i].i;
if (o->ignore) continue;
if (o->is_function) continue;
fprintf(f, "<a href=\"#%s\">%s</a><br>\n", o->name, o->name);
fprintf(f, "<br>\n");
}
fprintf(f, "<td width=\"67%%\" valign=\"top\">\n");
for (i = 0; i < dox->objectindex.n; ++i) {
o = dox->objects.p + dox->objectindex.p[i];
if (o->ignore || !o->is_function) continue;
fprintf(f, "\n<div id=\"%s\" class=\"func\">\n", o->name, o->name);
fprintf(f, "<h3><a href=\"#%s\">", o->name);
fprintf(f, "<strong class=\"name\">%s</strong></a></h3>", o->name);
fprintf(f, "<p>");
PrintText(f, o->javadown->title);
fprintf(f, "\n");
if (*o->javadown->text) {
fprintf(f, "<p>");
PrintText(f, o->javadown->text);
// lefthand index: functions
fprintf(f, "<p><span class=\"category\">functions</span>\n");
fprintf(f, "<p>\n");
for (i = 0; i < dox->index.n; ++i) {
if (dox->index.p[i].t != kObject) continue;
o = dox->objects.p + dox->index.p[i].i;
if (o->ignore) continue;
if (!o->is_function) continue;
fprintf(f, "<a href=\"#%s\">%s</a><br>\n", o->name, o->name);
}
// righthand contents
fprintf(f, "<td width=\"640\" valign=\"top\">\n");
for (i = 0; i < dox->index.n; ++i) {
if (dox->index.p[i].t == kObject) {
o = dox->objects.p + dox->index.p[i].i;
if (o->ignore) continue;
fprintf(f, "\n");
}
fprintf(f, "<p><strong>@param</strong>\n");
fprintf(f, "<div class=\"params indent\">\n");
if (o->params.n) {
fprintf(f, "<dl>\n");
for (j = 0; j < o->params.n; ++j) {
fprintf(f, "<dt>");
PrintText(f, o->params.p[j].type);
fprintf(f, " <em>");
PrintText(f, o->params.p[j].name);
fprintf(f, "</em>\n");
prefix = xasprintf("%s ", o->params.p[j].name);
for (k = 0; k < o->javadown->tags.n; ++k) {
if (!strcmp(o->javadown->tags.p[k].tag, "param") &&
startswith(o->javadown->tags.p[k].text, prefix)) {
fprintf(f, "<dd>");
PrintText(f, o->javadown->tags.p[k].text + strlen(prefix));
fprintf(f, "\n");
break;
}
}
free(prefix);
}
fprintf(f, "</dl>\n");
} else {
fprintf(f, "<p>None.\n");
}
fprintf(f, "</div>\n");
for (k = 0; k < o->javadown->tags.n; ++k) {
if (!strcmp(o->javadown->tags.p[k].tag, "param")) continue;
fprintf(f, "<p><strong>@");
PrintText(f, o->javadown->tags.p[k].tag);
fprintf(f, "</strong>\n");
if (*o->javadown->tags.p[k].text) {
PrintText(f, o->javadown->tags.p[k].text);
if (i) fprintf(f, "<hr>");
fprintf(f, "<div id=\"%s\" class=\"api\">\n", o->name);
fprintf(f, "<h3><a href=\"#%s\">%s</a></h3>", o->name, o->name);
// title
if (o->javadown && *o->javadown->title) {
fprintf(f, "<p>");
PrintText(f, o->javadown->title);
fprintf(f, "\n");
}
// text
if (o->javadown && *o->javadown->text) {
fprintf(f, "<p>");
PrintText(f, o->javadown->text);
fprintf(f, "\n");
}
// parameters
if (o->is_function && (o->params.n || HasTag(o->javadown, "param"))) {
fprintf(f, "<div class=\"tag\">\n");
fprintf(f, "<span class=\"tagname\">@param</span>\n");
fprintf(f, "<dl>\n");
if (o->params.n) {
for (j = 0; j < o->params.n; ++j) {
fprintf(f, "<dt>");
PrintText(f, o->params.p[j].type);
fprintf(f, " <em>");
PrintText(f, o->params.p[j].name);
fprintf(f, "</em>\n");
if (o->javadown) {
prefix = xasprintf("%s ", o->params.p[j].name);
for (k = 0; k < o->javadown->tags.n; ++k) {
if (!strcmp(o->javadown->tags.p[k].tag, "param") &&
startswith(o->javadown->tags.p[k].text, prefix)) {
fprintf(f, "<dd>");
PrintText(f, o->javadown->tags.p[k].text + strlen(prefix));
fprintf(f, "\n");
break;
}
}
free(prefix);
}
}
} else {
for (k = 0; k < o->javadown->tags.n; ++k) {
if (!strcmp(o->javadown->tags.p[k].tag, "param")) {
fprintf(f, "<dd>");
PrintText(f, o->javadown->tags.p[k].text);
fprintf(f, "\n");
break;
}
}
}
fprintf(f, "</dl>\n");
fprintf(f, "</div>\n"); // .tag
}
// return
if (o->is_function) {
fprintf(f, "<div class=\"tag\">\n");
if (IsNoReturn(o)) {
fprintf(f, "<span class=\"tagname\">@noreturn</span>\n");
} else {
fprintf(f, "<span class=\"tagname\">@return</span>\n");
was_outputted = false;
fprintf(f, "<dl>\n");
if (o->javadown) {
for (k = 0; k < o->javadown->tags.n; ++k) {
if (strcmp(o->javadown->tags.p[k].tag, "return")) continue;
if (!was_outputted) {
fprintf(f, "<dt>");
PrintText(f, o->type);
was_outputted = true;
}
fprintf(f, "\n<dd>");
PrintText(f, o->javadown->tags.p[k].text);
fprintf(f, "\n");
}
}
if (!was_outputted) {
fprintf(f, "<dt>");
PrintText(f, o->type);
}
fprintf(f, "</dl>\n");
fprintf(f, "</div>\n"); // .tag
}
}
// tags
if (o->javadown) {
for (k = 0; k < o->javadown->tags.n; ++k) {
if (!strcmp(o->javadown->tags.p[k].tag, "param")) continue;
if (!strcmp(o->javadown->tags.p[k].tag, "return")) continue;
if (!strcmp(o->javadown->tags.p[k].tag, "noreturn")) continue;
fprintf(f, "<div class=\"tag\">\n");
fprintf(f, "<span class=\"tagname\">@");
PrintText(f, o->javadown->tags.p[k].tag);
fprintf(f, "</span>\n");
if (*o->javadown->tags.p[k].text) {
PrintText(f, o->javadown->tags.p[k].text);
fprintf(f, "\n");
}
fprintf(f, "</div>\n"); // .tag
}
}
// sauce
if (strcmp(o->path, "missingno.c")) {
fprintf(f, "<div class=\"tag\">\n");
fprintf(f,
"<span class=\"tagname\">@see</span> <a "
"href=\"https://github.com/jart/cosmopolitan/blob/master/"
"%s#L%d\">%s</a>",
o->path, o->line, o->path);
fprintf(f, "</div>\n"); // .tag
}
fprintf(f, "</div>\n"); /* class=".api" */
} else {
continue;
m = dox->macros.p + dox->index.p[i].i;
if (m->ignore) continue;
fprintf(f, "\n");
if (i) fprintf(f, "<hr>");
fprintf(f, "<div id=\"%s\" class=\"api\">\n", m->name);
fprintf(f, "<h3><a href=\"#%s\">%s</a></h3>", m->name, m->name);
// title
if (m->javadown && *m->javadown->title) {
fprintf(f, "<p>");
PrintText(f, m->javadown->title);
fprintf(f, "\n");
}
// text
if (m->javadown && *m->javadown->text) {
fprintf(f, "<p>");
PrintText(f, m->javadown->text);
fprintf(f, "\n");
}
// parameters
if (!m->is_objlike && (m->params.n || HasTag(m->javadown, "param"))) {
fprintf(f, "<div class=\"tag\">\n");
fprintf(f, "<span class=\"tagname\">@param</span>\n");
fprintf(f, "<dl>\n");
if (m->params.n) {
for (j = 0; j < m->params.n; ++j) {
fprintf(f, "<dt>");
fprintf(f, "<em>");
PrintText(f, m->params.p[j].name);
fprintf(f, "</em>\n");
if (m->javadown) {
prefix = xasprintf("%s ", m->params.p[j].name);
for (k = 0; k < m->javadown->tags.n; ++k) {
if (!strcmp(m->javadown->tags.p[k].tag, "param") &&
startswith(m->javadown->tags.p[k].text, prefix)) {
fprintf(f, "<dd>");
PrintText(f, m->javadown->tags.p[k].text + strlen(prefix));
fprintf(f, "\n");
break;
}
}
free(prefix);
}
}
} else {
for (k = 0; k < m->javadown->tags.n; ++k) {
if (!strcmp(m->javadown->tags.p[k].tag, "param")) {
fprintf(f, "<dd>");
PrintText(f, m->javadown->tags.p[k].text);
fprintf(f, "\n");
break;
}
}
}
fprintf(f, "</dl>\n");
fprintf(f, "</div>\n"); // .tag
}
fprintf(f, "</div>\n"); /* class=".api" */
}
fprintf(f, "</div>\n");
}
fprintf(f, "</table>\n");
// footer
fprintf(f, "\
\n\
<footer>\n\
<p>\n\
<div style=\"float:right;text-align:right\">\n\
Free Libre &amp; Open Source<br>\n\
<a href=\"https://github.com/jart\">github.com/jart/cosmopolitan</a>\n\
</div>\n\
Feedback<br>\n\
jtunney@gmail.com\n\
</p>\n\
<div style=\"clear:both\"></div>\n\
</footer>\n\
");
}
/**

View file

@ -57,6 +57,7 @@ typedef struct {
bool is_destructor;
bool is_constructor;
bool is_externally_visible;
bool is_no_instrument_function;
bool is_force_align_arg_pointer;
bool is_no_caller_saved_registers;
int align;
@ -476,6 +477,10 @@ static Token *thing_attributes(Token *tok, void *arg) {
attr->is_externally_visible = true;
return tok;
}
if (consume_attribute(&tok, tok, "no_instrument_function")) {
attr->is_no_instrument_function = true;
return tok;
}
if (consume_attribute(&tok, tok, "force_align_arg_pointer")) {
attr->is_force_align_arg_pointer = true;
return tok;
@ -555,7 +560,6 @@ static Token *thing_attributes(Token *tok, void *arg) {
consume_attribute(&tok, tok, "no_split_stack") ||
consume_attribute(&tok, tok, "no_stack_limit") ||
consume_attribute(&tok, tok, "no_sanitize_undefined") ||
consume_attribute(&tok, tok, "no_instrument_function") ||
consume_attribute(&tok, tok, "no_profile_instrument_function")) {
return tok;
}
@ -1018,6 +1022,7 @@ static Type *enum_specifier(Token **rest, Token *tok) {
*rest = tok;
return ty;
}
ty->name = tag;
tok = skip(tok, '{');
// Read an enum-list.
int i = 0;
@ -2066,8 +2071,9 @@ int64_t eval2(Node *node, char ***label) {
}
error_tok(node->tok, "not a compile-time constant");
}
if (node->var->ty->kind != TY_ARRAY && node->var->ty->kind != TY_FUNC)
if (node->var->ty->kind != TY_ARRAY && node->var->ty->kind != TY_FUNC) {
error_tok(node->tok, "invalid initializer");
}
*label = &node->var->name;
return 0;
case ND_NUM:
@ -2727,6 +2733,7 @@ static Type *struct_union_decl(Token **rest, Token *tok) {
push_tag_scope(tag, ty);
return ty;
}
ty->name = tag;
tok = skip(tok, '{');
// Construct a struct object.
struct_members(&tok, tok, ty);
@ -3361,10 +3368,12 @@ static Obj *find_func(char *name) {
}
static void mark_live(Obj *var) {
int i;
Obj *fn;
if (!var->is_function || var->is_live) return;
var->is_live = true;
for (int i = 0; i < var->refs.len; i++) {
Obj *fn = find_func(var->refs.data[i]);
for (i = 0; i < var->refs.len; i++) {
fn = find_func(var->refs.data[i]);
if (fn) mark_live(fn);
}
}
@ -3385,25 +3394,28 @@ static Token *function(Token *tok, Type *basety, VarAttr *attr) {
fn->is_definition = fn->is_definition || EQUAL(tok, "{");
fn->is_weak |= attr->is_weak;
fn->is_noreturn |= attr->is_noreturn;
fn->tok = ty->name;
} else {
fn = new_gvar(name_str, ty);
fn->tok = ty->name;
fn->is_function = true;
fn->is_definition = EQUAL(tok, "{");
fn->is_static = attr->is_static || (attr->is_inline && !attr->is_extern);
fn->is_inline = attr->is_inline;
fn->is_weak = attr->is_weak;
fn->is_ms_abi = attr->is_ms_abi;
fn->is_aligned = attr->is_aligned;
fn->is_noreturn = attr->is_noreturn;
fn->is_destructor = attr->is_destructor;
fn->is_constructor = attr->is_constructor;
fn->is_externally_visible = attr->is_externally_visible;
fn->is_force_align_arg_pointer = attr->is_force_align_arg_pointer;
fn->is_no_caller_saved_registers = attr->is_no_caller_saved_registers;
fn->align = attr->align;
fn->section = attr->section;
fn->visibility = attr->visibility;
}
fn->align = MAX(fn->align, attr->align);
fn->is_weak |= attr->is_weak;
fn->section = fn->section ?: attr->section;
fn->is_ms_abi |= attr->is_ms_abi;
fn->visibility = fn->visibility ?: attr->visibility;
fn->is_aligned |= attr->is_aligned;
fn->is_noreturn |= attr->is_noreturn;
fn->is_destructor |= attr->is_destructor;
fn->is_constructor |= attr->is_constructor;
fn->is_externally_visible |= attr->is_externally_visible;
fn->is_no_instrument_function |= attr->is_no_instrument_function;
fn->is_force_align_arg_pointer |= attr->is_force_align_arg_pointer;
fn->is_no_caller_saved_registers |= attr->is_no_caller_saved_registers;
fn->javadown = fn->javadown ?: current_javadown;
fn->is_root = !(fn->is_static && fn->is_inline);
if (consume_attribute(&tok, tok, "asm")) {
@ -3452,6 +3464,7 @@ static Token *global_variable(Token *tok, Type *basety, VarAttr *attr) {
Type *ty = declarator(&tok, tok, basety);
if (!ty->name) error_tok(ty->name_pos, "variable name omitted");
Obj *var = new_gvar(get_ident(ty->name), ty);
if (!var->tok) var->tok = ty->name;
var->javadown = current_javadown;
if (consume_attribute(&tok, tok, "asm")) {
tok = skip(tok, '(');
@ -3459,9 +3472,16 @@ static Token *global_variable(Token *tok, Type *basety, VarAttr *attr) {
tok = skip(tok, ')');
}
tok = attribute_list(tok, attr, thing_attributes);
var->align = MAX(var->align, attr->align);
var->is_weak = attr->is_weak;
var->section = attr->section;
var->visibility = attr->visibility;
var->is_aligned = var->is_aligned | attr->is_aligned;
var->is_externally_visible = attr->is_externally_visible;
var->is_definition = !attr->is_extern;
var->is_static = attr->is_static;
var->is_tls = attr->is_tls;
var->section = attr->section;
if (attr->align) var->align = attr->align;
if (EQUAL(tok, "=")) {
gvar_initializer(&tok, tok->next, var);
@ -3535,15 +3555,30 @@ static Obj *declare3(char *s, Type *r, Type *a, Type *b, Type *c) {
return new_gvar(xstrcat("__builtin_", s), ty);
}
static void math0(char *name) {
declare0(name, ty_double);
declare0(xstrcat(name, 'f'), ty_float);
declare0(xstrcat(name, 'l'), ty_ldouble);
}
static void math1(char *name) {
declare1(name, ty_double, ty_double);
declare1(xstrcat(name, 'f'), ty_float, ty_float);
declare1(xstrcat(name, 'l'), ty_ldouble, ty_ldouble);
}
static void math2(char *name) {
declare2(name, ty_double, ty_double, ty_double);
declare2(xstrcat(name, 'f'), ty_float, ty_float, ty_float);
declare2(xstrcat(name, 'l'), ty_ldouble, ty_ldouble, ty_ldouble);
}
void declare_builtin_functions(void) {
Type *pvoid = pointer_to(ty_void);
Type *pchar = pointer_to(ty_char);
builtin_alloca = declare1("alloca", pointer_to(ty_void), ty_int);
declare0("trap", ty_int);
declare0("unreachable", ty_int);
declare0("inff", ty_float);
declare0("inf", ty_double);
declare0("infl", ty_ldouble);
declare1("ctz", ty_int, ty_int);
declare1("ctzl", ty_long, ty_long);
declare1("ctzll", ty_long, ty_long);
@ -3581,6 +3616,16 @@ void declare_builtin_functions(void) {
declare2("strchr", pchar, pchar, ty_int);
declare2("strstr", pchar, pchar, pchar);
declare1("frame_address", pvoid, ty_int);
declare2("scalbnf", ty_float, ty_float, ty_int);
declare2("scalbn", ty_double, ty_double, ty_int);
declare2("scalbnl", ty_ldouble, ty_ldouble, ty_int);
math0("inf");
math0("huge_val");
math1("fabs");
math1("logb");
math2("fmax");
math2("fmin");
math2("copysign");
}
// program = (typedef | function-definition | global-variable)*

View file

@ -119,7 +119,6 @@ static void PrintType(FILE *f, int l, const char *s, Type *t) {
PrintInt(f, l + 2, "align: ", t->align);
PrintBool(f, l + 2, "is_unsigned: ", t->is_unsigned);
PrintBool(f, l + 2, "is_atomic: ", t->is_atomic);
PrintType(f, l + 2, "origin: ", t->origin);
PrintType(f, l + 2, "base: ", t->base);
PrintTokStr(f, l + 2, "name: ", t->name);
PrintTokStr(f, l + 2, "name_pos: ", t->name_pos);
@ -231,6 +230,13 @@ static void PrintObj(FILE *f, int l, const char *s, Obj *o) {
PrintBool(f, l + 2, "is_noreturn: ", o->is_noreturn);
PrintBool(f, l + 2, "is_destructor: ", o->is_destructor);
PrintBool(f, l + 2, "is_constructor: ", o->is_constructor);
PrintBool(f, l + 2, "is_externally_visible: ", o->is_externally_visible);
PrintBool(f, l + 2,
"is_no_instrument_function: ", o->is_no_instrument_function);
PrintBool(f, l + 2,
"is_force_align_arg_pointer: ", o->is_force_align_arg_pointer);
PrintBool(f, l + 2,
"is_no_caller_saved_registers: ", o->is_no_caller_saved_registers);
PrintInt(f, l + 2, "stack_size: ", o->stack_size);
PrintObj(f, l + 2, "params: ", o->params);
PrintNode(f, l + 2, "body: ", o->body);

View file

@ -1,3 +1,4 @@
#include "libc/math.h"
#include "third_party/chibicc/test/test.h"
#define FPNAN 0
@ -115,6 +116,31 @@ void test_fpclassify(void) {
ASSERT(FPNAN, FPCLASSIFY(__builtin_nanl("")));
}
void test_logb(void) {
ASSERT(6, __builtin_logbl(123.456));
ASSERT(logbl(123.456L), __builtin_logbl(123.456L));
ASSERT(logbl(__LDBL_MIN__), __builtin_logbl(__LDBL_MIN__));
ASSERT(logbl(__LDBL_MAX__), __builtin_logbl(__LDBL_MAX__));
}
void test_fmax(void) {
ASSERT(fmaxl(1, 2), __builtin_fmaxl(1, 2));
ASSERT(2, __builtin_fmaxl(__builtin_nanl(""), 2));
ASSERT(1, __builtin_fmaxl(1, __builtin_nanl("")));
ASSERT(2, fmaxl(nanl(""), 2));
ASSERT(1, fmaxl(1, nanl("")));
ASSERT(fmaxf(1, 2), __builtin_fmaxf(1, 2));
ASSERT(2, __builtin_fmaxf(__builtin_nanl(""), 2));
ASSERT(1, __builtin_fmaxf(1, __builtin_nanl("")));
ASSERT(2, fmaxf(nanl(""), 2));
ASSERT(1, fmaxf(1, nanl("")));
ASSERT(fmax(1, 2), __builtin_fmax(1, 2));
ASSERT(2, __builtin_fmax(__builtin_nanl(""), 2));
ASSERT(1, __builtin_fmax(1, __builtin_nanl("")));
ASSERT(2, fmax(nanl(""), 2));
ASSERT(1, fmax(1, nanl("")));
}
void test_strlen(void) {
ASSERT(5, strlen("hello"));
ASSERT(5, __builtin_strlen("hello"));
@ -414,5 +440,7 @@ int main() {
test_strchr();
test_strpbrk();
test_strstr();
test_logb();
test_fmax();
return 0;
}

View file

@ -49,6 +49,7 @@ THIRD_PARTY_CHIBICC_TEST_DIRECTDEPS = \
LIBC_NEXGEN32E \
LIBC_UNICODE \
LIBC_MEM \
LIBC_TINYMATH \
LIBC_X \
THIRD_PARTY_CHIBICC \
THIRD_PARTY_COMPILER_RT

View file

@ -83,10 +83,11 @@ __ledf2(fp_t a, fp_t b) {
}
}
#if defined(__ELF__)
// Alias for libgcc compatibility
FNALIAS(__cmpdf2, __ledf2);
#endif
COMPILER_RT_ABI enum LE_RESULT
__cmpdf2(fp_t a, fp_t b) {
return __ledf2(a, b);
}
enum GE_RESULT {
GE_LESS = -1,

View file

@ -83,10 +83,11 @@ __lesf2(fp_t a, fp_t b) {
}
}
#if defined(__ELF__)
// Alias for libgcc compatibility
FNALIAS(__cmpsf2, __lesf2);
#endif
COMPILER_RT_ABI enum LE_RESULT
__cmpsf2(fp_t a, fp_t b) {
return __lesf2(a, b);
}
enum GE_RESULT {
GE_LESS = -1,

View file

@ -52,18 +52,14 @@ enum LE_RESULT {
};
COMPILER_RT_ABI enum LE_RESULT __letf2(fp_t a, fp_t b) {
const srep_t aInt = toRep(a);
const srep_t bInt = toRep(b);
const rep_t aAbs = aInt & absMask;
const rep_t bAbs = bInt & absMask;
// If either a or b is NaN, they are unordered.
if (aAbs > infRep || bAbs > infRep) return LE_UNORDERED;
// If a and b are both zeros, they are equal.
if ((aAbs | bAbs) == 0) return LE_EQUAL;
// If at least one of a and b is positive, we get the same result comparing
// a and b as signed integers as we would with a floating-point compare.
if ((aInt & bInt) >= 0) {
@ -82,10 +78,10 @@ COMPILER_RT_ABI enum LE_RESULT __letf2(fp_t a, fp_t b) {
}
}
#if defined(__ELF__)
// Alias for libgcc compatibility
FNALIAS(__cmptf2, __letf2);
#endif
COMPILER_RT_ABI enum LE_RESULT __cmptf2(fp_t a, fp_t b) {
return __letf2(a, b);
}
enum GE_RESULT {
GE_LESS = -1,

View file

@ -45,7 +45,7 @@
# define crt_isfinite(x) __builtin_isfinite((x))
#elif defined(__GNUC__)
# define crt_isfinite(x) \
__extension__(({ \
(({ \
__typeof((x)) x_ = (x); \
!crt_isinf(x_) && !crt_isnan(x_); \
}))

View file

@ -63,8 +63,8 @@ typedef union
} udwords;
#ifdef CRT_HAS_128BIT
typedef int ti_int __attribute__ ((mode (TI)));
typedef unsigned tu_int __attribute__ ((mode (TI)));
typedef __int128 ti_int;
typedef unsigned __int128 tu_int;
typedef union
{
@ -141,7 +141,7 @@ typedef union
long double f;
} long_double_bits;
#if __STDC_VERSION__ >= 199901L
#if __STDC_VERSION__ >= 199901L && !defined(__STDC_NO_COMPLEX__)
typedef float _Complex Fcomplex;
typedef double _Complex Dcomplex;
typedef long double _Complex Lcomplex;

View file

@ -71,7 +71,7 @@ forceinline du_int udiv128by64to64default(du_int u1, du_int u0, du_int v,
forceinline du_int udiv128by64to64(du_int u1, du_int u0, du_int v, du_int *r) {
#ifdef __x86_64__
du_int result;
asm("div\t%2" : "=a"(result), "=d"(*r) : "r"(v), "a"(u0), "d"(u1) : "cc");
asm("div\t%2" : "=a"(result), "=d"(*r) : "r"(v), "0"(u0), "1"(u1) : "cc");
return result;
#else
return udiv128by64to64default(u1, u0, v, r);

View file

@ -146,20 +146,20 @@ static void **ialloc(mstate m, size_t n_elements, size_t *sizes, int opts,
* but the number is not known at compile time, and some of the nodes
* may later need to be freed. For example:
*
* struct Node { int item; struct Node* next; };
* struct Node* build_list() {
* struct Node **pool;
* int n = read_number_of_nodes_needed();
* if (n <= 0) return 0;
* pool = (struct Node**)(independent_calloc(n, sizeof(struct Node), 0);
* if (pool == 0) __die();
* // organize into a linked list...
* struct Node* first = pool[0];
* for (i = 0; i < n-1; ++i)
* pool[i]->next = pool[i+1];
* free(pool); * // Can now free the array (or not, if it is needed later)
* return first;
* }
* struct Node { int item; struct Node* next; };
* struct Node* build_list() {
* struct Node **pool;
* int n = read_number_of_nodes_needed();
* if (n <= 0) return 0;
* pool = (struct Node**)(independent_calloc(n, sizeof(struct Node), 0);
* if (pool == 0) __die();
* // organize into a linked list...
* struct Node* first = pool[0];
* for (i = 0; i < n-1; ++i)
* pool[i]->next = pool[i+1];
* free(pool); * // Can now free the array (or not, if it is needed later)
* return first;
* }
*/
void **dlindependent_calloc(size_t n_elements, size_t elem_size,
void *chunks[]) {
@ -199,19 +199,18 @@ void **dlindependent_calloc(size_t n_elements, size_t elem_size,
* where several structs or objects must always be allocated at the
* same time. For example:
*
* struct Head { ... }
* struct Foot { ... }
*
* void send_message(char* msg) {
* int msglen = strlen(msg);
* size_t sizes[3] = { sizeof(struct Head), msglen, sizeof(struct Foot) };
* void* chunks[3];
* if (independent_comalloc(3, sizes, chunks) == 0) __die();
* struct Head* head = (struct Head*)(chunks[0]);
* char* body = (char*)(chunks[1]);
* struct Foot* foot = (struct Foot*)(chunks[2]);
* // ...
* }
* struct Head { ... }
* struct Foot { ... }
* void send_message(char* msg) {
* int msglen = strlen(msg);
* size_t sizes[3] = { sizeof(struct Head), msglen, sizeof(struct Foot) };
* void* chunks[3];
* if (independent_comalloc(3, sizes, chunks) == 0) __die();
* struct Head* head = (struct Head*)(chunks[0]);
* char* body = (char*)(chunks[1]);
* struct Foot* foot = (struct Foot*)(chunks[2]);
* // ...
* }
*
* In general though, independent_comalloc is worth using only for
* larger values of n_elements. For small values, you probably won't

View file

@ -1,5 +1,5 @@
#include "libc/bits/initializer.internal.h"
#include "libc/bits/safemacros.internal.h"
#include "libc/bits/safemacros.h"
#include "libc/calls/internal.h"
#include "libc/calls/struct/sysinfo.h"
#include "libc/dce.h"
@ -21,8 +21,8 @@ STATIC_YOINK("_init_dlmalloc");
#define OOM_WARNING "warning: running out of physical memory\n"
#define is_global(M) ((M) == g_dlmalloc)
struct MallocState g_dlmalloc[1];
struct MallocParams g_mparams;
hidden struct MallocState g_dlmalloc[1];
hidden struct MallocParams g_mparams;
/**
* Acquires more system memory for dlmalloc.

View file

@ -3,7 +3,7 @@
/**
* If possible, gives memory back to the system (via negative arguments
* to sbrk) if there is unused memory at the `high' end of the malloc
* to sbrk) if there is unused memory at the `high` end of the malloc
* pool or in unused MMAP segments. You can call this after freeing
* large blocks of memory to potentially reduce the system-level memory
* requirements of a program. However, it cannot guarantee to reduce
@ -11,7 +11,7 @@
* memory will be locked between two used chunks, so they cannot be
* given back to the system.
*
* The `pad' argument to malloc_trim represents the amount of free
* The `pad` argument to malloc_trim represents the amount of free
* trailing space to leave untrimmed. If this argument is zero, only the
* minimum amount of memory to maintain internal data structures will be
* left. Non-zero arguments can be supplied to maintain enough trailing

View file

@ -13,10 +13,10 @@
* use in this malloc, so setting them has no effect. But this malloc
* also supports other options in mallopt:
*
* Symbol param # default allowed param values
* M_TRIM_THRESHOLD -1 2*1024*1024 any (-1U disables trimming)
* M_GRANULARITY -2 page size any power of 2 >= page size
* M_MMAP_THRESHOLD -3 256*1024 any (or 0 if no MMAP support)
* Symbol param # default allowed param values
* M_TRIM_THRESHOLD -1 2*1024*1024 any (-1U disables trimming)
* M_GRANULARITY -2 page size any power of 2 >= page size
* M_MMAP_THRESHOLD -3 256*1024 any (or 0 if no MMAP support)
*/
bool32 mallopt(int param_number, int value) {
size_t val;

View file

@ -50,8 +50,8 @@ two letters:
and software emulations of Motorola 68xxx chips
that do not pad the way the 68xxx does, but
only store 80 bits
xL IEEE extended precision, as on Motorola 68xxx chips
Q quad precision, as on Sun Sparc chips
xL IEEE extended precision, as on Motorola 68xxx chips [jart: removed]
Q quad precision, as on Sun Sparc chips [jart: removed]
dd double double, pairs of IEEE double numbers
whose sum is the desired value

View file

@ -36,12 +36,8 @@ THIS SOFTWARE.
char *dtoa_result;
#endif
char *
#ifdef KR_headers
rv_alloc(i MTa) int i; MTk
#else
char *
rv_alloc(int i MTd)
#endif
{
int j, k, *r;
@ -59,12 +55,8 @@ rv_alloc(int i MTd)
(char *)(r+1);
}
char *
#ifdef KR_headers
nrv_alloc(s, rve, n MTa) char *s, **rve; int n; MTk
#else
char *
nrv_alloc(char *s, char **rve, int n MTd)
#endif
{
char *rv, *t;
@ -82,12 +74,8 @@ nrv_alloc(char *s, char **rve, int n MTd)
* when MULTIPLE_THREADS is not defined.
*/
void
#ifdef KR_headers
freedtoa(s) char *s;
#else
void
freedtoa(char *s)
#endif
{
#ifdef MULTIPLE_THREADS
ThInfo *TI = 0;
@ -101,13 +89,8 @@ freedtoa(char *s)
#endif
}
int
quorem
#ifdef KR_headers
(b, S) Bigint *b, *S;
#else
(Bigint *b, Bigint *S)
#endif
int
quorem(Bigint *b, Bigint *S)
{
int n;
ULong *bx, *bxe, q, *sx, *sxe;

View file

@ -73,14 +73,8 @@ THIS SOFTWARE.
#define Rounding Flt_Rounds
#endif
char *
dtoa
#ifdef KR_headers
(d0, mode, ndigits, decpt, sign, rve)
double d0; int mode, ndigits, *decpt, *sign; char **rve;
#else
(double d0, int mode, int ndigits, int *decpt, int *sign, char **rve)
#endif
char *
dtoa(double d0, int mode, int ndigits, int *decpt, int *sign, char **rve)
{
/* Arguments ndigits, decpt, sign are similar to those
of ecvt and fcvt; trailing zeros are suppressed from

View file

@ -1,120 +0,0 @@
#include "third_party/gdtoa/gdtoa.internal.h"
/* clang-format off */
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998, 2000 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
#undef _0
#undef _1
/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */
#ifdef IEEE_MC68k
#define _0 0
#define _1 1
#define _2 2
#define _3 3
#endif
#ifdef IEEE_8087
#define _0 3
#define _1 2
#define _2 1
#define _3 0
#endif
char*
#ifdef KR_headers
g_Qfmt(buf, V, ndig, bufsize) char *buf; char *V; int ndig; size_t bufsize;
#else
g_Qfmt(char *buf, void *V, int ndig, size_t bufsize)
#endif
{
static const FPI fpi0 = { 113, 1-16383-113+1, 32766 - 16383 - 113 + 1, 1, 0, Int_max };
char *b, *s, *se;
ULong bits[4], *L, sign;
int decpt, ex, i, mode;
#ifdef Honor_FLT_ROUNDS
#include "third_party/gdtoa/gdtoa_fltrnds.inc"
#else
#define fpi &fpi0
#endif
if (ndig < 0)
ndig = 0;
if (bufsize < (size_t)(ndig + 10))
return 0;
L = (ULong*)V;
sign = L[_0] & 0x80000000L;
bits[3] = L[_0] & 0xffff;
bits[2] = L[_1];
bits[1] = L[_2];
bits[0] = L[_3];
b = buf;
if ( (ex = (L[_0] & 0x7fff0000L) >> 16) !=0) {
if (ex == 0x7fff) {
/* Infinity or NaN */
if (bits[0] | bits[1] | bits[2] | bits[3])
b = strcp(b, "NaN");
else {
b = buf;
if (sign)
*b++ = '-';
b = strcp(b, "Infinity");
}
return b;
}
i = STRTOG_Normal;
bits[3] |= 0x10000;
}
else if (bits[0] | bits[1] | bits[2] | bits[3]) {
i = STRTOG_Denormal;
ex = 1;
}
else {
#ifndef IGNORE_ZERO_SIGN
if (sign)
*b++ = '-';
#endif
*b++ = '0';
*b = 0;
return b;
}
ex -= 0x3fff + 112;
mode = 2;
if (ndig <= 0) {
if (bufsize < 48)
return 0;
mode = 0;
}
s = gdtoa(fpi, ex, bits, &i, mode, ndig, &decpt, &se);
return g__fmt(buf, s, se, decpt, sign, bufsize);
}

View file

@ -1,133 +0,0 @@
#include "third_party/gdtoa/gdtoa.internal.h"
/* clang-format off */
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998, 2000 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
extern ULong NanDflt_Q_D2A[4];
#undef _0
#undef _1
/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */
#ifdef IEEE_MC68k
#define _0 0
#define _1 1
#define _2 2
#define _3 3
#endif
#ifdef IEEE_8087
#define _0 3
#define _1 2
#define _2 1
#define _3 0
#endif
char*
#ifdef KR_headers
g_Qfmt_p(buf, V, ndig, bufsize, nik) char *buf; char *V; int ndig; size_t bufsize; int nik;
#else
g_Qfmt_p(char *buf, void *V, int ndig, size_t bufsize, int nik)
#endif
{
static const FPI fpi0 = { 113, 1-16383-113+1, 32766 - 16383 - 113 + 1, 1, 0, Int_max };
char *b, *s, *se;
ULong bits[4], *L, sign;
int decpt, ex, i, mode;
#ifdef Honor_FLT_ROUNDS
#include "third_party/gdtoa/gdtoa_fltrnds.inc"
#else
#define fpi &fpi0
#endif
if (ndig < 0)
ndig = 0;
if (bufsize < (size_t)(ndig + 10))
return 0;
L = (ULong*)V;
sign = L[_0] & 0x80000000L;
bits[3] = L[_0] & 0xffff;
bits[2] = L[_1];
bits[1] = L[_2];
bits[0] = L[_3];
b = buf;
if ( (ex = (L[_0] & 0x7fff0000L) >> 16) !=0) {
if (ex == 0x7fff) {
/* Infinity or NaN */
if (nik < 0 || nik > 35)
nik = 0;
if (bits[0] | bits[1] | bits[2] | bits[3]) {
if (sign && nik < 18)
*b++ = '-';
b = strcp(b, NanName[nik%3]);
if (nik > 5 && (nik < 12
|| bits[0] != NanDflt_Q_D2A[0]
|| bits[1] != NanDflt_Q_D2A[1]
|| bits[2] != NanDflt_Q_D2A[2]
|| (bits[2] ^ NanDflt_Q_D2A[2]) & 0xffff))
b = add_nanbits(b, bufsize - (b-buf), bits, 4);
}
else {
b = buf;
if (sign)
*b++ = '-';
b = strcp(b, InfName[nik%6]);
}
return b;
}
i = STRTOG_Normal;
bits[3] |= 0x10000;
}
else if (bits[0] | bits[1] | bits[2] | bits[3]) {
i = STRTOG_Denormal;
ex = 1;
}
else {
#ifndef IGNORE_ZERO_SIGN
if (sign)
*b++ = '-';
#endif
*b++ = '0';
*b = 0;
return b;
}
ex -= 0x3fff + 112;
mode = 2;
if (ndig <= 0) {
if (bufsize < 48)
return 0;
mode = 0;
}
s = gdtoa(fpi, ex, bits, &i, mode, ndig, &decpt, &se);
return g__fmt(buf, s, se, decpt, sign, bufsize);
}

View file

@ -48,20 +48,16 @@ THIS SOFTWARE.
#define ldus_QNAN4 0
#endif
const char *const InfName[6] = { "Infinity", "infinity", "INFINITY", "Inf", "inf", "INF" };
const char *const NanName[3] = { "NaN", "nan", "NAN" };
const ULong NanDflt_Q_D2A[4] = { 0xffffffff, 0xffffffff, 0xffffffff, 0x7fffffff };
const ULong NanDflt_d_D2A[2] = { d_QNAN1, d_QNAN0 };
const ULong NanDflt_f_D2A[1] = { f_QNAN };
const ULong NanDflt_xL_D2A[3] = { 1, 0x80000000, 0x7fff0000 };
const UShort NanDflt_ldus_D2A[5] = { ldus_QNAN4, ldus_QNAN3, ldus_QNAN2, ldus_QNAN1, ldus_QNAN0 };
const char *const InfName[6] = { "Infinity", "infinity", "INFINITY", "Inf", "inf", "INF" };
const char *const NanName[3] = { "NaN", "nan", "NAN" };
const ULong __gdtoa_NanDflt_Q[4] = { 0xffffffff, 0xffffffff, 0xffffffff, 0x7fffffff };
const ULong __gdtoa_NanDflt_d[2] = { d_QNAN1, d_QNAN0 };
const ULong __gdtoa_NanDflt_f[1] = { f_QNAN };
const ULong __gdtoa_NanDflt_xL[3] = { 1, 0x80000000, 0x7fff0000 };
const UShort __gdtoa_NanDflt_ldus[5] = { ldus_QNAN4, ldus_QNAN3, ldus_QNAN2, ldus_QNAN1, ldus_QNAN0 };
char *
#ifdef KR_headers
g__fmt(b, s, se, decpt, sign, blen) char *b; char *s; char *se; int decpt; ULong sign; size_t blen;
#else
char *
g__fmt(char *b, char *s, char *se, int decpt, ULong sign, size_t blen)
#endif
{
int i, j, k;
char *be, *s0;
@ -168,7 +164,7 @@ g__fmt(char *b, char *s, char *se, int decpt, ULong sign, size_t blen)
}
char *
add_nanbits_D2A(char *b, size_t blen, ULong *bits, int nb)
__gdtoa_add_nanbits(char *b, size_t blen, ULong *bits, int nb)
{
ULong t;
char *rv;

View file

@ -31,12 +31,8 @@ THIS SOFTWARE.
/* Please send bug reports to David M. Gay (dmg@acm.org). */
char *
#ifdef KR_headers
g_ddfmt(buf, dd0, ndig, bufsize) char *buf; double *dd0; int ndig; size_t bufsize;
#else
char *
g_ddfmt(char *buf, double *dd0, int ndig, size_t bufsize)
#endif
{
FPI fpi;
char *b, *s, *se;

View file

@ -31,14 +31,10 @@ THIS SOFTWARE.
/* Please send bug reports to David M. Gay (dmg@acm.org). */
extern ULong NanDflt_d_D2A[2];
extern ULong __gdtoa_NanDflt_d[2];
char *
#ifdef KR_headers
g_ddfmt_p(buf, dd0, ndig, bufsize, nik) char *buf; double *dd0; int ndig; size_t bufsize; int nik;
#else
char *
g_ddfmt_p(char *buf, double *dd0, int ndig, size_t bufsize, int nik)
#endif
{
FPI fpi;
char *b, *s, *se;
@ -82,10 +78,10 @@ g_ddfmt_p(char *buf, double *dd0, int ndig, size_t bufsize, int nik)
*b++ = '-';
b = strcp(b, NanName[nik%3]);
if (nik > 5 && (nik < 12
|| L[_1] != NanDflt_d_D2A[0]
|| (L[_0] ^ NanDflt_d_D2A[1]) & 0xfffff
|| L[2+_1] != NanDflt_d_D2A[0]
|| (L[2+_0] ^ NanDflt_d_D2A[1]) & 0xfffff)) {
|| L[_1] != __gdtoa_NanDflt_d[0]
|| (L[_0] ^ __gdtoa_NanDflt_d[1]) & 0xfffff
|| L[2+_1] != __gdtoa_NanDflt_d[0]
|| (L[2+_0] ^ __gdtoa_NanDflt_d[1]) & 0xfffff)) {
bits0[0] = L[2+_1];
bits0[1] = (L[2+_0] & 0xfffff) | (L[_1] << 20);
bits0[2] = (L[_1] >> 12) | (L[_0] << 20);

View file

@ -32,12 +32,8 @@ THIS SOFTWARE.
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
char*
#ifdef KR_headers
g_dfmt(buf, d, ndig, bufsize) char *buf; double *d; int ndig; size_t bufsize;
#else
char*
g_dfmt(char *buf, double *d, int ndig, size_t bufsize)
#endif
{
static const FPI fpi0 = { 53, 1-1023-53+1, 2046-1023-53+1, 1, 0, Int_max };
char *b, *s, *se;

View file

@ -32,14 +32,10 @@ THIS SOFTWARE.
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
extern ULong NanDflt_d_D2A[2];
extern ULong __gdtoa_NanDflt_d[2];
char*
#ifdef KR_headers
g_dfmt_p(buf, d, ndig, bufsize, nik) char *buf; double *d; int ndig; size_t bufsize; int nik;
#else
char*
g_dfmt_p(char *buf, double *d, int ndig, size_t bufsize, int nik)
#endif
{
static const FPI fpi0 = { 53, 1-1023-53+1, 2046-1023-53+1, 1, 0, Int_max };
char *b, *s, *se;
@ -70,8 +66,8 @@ g_dfmt_p(char *buf, double *d, int ndig, size_t bufsize, int nik)
*b++ = '-';
b = strcp(b, NanName[nik%3]);
if (nik > 5 && (nik < 12
|| bits[0] != NanDflt_d_D2A[0]
|| (bits[1] ^ NanDflt_d_D2A[1]) & 0xfffff)) {
|| bits[0] != __gdtoa_NanDflt_d[0]
|| (bits[1] ^ __gdtoa_NanDflt_d[1]) & 0xfffff)) {
bits[0] = L[_1];
bits[1] = L[_0] & 0xfffff;
b = add_nanbits(b, bufsize - (b-buf), bits, 2);

View file

@ -32,12 +32,8 @@ THIS SOFTWARE.
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
char*
#ifdef KR_headers
g_ffmt(buf, f, ndig, bufsize) char *buf; float *f; int ndig; size_t bufsize;
#else
char*
g_ffmt(char *buf, float *f, int ndig, size_t bufsize)
#endif
{
static const FPI fpi0 = { 24, 1-127-24+1, 254-127-24+1, 1, 0, 6 };
char *b, *s, *se;

View file

@ -32,14 +32,10 @@ THIS SOFTWARE.
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
extern ULong NanDflt_f_D2A[1];
extern ULong __gdtoa_NanDflt_f[1];
char*
#ifdef KR_headers
g_ffmt_p(buf, f, ndig, bufsize, nik) char *buf; float *f; int ndig; size_t bufsize; int nik;
#else
char*
g_ffmt_p(char *buf, float *f, int ndig, size_t bufsize, int nik)
#endif
{
static const FPI fpi0 = { 24, 1-127-24+1, 254-127-24+1, 1, 0, 6 };
char *b, *s, *se;
@ -68,7 +64,7 @@ g_ffmt_p(char *buf, float *f, int ndig, size_t bufsize, int nik)
*b++ = '-';
b = strcp(b, NanName[nik%3]);
if (nik > 5 && (nik < 12
|| (bits[0] ^ NanDflt_f_D2A[0]) & 0x7fffff))
|| (bits[0] ^ __gdtoa_NanDflt_f[0]) & 0x7fffff))
b = add_nanbits(b, bufsize - (b-buf), bits, 1);
return b;
}

View file

@ -1,114 +0,0 @@
#include "third_party/gdtoa/gdtoa.internal.h"
/* clang-format off */
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
#undef _0
#undef _1
/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */
#ifdef IEEE_MC68k
#define _0 0
#define _1 1
#define _2 2
#endif
#ifdef IEEE_8087
#define _0 2
#define _1 1
#define _2 0
#endif
char*
#ifdef KR_headers
g_xLfmt(buf, V, ndig, bufsize) char *buf; char *V; int ndig; size_t bufsize;
#else
g_xLfmt(char *buf, void *V, int ndig, size_t bufsize)
#endif
{
static const FPI fpi0 = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, 0, Int_max };
char *b, *s, *se;
ULong bits[2], *L, sign;
int decpt, ex, i, mode;
#ifdef Honor_FLT_ROUNDS
#include "third_party/gdtoa/gdtoa_fltrnds.inc"
#else
#define fpi &fpi0
#endif
if (ndig < 0)
ndig = 0;
if (bufsize < (size_t)(ndig + 10))
return 0;
L = (ULong*)V;
sign = L[_0] & 0x80000000L;
bits[1] = L[_1];
bits[0] = L[_2];
if ( (ex = (L[_0] >> 16) & 0x7fff) !=0) {
if (ex == 0x7fff) {
/* Infinity or NaN */
if (bits[0] | bits[1])
b = strcp(buf, "NaN");
else {
b = buf;
if (sign)
*b++ = '-';
b = strcp(b, "Infinity");
}
return b;
}
i = STRTOG_Normal;
}
else if (bits[0] | bits[1]) {
i = STRTOG_Denormal;
}
else {
b = buf;
#ifndef IGNORE_ZERO_SIGN
if (sign)
*b++ = '-';
#endif
*b++ = '0';
*b = 0;
return b;
}
ex -= 0x3fff + 63;
mode = 2;
if (ndig <= 0) {
if (bufsize < 32)
return 0;
mode = 0;
}
s = gdtoa(fpi, ex, bits, &i, mode, ndig, &decpt, &se);
return g__fmt(buf, s, se, decpt, sign, bufsize);
}

View file

@ -1,126 +0,0 @@
#include "third_party/gdtoa/gdtoa.internal.h"
/* clang-format off */
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
extern ULong NanDflt_xL_D2A[3];
#undef _0
#undef _1
/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */
#ifdef IEEE_MC68k
#define _0 0
#define _1 1
#define _2 2
#endif
#ifdef IEEE_8087
#define _0 2
#define _1 1
#define _2 0
#endif
char*
#ifdef KR_headers
g_xLfmt_p(buf, V, ndig, bufsize, nik) char *buf; char *V; int ndig; size_t bufsize; int nik;
#else
g_xLfmt_p(char *buf, void *V, int ndig, size_t bufsize, int nik)
#endif
{
static const FPI fpi0 = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, 0, Int_max };
char *b, *s, *se;
ULong bits[2], *L, sign;
int decpt, ex, i, mode;
#ifdef Honor_FLT_ROUNDS
#include "third_party/gdtoa/gdtoa_fltrnds.inc"
#else
#define fpi &fpi0
#endif
if (ndig < 0)
ndig = 0;
if (bufsize < (size_t)(ndig + 10))
return 0;
L = (ULong*)V;
sign = L[_0] & 0x80000000L;
bits[1] = L[_1];
bits[0] = L[_2];
if ( (ex = (L[_0] >> 16) & 0x7fff) !=0) {
if (ex == 0x7fff) {
/* Infinity or NaN */
if (nik < 0 || nik > 35)
nik = 0;
if (!bits[0] && bits[1] == 0x80000000) {
b = buf;
if (sign)
*b++ = '-';
b = strcp(b, InfName[nik%6]);
}
else {
b = buf;
if (sign && nik < 18)
*b++ = '-';
b = strcp(b, NanName[nik%3]);
if (nik > 5 && (nik < 12
|| bits[0] != NanDflt_xL_D2A[0]
|| bits[1] != NanDflt_xL_D2A[1]))
b = add_nanbits(b, bufsize - (b-buf), bits, 2);
}
return b;
}
i = STRTOG_Normal;
}
else if (bits[0] | bits[1]) {
i = STRTOG_Denormal;
}
else {
b = buf;
#ifndef IGNORE_ZERO_SIGN
if (sign)
*b++ = '-';
#endif
*b++ = '0';
*b = 0;
return b;
}
ex -= 0x3fff + 63;
mode = 2;
if (ndig <= 0) {
if (bufsize < 32)
return 0;
mode = 0;
}
s = gdtoa(fpi, ex, bits, &i, mode, ndig, &decpt, &se);
return g__fmt(buf, s, se, decpt, sign, bufsize);
}

View file

@ -52,12 +52,8 @@ THIS SOFTWARE.
#define _4 0
#endif
char*
#ifdef KR_headers
g_xfmt(buf, V, ndig, bufsize) char *buf; char *V; int ndig; size_t bufsize;
#else
char*
g_xfmt(char *buf, void *V, int ndig, size_t bufsize)
#endif
{
static const FPI fpi0 = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, 0, Int_max };
char *b, *s, *se;

View file

@ -32,7 +32,7 @@ THIS SOFTWARE.
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
extern UShort NanDflt_ldus_D2A[5];
extern UShort __gdtoa_NanDflt_ldus[5];
#undef _0
#undef _1
@ -54,12 +54,8 @@ THIS SOFTWARE.
#define _4 0
#endif
char*
#ifdef KR_headers
g_xfmt_p(buf, V, ndig, bufsize, nik) char *buf; char *V; int ndig; size_t bufsize; int nik;
#else
char*
g_xfmt_p(char *buf, void *V, int ndig, size_t bufsize, int nik)
#endif
{
static const FPI fpi0 = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, 0, Int_max };
char *b, *s, *se;
@ -98,10 +94,10 @@ g_xfmt_p(char *buf, void *V, int ndig, size_t bufsize, int nik)
*b++ = '-';
b = strcp(b, NanName[nik%3]);
if (nik > 5 && (nik < 12
|| L[_1] != NanDflt_ldus_D2A[3]
|| L[_2] != NanDflt_ldus_D2A[2]
|| L[_3] != NanDflt_ldus_D2A[1]
|| L[_4] != NanDflt_ldus_D2A[0])) {
|| L[_1] != __gdtoa_NanDflt_ldus[3]
|| L[_2] != __gdtoa_NanDflt_ldus[2]
|| L[_3] != __gdtoa_NanDflt_ldus[1]
|| L[_4] != __gdtoa_NanDflt_ldus[0])) {
bits[1] &= 0x7fffffff;
b = add_nanbits(b, bufsize - (b-buf), bits, 2);
}

View file

@ -32,12 +32,8 @@ THIS SOFTWARE.
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
static Bigint *
#ifdef KR_headers
bitstob(bits, nbits, bbits MTa) ULong *bits; int nbits; int *bbits; MTk
#else
static Bigint *
bitstob(ULong *bits, int nbits, int *bbits MTd)
#endif
{
int i, k;
Bigint *b;
@ -109,15 +105,8 @@ bitstob(ULong *bits, int nbits, int *bbits MTd)
* calculation.
*/
char *
gdtoa
#ifdef KR_headers
(fpi, be, bits, kindp, mode, ndigits, decpt, rve)
CONST FPI *fpi; int be; ULong *bits;
int *kindp, mode, ndigits, *decpt; char **rve;
#else
(CONST FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, int *decpt, char **rve)
#endif
char *
gdtoa(CONST FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, int *decpt, char **rve)
{
/* Arguments ndigits and decpt are similar to the second and third
arguments of ecvt and fcvt; trailing zeros are suppressed from

View file

@ -137,7 +137,6 @@ THIS SOFTWARE.
* something other than "long long", #define Llong to be the name,
* and if "unsigned Llong" does not work as an unsigned version of
* Llong, #define #ULLong to be the corresponding unsigned type.
* #define KR_headers for old-style C function headers.
* #define Bad_float_h if your system lacks a float.h or if it does not
* define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP,
* FLT_RADIX, FLT_ROUNDS, and DBL_MAX.
@ -220,16 +219,6 @@ THIS SOFTWARE.
* #define USE_LOCALE to use the current locale's decimal_point value.
*/
#ifndef ANSI
#ifdef KR_headers
#define ANSI(x) ()
#define Void /*nothing*/
#else
#define ANSI(x) x
#define Void void
#endif
#endif /* ANSI */
#ifndef Long
#define Long int
#endif
@ -241,11 +230,7 @@ typedef unsigned short UShort;
#endif
#ifndef CONST
#ifdef KR_headers
#define CONST /* blank */
#else
#define CONST const
#endif
#endif /* CONST */
#ifdef DEBUG
@ -256,20 +241,20 @@ typedef unsigned short UShort;
}
#endif
#ifdef KR_headers
#define Char char
#else
/* #ifdef KR_headers */
/* #define Char char */
/* #else */
#define Char void
#endif
/* #endif */
#ifdef MALLOC
extern Char *MALLOC ANSI((size_t));
extern Char *MALLOC(size_t);
#else
#define MALLOC malloc
#endif
#ifdef REALLOC
extern Char *REALLOC ANSI((Char *, size_t));
extern Char *REALLOC(Char *, size_t);
#else
#define REALLOC realloc
#endif
@ -476,11 +461,7 @@ Exactly one of IEEE_8087, IEEE_MC68k, VAX, or IBM should be defined.
#ifdef RND_PRODQUOT
#define rounded_product(a, b) a = rnd_prod(a, b)
#define rounded_quotient(a, b) a = rnd_quot(a, b)
#ifdef KR_headers
extern double rnd_prod(), rnd_quot();
#else
extern double rnd_prod(double, double), rnd_quot(double, double);
#endif
#else
#define rounded_product(a, b) a *= b
#define rounded_quotient(a, b) a /= b
@ -531,9 +512,9 @@ extern double rnd_prod(double, double), rnd_quot(double, double);
#define MTb , &TI
#define MTd , ThInfo **PTI
#define MTk ThInfo **PTI;
extern void ACQUIRE_DTOA_LOCK ANSI((unsigned int));
extern void FREE_DTOA_LOCK ANSI((unsigned int));
extern unsigned int dtoa_get_threadno ANSI((void));
extern void ACQUIRE_DTOA_LOCK(unsigned int);
extern void FREE_DTOA_LOCK(unsigned int);
extern unsigned int dtoa_get_threadno(void);
#else /*}{*/
#define ACQUIRE_DTOA_LOCK(n) /*nothing*/
#define FREE_DTOA_LOCK(n) /*nothing*/
@ -562,111 +543,114 @@ typedef struct ThInfo {
#ifdef DECLARE_SIZE_T
typedef unsigned int size_t;
#endif
extern void memcpy_D2A ANSI((void *, const void *, size_t));
extern void __gdtoa_memcpy(void *, const void *, size_t);
#define Bcopy(x, y) \
memcpy_D2A(&x->sign, &y->sign, y->wds * sizeof(ULong) + 2 * sizeof(int))
__gdtoa_memcpy(&x->sign, &y->sign, y->wds * sizeof(ULong) + 2 * sizeof(int))
#else /* !NO_STRING_H */
#define Bcopy(x, y) \
memcpy(&x->sign, &y->sign, y->wds * sizeof(ULong) + 2 * sizeof(int))
#endif /* NO_STRING_H */
#define Balloc Balloc_D2A
#define Bfree Bfree_D2A
#define InfName InfName_D2A
#define NanName NanName_D2A
#define ULtoQ ULtoQ_D2A
#define ULtof ULtof_D2A
#define ULtod ULtod_D2A
#define ULtodd ULtodd_D2A
#define ULtox ULtox_D2A
#define ULtoxL ULtoxL_D2A
#define add_nanbits add_nanbits_D2A
#define any_on any_on_D2A
#define b2d b2d_D2A
#define bigtens bigtens_D2A
#define cmp cmp_D2A
#define copybits copybits_D2A
#define d2b d2b_D2A
#define decrement decrement_D2A
#define diff diff_D2A
#define dtoa_result dtoa_result_D2A
#define g__fmt g__fmt_D2A
#define gethex gethex_D2A
#define hexdig hexdig_D2A
#define hexnan hexnan_D2A
#define hi0bits(x) hi0bits_D2A((ULong)(x))
#define i2b i2b_D2A
#define increment increment_D2A
#define lo0bits lo0bits_D2A
#define lshift lshift_D2A
#define match match_D2A
#define mult mult_D2A
#define multadd multadd_D2A
#define nrv_alloc nrv_alloc_D2A
#define pow5mult pow5mult_D2A
#define quorem quorem_D2A
#define ratio ratio_D2A
#define rshift rshift_D2A
#define rv_alloc rv_alloc_D2A
#define s2b s2b_D2A
#define set_ones set_ones_D2A
#define strcp strcp_D2A
#define strtoIg strtoIg_D2A
#define sum sum_D2A
#define tens tens_D2A
#define tinytens tinytens_D2A
#define tinytens tinytens_D2A
#define trailz trailz_D2A
#define ulp ulp_D2A
#define Balloc __gdtoa_Balloc
#define Bfree __gdtoa_Bfree
#define InfName __gdtoa_InfName
#define NanName __gdtoa_NanName
#define ULtoQ __gdtoa_ULtoQ
#define ULtof __gdtoa_ULtof
#define ULtod __gdtoa_ULtod
#define ULtodd __gdtoa_ULtodd
#define ULtox __gdtoa_ULtox
#define ULtoxL __gdtoa_ULtoxL
#define add_nanbits __gdtoa_add_nanbits
#define any_on __gdtoa_any_on
#define b2d __gdtoa_b2d
#define bigtens __gdtoa_bigtens
#define cmp __gdtoa_cmp
#define copybits __gdtoa_copybits
#define d2b __gdtoa_d2b
#define decrement __gdtoa_decrement
#define diff __gdtoa_diff
#define dtoa_result __gdtoa_dtoa_result
#define g__fmt __gdtoa_g__fmt
#define gethex __gdtoa_gethex
#define hexdig __gdtoa_hexdig
#define hexnan __gdtoa_hexnan
#define hi0bits(x) __gdtoa_hi0bits((ULong)(x))
#define i2b __gdtoa_i2b
#define increment __gdtoa_increment
#define lo0bits __gdtoa_lo0bits
#define lshift __gdtoa_lshift
#define match __gdtoa_match
#define mult __gdtoa_mult
#define multadd __gdtoa_multadd
#define nrv_alloc __gdtoa_nrv_alloc
#define pow5mult __gdtoa_pow5mult
#define quorem __gdtoa_quorem
#define ratio __gdtoa_ratio
#define rshift __gdtoa_rshift
#define rv_alloc __gdtoa_rv_alloc
#define s2b __gdtoa_s2b
#define set_ones __gdtoa_set_ones
#define strcp __gdtoa_strcp
#define strtoIg __gdtoa_strtoIg
#define sum __gdtoa_sum
#define tens __gdtoa_tens
#define tinytens __gdtoa_tinytens
#define tinytens __gdtoa_tinytens
#define trailz __gdtoa_trailz
#define ulp __gdtoa_ulp
extern char *add_nanbits ANSI((char *, size_t, ULong *, int));
extern char *dtoa_result;
extern CONST double bigtens[], tens[], tinytens[];
extern const unsigned char hexdig[];
extern const char *const InfName[6], *const NanName[3];
extern char *add_nanbits(char *, size_t, ULong *, int);
extern Bigint *Balloc ANSI((int MTd));
extern void Bfree ANSI((Bigint * MTd));
extern void ULtof ANSI((ULong *, ULong *, Long, int));
extern void ULtod ANSI((ULong *, ULong *, Long, int));
extern void ULtodd ANSI((ULong *, ULong *, Long, int));
extern void ULtoQ ANSI((ULong *, ULong *, Long, int));
extern void ULtox ANSI((UShort *, ULong *, Long, int));
extern void ULtoxL ANSI((ULong *, ULong *, Long, int));
extern ULong any_on ANSI((Bigint *, int));
extern double b2d ANSI((Bigint *, int *));
extern int cmp ANSI((Bigint *, Bigint *));
extern void copybits ANSI((ULong *, int, Bigint *));
extern Bigint *d2b ANSI((double, int *, int *MTd));
extern void decrement ANSI((Bigint *));
extern Bigint *diff ANSI((Bigint *, Bigint *MTd));
extern char *g__fmt ANSI((char *, char *, char *, int, ULong, size_t));
extern int gethex ANSI((CONST char **, CONST FPI *, Long *, Bigint **,
int MTd));
extern void hexdig_init_D2A(Void);
extern int hexnan ANSI((CONST char **, CONST FPI *, ULong *));
extern int hi0bits_D2A ANSI((ULong));
extern Bigint *i2b ANSI((int MTd));
extern Bigint *increment ANSI((Bigint * MTd));
extern int lo0bits ANSI((ULong *));
extern Bigint *lshift ANSI((Bigint *, int MTd));
extern int match ANSI((CONST char **, char *));
extern Bigint *mult ANSI((Bigint *, Bigint *MTd));
extern Bigint *multadd ANSI((Bigint *, int, int MTd));
extern char *nrv_alloc ANSI((char *, char **, int MTd));
extern Bigint *pow5mult ANSI((Bigint *, int MTd));
extern int quorem ANSI((Bigint *, Bigint *));
extern double ratio ANSI((Bigint *, Bigint *));
extern void rshift ANSI((Bigint *, int));
extern char *rv_alloc ANSI((int MTd));
extern Bigint *s2b ANSI((CONST char *, int, int, ULong, int MTd));
extern Bigint *set_ones ANSI((Bigint *, int MTd));
extern char *strcp ANSI((char *, const char *));
extern int strtoIg ANSI((CONST char *, char **, CONST FPI *, Long *, Bigint **,
int *));
extern Bigint *sum ANSI((Bigint *, Bigint *MTd));
extern int trailz ANSI((Bigint *));
extern double ulp ANSI((U *));
hidden extern char *dtoa_result;
hidden extern CONST double bigtens[];
hidden extern CONST double tens[];
hidden extern CONST double tinytens[];
hidden extern const unsigned char hexdig[];
hidden extern const char *const InfName[6];
hidden extern const char *const NanName[3];
extern Bigint *Balloc(int MTd);
extern void Bfree(Bigint *MTd);
extern void ULtof(ULong *, ULong *, Long, int);
extern void ULtod(ULong *, ULong *, Long, int);
extern void ULtodd(ULong *, ULong *, Long, int);
extern void ULtoQ(ULong *, ULong *, Long, int);
extern void ULtox(UShort *, ULong *, Long, int);
extern void ULtoxL(ULong *, ULong *, Long, int);
extern ULong any_on(Bigint *, int);
extern double b2d(Bigint *, int *);
extern int cmp(Bigint *, Bigint *);
extern void copybits(ULong *, int, Bigint *);
extern Bigint *d2b(double, int *, int *MTd);
extern void decrement(Bigint *);
extern Bigint *diff(Bigint *, Bigint *MTd);
extern char *g__fmt(char *, char *, char *, int, ULong, size_t);
extern int gethex(CONST char **, CONST FPI *, Long *, Bigint **, int MTd);
extern void __gdtoa_hexdig_init(void);
extern int hexnan(CONST char **, CONST FPI *, ULong *);
extern int __gdtoa_hi0bits(ULong);
extern Bigint *i2b(int MTd);
extern Bigint *increment(Bigint *MTd);
extern int lo0bits(ULong *);
extern Bigint *lshift(Bigint *, int MTd);
extern int match(CONST char **, char *);
extern Bigint *mult(Bigint *, Bigint *MTd);
extern Bigint *multadd(Bigint *, int, int MTd);
extern char *nrv_alloc(char *, char **, int MTd);
extern Bigint *pow5mult(Bigint *, int MTd);
extern int quorem(Bigint *, Bigint *);
extern double ratio(Bigint *, Bigint *);
extern void rshift(Bigint *, int);
extern char *rv_alloc(int MTd);
extern Bigint *s2b(CONST char *, int, int, ULong, int MTd);
extern Bigint *set_ones(Bigint *, int MTd);
extern char *strcp(char *, const char *);
extern int strtoIg(CONST char *, char **, CONST FPI *, Long *, Bigint **,
int *);
extern Bigint *sum(Bigint *, Bigint *MTd);
extern int trailz(Bigint *);
extern double ulp(U *);
#ifdef __cplusplus
}

View file

@ -33,13 +33,8 @@ THIS SOFTWARE.
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
int
#ifdef KR_headers
gethex(sp, fpi, exp, bp, sign MTa)
CONST char **sp; CONST FPI *fpi; Long *exp; Bigint **bp; int sign; MTk
#else
int
gethex( CONST char **sp, CONST FPI *fpi, Long *exp, Bigint **bp, int sign MTd)
#endif
{
Bigint *b;
CONST unsigned char *decpt, *s0, *s, *s1;
@ -64,7 +59,7 @@ gethex( CONST char **sp, CONST FPI *fpi, Long *exp, Bigint **bp, int sign MTd)
#endif
#endif
/**** if (!hexdig['0']) hexdig_init_D2A(); ****/
/**** if (!hexdig['0']) __gdtoa_hexdig_init(); ****/
*bp = 0;
havedig = 0;
s0 = *(CONST unsigned char **)sp + 2;

View file

@ -32,12 +32,8 @@ THIS SOFTWARE.
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
void
#ifdef KR_headers
rshift(b, k) Bigint *b; int k;
#else
void
rshift(Bigint *b, int k)
#endif
{
ULong *x, *x1, *xe, y;
int n;
@ -65,12 +61,8 @@ rshift(Bigint *b, int k)
b->x[0] = 0;
}
int
#ifdef KR_headers
trailz(b) Bigint *b;
#else
int
trailz(Bigint *b)
#endif
{
ULong L, *x, *xe;
int n = 0;

View file

@ -33,23 +33,19 @@ THIS SOFTWARE.
* with " at " changed at "@" and " dot " changed to "."). */
#if 0
unsigned char hexdig[256];
unsigned char hexdig[256];
static void
#ifdef KR_headers
htinit(h, s, inc) unsigned char *h; unsigned char *s; int inc;
#else
static void
htinit(unsigned char *h, unsigned char *s, int inc)
#endif
{
int i, j;
for(i = 0; (j = s[i]) !=0; i++)
h[j] = i + inc;
}
void
hexdig_init_D2A(Void) /* Use of hexdig_init omitted 20121220 to avoid a */
/* race condition when multiple threads are used. */
void
__gdtoa_hexdig_init(Void) /* Use of hexdig_init omitted 20121220 to avoid a */
/* race condition when multiple threads are used. */
{
#define USC (unsigned char *)
htinit(hexdig, USC "0123456789", 0x10);
@ -57,7 +53,7 @@ hexdig_init_D2A(Void) /* Use of hexdig_init omitted 20121220 to avoid a */
htinit(hexdig, USC "ABCDEF", 0x10 + 10);
}
#else
const unsigned char hexdig[256] = {
const unsigned char hexdig[256] = {
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,

View file

@ -32,12 +32,8 @@ THIS SOFTWARE.
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
static void
#ifdef KR_headers
L_shift(x, x1, i) ULong *x; ULong *x1; int i;
#else
static void
L_shift(ULong *x, ULong *x1, int i)
#endif
{
int j;
@ -50,19 +46,14 @@ L_shift(ULong *x, ULong *x1, int i)
} while(++x < x1);
}
int
#ifdef KR_headers
hexnan(sp, fpi, x0)
CONST char **sp; CONST FPI *fpi; ULong *x0;
#else
int
hexnan( CONST char **sp, CONST FPI *fpi, ULong *x0)
#endif
{
ULong c, h, *x, *x1, *xe;
CONST char *s;
int havedig, hd0, i, nbits;
/**** if (!hexdig['0']) hexdig_init_D2A(); ****/
/**** if (!hexdig['0']) __gdtoa_hexdig_init(); ****/
nbits = fpi->nbits;
x = x0 + (nbits >> kshift);
if (nbits & kmask)

View file

@ -90,13 +90,8 @@ get_TI(void)
#define p5s TI0.P5s
#endif /*}}*/
Bigint *
Balloc
#ifdef KR_headers
(k MTa) int k; MTk
#else
(int k MTd)
#endif
Bigint *
Balloc(int k MTd)
{
int x;
Bigint *rv;
@ -152,13 +147,8 @@ Balloc
return rv;
}
void
Bfree
#ifdef KR_headers
(v MTa) Bigint *v; MTk
#else
(Bigint *v MTd)
#endif
void
Bfree(Bigint *v MTd)
{
#ifdef MULTIPLE_THREADS
ThInfo *TI;
@ -187,13 +177,8 @@ Bfree
}
}
int
lo0bits
#ifdef KR_headers
(y) ULong *y;
#else
(ULong *y)
#endif
int
lo0bits(ULong *y)
{
int k;
ULong x = *y;
@ -235,13 +220,8 @@ lo0bits
return k;
}
Bigint *
multadd
#ifdef KR_headers
(b, m, a MTa) Bigint *b; int m, a; MTk
#else
(Bigint *b, int m, int a MTd) /* multiply by m and add a */
#endif
Bigint *
multadd(Bigint *b, int m, int a MTd) /* multiply by m and add a */
{
int i, wds;
#ifdef ULLong
@ -292,13 +272,8 @@ multadd
return b;
}
int
hi0bits_D2A
#ifdef KR_headers
(x) ULong x;
#else
(ULong x)
#endif
int
__gdtoa_hi0bits(ULong x)
{
int k = 0;
@ -326,13 +301,8 @@ hi0bits_D2A
return k;
}
Bigint *
i2b
#ifdef KR_headers
(i MTa) int i; MTk
#else
(int i MTd)
#endif
Bigint *
i2b(int i MTd)
{
Bigint *b;
@ -342,13 +312,8 @@ i2b
return b;
}
Bigint *
mult
#ifdef KR_headers
(a, b MTa) Bigint *a, *b; MTk
#else
(Bigint *a, Bigint *b MTd)
#endif
Bigint *
mult(Bigint *a, Bigint *b MTd)
{
Bigint *c;
int k, wa, wb, wc;
@ -452,13 +417,8 @@ mult
return c;
}
Bigint *
pow5mult
#ifdef KR_headers
(b, k MTa) Bigint *b; int k; MTk
#else
(Bigint *b, int k MTd)
#endif
Bigint *
pow5mult(Bigint *b, int k MTd)
{
Bigint *b1, *p5, *p51;
#ifdef MULTIPLE_THREADS
@ -524,13 +484,8 @@ pow5mult
return b;
}
Bigint *
lshift
#ifdef KR_headers
(b, k MTa) Bigint *b; int k; MTk
#else
(Bigint *b, int k MTd)
#endif
Bigint *
lshift(Bigint *b, int k MTd)
{
int i, k1, n, n1;
Bigint *b1;
@ -578,13 +533,8 @@ lshift
return b1;
}
int
cmp
#ifdef KR_headers
(a, b) Bigint *a, *b;
#else
(Bigint *a, Bigint *b)
#endif
int
cmp(Bigint *a, Bigint *b)
{
ULong *xa, *xa0, *xb, *xb0;
int i, j;
@ -612,13 +562,8 @@ cmp
return 0;
}
Bigint *
diff
#ifdef KR_headers
(a, b MTa) Bigint *a, *b; MTk
#else
(Bigint *a, Bigint *b MTd)
#endif
Bigint *
diff(Bigint *a, Bigint *b MTd)
{
Bigint *c;
int i, wa, wb;
@ -706,13 +651,8 @@ diff
return c;
}
double
b2d
#ifdef KR_headers
(a, e) Bigint *a; int *e;
#else
(Bigint *a, int *e)
#endif
double
b2d(Bigint *a, int *e)
{
ULong *xa, *xa0, w, y, z;
int k;
@ -775,13 +715,8 @@ b2d
#undef d0
#undef d1
Bigint *
d2b
#ifdef KR_headers
(dd, e, bits MTa) double dd; int *e, *bits; MTk
#else
(double dd, int *e, int *bits MTd)
#endif
Bigint *
d2b(double dd, int *e, int *bits MTd)
{
Bigint *b;
U d;
@ -913,7 +848,7 @@ d2b
#undef d0
#undef d1
CONST double
CONST double
#ifdef IEEE_Arith
bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256
@ -928,7 +863,7 @@ CONST double tinytens[] = { 1e-16, 1e-32 };
#endif
#endif
CONST double
CONST double
tens[] = {
1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
@ -938,12 +873,8 @@ tens[] = {
#endif
};
char *
#ifdef KR_headers
strcp_D2A(a, b) char *a; char *b;
#else
strcp_D2A(char *a, CONST char *b)
#endif
char *
__gdtoa_strcp(char *a, CONST char *b)
{
while((*a = *b++))
a++;
@ -952,12 +883,8 @@ strcp_D2A(char *a, CONST char *b)
#ifdef NO_STRING_H
Char *
#ifdef KR_headers
memcpy_D2A(a, b, len) Char *a; Char *b; size_t len;
#else
memcpy_D2A(void *a1, void *b1, size_t len)
#endif
Char *
__gdtoa_memcpy(void *a1, void *b1, size_t len)
{
char *a = (char*)a1, *ae = a + len;
char *b = (char*)b1, *a0 = a;

View file

@ -1,10 +0,0 @@
/* clang-format off */
#ifdef __sun
#define Use_GDTOA_Qtype
#else
#if defined(__i386) || defined(__x86_64)
#define Use_GDTOA_for_i386_long_double
#endif
#endif
#include "third_party/gdtoa/printf.c0"

File diff suppressed because it is too large Load diff

View file

@ -32,13 +32,8 @@ THIS SOFTWARE.
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
Bigint *
s2b
#ifdef KR_headers
(s, nd0, nd, y9, dplen MTa) CONST char *s; int dplen, nd0, nd; ULong y9; MTk
#else
(CONST char *s, int nd0, int nd, ULong y9, int dplen MTd)
#endif
Bigint *
s2b(CONST char *s, int nd0, int nd, ULong y9, int dplen MTd)
{
Bigint *b;
int i, k;
@ -70,13 +65,8 @@ s2b
return b;
}
double
ratio
#ifdef KR_headers
(a, b) Bigint *a, *b;
#else
(Bigint *a, Bigint *b)
#endif
double
ratio(Bigint *a, Bigint *b)
{
U da, db;
int k, ka, kb;
@ -109,13 +99,8 @@ ratio
#ifdef INFNAN_CHECK
int
match
#ifdef KR_headers
(sp, t) char **sp, *t;
#else
(CONST char **sp, char *t)
#endif
int
match(CONST char **sp, char *t)
{
int c, d;
CONST char *s = *sp;
@ -131,12 +116,8 @@ match
}
#endif /* INFNAN_CHECK */
void
#ifdef KR_headers
copybits(c, n, b) ULong *c; int n; Bigint *b;
#else
void
copybits(ULong *c, int n, Bigint *b)
#endif
{
ULong *ce, *x, *xe;
#ifdef Pack_16
@ -161,12 +142,8 @@ copybits(ULong *c, int n, Bigint *b)
*c++ = 0;
}
ULong
#ifdef KR_headers
any_on(b, k) Bigint *b; int k;
#else
ULong
any_on(Bigint *b, int k)
#endif
{
int n, nwds;
ULong *x, *x0, x1, x2;

View file

@ -1,106 +0,0 @@
#include "libc/stdio/stdio.h"
/****************************************************************
Copyright (C) 1997-1999 Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* stdio1.h -- for using Printf, Fprintf, Sprintf while
* retaining the system-supplied printf, fprintf, sprintf.
*/
#ifndef STDIO1_H_included
#define STDIO1_H_included
#ifndef STDIO_H_included /* allow suppressing stdio.h */
#endif /* e.g., by cplex.h */
#ifdef KR_headers
#ifndef _SIZE_T
#define _SIZE_T
typedef unsigned int size_t;
#endif
#define ANSI(x) ()
#ifndef Char
#define Char char
#endif
#else
#define ANSI(x) x
#ifndef Char
#define Char void
#endif
#endif
#ifndef NO_STDIO1
#ifdef _WIN32
/* Avoid Microsoft bug that perrror may appear in stdlib.h. */
/* It should only be declared in stdio.h. */
#endif
#ifdef __cplusplus
extern "C" {
#endif
extern int Fprintf ANSI((FILE *, const char *, ...));
extern int Printf ANSI((const char *, ...));
extern int Sprintf ANSI((char *, const char *, ...));
extern int Snprintf ANSI((char *, size_t, const char *, ...));
extern void Perror ANSI((const char *));
extern int Vfprintf ANSI((FILE *, const char *, va_list));
extern int Vsprintf ANSI((char *, const char *, va_list));
extern int Vsnprintf ANSI((char *, size_t, const char *, va_list));
#ifdef PF_BUF
extern FILE *stderr_ASL;
extern void(*pfbuf_print_ASL) ANSI((char *));
extern char *pfbuf_ASL;
extern void fflush_ASL ANSI((FILE *));
#ifdef fflush
#define old_fflush_ASL fflush
#undef fflush
#endif
#define fflush fflush_ASL
#endif
#ifdef __cplusplus
}
#endif
#undef printf
#undef fprintf
#undef sprintf
#undef perror
#undef vfprintf
#undef vsprintf
#define printf Printf
#define fprintf Fprintf
#undef snprintf /* for MacOSX */
#undef vsnprintf /* for MacOSX */
#define snprintf Snprintf
#define sprintf Sprintf
#define perror Perror
#define vfprintf Vfprintf
#define vsnprintf Vsnprintf
#define vsprintf Vsprintf
#endif /* NO_STDIO1 */
#endif /* STDIO1_H_included */

View file

@ -1,67 +0,0 @@
#include "third_party/gdtoa/gdtoa.internal.h"
/* clang-format off */
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
int
#ifdef KR_headers
strtoIQ(s, sp, a, b) CONST char *s; char **sp; void *a; void *b;
#else
strtoIQ(CONST char *s, char **sp, void *a, void *b)
#endif
{
static const FPI fpi = { 113, 1-16383-113+1, 32766-16383-113+1, 1, SI, 0 /*unused*/ };
Long exp[2];
Bigint *B[2];
int k, rv[2];
ULong *L = (ULong *)a, *M = (ULong *)b;
#ifdef MULTIPLE_THREADS
ThInfo *TI = 0;
#endif
B[0] = Balloc(2 MTb);
B[0]->wds = 4;
k = strtoIg(s, sp, &fpi, exp, B, rv);
ULtoQ(L, B[0]->x, exp[0], rv[0]);
Bfree(B[0] MTb);
if (B[1]) {
ULtoQ(M, B[1]->x, exp[1], rv[1]);
Bfree(B[1] MTb);
}
else {
M[0] = L[0];
M[1] = L[1];
M[2] = L[2];
M[3] = L[3];
}
return k;
}

View file

@ -32,12 +32,8 @@ THIS SOFTWARE.
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
int
#ifdef KR_headers
strtoId(s, sp, f0, f1) CONST char *s; char **sp; double *f0, *f1;
#else
int
strtoId(CONST char *s, char **sp, double *f0, double *f1)
#endif
{
static const FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI, 0 /*unused*/ };
Long exp[2];

View file

@ -32,12 +32,8 @@ THIS SOFTWARE.
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
int
#ifdef KR_headers
strtoIdd(s, sp, f0, f1) CONST char *s; char **sp; double *f0, *f1;
#else
int
strtoIdd(CONST char *s, char **sp, double *f0, double *f1)
#endif
{
#ifdef Sudden_Underflow
static const FPI fpi = { 106, 1-1023, 2046-1023-106+1, 1, 1, 0 /*unused*/ };

View file

@ -32,12 +32,8 @@ THIS SOFTWARE.
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
int
#ifdef KR_headers
strtoIf(s, sp, f0, f1) CONST char *s; char **sp; float *f0, *f1;
#else
int
strtoIf(CONST char *s, char **sp, float *f0, float *f1)
#endif
{
static const FPI fpi = { 24, 1-127-24+1, 254-127-24+1, 1, SI, 0 /*unused*/ };
Long exp[2];

View file

@ -32,12 +32,8 @@ THIS SOFTWARE.
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
int
#ifdef KR_headers
strtoIg(s00, se, fpi, exp, B, rvp) CONST char *s00; char **se; CONST FPI *fpi; Long *exp; Bigint **B; int *rvp;
#else
int
strtoIg(CONST char *s00, char **se, CONST FPI *fpi, Long *exp, Bigint **B, int *rvp)
#endif
{
Bigint *b, *b1;
int i, nb, nw, nw1, rv, rv1, swap;

View file

@ -32,12 +32,8 @@ THIS SOFTWARE.
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
int
#ifdef KR_headers
strtoIx(s, sp, a, b) CONST char *s; char **sp; void *a; void *b;
#else
int
strtoIx(CONST char *s, char **sp, void *a, void *b)
#endif
{
static const FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI, 0 /*unused*/ };
Long exp[2];

View file

@ -1,66 +0,0 @@
#include "third_party/gdtoa/gdtoa.internal.h"
/* clang-format off */
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
int
#ifdef KR_headers
strtoIxL(s, sp, a, b) CONST char *s; char **sp; void *a; void *b;
#else
strtoIxL(CONST char *s, char **sp, void *a, void *b)
#endif
{
static const FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI, 0 /*unused*/ };
Long exp[2];
Bigint *B[2];
int k, rv[2];
ULong *L = (ULong *)a, *M = (ULong *)b;
#ifdef MULTIPLE_THREADS
ThInfo *TI = 0;
#endif
B[0] = Balloc(1 MTb);
B[0]->wds = 2;
k = strtoIg(s, sp, &fpi, exp, B, rv);
ULtoxL(L, B[0]->x, exp[0], rv[0]);
Bfree(B[0] MTb);
if (B[1]) {
ULtoxL(M, B[1]->x, exp[1], rv[1]);
Bfree(B[1] MTb);
}
else {
M[0] = L[0];
M[1] = L[1];
M[2] = L[2];
}
return k;
}

View file

@ -50,13 +50,8 @@ static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128,
#endif
#ifdef Avoid_Underflow /*{*/
static double
sulp
#ifdef KR_headers
(x, scale) U *x; int scale;
#else
(U *x, int scale)
#endif
static double
sulp(U *x, int scale)
{
U u;
double rv;
@ -71,13 +66,8 @@ sulp
}
#endif /*}*/
double
strtod
#ifdef KR_headers
(s00, se) CONST char *s00; char **se;
#else
(CONST char *s00, char **se)
#endif
double
strtod(CONST char *s00, char **se)
{
#ifdef Avoid_Underflow
int scale;

View file

@ -32,12 +32,8 @@ THIS SOFTWARE.
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
static double
#ifdef KR_headers
ulpdown(d) U *d;
#else
static double
ulpdown(U *d)
#endif
{
double u;
ULong *L = d->L;
@ -49,12 +45,8 @@ ulpdown(U *d)
return u;
}
int
#ifdef KR_headers
strtodI(s, sp, dd) CONST char *s; char **sp; double *dd;
#else
int
strtodI(CONST char *s, char **sp, double *dd)
#endif
{
static const FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI, 0 /*unused*/ };
ULong bits[2], sign;

View file

@ -42,12 +42,8 @@ fivesbits[] = { 0, 3, 5, 7, 10, 12, 14, 17, 19, 21,
#endif
};
Bigint *
#ifdef KR_headers
increment(b MTa) Bigint *b; MTk
#else
Bigint *
increment(Bigint *b MTd)
#endif
{
ULong *x, *xe;
Bigint *b1;
@ -87,12 +83,8 @@ increment(Bigint *b MTd)
return b;
}
void
#ifdef KR_headers
decrement(b) Bigint *b;
#else
void
decrement(Bigint *b)
#endif
{
ULong *x, *xe;
#ifdef Pack_16
@ -119,12 +111,8 @@ decrement(Bigint *b)
#endif
}
static int
#ifdef KR_headers
all_on(b, n) Bigint *b; int n;
#else
static int
all_on(Bigint *b, int n)
#endif
{
ULong *x, *xe;
@ -138,12 +126,8 @@ all_on(Bigint *b, int n)
return 1;
}
Bigint *
#ifdef KR_headers
set_ones(b, n MTa) Bigint *b; int n; MTk
#else
Bigint *
set_ones(Bigint *b, int n MTd)
#endif
{
int k;
ULong *x, *xe;
@ -166,14 +150,8 @@ set_ones(Bigint *b, int n MTd)
return b;
}
static int
rvOK
#ifdef KR_headers
(d, fpi, exp, bits, exact, rd, irv MTa)
U *d; CONST FPI *fpi; Long *exp; ULong *bits; int exact, rd, *irv; MTk
#else
(U *d, CONST FPI *fpi, Long *exp, ULong *bits, int exact, int rd, int *irv MTd)
#endif
static int
rvOK(U *d, CONST FPI *fpi, Long *exp, ULong *bits, int exact, int rd, int *irv MTd)
{
Bigint *b;
ULong carry, inex, lostbits;
@ -287,12 +265,8 @@ rvOK
return rv;
}
static int
#ifdef KR_headers
mantbits(d) U *d;
#else
static int
mantbits(U *d)
#endif
{
ULong L;
#ifdef VAX
@ -310,14 +284,8 @@ mantbits(U *d)
return P - 32 - lo0bits(&L);
}
int
strtodg
#ifdef KR_headers
(s00, se, fpi, exp, bits)
CONST char *s00; char **se; CONST FPI *fpi; Long *exp; ULong *bits;
#else
(CONST char *s00, char **se, CONST FPI *fpi, Long *exp, ULong *bits)
#endif
int
strtodg(CONST char *s00, char **se, CONST FPI *fpi, Long *exp, ULong *bits)
{
int abe, abits, asub;
int bb0, bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, decpt, denorm;

View file

@ -38,12 +38,8 @@ THIS SOFTWARE.
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
double
#ifdef KR_headers
strtod(s, sp) CONST char *s; char **sp;
#else
double
strtod(CONST char *s, char **sp)
#endif
{
static const FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI, 0 /*unused*/ };
ULong bits[2];

View file

@ -32,12 +32,8 @@ THIS SOFTWARE.
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
float
#ifdef KR_headers
strtof(s, sp) CONST char *s; char **sp;
#else
float
strtof(CONST char *s, char **sp)
#endif
{
static FPI fpi0 = { 24, 1-127-24+1, 254-127-24+1, 1, SI, 0 /*unused*/ };
ULong bits[1];

View file

@ -1,110 +0,0 @@
#include "third_party/gdtoa/gdtoa.internal.h"
/* clang-format off */
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998, 2000 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
#undef _0
#undef _1
/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */
#ifdef IEEE_MC68k
#define _0 0
#define _1 1
#define _2 2
#define _3 3
#endif
#ifdef IEEE_8087
#define _0 3
#define _1 2
#define _2 1
#define _3 0
#endif
extern ULong NanDflt_Q_D2A[4];
int
#ifdef KR_headers
strtopQ(s, sp, V) CONST char *s; char **sp; void *V;
#else
strtopQ(CONST char *s, char **sp, void *V)
#endif
{
static const FPI fpi0 = { 113, 1-16383-113+1, 32766 - 16383 - 113 + 1, 1, SI, 0 /*unused*/ };
ULong bits[4];
Long exp;
int k;
ULong *L = (ULong*)V;
#ifdef Honor_FLT_ROUNDS
#include "third_party/gdtoa/gdtoa_fltrnds.inc"
#else
#define fpi &fpi0
#endif
k = strtodg(s, sp, fpi, &exp, bits);
switch(k & STRTOG_Retmask) {
case STRTOG_NoNumber:
case STRTOG_Zero:
L[0] = L[1] = L[2] = L[3] = 0;
break;
case STRTOG_Normal:
case STRTOG_NaNbits:
L[_3] = bits[0];
L[_2] = bits[1];
L[_1] = bits[2];
L[_0] = (bits[3] & ~0x10000) | ((exp + 0x3fff + 112) << 16);
break;
case STRTOG_Denormal:
L[_3] = bits[0];
L[_2] = bits[1];
L[_1] = bits[2];
L[_0] = bits[3];
break;
case STRTOG_Infinite:
L[_0] = 0x7fff0000;
L[_1] = L[_2] = L[_3] = 0;
break;
case STRTOG_NaN:
L[_0] = NanDflt_Q_D2A[3];
L[_1] = NanDflt_Q_D2A[2];
L[_2] = NanDflt_Q_D2A[1];
L[_3] = NanDflt_Q_D2A[0];
}
if (k & STRTOG_Neg)
L[_0] |= 0x80000000L;
return k;
}

View file

@ -32,12 +32,8 @@ THIS SOFTWARE.
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
int
#ifdef KR_headers
strtopd(s, sp, d) char *s; char **sp; double *d;
#else
int
strtopd(CONST char *s, char **sp, double *d)
#endif
{
static const FPI fpi0 = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI, 0 /*unused*/ };
ULong bits[2];

View file

@ -32,12 +32,8 @@ THIS SOFTWARE.
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
int
#ifdef KR_headers
strtopdd(s, sp, dd) CONST char *s; char **sp; double *dd;
#else
int
strtopdd(CONST char *s, char **sp, double *dd)
#endif
{
#ifdef Sudden_Underflow
static const FPI fpi0 = { 106, 1-1023, 2046-1023-106+1, 1, 1, 0 /*unused*/ };

View file

@ -32,12 +32,8 @@ THIS SOFTWARE.
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
int
#ifdef KR_headers
strtopf(s, sp, f) CONST char *s; char **sp; float *f;
#else
int
strtopf(CONST char *s, char **sp, float *f)
#endif
{
static const FPI fpi0 = { 24, 1-127-24+1, 254-127-24+1, 1, SI, 0 /*unused*/ };
ULong bits[1], *L;

View file

@ -32,7 +32,7 @@ THIS SOFTWARE.
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
extern UShort NanDflt_ldus_D2A[5];
extern UShort __gdtoa_NanDflt_ldus[5];
#undef _0
#undef _1
@ -54,12 +54,8 @@ THIS SOFTWARE.
#define _4 0
#endif
int
#ifdef KR_headers
strtopx(s, sp, V) CONST char *s; char **sp; void *V;
#else
int
strtopx(CONST char *s, char **sp, void *V)
#endif
{
const static FPI fpi0 = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI, 0 /*unused*/ };
ULong bits[2];
@ -100,11 +96,11 @@ strtopx(CONST char *s, char **sp, void *V)
break;
case STRTOG_NaN:
L[_4] = NanDflt_ldus_D2A[0];
L[_3] = NanDflt_ldus_D2A[1];
L[_2] = NanDflt_ldus_D2A[2];
L[_1] = NanDflt_ldus_D2A[3];
L[_0] = NanDflt_ldus_D2A[4];
L[_4] = __gdtoa_NanDflt_ldus[0];
L[_3] = __gdtoa_NanDflt_ldus[1];
L[_2] = __gdtoa_NanDflt_ldus[2];
L[_1] = __gdtoa_NanDflt_ldus[3];
L[_0] = __gdtoa_NanDflt_ldus[4];
}
if (k & STRTOG_Neg)
L[_0] |= 0x8000;

View file

@ -1,100 +0,0 @@
#include "third_party/gdtoa/gdtoa.internal.h"
/* clang-format off */
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998, 2000 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
extern ULong NanDflt_xL_D2A[3];
#undef _0
#undef _1
/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */
#ifdef IEEE_MC68k
#define _0 0
#define _1 1
#define _2 2
#endif
#ifdef IEEE_8087
#define _0 2
#define _1 1
#define _2 0
#endif
int
#ifdef KR_headers
strtopxL(s, sp, V) CONST char *s; char **sp; void *V;
#else
strtopxL(CONST char *s, char **sp, void *V)
#endif
{
static const FPI fpi0 = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI, 0 /*unused*/ };
ULong bits[2];
Long exp;
int k;
ULong *L = (ULong*)V;
#ifdef Honor_FLT_ROUNDS
#include "third_party/gdtoa/gdtoa_fltrnds.inc"
#else
#define fpi &fpi0
#endif
k = strtodg(s, sp, fpi, &exp, bits);
switch(k & STRTOG_Retmask) {
case STRTOG_NoNumber:
case STRTOG_Zero:
L[0] = L[1] = L[2] = 0;
break;
case STRTOG_Normal:
case STRTOG_Denormal:
case STRTOG_NaNbits:
L[_2] = bits[0];
L[_1] = bits[1];
L[_0] = (exp + 0x3fff + 63) << 16;
break;
case STRTOG_Infinite:
L[_0] = 0x7fff << 16;
L[_1] = 0x80000000;
L[_2] = 0;
break;
case STRTOG_NaN:
L[_0] = NanDflt_xL_D2A[2];
L[_1] = NanDflt_xL_D2A[1];
L[_2] = NanDflt_xL_D2A[0];
}
if (k & STRTOG_Neg)
L[_0] |= 0x80000000L;
return k;
}

View file

@ -1,120 +0,0 @@
#include "third_party/gdtoa/gdtoa.internal.h"
/* clang-format off */
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998, 2000 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
#undef _0
#undef _1
/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */
#ifdef IEEE_MC68k
#define _0 0
#define _1 1
#define _2 2
#define _3 3
#endif
#ifdef IEEE_8087
#define _0 3
#define _1 2
#define _2 1
#define _3 0
#endif
extern ULong NanDflt_Q_D2A[4];
void
#ifdef KR_headers
ULtoQ(L, bits, exp, k) ULong *L; ULong *bits; Long exp; int k;
#else
ULtoQ(ULong *L, ULong *bits, Long exp, int k)
#endif
{
switch(k & STRTOG_Retmask) {
case STRTOG_NoNumber:
case STRTOG_Zero:
L[0] = L[1] = L[2] = L[3] = 0;
break;
case STRTOG_Normal:
case STRTOG_NaNbits:
L[_3] = bits[0];
L[_2] = bits[1];
L[_1] = bits[2];
L[_0] = (bits[3] & ~0x10000) | ((exp + 0x3fff + 112) << 16);
break;
case STRTOG_Denormal:
L[_3] = bits[0];
L[_2] = bits[1];
L[_1] = bits[2];
L[_0] = bits[3];
break;
case STRTOG_Infinite:
L[_0] = 0x7fff0000;
L[_1] = L[_2] = L[_3] = 0;
break;
case STRTOG_NaN:
L[_0] = NanDflt_Q_D2A[3];
L[_1] = NanDflt_Q_D2A[2];
L[_2] = NanDflt_Q_D2A[1];
L[_3] = NanDflt_Q_D2A[0];
}
if (k & STRTOG_Neg)
L[_0] |= 0x80000000L;
}
int
#ifdef KR_headers
strtorQ(s, sp, rounding, L) CONST char *s; char **sp; int rounding; void *L;
#else
strtorQ(CONST char *s, char **sp, int rounding, void *L)
#endif
{
static const FPI fpi0 = { 113, 1-16383-113+1, 32766-16383-113+1, 1, SI, 0 /*unused*/ };
FPI *fpi, fpi1;
ULong bits[4];
Long exp;
int k;
fpi = &fpi0;
if (rounding != FPI_Round_near) {
fpi1 = fpi0;
fpi1.rounding = rounding;
fpi = &fpi1;
}
k = strtodg(s, sp, fpi, &exp, bits);
ULtoQ((ULong*)L, bits, exp, k);
return k;
}

View file

@ -32,14 +32,10 @@ THIS SOFTWARE.
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
extern ULong NanDflt_d_D2A[2];
extern ULong __gdtoa_NanDflt_d[2];
void
#ifdef KR_headers
ULtod(L, bits, exp, k) ULong *L; ULong *bits; Long exp; int k;
#else
void
ULtod(ULong *L, ULong *bits, Long exp, int k)
#endif
{
switch(k & STRTOG_Retmask) {
case STRTOG_NoNumber:
@ -64,19 +60,15 @@ ULtod(ULong *L, ULong *bits, Long exp, int k)
break;
case STRTOG_NaN:
L[_0] = NanDflt_d_D2A[1];
L[_1] = NanDflt_d_D2A[0];
L[_0] = __gdtoa_NanDflt_d[1];
L[_1] = __gdtoa_NanDflt_d[0];
}
if (k & STRTOG_Neg)
L[_0] |= 0x80000000L;
}
int
#ifdef KR_headers
strtord(s, sp, rounding, d) CONST char *s; char **sp; int rounding; double *d;
#else
int
strtord(CONST char *s, char **sp, int rounding, double *d)
#endif
{
static const FPI fpi0 = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI, 0 /*unused*/ };
FPI *fpi, fpi1;

View file

@ -32,14 +32,10 @@ THIS SOFTWARE.
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
extern ULong NanDflt_d_D2A[2];
extern ULong __gdtoa_NanDflt_d[2];
void
#ifdef KR_headers
ULtodd(L, bits, exp, k) ULong *L; ULong *bits; Long exp; int k;
#else
void
ULtodd(ULong *L, ULong *bits, Long exp, int k)
#endif
{
int i, j;
@ -156,8 +152,8 @@ ULtodd(ULong *L, ULong *bits, Long exp, int k)
break;
case STRTOG_NaN:
L[_0] = L[_0+2] = NanDflt_d_D2A[1];
L[_1] = L[_1+2] = NanDflt_d_D2A[0];
L[_0] = L[_0+2] = __gdtoa_NanDflt_d[1];
L[_1] = L[_1+2] = __gdtoa_NanDflt_d[0];
break;
case STRTOG_NaNbits:
@ -174,12 +170,8 @@ ULtodd(ULong *L, ULong *bits, Long exp, int k)
}
}
int
#ifdef KR_headers
strtordd(s, sp, rounding, dd) CONST char *s; char **sp; int rounding; double *dd;
#else
int
strtordd(CONST char *s, char **sp, int rounding, double *dd)
#endif
{
#ifdef Sudden_Underflow
static const FPI fpi0 = { 106, 1-1023, 2046-1023-106+1, 1, 1, 0 /*unused*/ };

View file

@ -32,14 +32,10 @@ THIS SOFTWARE.
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
extern ULong NanDflt_f_D2A[1];
extern ULong __gdtoa_NanDflt_f[1];
void
#ifdef KR_headers
ULtof(L, bits, exp, k) ULong *L; ULong *bits; Long exp; int k;
#else
void
ULtof(ULong *L, ULong *bits, Long exp, int k)
#endif
{
switch(k & STRTOG_Retmask) {
case STRTOG_NoNumber:
@ -61,18 +57,14 @@ ULtof(ULong *L, ULong *bits, Long exp, int k)
break;
case STRTOG_NaN:
L[0] = NanDflt_f_D2A[0];
L[0] = __gdtoa_NanDflt_f[0];
}
if (k & STRTOG_Neg)
L[0] |= 0x80000000L;
}
int
#ifdef KR_headers
strtorf(s, sp, rounding, f) CONST char *s; char **sp; int rounding; float *f;
#else
int
strtorf(CONST char *s, char **sp, int rounding, float *f)
#endif
{
static const FPI fpi0 = { 24, 1-127-24+1, 254-127-24+1, 1, SI, 0 /*unused*/ };
FPI *fpi, fpi1;

View file

@ -52,14 +52,10 @@ THIS SOFTWARE.
#define _4 0
#endif
extern UShort NanDflt_ldus_D2A[5];
extern UShort __gdtoa_NanDflt_ldus[5];
void
#ifdef KR_headers
ULtox(L, bits, exp, k) UShort *L; ULong *bits; Long exp; int k;
#else
void
ULtox(UShort *L, ULong *bits, Long exp, int k)
#endif
{
switch(k & STRTOG_Retmask) {
case STRTOG_NoNumber:
@ -88,22 +84,18 @@ ULtox(UShort *L, ULong *bits, Long exp, int k)
break;
case STRTOG_NaN:
L[_4] = NanDflt_ldus_D2A[0];
L[_3] = NanDflt_ldus_D2A[1];
L[_2] = NanDflt_ldus_D2A[2];
L[_1] = NanDflt_ldus_D2A[3];
L[_0] = NanDflt_ldus_D2A[4];
L[_4] = __gdtoa_NanDflt_ldus[0];
L[_3] = __gdtoa_NanDflt_ldus[1];
L[_2] = __gdtoa_NanDflt_ldus[2];
L[_1] = __gdtoa_NanDflt_ldus[3];
L[_0] = __gdtoa_NanDflt_ldus[4];
}
if (k & STRTOG_Neg)
L[_0] |= 0x8000;
}
int
#ifdef KR_headers
strtorx(s, sp, rounding, L) CONST char *s; char **sp; int rounding; void *L;
#else
int
strtorx(CONST char *s, char **sp, int rounding, void *L)
#endif
{
static const FPI fpi0 = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI, 0 /*unused*/ };
FPI *fpi, fpi1;

View file

@ -1,111 +0,0 @@
#include "third_party/gdtoa/gdtoa.internal.h"
/* clang-format off */
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998, 2000 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
#undef _0
#undef _1
/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */
#ifdef IEEE_MC68k
#define _0 0
#define _1 1
#define _2 2
#endif
#ifdef IEEE_8087
#define _0 2
#define _1 1
#define _2 0
#endif
extern ULong NanDflt_xL_D2A[3];
void
#ifdef KR_headers
ULtoxL(L, bits, exp, k) ULong *L; ULong *bits; Long exp; int k;
#else
ULtoxL(ULong *L, ULong *bits, Long exp, int k)
#endif
{
switch(k & STRTOG_Retmask) {
case STRTOG_NoNumber:
case STRTOG_Zero:
L[0] = L[1] = L[2] = 0;
break;
case STRTOG_Normal:
case STRTOG_Denormal:
case STRTOG_NaNbits:
L[_0] = (exp + 0x3fff + 63) << 16;
L[_1] = bits[1];
L[_2] = bits[0];
break;
case STRTOG_Infinite:
L[_0] = 0x7fff0000;
L[_1] = 0x80000000;
L[_2] = 0;
break;
case STRTOG_NaN:
L[_0] = NanDflt_xL_D2A[2];
L[_1] = NanDflt_xL_D2A[1];
L[_2] = NanDflt_xL_D2A[0];
}
if (k & STRTOG_Neg)
L[_0] |= 0x80000000L;
}
int
#ifdef KR_headers
strtorxL(s, sp, rounding, L) CONST char *s; char **sp; int rounding; void *L;
#else
strtorxL(CONST char *s, char **sp, int rounding, void *L)
#endif
{
static const FPI fpi0 = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI, 0 /*unused*/ };
FPI *fpi, fpi1;
ULong bits[2];
Long exp;
int k;
fpi = &fpi0;
if (rounding != FPI_Round_near) {
fpi1 = fpi0;
fpi1.rounding = rounding;
fpi = &fpi1;
}
k = strtodg(s, sp, fpi, &exp, bits);
ULtoxL((ULong*)L, bits, exp, k);
return k;
}

View file

@ -32,12 +32,8 @@ THIS SOFTWARE.
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
Bigint *
#ifdef KR_headers
sum(a, b MTa) Bigint *a; Bigint *b; MTk
#else
Bigint *
sum(Bigint *a, Bigint *b MTd)
#endif
{
Bigint *c;
ULong carry, *xc, *xa, *xb, *xe, y;

View file

@ -32,13 +32,8 @@ THIS SOFTWARE.
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
double
ulp
#ifdef KR_headers
(x) U *x;
#else
(U *x)
#endif
double
ulp(U *x)
{
Long L;
U a;

View file

@ -3,7 +3,6 @@ getopt (BSD-3)\\n\
Copyright 1987, 1993, 1994 The Regents of the University of California\"");
asm(".include \"libc/disclaimer.inc\"");
/* clang-format off */
/* $NetBSD: getopt.c,v 1.26 2003/08/07 16:43:40 agc Exp $ */
/*
@ -36,105 +35,122 @@ asm(".include \"libc/disclaimer.inc\"");
*
* @(#)getopt.c 8.3 (Berkeley) 4/27/95
* $FreeBSD: src/lib/libc/stdlib/getopt.c,v 1.8 2007/01/09 00:28:10 imp Exp $
* $DragonFly: src/lib/libc/stdlib/getopt.c,v 1.7 2005/11/20 12:37:48 swildner Exp $
* $DragonFly: src/lib/libc/stdlib/getopt.c,v 1.7 2005/11/20 12:37:48 swildner
*Exp $
*/
#include "libc/str/str.h"
#include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
STATIC_YOINK("_init_getopt");
#define BADCH (int)'?'
#define BADARG (int)':'
#define BADCH (int)'?'
#define BADARG (int)':'
int opterr, /* if error message should be printed */
optind, /* index into parent argv vector */
optopt, /* character checked for validity */
optreset; /* reset getopt */
char *optarg; /* argument associated with option */
char *getopt_place; /* option letter processing */
char kGetoptEmsg[1];
/*
* getopt --
* Parse argc/argv argument vector.
/**
* If error message should be printed.
*/
int
getopt(int nargc, char * const nargv[], const char *ostr)
{
char *oli; /* option letter list index */
int opterr;
/*
* Some programs like cvs expect optind = 0 to trigger
* a reset of getopt.
*/
if (optind == 0)
optind = 1;
/**
* Index into parent argv vector.
*/
int optind;
if (optreset || *getopt_place == 0) { /* update scanning pointer */
optreset = 0;
getopt_place = nargv[optind];
if (optind >= nargc || *getopt_place++ != '-') {
/* Argument is absent or is not an option */
getopt_place = kGetoptEmsg;
return (-1);
}
optopt = *getopt_place++;
if (optopt == '-' && *getopt_place == 0) {
/* "--" => end of options */
++optind;
getopt_place = kGetoptEmsg;
return (-1);
}
if (optopt == 0) {
/* Solitary '-', treat as a '-' option
if the program (eg su) is looking for it. */
getopt_place = kGetoptEmsg;
if (strchr(ostr, '-') == NULL)
return (-1);
optopt = '-';
}
} else
optopt = *getopt_place++;
/**
* Character checked for validity.
*/
int optopt;
/* See if option letter is one the caller wanted... */
if (optopt == ':' || (oli = strchr(ostr, optopt)) == NULL) {
if (*getopt_place == 0)
++optind;
if (opterr && *ostr != ':')
fprintf(stderr,
"%s: illegal option -- %c\n", program_invocation_name,
optopt);
return (BADCH);
}
/**
* Reset getopt.
*/
int optreset;
/* Does this option need an argument? */
if (oli[1] != ':') {
/* don't need argument */
optarg = NULL;
if (*getopt_place == 0)
++optind;
} else {
/* Option-argument is either the rest of this argument or the
entire next argument. */
if (*getopt_place)
optarg = getopt_place;
else if (nargc > ++optind)
optarg = nargv[optind];
else {
/* option-argument absent */
getopt_place = kGetoptEmsg;
if (*ostr == ':')
return (BADARG);
if (opterr)
fprintf(stderr,
"%s: option requires an argument -- %c\n",
program_invocation_name, optopt);
return (BADCH);
}
getopt_place = kGetoptEmsg;
++optind;
}
return (optopt); /* return option letter */
/**
* Argument associated with option.
*/
char *optarg;
/**
* Option letter processing.
*/
char *getopt_place;
char kGetoptEmsg[1] hidden;
/**
* Parses argc/argv argument vector.
*/
int getopt(int nargc, char *const nargv[], const char *ostr) {
char *oli; /* option letter list index */
/*
* Some programs like cvs expect optind = 0 to trigger
* a reset of getopt.
*/
if (optind == 0) optind = 1;
if (optreset || *getopt_place == 0) { /* update scanning pointer */
optreset = 0;
getopt_place = nargv[optind];
if (optind >= nargc || *getopt_place++ != '-') {
/* Argument is absent or is not an option */
getopt_place = kGetoptEmsg;
return -1;
}
optopt = *getopt_place++;
if (optopt == '-' && *getopt_place == 0) {
/* "--" => end of options */
++optind;
getopt_place = kGetoptEmsg;
return -1;
}
if (optopt == 0) {
/* Solitary '-', treat as a '-' option
if the program (eg su) is looking for it. */
getopt_place = kGetoptEmsg;
if (strchr(ostr, '-') == NULL) return -1;
optopt = '-';
}
} else {
optopt = *getopt_place++;
}
/* See if option letter is one the caller wanted... */
if (optopt == ':' || (oli = strchr(ostr, optopt)) == NULL) {
if (*getopt_place == 0) ++optind;
if (opterr && *ostr != ':') {
fprintf(stderr, "%s: illegal option -- %c\n", program_invocation_name,
optopt);
}
return (BADCH);
}
/* Does this option need an argument? */
if (oli[1] != ':') {
/* don't need argument */
optarg = NULL;
if (*getopt_place == 0) ++optind;
} else {
/* Option-argument is either the rest of this argument or the
entire next argument. */
if (*getopt_place) {
optarg = getopt_place;
} else if (nargc > ++optind) {
optarg = nargv[optind];
} else {
/* option-argument absent */
getopt_place = kGetoptEmsg;
if (*ostr == ':') return (BADARG);
if (opterr)
fprintf(stderr, "%s: option requires an argument -- %c\n",
program_invocation_name, optopt);
return (BADCH);
}
getopt_place = kGetoptEmsg;
++optind;
}
return (optopt); /* return option letter */
}

View file

@ -17,7 +17,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/bits/safemacros.internal.h"
#include "libc/bits/safemacros.h"
#include "libc/fmt/fmt.h"
#include "libc/str/str.h"
#include "third_party/regex/regex.h"

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