diff --git a/.github/workflows/checkCI.yml b/.github/workflows/checkCI.yml index 6d3f838..95795f5 100644 --- a/.github/workflows/checkCI.yml +++ b/.github/workflows/checkCI.yml @@ -10,8 +10,35 @@ defaults: shell: bash jobs: + build: + name: build_linux64 + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 5 + - name: Build with gcc + run: | + docker run --rm -v ${{ github.workspace }}:/workspace -w /workspace ubuntu:16.04 bash -c " + apt-get update && + apt-get install -y software-properties-common build-essential && + add-apt-repository -y ppa:ubuntu-toolchain-r/test && + apt-get update && + apt-get install -y gcc-4.8 g++-4.8 && + update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 10 && + update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.8 10 && + pushd ExternData/Resources/C-Sources && + make CFLAGS="-O3 -DNDEBUG -fPIC" CXXFLAGS="-O3 -DNDEBUG -fPIC" TARGETDIR=linux64 + " + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: ExternData_linux64 + path: ExternData/Resources/Library/linux64/*.a + test: - name: build_cmake_${{ matrix.toolchain }} + name: test_cmake_${{ matrix.toolchain }} runs-on: ${{ matrix.os }} timeout-minutes: 10 strategy: @@ -49,7 +76,7 @@ jobs: fi env: SRCDIR: ${{ github.workspace }}/ExternData/Resources - - name: Build with ${{ matrix.compiler }} + - name: Build tests with ${{ matrix.compiler }} run: | if [ "${{ matrix.compiler }}" == "msvc" ]; then cmake --build build --config ${{ matrix.configuration }} diff --git a/ExternData/Resources/C-Sources/Makefile b/ExternData/Resources/C-Sources/Makefile index 5a0f1df..e10dfa4 100644 --- a/ExternData/Resources/C-Sources/Makefile +++ b/ExternData/Resources/C-Sources/Makefile @@ -2,7 +2,7 @@ AR = ar -ru RM = rm -f CFLAGS = -O3 -CPPFLAGS = -DHAVE_UNISTD_H=1 -DHAVE_STDARG_H=1 -DHAVE_HIDDEN=1 -DHAVE_MEMCPY=1 -DHAVE_MEMMOVE=1 -DHAVE_ZLIB=1 -DHAVE_HDF5=1 -DNDEBUG -DXML_POOR_ENTROPY -DHAVE_EXPAT_CONFIG_H -DLIBXML_STATIC +CPPFLAGS = -DHAVE_UNISTD_H=1 -DHAVE_STDARG_H=1 -DHAVE_STDINT_H=1 -DHAVE_HIDDEN=1 -DHAVE_MEMCPY=1 -DHAVE_MEMMOVE=1 -DHAVE_ZLIB=1 -DHAVE_HDF5=1 -DNDEBUG -DXML_POOR_ENTROPY -DHAVE_EXPAT_CONFIG_H -DLIBXML_STATIC INC = -I"bsxml-json" -I"expat/lib" -I"hdf5/include" -I"inih" -I"libxls/include" -I"minizip" -I"modelica" -I"zlib" -I"parson" -I"libxml2/include" TARGETDIR = linux64 @@ -29,6 +29,52 @@ INI_OBJS = \ JSON_OBJS = \ ED_JSONFile.o +LIBXML2_OBJS = \ + libxml2/buf.o \ + libxml2/c14n.o \ + libxml2/catalog.o \ + libxml2/chvalid.o \ + libxml2/debugXML.o \ + libxml2/dict.o \ + libxml2/encoding.o \ + libxml2/entities.o \ + libxml2/error.o \ + libxml2/globals.o \ + libxml2/hash.o \ + libxml2/HTMLparser.o \ + libxml2/HTMLtree.o \ + libxml2/legacy.o \ + libxml2/list.o \ + libxml2/nanoftp.o \ + libxml2/nanohttp.o \ + libxml2/parser.o \ + libxml2/parserInternals.o \ + libxml2/pattern.o \ + libxml2/relaxng.o \ + libxml2/SAX.o \ + libxml2/SAX2.o \ + libxml2/schematron.o \ + libxml2/threads.o \ + libxml2/tree.o \ + libxml2/uri.o \ + libxml2/valid.o \ + libxml2/xinclude.o \ + libxml2/xlink.o \ + libxml2/xmlIO.o \ + libxml2/xmlmemory.o \ + libxml2/xmlmodule.o \ + libxml2/xmlreader.o \ + libxml2/xmlregexp.o \ + libxml2/xmlsave.o \ + libxml2/xmlschemas.o \ + libxml2/xmlschemastypes.o \ + libxml2/xmlstring.o \ + libxml2/xmlunicode.o \ + libxml2/xmlwriter.o \ + libxml2/xpath.o \ + libxml2/xpointer.o \ + libxml2/xzlib.o + LIBXLS_OBJS = \ libxls/src/endian.o \ libxls/src/locale.o \ @@ -37,6 +83,9 @@ LIBXLS_OBJS = \ libxls/src/xlstool.o MAT_OBJS = \ + modelica/ModelicaIO.o \ + modelica/ModelicaMatIO.o \ + modelica/snprintf.o \ ED_MATFile.o MINIZIP_OBJS = \ @@ -82,6 +131,7 @@ ALL_OBJS = \ $(INI_OBJS) \ $(JSON_OBJS) \ $(LIBXLS_OBJS) \ + $(LIBXML2_OBJS) \ $(MAT_OBJS) \ $(MINIZIP_OBJS) \ $(PARSON_OBJS) \ @@ -93,7 +143,7 @@ ALL_OBJS = \ all: clean libs -libs: libED_CSVFile.a libED_INIFile.a libED_JSONFile.a libED_MATFile.a libED_XLSFile.a libED_XLSXFile.a libED_XMLFile.a libED_XML2File.a libbsxml-json.a libexpat.a libminizip.a libparson.a libxlsreader.a libzlib.a +libs: libED_CSVFile.a libED_INIFile.a libED_JSONFile.a libED_MATFile.a libED_XLSFile.a libED_XLSXFile.a libED_XMLFile.a libED_XML2File.a libbsxml-json.a libexpat.a libminizip.a libparson.a libxlsreader.a libxml2.a libzlib.a mkdir -p ../Library/$(TARGETDIR) cp $^ ../Library/$(TARGETDIR) @@ -136,6 +186,9 @@ libminizip.a: $(MINIZIP_OBJS) libxlsreader.a: $(LIBXLS_OBJS) $(AR) $@ $(LIBXLS_OBJS) +libxml2.a: $(LIBXML2_OBJS) + $(AR) $@ $(LIBXML2_OBJS) + libzlib.a: $(ZLIB_OBJS) $(AR) $@ $(ZLIB_OBJS) diff --git a/ExternData/Resources/C-Sources/modelica/read_data_impl.h b/ExternData/Resources/C-Sources/modelica/read_data_impl.h new file mode 100644 index 0000000..6de4cdf --- /dev/null +++ b/ExternData/Resources/C-Sources/modelica/read_data_impl.h @@ -0,0 +1,596 @@ +/* + * Copyright (c) 2019-2020, Christopher C. Hulbert + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#define READ_TYPE_DOUBLE_DATA CAT(READ_TYPED_FUNC1, Double) +#define READ_TYPE_SINGLE_DATA CAT(READ_TYPED_FUNC1, Single) +#define READ_TYPE_INT32_DATA CAT(READ_TYPED_FUNC1, Int32) +#define READ_TYPE_UINT32_DATA CAT(READ_TYPED_FUNC1, UInt32) +#define READ_TYPE_INT16_DATA CAT(READ_TYPED_FUNC1, Int16) +#define READ_TYPE_UINT16_DATA CAT(READ_TYPED_FUNC1, UInt16) +#define READ_TYPE_INT8_DATA CAT(READ_TYPED_FUNC1, Int8) +#define READ_TYPE_UINT8_DATA CAT(READ_TYPED_FUNC1, UInt8) +#ifdef HAVE_MATIO_INT64_T +#define READ_TYPE_INT64_DATA CAT(READ_TYPED_FUNC1, Int64) +#endif /* HAVE_MATIO_INT64_T */ +#ifdef HAVE_MATIO_UINT64_T +#define READ_TYPE_UINT64_DATA CAT(READ_TYPED_FUNC1, UInt64) +#endif /* HAVE_MATIO_UINT64_T */ + +static size_t +READ_TYPE_DOUBLE_DATA(mat_t *mat, READ_TYPE *data, size_t len) +{ + size_t readcount; +#if READ_TYPE_TYPE == READ_TYPE_DOUBLE + readcount = fread(data, sizeof(double), len, (FILE*)mat->fp); + if ( readcount == len && mat->byteswap ) { + size_t i; + for ( i = 0; i < len; i++ ) { + (void)Mat_doubleSwap(data + i); + } + } +#else + size_t i; + const size_t data_size = sizeof(double); + double v[READ_BLOCK_SIZE/sizeof(double)]; + READ_DATA(READ_TYPE, Mat_doubleSwap); +#endif + return readcount; +} + +static size_t +READ_TYPE_SINGLE_DATA(mat_t *mat, READ_TYPE *data, size_t len) +{ + size_t readcount; +#if READ_TYPE_TYPE == READ_TYPE_SINGLE + readcount = fread(data, sizeof(float), len, (FILE*)mat->fp); + if ( readcount == len && mat->byteswap ) { + size_t i; + for ( i = 0; i < len; i++ ) { + (void)Mat_floatSwap(data + i); + } + } +#else + size_t i; + const size_t data_size = sizeof(float); + float v[READ_BLOCK_SIZE/sizeof(float)]; + READ_DATA(READ_TYPE, Mat_floatSwap); +#endif + return readcount; +} + +static size_t +READ_TYPE_INT32_DATA(mat_t *mat, READ_TYPE *data, size_t len) +{ + size_t readcount; +#if READ_TYPE_TYPE == READ_TYPE_INT32 + readcount = fread(data, sizeof(mat_int32_t), len, (FILE*)mat->fp); + if ( readcount == len && mat->byteswap ) { + size_t i; + for ( i = 0; i < len; i++ ) { + (void)Mat_int32Swap(data + i); + } + } +#else + size_t i; + const size_t data_size = sizeof(mat_int32_t); + mat_int32_t v[READ_BLOCK_SIZE/sizeof(mat_int32_t)]; + READ_DATA(READ_TYPE, Mat_int32Swap); +#endif + return readcount; +} + +static size_t +READ_TYPE_UINT32_DATA(mat_t *mat, READ_TYPE *data, size_t len) +{ + size_t readcount; +#if READ_TYPE_TYPE == READ_TYPE_UINT32 + readcount = fread(data, sizeof(mat_uint32_t), len, (FILE*)mat->fp); + if ( readcount == len && mat->byteswap ) { + size_t i; + for ( i = 0; i < len; i++ ) { + (void)Mat_uint32Swap(data + i); + } + } +#else + size_t i; + const size_t data_size = sizeof(mat_uint32_t); + mat_uint32_t v[READ_BLOCK_SIZE/sizeof(mat_uint32_t)]; + READ_DATA(READ_TYPE, Mat_uint32Swap); +#endif + return readcount; +} + +static size_t +READ_TYPE_INT16_DATA(mat_t *mat, READ_TYPE *data, size_t len) +{ + size_t readcount; +#if READ_TYPE_TYPE == READ_TYPE_INT16 + readcount = fread(data, sizeof(mat_int16_t), len, (FILE*)mat->fp); + if ( readcount == len && mat->byteswap ) { + size_t i; + for ( i = 0; i < len; i++ ) { + (void)Mat_int16Swap(data + i); + } + } +#else + size_t i; + const size_t data_size = sizeof(mat_int16_t); + mat_int16_t v[READ_BLOCK_SIZE/sizeof(mat_int16_t)]; + READ_DATA(READ_TYPE, Mat_int16Swap); +#endif + return readcount; +} + +static size_t +READ_TYPE_UINT16_DATA(mat_t *mat, READ_TYPE *data, size_t len) +{ + size_t readcount; +#if READ_TYPE_TYPE == READ_TYPE_UINT16 + readcount = fread(data, sizeof(mat_uint16_t), len, (FILE*)mat->fp); + if ( readcount == len && mat->byteswap ) { + size_t i; + for ( i = 0; i < len; i++ ) { + (void)Mat_uint16Swap(data + i); + } + } +#else + size_t i; + const size_t data_size = sizeof(mat_uint16_t); + mat_uint16_t v[READ_BLOCK_SIZE/sizeof(mat_uint16_t)]; + READ_DATA(READ_TYPE, Mat_uint16Swap); +#endif + return readcount; +} + +static size_t +READ_TYPE_INT8_DATA(mat_t *mat, READ_TYPE *data, size_t len) +{ + size_t readcount; +#if READ_TYPE_TYPE == READ_TYPE_INT8 + readcount = fread(data, sizeof(mat_int8_t), len, (FILE*)mat->fp); +#else + size_t i; + const size_t data_size = sizeof(mat_int8_t); + mat_int8_t v[READ_BLOCK_SIZE/sizeof(mat_int8_t)]; + READ_DATA_NOSWAP(READ_TYPE); +#endif + return readcount; +} + +static size_t +READ_TYPE_UINT8_DATA(mat_t *mat, READ_TYPE *data, size_t len) +{ + size_t readcount; +#if READ_TYPE_TYPE == READ_TYPE_UINT8 + readcount = fread(data, sizeof(mat_uint8_t), len, (FILE*)mat->fp); +#else + size_t i; + const size_t data_size = sizeof(mat_uint8_t); + mat_uint8_t v[READ_BLOCK_SIZE/sizeof(mat_uint8_t)]; + READ_DATA_NOSWAP(READ_TYPE); +#endif + return readcount; +} + +#ifdef HAVE_MATIO_INT64_T +static size_t +READ_TYPE_INT64_DATA(mat_t *mat, READ_TYPE *data, size_t len) +{ + size_t readcount; +#if READ_TYPE_TYPE == READ_TYPE_INT64 + readcount = fread(data, sizeof(mat_int64_t), len, (FILE*)mat->fp); + if ( readcount == len && mat->byteswap ) { + size_t i; + for ( i = 0; i < len; i++ ) { + (void)Mat_int64Swap(data + i); + } + } +#else + size_t i; + const size_t data_size = sizeof(mat_int64_t); + mat_int64_t v[READ_BLOCK_SIZE/sizeof(mat_int64_t)]; + READ_DATA(READ_TYPE, Mat_int64Swap); +#endif + return readcount; +} +#endif /* HAVE_MATIO_INT64_T */ + +#ifdef HAVE_MATIO_UINT64_T +static size_t +READ_TYPE_UINT64_DATA(mat_t *mat, READ_TYPE *data, size_t len) +{ + size_t readcount; +#if READ_TYPE_TYPE == READ_TYPE_UINT64 + readcount = fread(data, sizeof(mat_uint64_t), len, (FILE*)mat->fp); + if ( readcount == len && mat->byteswap ) { + size_t i; + for ( i = 0; i < len; i++ ) { + (void)Mat_uint64Swap(data + i); + } + } +#else + size_t i; + const size_t data_size = sizeof(mat_uint64_t); + mat_uint64_t v[READ_BLOCK_SIZE/sizeof(mat_uint64_t)]; + READ_DATA(READ_TYPE, Mat_uint64Swap); +#endif + return readcount; +} +#endif /* HAVE_MATIO_UINT64_T */ + + +/** @brief Reads data of type @c data_type into a READ_TYPE type + * + * Reads from the MAT file @c len elements of data type @c data_type storing + * them as READ_TYPE's in @c data. + * @ingroup mat_internal + * @param mat MAT file pointer + * @param data Pointer to store the output values (len*sizeof(READ_TYPE)) + * @param data_type one of the @c matio_types enumerations which is the source + * data type in the file + * @param len Number of elements of type @c data_type to read from the file + * @retval Number of elements read from the file + */ +static size_t +READ_TYPED_FUNC1(mat_t *mat, READ_TYPE *data, enum matio_types data_type, size_t len) +{ + size_t readcount; + + if ( mat == NULL || data == NULL || mat->fp == NULL ) + return 0; + + switch ( data_type ) { + case MAT_T_DOUBLE: + readcount = READ_TYPE_DOUBLE_DATA(mat, data, len); + break; + case MAT_T_SINGLE: + readcount = READ_TYPE_SINGLE_DATA(mat, data, len); + break; +#ifdef HAVE_MATIO_INT64_T + case MAT_T_INT64: + readcount = READ_TYPE_INT64_DATA(mat, data, len); + break; +#endif /* HAVE_MATIO_UINT64_T */ +#ifdef HAVE_MATIO_UINT64_T + case MAT_T_UINT64: + readcount = READ_TYPE_UINT64_DATA(mat, data, len); + break; +#endif /* HAVE_MATIO_UINT64_T */ + case MAT_T_INT32: + readcount = READ_TYPE_INT32_DATA(mat, data, len); + break; + case MAT_T_UINT32: + readcount = READ_TYPE_UINT32_DATA(mat, data, len); + break; + case MAT_T_INT16: + readcount = READ_TYPE_INT16_DATA(mat, data, len); + break; + case MAT_T_UINT16: + readcount = READ_TYPE_UINT16_DATA(mat, data, len); + break; + case MAT_T_INT8: + readcount = READ_TYPE_INT8_DATA(mat, data, len); + break; + case MAT_T_UINT8: + readcount = READ_TYPE_UINT8_DATA(mat, data, len); + break; + default: + readcount = 0; + break; + } + return readcount; +} + +#undef READ_TYPE_DOUBLE_DATA +#undef READ_TYPE_SINGLE_DATA +#undef READ_TYPE_INT32_DATA +#undef READ_TYPE_UINT32_DATA +#undef READ_TYPE_INT16_DATA +#undef READ_TYPE_UINT16_DATA +#undef READ_TYPE_INT8_DATA +#undef READ_TYPE_UINT8_DATA +#ifdef HAVE_MATIO_INT64_T +#undef READ_TYPE_INT64_DATA +#endif /* HAVE_MATIO_INT64_T */ +#ifdef HAVE_MATIO_UINT64_T +#undef READ_TYPE_UINT64_DATA +#endif /* HAVE_MATIO_UINT64_T */ + +#if HAVE_ZLIB + +#define READ_TYPE_DOUBLE_DATA CAT(READ_TYPED_FUNC2, Double) +#define READ_TYPE_SINGLE_DATA CAT(READ_TYPED_FUNC2, Single) +#define READ_TYPE_INT32_DATA CAT(READ_TYPED_FUNC2, Int32) +#define READ_TYPE_UINT32_DATA CAT(READ_TYPED_FUNC2, UInt32) +#define READ_TYPE_INT16_DATA CAT(READ_TYPED_FUNC2, Int16) +#define READ_TYPE_UINT16_DATA CAT(READ_TYPED_FUNC2, UInt16) +#define READ_TYPE_INT8_DATA CAT(READ_TYPED_FUNC2, Int8) +#define READ_TYPE_UINT8_DATA CAT(READ_TYPED_FUNC2, UInt8) +#ifdef HAVE_MATIO_INT64_T +#define READ_TYPE_INT64_DATA CAT(READ_TYPED_FUNC2, Int64) +#endif /* HAVE_MATIO_INT64_T */ +#ifdef HAVE_MATIO_UINT64_T +#define READ_TYPE_UINT64_DATA CAT(READ_TYPED_FUNC2, UInt64) +#endif /* HAVE_MATIO_UINT64_T */ + +static void +READ_TYPE_DOUBLE_DATA(mat_t *mat, z_streamp z, READ_TYPE *data, mat_uint32_t len) +{ +#if READ_TYPE_TYPE == READ_TYPE_DOUBLE + InflateData(mat, z, data, len*sizeof(double)); + if ( mat->byteswap ) { + mat_uint32_t i; + for ( i = 0; i < len; i++ ) { + (void)Mat_doubleSwap(data + i); + } + } +#else + mat_uint32_t i; + const size_t data_size = sizeof(double); + double v[READ_BLOCK_SIZE/sizeof(double)]; + READ_COMPRESSED_DATA(READ_TYPE, Mat_doubleSwap); +#endif +} + +static void +READ_TYPE_SINGLE_DATA(mat_t *mat, z_streamp z, READ_TYPE *data, mat_uint32_t len) +{ +#if READ_TYPE_TYPE == READ_TYPE_SINGLE + InflateData(mat, z, data, len*sizeof(float)); + if ( mat->byteswap ) { + mat_uint32_t i; + for ( i = 0; i < len; i++ ) { + (void)Mat_floatSwap(data + i); + } + } +#else + mat_uint32_t i; + const size_t data_size = sizeof(float); + float v[READ_BLOCK_SIZE/sizeof(float)]; + READ_COMPRESSED_DATA(READ_TYPE, Mat_floatSwap); +#endif +} + +#ifdef HAVE_MATIO_INT64_T +static void +READ_TYPE_INT64_DATA(mat_t *mat, z_streamp z, READ_TYPE *data, mat_uint32_t len) +{ +#if READ_TYPE_TYPE == READ_TYPE_INT64 + InflateData(mat, z, data, len*sizeof(mat_int64_t)); + if ( mat->byteswap ) { + mat_uint32_t i; + for ( i = 0; i < len; i++ ) { + (void)Mat_int64Swap(data + i); + } + } +#else + mat_uint32_t i; + const size_t data_size = sizeof(mat_int64_t); + mat_int64_t v[READ_BLOCK_SIZE/sizeof(mat_int64_t)]; + READ_COMPRESSED_DATA(READ_TYPE, Mat_int64Swap); +#endif +} +#endif /* HAVE_MATIO_INT64_T */ + +#ifdef HAVE_MATIO_UINT64_T +static void +READ_TYPE_UINT64_DATA(mat_t *mat, z_streamp z, READ_TYPE *data, mat_uint32_t len) +{ +#if READ_TYPE_TYPE == READ_TYPE_UINT64 + InflateData(mat, z, data, len*sizeof(mat_uint64_t)); + if ( mat->byteswap ) { + mat_uint32_t i; + for ( i = 0; i < len; i++ ) { + (void)Mat_uint64Swap(data + i); + } + } +#else + mat_uint32_t i; + const size_t data_size = sizeof(mat_uint64_t); + mat_uint64_t v[READ_BLOCK_SIZE/sizeof(mat_uint64_t)]; + READ_COMPRESSED_DATA(READ_TYPE, Mat_uint64Swap); +#endif +} +#endif /* HAVE_MATIO_UINT64_T */ + +static void +READ_TYPE_INT32_DATA(mat_t *mat, z_streamp z, READ_TYPE *data, mat_uint32_t len) +{ +#if READ_TYPE_TYPE == READ_TYPE_INT32 + InflateData(mat, z, data, len*sizeof(mat_int32_t)); + if ( mat->byteswap ) { + mat_uint32_t i; + for ( i = 0; i < len; i++ ) { + (void)Mat_int32Swap(data + i); + } + } +#else + mat_uint32_t i; + const size_t data_size = sizeof(mat_int32_t); + mat_int32_t v[READ_BLOCK_SIZE/sizeof(mat_int32_t)]; + READ_COMPRESSED_DATA(READ_TYPE, Mat_int32Swap); +#endif +} + +static void +READ_TYPE_UINT32_DATA(mat_t *mat, z_streamp z, READ_TYPE *data, mat_uint32_t len) +{ +#if READ_TYPE_TYPE == READ_TYPE_UINT32 + InflateData(mat, z, data, len*sizeof(mat_uint32_t)); + if ( mat->byteswap ) { + mat_uint32_t i; + for ( i = 0; i < len; i++ ) { + (void)Mat_uint32Swap(data + i); + } + } +#else + mat_uint32_t i; + const size_t data_size = sizeof(mat_uint32_t); + mat_uint32_t v[READ_BLOCK_SIZE/sizeof(mat_uint32_t)]; + READ_COMPRESSED_DATA(READ_TYPE, Mat_uint32Swap); +#endif +} + +static void +READ_TYPE_INT16_DATA(mat_t *mat, z_streamp z, READ_TYPE *data, mat_uint32_t len) +{ +#if READ_TYPE_TYPE == READ_TYPE_INT16 + InflateData(mat, z, data, len*sizeof(mat_int16_t)); + if ( mat->byteswap ) { + mat_uint32_t i; + for ( i = 0; i < len; i++ ) { + (void)Mat_int16Swap(data + i); + } + } +#else + mat_uint32_t i; + const size_t data_size = sizeof(mat_int16_t); + mat_int16_t v[READ_BLOCK_SIZE/sizeof(mat_int16_t)]; + READ_COMPRESSED_DATA(READ_TYPE, Mat_int16Swap); +#endif +} + +static void +READ_TYPE_UINT16_DATA(mat_t *mat, z_streamp z, READ_TYPE *data, mat_uint32_t len) +{ +#if READ_TYPE_TYPE == READ_TYPE_UINT16 + InflateData(mat, z, data, len*sizeof(mat_uint16_t)); + if ( mat->byteswap ) { + mat_uint32_t i; + for ( i = 0; i < len; i++ ) { + (void)Mat_uint16Swap(data + i); + } + } +#else + mat_uint32_t i; + const size_t data_size = sizeof(mat_uint16_t); + mat_uint16_t v[READ_BLOCK_SIZE/sizeof(mat_uint16_t)]; + READ_COMPRESSED_DATA(READ_TYPE, Mat_uint16Swap); +#endif +} + +static void +READ_TYPE_INT8_DATA(mat_t *mat, z_streamp z, READ_TYPE *data, mat_uint32_t len) +{ +#if READ_TYPE_TYPE == READ_TYPE_INT8 + InflateData(mat, z, data, len*sizeof(mat_int8_t)); +#else + mat_uint32_t i; + const size_t data_size = sizeof(mat_int8_t); + mat_int8_t v[READ_BLOCK_SIZE/sizeof(mat_int8_t)]; + READ_COMPRESSED_DATA_NOSWAP(READ_TYPE); +#endif +} + +static void +READ_TYPE_UINT8_DATA(mat_t *mat, z_streamp z, READ_TYPE *data, mat_uint32_t len) +{ +#if READ_TYPE_TYPE == READ_TYPE_UINT8 + InflateData(mat, z, data, len*sizeof(mat_uint8_t)); +#else + mat_uint32_t i; + const size_t data_size = sizeof(mat_uint8_t); + mat_uint8_t v[READ_BLOCK_SIZE/sizeof(mat_uint8_t)]; + READ_COMPRESSED_DATA_NOSWAP(READ_TYPE); +#endif +} + +/** @brief Reads data of type @c data_type into a READ_TYPE type + * + * Reads from the MAT file @c len compressed elements of data type @c data_type + * storing them as READ_TYPE's in @c data. + * @ingroup mat_internal + * @param mat MAT file pointer + * @param z Pointer to the zlib stream for inflation + * @param data Pointer to store the output values (len*sizeof(READ_TYPE)) + * @param data_type one of the @c matio_types enumerations which is the source + * data type in the file + * @param len Number of elements of type @c data_type to read from the file + * @retval Number of bytes read from the file + */ +static int +READ_TYPED_FUNC2(mat_t *mat, z_streamp z, READ_TYPE *data, enum matio_types data_type, int len) +{ + if ( mat == NULL || data == NULL || mat->fp == NULL ) + return 0; + + switch ( data_type ) { + case MAT_T_DOUBLE: + READ_TYPE_DOUBLE_DATA(mat, z, data, len); + break; + case MAT_T_SINGLE: + READ_TYPE_SINGLE_DATA(mat, z, data, len); + break; +#ifdef HAVE_MATIO_INT64_T + case MAT_T_INT64: + READ_TYPE_INT64_DATA(mat, z, data, len); + break; +#endif /* HAVE_MATIO_UINT64_T */ +#ifdef HAVE_MATIO_UINT64_T + case MAT_T_UINT64: + READ_TYPE_UINT64_DATA(mat, z, data, len); + break; +#endif /* HAVE_MATIO_UINT64_T */ + case MAT_T_INT32: + READ_TYPE_INT32_DATA(mat, z, data, len); + break; + case MAT_T_UINT32: + READ_TYPE_UINT32_DATA(mat, z, data, len); + break; + case MAT_T_INT16: + READ_TYPE_INT16_DATA(mat, z, data, len); + break; + case MAT_T_UINT16: + READ_TYPE_UINT16_DATA(mat, z, data, len); + break; + case MAT_T_INT8: + READ_TYPE_INT8_DATA(mat, z, data, len); + break; + case MAT_T_UINT8: + READ_TYPE_UINT8_DATA(mat, z, data, len); + break; + default: + break; + } + return len*Mat_SizeOf(data_type); +} + +#undef READ_TYPE_DOUBLE_DATA +#undef READ_TYPE_SINGLE_DATA +#undef READ_TYPE_INT32_DATA +#undef READ_TYPE_UINT32_DATA +#undef READ_TYPE_INT16_DATA +#undef READ_TYPE_UINT16_DATA +#undef READ_TYPE_INT8_DATA +#undef READ_TYPE_UINT8_DATA +#ifdef HAVE_MATIO_INT64_T +#undef READ_TYPE_INT64_DATA +#endif /* HAVE_MATIO_INT64_T */ +#ifdef HAVE_MATIO_UINT64_T +#undef READ_TYPE_UINT64_DATA +#endif /* HAVE_MATIO_UINT64_T */ + +#endif diff --git a/ExternData/Resources/C-Sources/modelica/safe-math.h b/ExternData/Resources/C-Sources/modelica/safe-math.h new file mode 100644 index 0000000..7fa270e --- /dev/null +++ b/ExternData/Resources/C-Sources/modelica/safe-math.h @@ -0,0 +1,1078 @@ +/* Overflow-safe math functions + * Portable Snippets - https://github.com/nemequ/portable-snippets + * Created by Evan Nemerson + * + * To the extent possible under law, the authors have waived all + * copyright and related or neighboring rights to this code. For + * details, see the Creative Commons Zero 1.0 Universal license at + * https://creativecommons.org/publicdomain/zero/1.0/ + */ + +#if !defined(PSNIP_SAFE_H) +#define PSNIP_SAFE_H + +#if !defined(PSNIP_SAFE_FORCE_PORTABLE) +# if defined(__has_builtin) +# if __has_builtin(__builtin_add_overflow) && !defined(__ibmxl__) +# define PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW +# endif +# elif defined(__GNUC__) && (__GNUC__ >= 5) && !defined(__INTEL_COMPILER) +# define PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW +# endif +# if defined(HAVE_INTSAFE_H) +# define PSNIP_SAFE_HAVE_INTSAFE_H +# elif defined(__has_include) +# if __has_include() +# define PSNIP_SAFE_HAVE_INTSAFE_H +# endif +# elif defined(_MSC_VER) && _MSC_VER >= 1600 +# define PSNIP_SAFE_HAVE_INTSAFE_H +# elif defined(__CYGWIN__) && defined(__GNUC__) && __GNUC__ >= 5 +# define PSNIP_SAFE_HAVE_INTSAFE_H +# endif +#endif /* !defined(PSNIP_SAFE_FORCE_PORTABLE) */ + +#if defined(__GNUC__) +# define PSNIP_SAFE_LIKELY(expr) __builtin_expect(!!(expr), 1) +# define PSNIP_SAFE_UNLIKELY(expr) __builtin_expect(!!(expr), 0) +#else +# define PSNIP_SAFE_LIKELY(expr) !!(expr) +# define PSNIP_SAFE_UNLIKELY(expr) !!(expr) +#endif /* defined(__GNUC__) */ + +#if !defined(PSNIP_SAFE_STATIC_INLINE) +# if defined(__GNUC__) +# define PSNIP_SAFE__COMPILER_ATTRIBUTES __attribute__((__unused__)) +# else +# define PSNIP_SAFE__COMPILER_ATTRIBUTES +# endif + +# if defined(HEDLEY_INLINE) +# define PSNIP_SAFE__INLINE HEDLEY_INLINE +# elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +# define PSNIP_SAFE__INLINE inline +# elif defined(__GNUC_STDC_INLINE__) +# define PSNIP_SAFE__INLINE __inline__ +# elif defined(_MSC_VER) && _MSC_VER >= 1200 +# define PSNIP_SAFE__INLINE __inline +# else +# define PSNIP_SAFE__INLINE +# endif + +# define PSNIP_SAFE__FUNCTION PSNIP_SAFE__COMPILER_ATTRIBUTES static PSNIP_SAFE__INLINE +#endif + +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +# define psnip_safe_bool _Bool +#else +# define psnip_safe_bool int +#endif + +#if !defined(PSNIP_SAFE_NO_FIXED) +/* For maximum portability include the exact-int module from + portable snippets. */ +# if \ + !defined(psnip_int64_t) || !defined(psnip_uint64_t) || \ + !defined(psnip_int32_t) || !defined(psnip_uint32_t) || \ + !defined(psnip_int16_t) || !defined(psnip_uint16_t) || \ + !defined(psnip_int8_t) || !defined(psnip_uint8_t) +# include +# if !defined(psnip_int64_t) +# define psnip_int64_t int64_t +# endif +# if !defined(psnip_uint64_t) +# define psnip_uint64_t uint64_t +# endif +# if !defined(psnip_int32_t) +# define psnip_int32_t int32_t +# endif +# if !defined(psnip_uint32_t) +# define psnip_uint32_t uint32_t +# endif +# if !defined(psnip_int16_t) +# define psnip_int16_t int16_t +# endif +# if !defined(psnip_uint16_t) +# define psnip_uint16_t uint16_t +# endif +# if !defined(psnip_int8_t) +# define psnip_int8_t int8_t +# endif +# if !defined(psnip_uint8_t) +# define psnip_uint8_t uint8_t +# endif +# endif +#endif /* !defined(PSNIP_SAFE_NO_FIXED) */ +#include +#include + +#if !defined(PSNIP_SAFE_SIZE_MAX) +# if defined(__SIZE_MAX__) +# define PSNIP_SAFE_SIZE_MAX __SIZE_MAX__ +# elif defined(PSNIP_EXACT_INT_HAVE_STDINT) +# include +# endif +#endif + +#if defined(PSNIP_SAFE_SIZE_MAX) +# define PSNIP_SAFE__SIZE_MAX_RT PSNIP_SAFE_SIZE_MAX +#else +# define PSNIP_SAFE__SIZE_MAX_RT (~((size_t) 0)) +#endif + +#if defined(PSNIP_SAFE_HAVE_INTSAFE_H) +/* In VS 10, stdint.h and intsafe.h both define (U)INTN_MIN/MAX, which + triggers warning C4005 (level 1). */ +# if defined(_MSC_VER) && (_MSC_VER == 1600) +# pragma warning(push) +# pragma warning(disable:4005) +# endif +# include +# if defined(_MSC_VER) && (_MSC_VER == 1600) +# pragma warning(pop) +# endif +#endif /* defined(PSNIP_SAFE_HAVE_INTSAFE_H) */ + +/* If there is a type larger than the one we're concerned with it's + * likely much faster to simply promote the operands, perform the + * requested operation, verify that the result falls within the + * original type, then cast the result back to the original type. */ + +#if !defined(PSNIP_SAFE_NO_PROMOTIONS) + +#define PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, op_name, op) \ + PSNIP_SAFE__FUNCTION psnip_safe_##name##_larger \ + psnip_safe_larger_##name##_##op_name (T a, T b) { \ + return ((psnip_safe_##name##_larger) a) op ((psnip_safe_##name##_larger) b); \ + } + +#define PSNIP_SAFE_DEFINE_LARGER_UNARY_OP(T, name, op_name, op) \ + PSNIP_SAFE__FUNCTION psnip_safe_##name##_larger \ + psnip_safe_larger_##name##_##op_name (T value) { \ + return (op ((psnip_safe_##name##_larger) value)); \ + } + +#define PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(T, name) \ + PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, add, +) \ + PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, sub, -) \ + PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, mul, *) \ + PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, div, /) \ + PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, mod, %) \ + PSNIP_SAFE_DEFINE_LARGER_UNARY_OP (T, name, neg, -) + +#define PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(T, name) \ + PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, add, +) \ + PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, sub, -) \ + PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, mul, *) \ + PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, div, /) \ + PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, mod, %) + +#define PSNIP_SAFE_IS_LARGER(ORIG_MAX, DEST_MAX) ((DEST_MAX / ORIG_MAX) >= ORIG_MAX) + +#if defined(__GNUC__) && ((__GNUC__ >= 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__SIZEOF_INT128__) && !defined(__ibmxl__) +#define PSNIP_SAFE_HAVE_128 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpedantic" +typedef __int128 psnip_safe_int128_t; +typedef unsigned __int128 psnip_safe_uint128_t; +#pragma GCC diagnostic pop +#endif /* defined(__GNUC__) */ + +#if !defined(PSNIP_SAFE_NO_FIXED) +#define PSNIP_SAFE_HAVE_INT8_LARGER +#define PSNIP_SAFE_HAVE_UINT8_LARGER +typedef psnip_int16_t psnip_safe_int8_larger; +typedef psnip_uint16_t psnip_safe_uint8_larger; + +#define PSNIP_SAFE_HAVE_INT16_LARGER +typedef psnip_int32_t psnip_safe_int16_larger; +typedef psnip_uint32_t psnip_safe_uint16_larger; + +#define PSNIP_SAFE_HAVE_INT32_LARGER +typedef psnip_int64_t psnip_safe_int32_larger; +typedef psnip_uint64_t psnip_safe_uint32_larger; + +#if defined(PSNIP_SAFE_HAVE_128) +#define PSNIP_SAFE_HAVE_INT64_LARGER +typedef psnip_safe_int128_t psnip_safe_int64_larger; +typedef psnip_safe_uint128_t psnip_safe_uint64_larger; +#endif /* defined(PSNIP_SAFE_HAVE_128) */ +#endif /* !defined(PSNIP_SAFE_NO_FIXED) */ + +#define PSNIP_SAFE_HAVE_LARGER_SCHAR +#if PSNIP_SAFE_IS_LARGER(SCHAR_MAX, SHRT_MAX) +typedef short psnip_safe_schar_larger; +#elif PSNIP_SAFE_IS_LARGER(SCHAR_MAX, INT_MAX) +typedef int psnip_safe_schar_larger; +#elif PSNIP_SAFE_IS_LARGER(SCHAR_MAX, LONG_MAX) +typedef long psnip_safe_schar_larger; +#elif PSNIP_SAFE_IS_LARGER(SCHAR_MAX, LLONG_MAX) +typedef long long psnip_safe_schar_larger; +#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(SCHAR_MAX, 0x7fff) +typedef psnip_int16_t psnip_safe_schar_larger; +#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(SCHAR_MAX, 0x7fffffffLL) +typedef psnip_int32_t psnip_safe_schar_larger; +#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(SCHAR_MAX, 0x7fffffffffffffffLL) +typedef psnip_int64_t psnip_safe_schar_larger; +#elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (SCHAR_MAX <= 0x7fffffffffffffffLL) +typedef psnip_safe_int128_t psnip_safe_schar_larger; +#else +#undef PSNIP_SAFE_HAVE_LARGER_SCHAR +#endif + +#define PSNIP_SAFE_HAVE_LARGER_UCHAR +#if PSNIP_SAFE_IS_LARGER(UCHAR_MAX, USHRT_MAX) +typedef unsigned short psnip_safe_uchar_larger; +#elif PSNIP_SAFE_IS_LARGER(UCHAR_MAX, UINT_MAX) +typedef unsigned int psnip_safe_uchar_larger; +#elif PSNIP_SAFE_IS_LARGER(UCHAR_MAX, ULONG_MAX) +typedef unsigned long psnip_safe_uchar_larger; +#elif PSNIP_SAFE_IS_LARGER(UCHAR_MAX, ULLONG_MAX) +typedef unsigned long long psnip_safe_uchar_larger; +#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(UCHAR_MAX, 0xffffU) +typedef psnip_uint16_t psnip_safe_uchar_larger; +#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(UCHAR_MAX, 0xffffffffUL) +typedef psnip_uint32_t psnip_safe_uchar_larger; +#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(UCHAR_MAX, 0xffffffffffffffffULL) +typedef psnip_uint64_t psnip_safe_uchar_larger; +#elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (UCHAR_MAX <= 0xffffffffffffffffULL) +typedef psnip_safe_uint128_t psnip_safe_uchar_larger; +#else +#undef PSNIP_SAFE_HAVE_LARGER_UCHAR +#endif + +#if CHAR_MIN == 0 && defined(PSNIP_SAFE_HAVE_LARGER_UCHAR) +#define PSNIP_SAFE_HAVE_LARGER_CHAR +typedef psnip_safe_uchar_larger psnip_safe_char_larger; +#elif CHAR_MIN < 0 && defined(PSNIP_SAFE_HAVE_LARGER_SCHAR) +#define PSNIP_SAFE_HAVE_LARGER_CHAR +typedef psnip_safe_schar_larger psnip_safe_char_larger; +#endif + +#define PSNIP_SAFE_HAVE_LARGER_SHRT +#if PSNIP_SAFE_IS_LARGER(SHRT_MAX, INT_MAX) +typedef int psnip_safe_short_larger; +#elif PSNIP_SAFE_IS_LARGER(SHRT_MAX, LONG_MAX) +typedef long psnip_safe_short_larger; +#elif PSNIP_SAFE_IS_LARGER(SHRT_MAX, LLONG_MAX) +typedef long long psnip_safe_short_larger; +#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(SHRT_MAX, 0x7fff) +typedef psnip_int16_t psnip_safe_short_larger; +#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(SHRT_MAX, 0x7fffffffLL) +typedef psnip_int32_t psnip_safe_short_larger; +#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(SHRT_MAX, 0x7fffffffffffffffLL) +typedef psnip_int64_t psnip_safe_short_larger; +#elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (SHRT_MAX <= 0x7fffffffffffffffLL) +typedef psnip_safe_int128_t psnip_safe_short_larger; +#else +#undef PSNIP_SAFE_HAVE_LARGER_SHRT +#endif + +#define PSNIP_SAFE_HAVE_LARGER_USHRT +#if PSNIP_SAFE_IS_LARGER(USHRT_MAX, UINT_MAX) +typedef unsigned int psnip_safe_ushort_larger; +#elif PSNIP_SAFE_IS_LARGER(USHRT_MAX, ULONG_MAX) +typedef unsigned long psnip_safe_ushort_larger; +#elif PSNIP_SAFE_IS_LARGER(USHRT_MAX, ULLONG_MAX) +typedef unsigned long long psnip_safe_ushort_larger; +#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(USHRT_MAX, 0xffff) +typedef psnip_uint16_t psnip_safe_ushort_larger; +#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(USHRT_MAX, 0xffffffffUL) +typedef psnip_uint32_t psnip_safe_ushort_larger; +#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(USHRT_MAX, 0xffffffffffffffffULL) +typedef psnip_uint64_t psnip_safe_ushort_larger; +#elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (USHRT_MAX <= 0xffffffffffffffffULL) +typedef psnip_safe_uint128_t psnip_safe_ushort_larger; +#else +#undef PSNIP_SAFE_HAVE_LARGER_USHRT +#endif + +#define PSNIP_SAFE_HAVE_LARGER_INT +#if PSNIP_SAFE_IS_LARGER(INT_MAX, LONG_MAX) +typedef long psnip_safe_int_larger; +#elif PSNIP_SAFE_IS_LARGER(INT_MAX, LLONG_MAX) +typedef long long psnip_safe_int_larger; +#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(INT_MAX, 0x7fff) +typedef psnip_int16_t psnip_safe_int_larger; +#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(INT_MAX, 0x7fffffffLL) +typedef psnip_int32_t psnip_safe_int_larger; +#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(INT_MAX, 0x7fffffffffffffffLL) +typedef psnip_int64_t psnip_safe_int_larger; +#elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (INT_MAX <= 0x7fffffffffffffffLL) +typedef psnip_safe_int128_t psnip_safe_int_larger; +#else +#undef PSNIP_SAFE_HAVE_LARGER_INT +#endif + +#define PSNIP_SAFE_HAVE_LARGER_UINT +#if PSNIP_SAFE_IS_LARGER(UINT_MAX, ULONG_MAX) +typedef unsigned long psnip_safe_uint_larger; +#elif PSNIP_SAFE_IS_LARGER(UINT_MAX, ULLONG_MAX) +typedef unsigned long long psnip_safe_uint_larger; +#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(UINT_MAX, 0xffff) +typedef psnip_uint16_t psnip_safe_uint_larger; +#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(UINT_MAX, 0xffffffffUL) +typedef psnip_uint32_t psnip_safe_uint_larger; +#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(UINT_MAX, 0xffffffffffffffffULL) +typedef psnip_uint64_t psnip_safe_uint_larger; +#elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (UINT_MAX <= 0xffffffffffffffffULL) +typedef psnip_safe_uint128_t psnip_safe_uint_larger; +#else +#undef PSNIP_SAFE_HAVE_LARGER_UINT +#endif + +#define PSNIP_SAFE_HAVE_LARGER_LONG +#if PSNIP_SAFE_IS_LARGER(LONG_MAX, LLONG_MAX) +typedef long long psnip_safe_long_larger; +#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(LONG_MAX, 0x7fff) +typedef psnip_int16_t psnip_safe_long_larger; +#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(LONG_MAX, 0x7fffffffLL) +typedef psnip_int32_t psnip_safe_long_larger; +#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(LONG_MAX, 0x7fffffffffffffffLL) +typedef psnip_int64_t psnip_safe_long_larger; +#elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (LONG_MAX <= 0x7fffffffffffffffLL) +typedef psnip_safe_int128_t psnip_safe_long_larger; +#else +#undef PSNIP_SAFE_HAVE_LARGER_LONG +#endif + +#define PSNIP_SAFE_HAVE_LARGER_ULONG +#if PSNIP_SAFE_IS_LARGER(ULONG_MAX, ULLONG_MAX) +typedef unsigned long long psnip_safe_ulong_larger; +#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(ULONG_MAX, 0xffff) +typedef psnip_uint16_t psnip_safe_ulong_larger; +#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(ULONG_MAX, 0xffffffffUL) +typedef psnip_uint32_t psnip_safe_ulong_larger; +#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(ULONG_MAX, 0xffffffffffffffffULL) +typedef psnip_uint64_t psnip_safe_ulong_larger; +#elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (ULONG_MAX <= 0xffffffffffffffffULL) +typedef psnip_safe_uint128_t psnip_safe_ulong_larger; +#else +#undef PSNIP_SAFE_HAVE_LARGER_ULONG +#endif + +#define PSNIP_SAFE_HAVE_LARGER_LLONG +#if !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(LLONG_MAX, 0x7fff) +typedef psnip_int16_t psnip_safe_llong_larger; +#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(LLONG_MAX, 0x7fffffffLL) +typedef psnip_int32_t psnip_safe_llong_larger; +#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(LLONG_MAX, 0x7fffffffffffffffLL) +typedef psnip_int64_t psnip_safe_llong_larger; +#elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (LLONG_MAX <= 0x7fffffffffffffffLL) +typedef psnip_safe_int128_t psnip_safe_llong_larger; +#else +#undef PSNIP_SAFE_HAVE_LARGER_LLONG +#endif + +#define PSNIP_SAFE_HAVE_LARGER_ULLONG +#if !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(ULLONG_MAX, 0xffff) +typedef psnip_uint16_t psnip_safe_ullong_larger; +#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(ULLONG_MAX, 0xffffffffUL) +typedef psnip_uint32_t psnip_safe_ullong_larger; +#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(ULLONG_MAX, 0xffffffffffffffffULL) +typedef psnip_uint64_t psnip_safe_ullong_larger; +#elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (ULLONG_MAX <= 0xffffffffffffffffULL) +typedef psnip_safe_uint128_t psnip_safe_ullong_larger; +#else +#undef PSNIP_SAFE_HAVE_LARGER_ULLONG +#endif + +#if defined(PSNIP_SAFE_SIZE_MAX) +#define PSNIP_SAFE_HAVE_LARGER_SIZE +#if PSNIP_SAFE_IS_LARGER(PSNIP_SAFE_SIZE_MAX, USHRT_MAX) +typedef unsigned short psnip_safe_size_larger; +#elif PSNIP_SAFE_IS_LARGER(PSNIP_SAFE_SIZE_MAX, UINT_MAX) +typedef unsigned int psnip_safe_size_larger; +#elif PSNIP_SAFE_IS_LARGER(PSNIP_SAFE_SIZE_MAX, ULONG_MAX) +typedef unsigned long psnip_safe_size_larger; +#elif PSNIP_SAFE_IS_LARGER(PSNIP_SAFE_SIZE_MAX, ULLONG_MAX) +typedef unsigned long long psnip_safe_size_larger; +#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(PSNIP_SAFE_SIZE_MAX, 0xffff) +typedef psnip_uint16_t psnip_safe_size_larger; +#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(PSNIP_SAFE_SIZE_MAX, 0xffffffffUL) +typedef psnip_uint32_t psnip_safe_size_larger; +#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(PSNIP_SAFE_SIZE_MAX, 0xffffffffffffffffULL) +typedef psnip_uint64_t psnip_safe_size_larger; +#elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (PSNIP_SAFE_SIZE_MAX <= 0xffffffffffffffffULL) +typedef psnip_safe_uint128_t psnip_safe_size_larger; +#else +#undef PSNIP_SAFE_HAVE_LARGER_SIZE +#endif +#endif + +#if defined(PSNIP_SAFE_HAVE_LARGER_SCHAR) +PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(signed char, schar) +#endif + +#if defined(PSNIP_SAFE_HAVE_LARGER_UCHAR) +PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(unsigned char, uchar) +#endif + +#if defined(PSNIP_SAFE_HAVE_LARGER_CHAR) +#if CHAR_MIN == 0 +PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(char, char) +#else +PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(char, char) +#endif +#endif + +#if defined(PSNIP_SAFE_HAVE_LARGER_SHORT) +PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(short, short) +#endif + +#if defined(PSNIP_SAFE_HAVE_LARGER_USHORT) +PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(unsigned short, ushort) +#endif + +#if defined(PSNIP_SAFE_HAVE_LARGER_INT) +PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(int, int) +#endif + +#if defined(PSNIP_SAFE_HAVE_LARGER_UINT) +PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(unsigned int, uint) +#endif + +#if defined(PSNIP_SAFE_HAVE_LARGER_LONG) +PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(long, long) +#endif + +#if defined(PSNIP_SAFE_HAVE_LARGER_ULONG) +PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(unsigned long, ulong) +#endif + +#if defined(PSNIP_SAFE_HAVE_LARGER_LLONG) +PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(long long, llong) +#endif + +#if defined(PSNIP_SAFE_HAVE_LARGER_ULLONG) +PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(unsigned long long, ullong) +#endif + +#if defined(PSNIP_SAFE_HAVE_LARGER_SIZE) +PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(size_t, size) +#endif + +#if !defined(PSNIP_SAFE_NO_FIXED) +PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(psnip_int8_t, int8) +PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(psnip_uint8_t, uint8) +PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(psnip_int16_t, int16) +PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(psnip_uint16_t, uint16) +PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(psnip_int32_t, int32) +PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(psnip_uint32_t, uint32) +#if defined(PSNIP_SAFE_HAVE_128) +PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(psnip_int64_t, int64) +PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(psnip_uint64_t, uint64) +#endif +#endif + +#endif /* !defined(PSNIP_SAFE_NO_PROMOTIONS) */ + +#define PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(T, name, op_name) \ + PSNIP_SAFE__FUNCTION psnip_safe_bool \ + psnip_safe_##name##_##op_name(T* res, T a, T b) { \ + return !__builtin_##op_name##_overflow(a, b, res); \ + } + +#define PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(T, name, op_name, min, max) \ + PSNIP_SAFE__FUNCTION psnip_safe_bool \ + psnip_safe_##name##_##op_name(T* res, T a, T b) { \ + const psnip_safe_##name##_larger r = psnip_safe_larger_##name##_##op_name(a, b); \ + *res = (T) r; \ + return (r >= min) && (r <= max); \ + } + +#define PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(T, name, op_name, max) \ + PSNIP_SAFE__FUNCTION psnip_safe_bool \ + psnip_safe_##name##_##op_name(T* res, T a, T b) { \ + const psnip_safe_##name##_larger r = psnip_safe_larger_##name##_##op_name(a, b); \ + *res = (T) r; \ + return (r <= max); \ + } + +#define PSNIP_SAFE_DEFINE_SIGNED_ADD(T, name, min, max) \ + PSNIP_SAFE__FUNCTION psnip_safe_bool \ + psnip_safe_##name##_add (T* res, T a, T b) { \ + psnip_safe_bool r = !( ((b > 0) && (a > (max - b))) || \ + ((b < 0) && (a < (min - b))) ); \ + if(PSNIP_SAFE_LIKELY(r)) \ + *res = a + b; \ + return r; \ + } + +#define PSNIP_SAFE_DEFINE_UNSIGNED_ADD(T, name, max) \ + PSNIP_SAFE__FUNCTION psnip_safe_bool \ + psnip_safe_##name##_add (T* res, T a, T b) { \ + *res = (T) (a + b); \ + return !PSNIP_SAFE_UNLIKELY((b > 0) && (a > (max - b))); \ + } + +#define PSNIP_SAFE_DEFINE_SIGNED_SUB(T, name, min, max) \ + PSNIP_SAFE__FUNCTION psnip_safe_bool \ + psnip_safe_##name##_sub (T* res, T a, T b) { \ + psnip_safe_bool r = !((b > 0 && a < (min + b)) || \ + (b < 0 && a > (max + b))); \ + if(PSNIP_SAFE_LIKELY(r)) \ + *res = a - b; \ + return r; \ + } + +#define PSNIP_SAFE_DEFINE_UNSIGNED_SUB(T, name, max) \ + PSNIP_SAFE__FUNCTION psnip_safe_bool \ + psnip_safe_##name##_sub (T* res, T a, T b) { \ + *res = a - b; \ + return !PSNIP_SAFE_UNLIKELY(b > a); \ + } + +#define PSNIP_SAFE_DEFINE_SIGNED_MUL(T, name, min, max) \ + PSNIP_SAFE__FUNCTION psnip_safe_bool \ + psnip_safe_##name##_mul (T* res, T a, T b) { \ + psnip_safe_bool r = 1; \ + if (a > 0) { \ + if (b > 0) { \ + if (a > (max / b)) { \ + r = 0; \ + } \ + } else { \ + if (b < (min / a)) { \ + r = 0; \ + } \ + } \ + } else { \ + if (b > 0) { \ + if (a < (min / b)) { \ + r = 0; \ + } \ + } else { \ + if ( (a != 0) && (b < (max / a))) { \ + r = 0; \ + } \ + } \ + } \ + if(PSNIP_SAFE_LIKELY(r)) \ + *res = a * b; \ + return r; \ + } + +#define PSNIP_SAFE_DEFINE_UNSIGNED_MUL(T, name, max) \ + PSNIP_SAFE__FUNCTION psnip_safe_bool \ + psnip_safe_##name##_mul (T* res, T a, T b) { \ + *res = (T) (a * b); \ + return !PSNIP_SAFE_UNLIKELY((a > 0) && (b > 0) && (a > (max / b))); \ + } + +#define PSNIP_SAFE_DEFINE_SIGNED_DIV(T, name, min, max) \ + PSNIP_SAFE__FUNCTION psnip_safe_bool \ + psnip_safe_##name##_div (T* res, T a, T b) { \ + if (PSNIP_SAFE_UNLIKELY(b == 0)) { \ + *res = 0; \ + return 0; \ + } else if (PSNIP_SAFE_UNLIKELY(a == min && b == -1)) { \ + *res = min; \ + return 0; \ + } else { \ + *res = (T) (a / b); \ + return 1; \ + } \ + } + +#define PSNIP_SAFE_DEFINE_UNSIGNED_DIV(T, name, max) \ + PSNIP_SAFE__FUNCTION psnip_safe_bool \ + psnip_safe_##name##_div (T* res, T a, T b) { \ + if (PSNIP_SAFE_UNLIKELY(b == 0)) { \ + *res = 0; \ + return 0; \ + } else { \ + *res = a / b; \ + return 1; \ + } \ + } + +#define PSNIP_SAFE_DEFINE_SIGNED_MOD(T, name, min, max) \ + PSNIP_SAFE__FUNCTION psnip_safe_bool \ + psnip_safe_##name##_mod (T* res, T a, T b) { \ + if (PSNIP_SAFE_UNLIKELY(b == 0)) { \ + *res = 0; \ + return 0; \ + } else if (PSNIP_SAFE_UNLIKELY(a == min && b == -1)) { \ + *res = min; \ + return 0; \ + } else { \ + *res = (T) (a % b); \ + return 1; \ + } \ + } + +#define PSNIP_SAFE_DEFINE_UNSIGNED_MOD(T, name, max) \ + PSNIP_SAFE__FUNCTION psnip_safe_bool \ + psnip_safe_##name##_mod (T* res, T a, T b) { \ + if (PSNIP_SAFE_UNLIKELY(b == 0)) { \ + *res = 0; \ + return 0; \ + } else { \ + *res = a % b; \ + return 1; \ + } \ + } + +#define PSNIP_SAFE_DEFINE_SIGNED_NEG(T, name, min, max) \ + PSNIP_SAFE__FUNCTION psnip_safe_bool \ + psnip_safe_##name##_neg (T* res, T value) { \ + psnip_safe_bool r = value != min; \ + *res = PSNIP_SAFE_LIKELY(r) ? -value : max; \ + return r; \ + } + +#define PSNIP_SAFE_DEFINE_INTSAFE(T, name, op, isf) \ + PSNIP_SAFE__FUNCTION psnip_safe_bool \ + psnip_safe_##name##_##op (T* res, T a, T b) { \ + return isf(a, b, res) == S_OK; \ + } + +#if CHAR_MIN == 0 +#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(char, char, add) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(char, char, sub) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(char, char, mul) +#elif defined(PSNIP_SAFE_HAVE_LARGER_CHAR) +PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(char, char, add, CHAR_MAX) +PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(char, char, sub, CHAR_MAX) +PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(char, char, mul, CHAR_MAX) +#else +PSNIP_SAFE_DEFINE_UNSIGNED_ADD(char, char, CHAR_MAX) +PSNIP_SAFE_DEFINE_UNSIGNED_SUB(char, char, CHAR_MAX) +PSNIP_SAFE_DEFINE_UNSIGNED_MUL(char, char, CHAR_MAX) +#endif +PSNIP_SAFE_DEFINE_UNSIGNED_DIV(char, char, CHAR_MAX) +PSNIP_SAFE_DEFINE_UNSIGNED_MOD(char, char, CHAR_MAX) +#else /* CHAR_MIN != 0 */ +#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(char, char, add) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(char, char, sub) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(char, char, mul) +#elif defined(PSNIP_SAFE_HAVE_LARGER_CHAR) +PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(char, char, add, CHAR_MIN, CHAR_MAX) +PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(char, char, sub, CHAR_MIN, CHAR_MAX) +PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(char, char, mul, CHAR_MIN, CHAR_MAX) +#else +PSNIP_SAFE_DEFINE_SIGNED_ADD(char, char, CHAR_MIN, CHAR_MAX) +PSNIP_SAFE_DEFINE_SIGNED_SUB(char, char, CHAR_MIN, CHAR_MAX) +PSNIP_SAFE_DEFINE_SIGNED_MUL(char, char, CHAR_MIN, CHAR_MAX) +#endif +PSNIP_SAFE_DEFINE_SIGNED_DIV(char, char, CHAR_MIN, CHAR_MAX) +PSNIP_SAFE_DEFINE_SIGNED_MOD(char, char, CHAR_MIN, CHAR_MAX) +PSNIP_SAFE_DEFINE_SIGNED_NEG(char, char, CHAR_MIN, CHAR_MAX) +#endif + +#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(signed char, schar, add) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(signed char, schar, sub) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(signed char, schar, mul) +#elif defined(PSNIP_SAFE_HAVE_LARGER_SCHAR) +PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(signed char, schar, add, SCHAR_MIN, SCHAR_MAX) +PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(signed char, schar, sub, SCHAR_MIN, SCHAR_MAX) +PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(signed char, schar, mul, SCHAR_MIN, SCHAR_MAX) +#else +PSNIP_SAFE_DEFINE_SIGNED_ADD(signed char, schar, SCHAR_MIN, SCHAR_MAX) +PSNIP_SAFE_DEFINE_SIGNED_SUB(signed char, schar, SCHAR_MIN, SCHAR_MAX) +PSNIP_SAFE_DEFINE_SIGNED_MUL(signed char, schar, SCHAR_MIN, SCHAR_MAX) +#endif +PSNIP_SAFE_DEFINE_SIGNED_DIV(signed char, schar, SCHAR_MIN, SCHAR_MAX) +PSNIP_SAFE_DEFINE_SIGNED_MOD(signed char, schar, SCHAR_MIN, SCHAR_MAX) +PSNIP_SAFE_DEFINE_SIGNED_NEG(signed char, schar, SCHAR_MIN, SCHAR_MAX) + +#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned char, uchar, add) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned char, uchar, sub) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned char, uchar, mul) +#elif defined(PSNIP_SAFE_HAVE_LARGER_UCHAR) +PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned char, uchar, add, UCHAR_MAX) +PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned char, uchar, sub, UCHAR_MAX) +PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned char, uchar, mul, UCHAR_MAX) +#else +PSNIP_SAFE_DEFINE_UNSIGNED_ADD(unsigned char, uchar, UCHAR_MAX) +PSNIP_SAFE_DEFINE_UNSIGNED_SUB(unsigned char, uchar, UCHAR_MAX) +PSNIP_SAFE_DEFINE_UNSIGNED_MUL(unsigned char, uchar, UCHAR_MAX) +#endif +PSNIP_SAFE_DEFINE_UNSIGNED_DIV(unsigned char, uchar, UCHAR_MAX) +PSNIP_SAFE_DEFINE_UNSIGNED_MOD(unsigned char, uchar, UCHAR_MAX) + +#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(short, short, add) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(short, short, sub) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(short, short, mul) +#elif defined(PSNIP_SAFE_HAVE_LARGER_SHORT) +PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(short, short, add, SHRT_MIN, SHRT_MAX) +PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(short, short, sub, SHRT_MIN, SHRT_MAX) +PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(short, short, mul, SHRT_MIN, SHRT_MAX) +#else +PSNIP_SAFE_DEFINE_SIGNED_ADD(short, short, SHRT_MIN, SHRT_MAX) +PSNIP_SAFE_DEFINE_SIGNED_SUB(short, short, SHRT_MIN, SHRT_MAX) +PSNIP_SAFE_DEFINE_SIGNED_MUL(short, short, SHRT_MIN, SHRT_MAX) +#endif +PSNIP_SAFE_DEFINE_SIGNED_DIV(short, short, SHRT_MIN, SHRT_MAX) +PSNIP_SAFE_DEFINE_SIGNED_MOD(short, short, SHRT_MIN, SHRT_MAX) +PSNIP_SAFE_DEFINE_SIGNED_NEG(short, short, SHRT_MIN, SHRT_MAX) + +#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned short, ushort, add) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned short, ushort, sub) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned short, ushort, mul) +#elif defined(PSNIP_SAFE_HAVE_INTSAFE_H) +PSNIP_SAFE_DEFINE_INTSAFE(USHORT, ushort, add, UShortAdd) +PSNIP_SAFE_DEFINE_INTSAFE(USHORT, ushort, sub, UShortSub) +PSNIP_SAFE_DEFINE_INTSAFE(USHORT, ushort, mul, UShortMult) +#elif defined(PSNIP_SAFE_HAVE_LARGER_USHORT) +PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned short, ushort, add, USHRT_MAX) +PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned short, ushort, sub, USHRT_MAX) +PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned short, ushort, mul, USHRT_MAX) +#else +PSNIP_SAFE_DEFINE_UNSIGNED_ADD(unsigned short, ushort, USHRT_MAX) +PSNIP_SAFE_DEFINE_UNSIGNED_SUB(unsigned short, ushort, USHRT_MAX) +PSNIP_SAFE_DEFINE_UNSIGNED_MUL(unsigned short, ushort, USHRT_MAX) +#endif +PSNIP_SAFE_DEFINE_UNSIGNED_DIV(unsigned short, ushort, USHRT_MAX) +PSNIP_SAFE_DEFINE_UNSIGNED_MOD(unsigned short, ushort, USHRT_MAX) + +#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(int, int, add) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(int, int, sub) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(int, int, mul) +#elif defined(PSNIP_SAFE_HAVE_LARGER_INT) +PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(int, int, add, INT_MIN, INT_MAX) +PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(int, int, sub, INT_MIN, INT_MAX) +PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(int, int, mul, INT_MIN, INT_MAX) +#else +PSNIP_SAFE_DEFINE_SIGNED_ADD(int, int, INT_MIN, INT_MAX) +PSNIP_SAFE_DEFINE_SIGNED_SUB(int, int, INT_MIN, INT_MAX) +PSNIP_SAFE_DEFINE_SIGNED_MUL(int, int, INT_MIN, INT_MAX) +#endif +PSNIP_SAFE_DEFINE_SIGNED_DIV(int, int, INT_MIN, INT_MAX) +PSNIP_SAFE_DEFINE_SIGNED_MOD(int, int, INT_MIN, INT_MAX) +PSNIP_SAFE_DEFINE_SIGNED_NEG(int, int, INT_MIN, INT_MAX) + +#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned int, uint, add) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned int, uint, sub) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned int, uint, mul) +#elif defined(PSNIP_SAFE_HAVE_INTSAFE_H) +PSNIP_SAFE_DEFINE_INTSAFE(UINT, uint, add, UIntAdd) +PSNIP_SAFE_DEFINE_INTSAFE(UINT, uint, sub, UIntSub) +PSNIP_SAFE_DEFINE_INTSAFE(UINT, uint, mul, UIntMult) +#elif defined(PSNIP_SAFE_HAVE_LARGER_UINT) +PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned int, uint, add, UINT_MAX) +PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned int, uint, sub, UINT_MAX) +PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned int, uint, mul, UINT_MAX) +#else +PSNIP_SAFE_DEFINE_UNSIGNED_ADD(unsigned int, uint, UINT_MAX) +PSNIP_SAFE_DEFINE_UNSIGNED_SUB(unsigned int, uint, UINT_MAX) +PSNIP_SAFE_DEFINE_UNSIGNED_MUL(unsigned int, uint, UINT_MAX) +#endif +PSNIP_SAFE_DEFINE_UNSIGNED_DIV(unsigned int, uint, UINT_MAX) +PSNIP_SAFE_DEFINE_UNSIGNED_MOD(unsigned int, uint, UINT_MAX) + +#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(long, long, add) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(long, long, sub) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(long, long, mul) +#elif defined(PSNIP_SAFE_HAVE_LARGER_LONG) +PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(long, long, add, LONG_MIN, LONG_MAX) +PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(long, long, sub, LONG_MIN, LONG_MAX) +PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(long, long, mul, LONG_MIN, LONG_MAX) +#else +PSNIP_SAFE_DEFINE_SIGNED_ADD(long, long, LONG_MIN, LONG_MAX) +PSNIP_SAFE_DEFINE_SIGNED_SUB(long, long, LONG_MIN, LONG_MAX) +PSNIP_SAFE_DEFINE_SIGNED_MUL(long, long, LONG_MIN, LONG_MAX) +#endif +PSNIP_SAFE_DEFINE_SIGNED_DIV(long, long, LONG_MIN, LONG_MAX) +PSNIP_SAFE_DEFINE_SIGNED_MOD(long, long, LONG_MIN, LONG_MAX) +PSNIP_SAFE_DEFINE_SIGNED_NEG(long, long, LONG_MIN, LONG_MAX) + +#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned long, ulong, add) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned long, ulong, sub) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned long, ulong, mul) +#elif defined(PSNIP_SAFE_HAVE_INTSAFE_H) +PSNIP_SAFE_DEFINE_INTSAFE(ULONG, ulong, add, ULongAdd) +PSNIP_SAFE_DEFINE_INTSAFE(ULONG, ulong, sub, ULongSub) +PSNIP_SAFE_DEFINE_INTSAFE(ULONG, ulong, mul, ULongMult) +#elif defined(PSNIP_SAFE_HAVE_LARGER_ULONG) +PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned long, ulong, add, ULONG_MAX) +PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned long, ulong, sub, ULONG_MAX) +PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned long, ulong, mul, ULONG_MAX) +#else +PSNIP_SAFE_DEFINE_UNSIGNED_ADD(unsigned long, ulong, ULONG_MAX) +PSNIP_SAFE_DEFINE_UNSIGNED_SUB(unsigned long, ulong, ULONG_MAX) +PSNIP_SAFE_DEFINE_UNSIGNED_MUL(unsigned long, ulong, ULONG_MAX) +#endif +PSNIP_SAFE_DEFINE_UNSIGNED_DIV(unsigned long, ulong, ULONG_MAX) +PSNIP_SAFE_DEFINE_UNSIGNED_MOD(unsigned long, ulong, ULONG_MAX) + +#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(long long, llong, add) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(long long, llong, sub) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(long long, llong, mul) +#elif defined(PSNIP_SAFE_HAVE_LARGER_LLONG) +PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(long long, llong, add, LLONG_MIN, LLONG_MAX) +PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(long long, llong, sub, LLONG_MIN, LLONG_MAX) +PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(long long, llong, mul, LLONG_MIN, LLONG_MAX) +#else +PSNIP_SAFE_DEFINE_SIGNED_ADD(long long, llong, LLONG_MIN, LLONG_MAX) +PSNIP_SAFE_DEFINE_SIGNED_SUB(long long, llong, LLONG_MIN, LLONG_MAX) +PSNIP_SAFE_DEFINE_SIGNED_MUL(long long, llong, LLONG_MIN, LLONG_MAX) +#endif +PSNIP_SAFE_DEFINE_SIGNED_DIV(long long, llong, LLONG_MIN, LLONG_MAX) +PSNIP_SAFE_DEFINE_SIGNED_MOD(long long, llong, LLONG_MIN, LLONG_MAX) +PSNIP_SAFE_DEFINE_SIGNED_NEG(long long, llong, LLONG_MIN, LLONG_MAX) + +#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned long long, ullong, add) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned long long, ullong, sub) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned long long, ullong, mul) +#elif defined(PSNIP_SAFE_HAVE_INTSAFE_H) +PSNIP_SAFE_DEFINE_INTSAFE(ULONGLONG, ullong, add, ULongLongAdd) +PSNIP_SAFE_DEFINE_INTSAFE(ULONGLONG, ullong, sub, ULongLongSub) +PSNIP_SAFE_DEFINE_INTSAFE(ULONGLONG, ullong, mul, ULongLongMult) +#elif defined(PSNIP_SAFE_HAVE_LARGER_ULLONG) +PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned long long, ullong, add, ULLONG_MAX) +PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned long long, ullong, sub, ULLONG_MAX) +PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned long long, ullong, mul, ULLONG_MAX) +#else +PSNIP_SAFE_DEFINE_UNSIGNED_ADD(unsigned long long, ullong, ULLONG_MAX) +PSNIP_SAFE_DEFINE_UNSIGNED_SUB(unsigned long long, ullong, ULLONG_MAX) +PSNIP_SAFE_DEFINE_UNSIGNED_MUL(unsigned long long, ullong, ULLONG_MAX) +#endif +PSNIP_SAFE_DEFINE_UNSIGNED_DIV(unsigned long long, ullong, ULLONG_MAX) +PSNIP_SAFE_DEFINE_UNSIGNED_MOD(unsigned long long, ullong, ULLONG_MAX) + +#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(size_t, size, add) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(size_t, size, sub) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(size_t, size, mul) +#elif defined(PSNIP_SAFE_HAVE_INTSAFE_H) +PSNIP_SAFE_DEFINE_INTSAFE(size_t, size, add, SizeTAdd) +PSNIP_SAFE_DEFINE_INTSAFE(size_t, size, sub, SizeTSub) +PSNIP_SAFE_DEFINE_INTSAFE(size_t, size, mul, SizeTMult) +#elif defined(PSNIP_SAFE_HAVE_LARGER_SIZE) +PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(size_t, size, add, PSNIP_SAFE__SIZE_MAX_RT) +PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(size_t, size, sub, PSNIP_SAFE__SIZE_MAX_RT) +PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(size_t, size, mul, PSNIP_SAFE__SIZE_MAX_RT) +#else +PSNIP_SAFE_DEFINE_UNSIGNED_ADD(size_t, size, PSNIP_SAFE__SIZE_MAX_RT) +PSNIP_SAFE_DEFINE_UNSIGNED_SUB(size_t, size, PSNIP_SAFE__SIZE_MAX_RT) +PSNIP_SAFE_DEFINE_UNSIGNED_MUL(size_t, size, PSNIP_SAFE__SIZE_MAX_RT) +#endif +PSNIP_SAFE_DEFINE_UNSIGNED_DIV(size_t, size, PSNIP_SAFE__SIZE_MAX_RT) +PSNIP_SAFE_DEFINE_UNSIGNED_MOD(size_t, size, PSNIP_SAFE__SIZE_MAX_RT) + +#if !defined(PSNIP_SAFE_NO_FIXED) + +#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int8_t, int8, add) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int8_t, int8, sub) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int8_t, int8, mul) +#elif defined(PSNIP_SAFE_HAVE_LARGER_INT8) +PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int8_t, int8, add, (-0x7fLL-1), 0x7f) +PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int8_t, int8, sub, (-0x7fLL-1), 0x7f) +PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int8_t, int8, mul, (-0x7fLL-1), 0x7f) +#else +PSNIP_SAFE_DEFINE_SIGNED_ADD(psnip_int8_t, int8, (-0x7fLL-1), 0x7f) +PSNIP_SAFE_DEFINE_SIGNED_SUB(psnip_int8_t, int8, (-0x7fLL-1), 0x7f) +PSNIP_SAFE_DEFINE_SIGNED_MUL(psnip_int8_t, int8, (-0x7fLL-1), 0x7f) +#endif +PSNIP_SAFE_DEFINE_SIGNED_DIV(psnip_int8_t, int8, (-0x7fLL-1), 0x7f) +PSNIP_SAFE_DEFINE_SIGNED_MOD(psnip_int8_t, int8, (-0x7fLL-1), 0x7f) +PSNIP_SAFE_DEFINE_SIGNED_NEG(psnip_int8_t, int8, (-0x7fLL-1), 0x7f) + +#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint8_t, uint8, add) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint8_t, uint8, sub) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint8_t, uint8, mul) +#elif defined(PSNIP_SAFE_HAVE_LARGER_UINT8) +PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint8_t, uint8, add, 0xff) +PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint8_t, uint8, sub, 0xff) +PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint8_t, uint8, mul, 0xff) +#else +PSNIP_SAFE_DEFINE_UNSIGNED_ADD(psnip_uint8_t, uint8, 0xff) +PSNIP_SAFE_DEFINE_UNSIGNED_SUB(psnip_uint8_t, uint8, 0xff) +PSNIP_SAFE_DEFINE_UNSIGNED_MUL(psnip_uint8_t, uint8, 0xff) +#endif +PSNIP_SAFE_DEFINE_UNSIGNED_DIV(psnip_uint8_t, uint8, 0xff) +PSNIP_SAFE_DEFINE_UNSIGNED_MOD(psnip_uint8_t, uint8, 0xff) + +#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int16_t, int16, add) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int16_t, int16, sub) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int16_t, int16, mul) +#elif defined(PSNIP_SAFE_HAVE_LARGER_INT16) +PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int16_t, int16, add, (-32767-1), 0x7fff) +PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int16_t, int16, sub, (-32767-1), 0x7fff) +PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int16_t, int16, mul, (-32767-1), 0x7fff) +#else +PSNIP_SAFE_DEFINE_SIGNED_ADD(psnip_int16_t, int16, (-32767-1), 0x7fff) +PSNIP_SAFE_DEFINE_SIGNED_SUB(psnip_int16_t, int16, (-32767-1), 0x7fff) +PSNIP_SAFE_DEFINE_SIGNED_MUL(psnip_int16_t, int16, (-32767-1), 0x7fff) +#endif +PSNIP_SAFE_DEFINE_SIGNED_DIV(psnip_int16_t, int16, (-32767-1), 0x7fff) +PSNIP_SAFE_DEFINE_SIGNED_MOD(psnip_int16_t, int16, (-32767-1), 0x7fff) +PSNIP_SAFE_DEFINE_SIGNED_NEG(psnip_int16_t, int16, (-32767-1), 0x7fff) + +#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint16_t, uint16, add) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint16_t, uint16, sub) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint16_t, uint16, mul) +#elif defined(PSNIP_SAFE_HAVE_INTSAFE_H) && defined(_WIN32) +PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint16_t, uint16, add, UShortAdd) +PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint16_t, uint16, sub, UShortSub) +PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint16_t, uint16, mul, UShortMult) +#elif defined(PSNIP_SAFE_HAVE_LARGER_UINT16) +PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint16_t, uint16, add, 0xffff) +PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint16_t, uint16, sub, 0xffff) +PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint16_t, uint16, mul, 0xffff) +#else +PSNIP_SAFE_DEFINE_UNSIGNED_ADD(psnip_uint16_t, uint16, 0xffff) +PSNIP_SAFE_DEFINE_UNSIGNED_SUB(psnip_uint16_t, uint16, 0xffff) +PSNIP_SAFE_DEFINE_UNSIGNED_MUL(psnip_uint16_t, uint16, 0xffff) +#endif +PSNIP_SAFE_DEFINE_UNSIGNED_DIV(psnip_uint16_t, uint16, 0xffff) +PSNIP_SAFE_DEFINE_UNSIGNED_MOD(psnip_uint16_t, uint16, 0xffff) + +#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int32_t, int32, add) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int32_t, int32, sub) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int32_t, int32, mul) +#elif defined(PSNIP_SAFE_HAVE_LARGER_INT32) +PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int32_t, int32, add, (-0x7fffffffLL-1), 0x7fffffffLL) +PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int32_t, int32, sub, (-0x7fffffffLL-1), 0x7fffffffLL) +PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int32_t, int32, mul, (-0x7fffffffLL-1), 0x7fffffffLL) +#else +PSNIP_SAFE_DEFINE_SIGNED_ADD(psnip_int32_t, int32, (-0x7fffffffLL-1), 0x7fffffffLL) +PSNIP_SAFE_DEFINE_SIGNED_SUB(psnip_int32_t, int32, (-0x7fffffffLL-1), 0x7fffffffLL) +PSNIP_SAFE_DEFINE_SIGNED_MUL(psnip_int32_t, int32, (-0x7fffffffLL-1), 0x7fffffffLL) +#endif +PSNIP_SAFE_DEFINE_SIGNED_DIV(psnip_int32_t, int32, (-0x7fffffffLL-1), 0x7fffffffLL) +PSNIP_SAFE_DEFINE_SIGNED_MOD(psnip_int32_t, int32, (-0x7fffffffLL-1), 0x7fffffffLL) +PSNIP_SAFE_DEFINE_SIGNED_NEG(psnip_int32_t, int32, (-0x7fffffffLL-1), 0x7fffffffLL) + +#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint32_t, uint32, add) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint32_t, uint32, sub) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint32_t, uint32, mul) +#elif defined(PSNIP_SAFE_HAVE_INTSAFE_H) && defined(_WIN32) +PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint32_t, uint32, add, UIntAdd) +PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint32_t, uint32, sub, UIntSub) +PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint32_t, uint32, mul, UIntMult) +#elif defined(PSNIP_SAFE_HAVE_LARGER_UINT32) +PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint32_t, uint32, add, 0xffffffffUL) +PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint32_t, uint32, sub, 0xffffffffUL) +PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint32_t, uint32, mul, 0xffffffffUL) +#else +PSNIP_SAFE_DEFINE_UNSIGNED_ADD(psnip_uint32_t, uint32, 0xffffffffUL) +PSNIP_SAFE_DEFINE_UNSIGNED_SUB(psnip_uint32_t, uint32, 0xffffffffUL) +PSNIP_SAFE_DEFINE_UNSIGNED_MUL(psnip_uint32_t, uint32, 0xffffffffUL) +#endif +PSNIP_SAFE_DEFINE_UNSIGNED_DIV(psnip_uint32_t, uint32, 0xffffffffUL) +PSNIP_SAFE_DEFINE_UNSIGNED_MOD(psnip_uint32_t, uint32, 0xffffffffUL) + +#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int64_t, int64, add) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int64_t, int64, sub) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int64_t, int64, mul) +#elif defined(PSNIP_SAFE_HAVE_LARGER_INT64) +PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int64_t, int64, add, (-0x7fffffffffffffffLL-1), 0x7fffffffffffffffLL) +PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int64_t, int64, sub, (-0x7fffffffffffffffLL-1), 0x7fffffffffffffffLL) +PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int64_t, int64, mul, (-0x7fffffffffffffffLL-1), 0x7fffffffffffffffLL) +#else +PSNIP_SAFE_DEFINE_SIGNED_ADD(psnip_int64_t, int64, (-0x7fffffffffffffffLL-1), 0x7fffffffffffffffLL) +PSNIP_SAFE_DEFINE_SIGNED_SUB(psnip_int64_t, int64, (-0x7fffffffffffffffLL-1), 0x7fffffffffffffffLL) +PSNIP_SAFE_DEFINE_SIGNED_MUL(psnip_int64_t, int64, (-0x7fffffffffffffffLL-1), 0x7fffffffffffffffLL) +#endif +PSNIP_SAFE_DEFINE_SIGNED_DIV(psnip_int64_t, int64, (-0x7fffffffffffffffLL-1), 0x7fffffffffffffffLL) +PSNIP_SAFE_DEFINE_SIGNED_MOD(psnip_int64_t, int64, (-0x7fffffffffffffffLL-1), 0x7fffffffffffffffLL) +PSNIP_SAFE_DEFINE_SIGNED_NEG(psnip_int64_t, int64, (-0x7fffffffffffffffLL-1), 0x7fffffffffffffffLL) + +#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint64_t, uint64, add) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint64_t, uint64, sub) +PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint64_t, uint64, mul) +#elif defined(PSNIP_SAFE_HAVE_INTSAFE_H) && defined(_WIN32) +PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint64_t, uint64, add, ULongLongAdd) +PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint64_t, uint64, sub, ULongLongSub) +PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint64_t, uint64, mul, ULongLongMult) +#elif defined(PSNIP_SAFE_HAVE_LARGER_UINT64) +PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint64_t, uint64, add, 0xffffffffffffffffULL) +PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint64_t, uint64, sub, 0xffffffffffffffffULL) +PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint64_t, uint64, mul, 0xffffffffffffffffULL) +#else +PSNIP_SAFE_DEFINE_UNSIGNED_ADD(psnip_uint64_t, uint64, 0xffffffffffffffffULL) +PSNIP_SAFE_DEFINE_UNSIGNED_SUB(psnip_uint64_t, uint64, 0xffffffffffffffffULL) +PSNIP_SAFE_DEFINE_UNSIGNED_MUL(psnip_uint64_t, uint64, 0xffffffffffffffffULL) +#endif +PSNIP_SAFE_DEFINE_UNSIGNED_DIV(psnip_uint64_t, uint64, 0xffffffffffffffffULL) +PSNIP_SAFE_DEFINE_UNSIGNED_MOD(psnip_uint64_t, uint64, 0xffffffffffffffffULL) + +#endif /* !defined(PSNIP_SAFE_NO_FIXED) */ + +#define PSNIP_SAFE_C11_GENERIC_SELECTION(res, op) \ + _Generic((*res), \ + char: psnip_safe_char_##op, \ + unsigned char: psnip_safe_uchar_##op, \ + short: psnip_safe_short_##op, \ + unsigned short: psnip_safe_ushort_##op, \ + int: psnip_safe_int_##op, \ + unsigned int: psnip_safe_uint_##op, \ + long: psnip_safe_long_##op, \ + unsigned long: psnip_safe_ulong_##op, \ + long long: psnip_safe_llong_##op, \ + unsigned long long: psnip_safe_ullong_##op) + +#define PSNIP_SAFE_C11_GENERIC_BINARY_OP(op, res, a, b) \ + PSNIP_SAFE_C11_GENERIC_SELECTION(res, op)(res, a, b) +#define PSNIP_SAFE_C11_GENERIC_UNARY_OP(op, res, v) \ + PSNIP_SAFE_C11_GENERIC_SELECTION(res, op)(res, v) + +#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW) +#define psnip_safe_add(res, a, b) !__builtin_add_overflow(a, b, res) +#define psnip_safe_sub(res, a, b) !__builtin_sub_overflow(a, b, res) +#define psnip_safe_mul(res, a, b) !__builtin_mul_overflow(a, b, res) +#define psnip_safe_div(res, a, b) !__builtin_div_overflow(a, b, res) +#define psnip_safe_mod(res, a, b) !__builtin_mod_overflow(a, b, res) +#define psnip_safe_neg(res, v) PSNIP_SAFE_C11_GENERIC_UNARY_OP (neg, res, v) + +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) +/* The are no fixed-length or size selections because they cause an + * error about _Generic specifying two compatible types. Hopefully + * this doesn't cause problems on exotic platforms, but if it does + * please let me know and I'll try to figure something out. */ + +#define psnip_safe_add(res, a, b) PSNIP_SAFE_C11_GENERIC_BINARY_OP(add, res, a, b) +#define psnip_safe_sub(res, a, b) PSNIP_SAFE_C11_GENERIC_BINARY_OP(sub, res, a, b) +#define psnip_safe_mul(res, a, b) PSNIP_SAFE_C11_GENERIC_BINARY_OP(mul, res, a, b) +#define psnip_safe_div(res, a, b) PSNIP_SAFE_C11_GENERIC_BINARY_OP(div, res, a, b) +#define psnip_safe_mod(res, a, b) PSNIP_SAFE_C11_GENERIC_BINARY_OP(mod, res, a, b) +#define psnip_safe_neg(res, v) PSNIP_SAFE_C11_GENERIC_UNARY_OP (neg, res, v) +#endif + +#if !defined(PSNIP_SAFE_HAVE_BUILTINS) && (defined(PSNIP_SAFE_EMULATE_NATIVE) || defined(PSNIP_BUILTIN_EMULATE_NATIVE)) +# define __builtin_sadd_overflow(a, b, res) (!psnip_safe_int_add(res, a, b)) +# define __builtin_saddl_overflow(a, b, res) (!psnip_safe_long_add(res, a, b)) +# define __builtin_saddll_overflow(a, b, res) (!psnip_safe_llong_add(res, a, b)) +# define __builtin_uadd_overflow(a, b, res) (!psnip_safe_uint_add(res, a, b)) +# define __builtin_uaddl_overflow(a, b, res) (!psnip_safe_ulong_add(res, a, b)) +# define __builtin_uaddll_overflow(a, b, res) (!psnip_safe_ullong_add(res, a, b)) + +# define __builtin_ssub_overflow(a, b, res) (!psnip_safe_int_sub(res, a, b)) +# define __builtin_ssubl_overflow(a, b, res) (!psnip_safe_long_sub(res, a, b)) +# define __builtin_ssubll_overflow(a, b, res) (!psnip_safe_llong_sub(res, a, b)) +# define __builtin_usub_overflow(a, b, res) (!psnip_safe_uint_sub(res, a, b)) +# define __builtin_usubl_overflow(a, b, res) (!psnip_safe_ulong_sub(res, a, b)) +# define __builtin_usubll_overflow(a, b, res) (!psnip_safe_ullong_sub(res, a, b)) + +# define __builtin_smul_overflow(a, b, res) (!psnip_safe_int_mul(res, a, b)) +# define __builtin_smull_overflow(a, b, res) (!psnip_safe_long_mul(res, a, b)) +# define __builtin_smulll_overflow(a, b, res) (!psnip_safe_llong_mul(res, a, b)) +# define __builtin_umul_overflow(a, b, res) (!psnip_safe_uint_mul(res, a, b)) +# define __builtin_umull_overflow(a, b, res) (!psnip_safe_ulong_mul(res, a, b)) +# define __builtin_umulll_overflow(a, b, res) (!psnip_safe_ullong_mul(res, a, b)) +#endif + +#endif /* !defined(PSNIP_SAFE_H) */ diff --git a/ExternData/Resources/C-Sources/modelica/snprintf.c b/ExternData/Resources/C-Sources/modelica/snprintf.c new file mode 100644 index 0000000..765f463 --- /dev/null +++ b/ExternData/Resources/C-Sources/modelica/snprintf.c @@ -0,0 +1,1575 @@ +/* + * Copyright (c) 1995 Patrick Powell. + * + * This code is based on code written by Patrick Powell . + * It may be used for any purpose as long as this notice remains intact on all + * source code distributions. + */ + +/* + * Copyright (c) 2008 Holger Weiss. + * + * This version of the code is maintained by Holger Weiss . + * My changes to the code may freely be used, modified and/or redistributed for + * any purpose. It would be nice if additions and fixes to this file (including + * trivial code cleanups) would be sent back in order to let me include them in + * the version available at . + * However, this is not a requirement for using or redistributing (possibly + * modified) versions of this file, nor is leaving this notice intact mandatory. + */ + +/* + * History + * + * 2008-01-20 Holger Weiss for C99-snprintf 1.1: + * + * Fixed the detection of infinite floating point values on IRIX (and + * possibly other systems) and applied another few minor cleanups. + * + * 2008-01-06 Holger Weiss for C99-snprintf 1.0: + * + * Added a lot of new features, fixed many bugs, and incorporated various + * improvements done by Andrew Tridgell , Russ Allbery + * , Hrvoje Niksic , Damien Miller + * , and others for the Samba, INN, Wget, and OpenSSH + * projects. The additions include: support the "e", "E", "g", "G", and + * "F" conversion specifiers (and use conversion style "f" or "F" for the + * still unsupported "a" and "A" specifiers); support the "hh", "ll", "j", + * "t", and "z" length modifiers; support the "#" flag and the (non-C99) + * "'" flag; use localeconv(3) (if available) to get both the current + * locale's decimal point character and the separator between groups of + * digits; fix the handling of various corner cases of field width and + * precision specifications; fix various floating point conversion bugs; + * handle infinite and NaN floating point values; don't attempt to write to + * the output buffer (which may be NULL) if a size of zero was specified; + * check for integer overflow of the field width, precision, and return + * values and during the floating point conversion; use the OUTCHAR() macro + * instead of a function for better performance; provide asprintf(3) and + * vasprintf(3) functions; add new test cases. The replacement functions + * have been renamed to use an "rpl_" prefix, the function calls in the + * main project (and in this file) must be redefined accordingly for each + * replacement function which is needed (by using Autoconf or other means). + * Various other minor improvements have been applied and the coding style + * was cleaned up for consistency. + * + * 2007-07-23 Holger Weiss for Mutt 1.5.13: + * + * C99 compliant snprintf(3) and vsnprintf(3) functions return the number + * of characters that would have been written to a sufficiently sized + * buffer (excluding the '\0'). The original code simply returned the + * length of the resulting output string, so that's been fixed. + * + * 1998-03-05 Michael Elkins for Mutt 0.90.8: + * + * The original code assumed that both snprintf(3) and vsnprintf(3) were + * missing. Some systems only have snprintf(3) but not vsnprintf(3), so + * the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF. + * + * 1998-01-27 Thomas Roessler for Mutt 0.89i: + * + * The PGP code was using unsigned hexadecimal formats. Unfortunately, + * unsigned formats simply didn't work. + * + * 1997-10-22 Brandon Long for Mutt 0.87.1: + * + * Ok, added some minimal floating point support, which means this probably + * requires libm on most operating systems. Don't yet support the exponent + * (e,E) and sigfig (g,G). Also, fmtint() was pretty badly broken, it just + * wasn't being exercised in ways which showed it, so that's been fixed. + * Also, formatted the code to Mutt conventions, and removed dead code left + * over from the original. Also, there is now a builtin-test, run with: + * gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm && ./snprintf + * + * 2996-09-15 Brandon Long for Mutt 0.43: + * + * This was ugly. It is still ugly. I opted out of floating point + * numbers, but the formatter understands just about everything from the + * normal C string format, at least as far as I can tell from the Solaris + * 2.5 printf(3S) man page. + */ + +/* + * ToDo + * + * - Add wide character support. + * - Add support for "%a" and "%A" conversions. + * - Create test routines which predefine the expected results. Our test cases + * usually expose bugs in system implementations rather than in ours :-) + */ + +/* + * Usage + * + * 1) The following preprocessor macros should be defined to 1 if the feature or + * file in question is available on the target system (by using Autoconf or + * other means), though basic functionality should be available as long as + * HAVE_STDARG_H and HAVE_STDLIB_H are defined correctly: + * + * HAVE_VSNPRINTF + * HAVE_SNPRINTF + * HAVE_VASPRINTF + * HAVE_ASPRINTF + * HAVE_STDARG_H + * HAVE_STDDEF_H + * HAVE_STDINT_H + * HAVE_STDLIB_H + * HAVE_FLOAT_H + * HAVE_INTTYPES_H + * HAVE_LOCALE_H + * HAVE_LOCALECONV + * HAVE_LCONV_DECIMAL_POINT + * HAVE_LCONV_THOUSANDS_SEP + * HAVE_LONG_DOUBLE + * HAVE_LONG_LONG_INT + * HAVE_UNSIGNED_LONG_LONG_INT + * HAVE_INTMAX_T + * HAVE_UINTMAX_T + * HAVE_UINTPTR_T + * HAVE_PTRDIFF_T + * HAVE_VA_COPY + * HAVE___VA_COPY + * + * 2) The calls to the functions which should be replaced must be redefined + * throughout the project files (by using Autoconf or other means): + * + * #define vsnprintf rpl_vsnprintf + * #define snprintf rpl_snprintf + * #define vasprintf rpl_vasprintf + * #define asprintf rpl_asprintf + * + * 3) The required replacement functions should be declared in some header file + * included throughout the project files: + * + * #if HAVE_CONFIG_H + * #include + * #endif + * #if HAVE_STDARG_H + * #include + * #if !HAVE_VSNPRINTF + * int rpl_vsnprintf(char *, size_t, const char *, va_list); + * #endif + * #if !HAVE_SNPRINTF + * int rpl_snprintf(char *, size_t, const char *, ...); + * #endif + * #if !HAVE_VASPRINTF + * int rpl_vasprintf(char **, const char *, va_list); + * #endif + * #if !HAVE_ASPRINTF + * int rpl_asprintf(char **, const char *, ...); + * #endif + * #endif + * + * Autoconf macros for handling step 1 and step 2 are available at + * . + */ + + +#ifndef HAVE_STDARG_H +#define HAVE_STDARG_H 1 +#endif +#ifndef HAVE_STDLIB_H +#define HAVE_STDLIB_H 1 +#endif +#ifndef HAVE_FLOAT_H +#define HAVE_FLOAT_H 1 +#endif + +/* Define to 1 if you have a C99 compliant `snprintf' function. */ +#if defined(STDC99) +#define HAVE_SNPRINTF 1 +#elif defined(__MINGW32__) || defined(__CYGWIN__) +#if __STDC_VERSION__ >= 199901L +#define HAVE_SNPRINTF 1 +#endif +#elif defined(__WATCOMC__) +#define HAVE_SNPRINTF 1 +#elif defined(__TURBOC__) && __TURBOC__ >= 0x550 +#define HAVE_SNPRINTF 1 +#elif defined(MSDOS) && defined(__BORLANDC__) && (BORLANDC > 0x410) +#define HAVE_SNPRINTF 1 +#elif defined(_MSC_VER) && _MSC_VER >= 1900 +#define HAVE_SNPRINTF 1 +#else +#undef HAVE_SNPRINTF +#endif + +/* Define to 1 if you have a C99 compliant `vsnprintf' function. */ +#if defined(STDC99) +#define HAVE_VSNPRINTF 1 +#elif defined(__MINGW32__) || defined(__CYGWIN__) +#if __STDC_VERSION__ >= 199901L +#define HAVE_VSNPRINTF 1 +#endif +#elif defined(__WATCOMC__) +#define HAVE_VSNPRINTF 1 +#elif defined(__TURBOC__) && __TURBOC__ >= 0x550 +#define HAVE_VSNPRINTF 1 +#elif defined(MSDOS) && defined(__BORLANDC__) && (BORLANDC > 0x410) +#define HAVE_VSNPRINTF 1 +#elif defined(_MSC_VER) && _MSC_VER >= 1900 +#define HAVE_VSNPRINTF 1 +#else +#undef HAVE_VSNPRINTF +#endif + +/* Define to 1 if you have the `asprintf' function. */ +#if defined(__CYGWIN__) || defined(__gnu_linux__) +#define HAVE_ASPRINTF 1 +#else +#undef HAVE_ASPRINTF +#endif + +/* Define to 1 if you have the `vasprintf' function. */ +#if defined(__CYGWIN__) || defined(__gnu_linux__) +#define HAVE_VASPRINTF 1 +#else +#undef HAVE_VASPRINTF +#endif + + +/* Define to 1 if you have the header file. */ +#if defined(_WIN32) +#if defined(_MSC_VER) && _MSC_VER >= 1600 +#define HAVE_STDINT_H 1 +#elif defined(__WATCOMC__) || defined(__MINGW32__) || defined(__CYGWIN__) +#define HAVE_STDINT_H 1 +#else +#undef HAVE_STDINT_H +#endif +#elif defined(__GNUC__) && !defined(__VXWORKS__) +#define HAVE_STDINT_H 1 +#else +#undef HAVE_STDINT_H +#endif + +/* Define to 1 if the system has the type `intmax_t'. */ +#if defined(_WIN32) +#if defined(_MSC_VER) && _MSC_VER >= 1600 +#define HAVE_INTMAX_T 1 +#elif defined(__WATCOMC__) || defined(__MINGW32__) || defined(__CYGWIN__) +#define HAVE_INTMAX_T 1 +#else +#undef HAVE_INTMAX_T +#endif +#elif defined(__GNUC__) && !defined(__VXWORKS__) +#define HAVE_INTMAX_T 1 +#else +#undef HAVE_INTMAX_T +#endif + +/* Define to 1 if the system has the type `uintmax_t'. */ +#if defined(_WIN32) +#if defined(_MSC_VER) && _MSC_VER >= 1600 +#define HAVE_UINTMAX_T 1 +#elif defined(__WATCOMC__) || defined(__MINGW32__) || defined(__CYGWIN__) +#define HAVE_UINTMAX_T 1 +#else +#undef HAVE_UINTMAX_T +#endif +#elif defined(__GNUC__) && !defined(__VXWORKS__) +#define HAVE_UINTMAX_T 1 +#else +#undef HAVE_UINTMAX_T +#endif + +/* Define to 1 if the system has the type `uintptr_t'. */ +#if defined(__LCC__) || (defined(_MSC_VER) && _MSC_VER <= 1200) +#undef HAVE_UINTPTR_T +#else +#define HAVE_UINTPTR_T 1 +#endif + +#if !HAVE_SNPRINTF || !HAVE_VSNPRINTF || !HAVE_ASPRINTF || !HAVE_VASPRINTF +#include /* For NULL, size_t, vsnprintf(3), and vasprintf(3). */ +#ifdef VA_START +#undef VA_START +#endif /* defined(VA_START) */ +#ifdef VA_SHIFT +#undef VA_SHIFT +#endif /* defined(VA_SHIFT) */ +#if HAVE_STDARG_H +#include +#define VA_START(ap, last) va_start(ap, last) +#define VA_SHIFT(ap, value, type) /* No-op for ANSI C. */ +#else /* Assume is available. */ +#include +#define VA_START(ap, last) va_start(ap) /* "last" is ignored. */ +#define VA_SHIFT(ap, value, type) value = va_arg(ap, type) +#endif /* HAVE_STDARG_H */ + +#if !HAVE_VASPRINTF +#if HAVE_STDLIB_H +#include /* For malloc(3). */ +#endif /* HAVE_STDLIB_H */ +#ifdef VA_COPY +#undef VA_COPY +#endif /* defined(VA_COPY) */ +#ifdef VA_END_COPY +#undef VA_END_COPY +#endif /* defined(VA_END_COPY) */ +#if HAVE_VA_COPY +#define VA_COPY(dest, src) va_copy(dest, src) +#define VA_END_COPY(ap) va_end(ap) +#elif HAVE___VA_COPY +#define VA_COPY(dest, src) __va_copy(dest, src) +#define VA_END_COPY(ap) va_end(ap) +#else +#define VA_COPY(dest, src) (void)mymemcpy(&dest, &src, sizeof(va_list)) +#define VA_END_COPY(ap) /* No-op. */ +#define NEED_MYMEMCPY 1 +static void *mymemcpy(void *, const void *, size_t); +#endif /* HAVE_VA_COPY */ +#endif /* !HAVE_VASPRINTF */ + +#if !HAVE_VSNPRINTF +#include /* For ERANGE and errno. */ +#include /* For *_MAX. */ +#if HAVE_FLOAT_H +#include /* For *DBL_{MIN,MAX}_10_EXP. */ +#endif /* HAVE_FLOAT_H */ +#if HAVE_INTTYPES_H +#include /* For intmax_t (if not defined in ). */ +#endif /* HAVE_INTTYPES_H */ +#if HAVE_LOCALE_H +#include /* For localeconv(3). */ +#endif /* HAVE_LOCALE_H */ +#if HAVE_STDDEF_H +#include /* For ptrdiff_t. */ +#endif /* HAVE_STDDEF_H */ +#if HAVE_STDINT_H +#include /* For intmax_t. */ +#endif /* HAVE_STDINT_H */ + +/* Support for unsigned long long int. We may also need ULLONG_MAX. */ +#ifndef ULONG_MAX /* We may need ULONG_MAX as a fallback. */ +#ifdef UINT_MAX +#define ULONG_MAX UINT_MAX +#else +#define ULONG_MAX INT_MAX +#endif /* defined(UINT_MAX) */ +#endif /* !defined(ULONG_MAX) */ +#ifdef ULLONG +#undef ULLONG +#endif /* defined(ULLONG) */ +#if HAVE_UNSIGNED_LONG_LONG_INT +#define ULLONG unsigned long long int +#ifndef ULLONG_MAX +#define ULLONG_MAX ULONG_MAX +#endif /* !defined(ULLONG_MAX) */ +#else +#define ULLONG unsigned long int +#ifdef ULLONG_MAX +#undef ULLONG_MAX +#endif /* defined(ULLONG_MAX) */ +#define ULLONG_MAX ULONG_MAX +#endif /* HAVE_LONG_LONG_INT */ + +/* Support for uintmax_t. We also need UINTMAX_MAX. */ +#ifdef UINTMAX_T +#undef UINTMAX_T +#endif /* defined(UINTMAX_T) */ +#if HAVE_UINTMAX_T || defined(uintmax_t) +#define UINTMAX_T uintmax_t +#ifndef UINTMAX_MAX +#define UINTMAX_MAX ULLONG_MAX +#endif /* !defined(UINTMAX_MAX) */ +#else +#define UINTMAX_T ULLONG +#ifdef UINTMAX_MAX +#undef UINTMAX_MAX +#endif /* defined(UINTMAX_MAX) */ +#define UINTMAX_MAX ULLONG_MAX +#endif /* HAVE_UINTMAX_T || defined(uintmax_t) */ + +/* Support for long double. */ +#ifndef LDOUBLE +#if HAVE_LONG_DOUBLE +#define LDOUBLE long double +#define LDOUBLE_MIN_10_EXP LDBL_MIN_10_EXP +#define LDOUBLE_MAX_10_EXP LDBL_MAX_10_EXP +#else +#define LDOUBLE double +#define LDOUBLE_MIN_10_EXP DBL_MIN_10_EXP +#define LDOUBLE_MAX_10_EXP DBL_MAX_10_EXP +#endif /* HAVE_LONG_DOUBLE */ +#endif /* !defined(LDOUBLE) */ + +/* Support for long long int. */ +#ifndef LLONG +#if HAVE_LONG_LONG_INT +#define LLONG long long int +#else +#define LLONG long int +#endif /* HAVE_LONG_LONG_INT */ +#endif /* !defined(LLONG) */ + +/* Support for intmax_t. */ +#ifndef INTMAX_T +#if HAVE_INTMAX_T || defined(intmax_t) +#define INTMAX_T intmax_t +#else +#define INTMAX_T LLONG +#endif /* HAVE_INTMAX_T || defined(intmax_t) */ +#endif /* !defined(INTMAX_T) */ + +/* Support for uintptr_t. */ +#ifndef UINTPTR_T +#if HAVE_UINTPTR_T || defined(uintptr_t) +#define UINTPTR_T uintptr_t +#else +#define UINTPTR_T unsigned long int +#endif /* HAVE_UINTPTR_T || defined(uintptr_t) */ +#endif /* !defined(UINTPTR_T) */ + +/* Support for ptrdiff_t. */ +#ifndef PTRDIFF_T +#if HAVE_PTRDIFF_T || defined(ptrdiff_t) +#define PTRDIFF_T ptrdiff_t +#else +#define PTRDIFF_T long int +#endif /* HAVE_PTRDIFF_T || defined(ptrdiff_t) */ +#endif /* !defined(PTRDIFF_T) */ + +/* + * We need an unsigned integer type corresponding to ptrdiff_t (cf. C99: + * 7.19.6.1, 7). However, we'll simply use PTRDIFF_T and convert it to an + * unsigned type if necessary. This should work just fine in practice. + */ +#ifndef UPTRDIFF_T +#define UPTRDIFF_T PTRDIFF_T +#endif /* !defined(UPTRDIFF_T) */ + +/* + * We need a signed integer type corresponding to size_t (cf. C99: 7.19.6.1, 7). + * However, we'll simply use size_t and convert it to a signed type if + * necessary. This should work just fine in practice. + */ +#ifndef SSIZE_T +#define SSIZE_T size_t +#endif /* !defined(SSIZE_T) */ + +/* Either ERANGE or E2BIG should be available everywhere. */ +#ifndef ERANGE +#define ERANGE E2BIG +#endif /* !defined(ERANGE) */ +#ifndef EOVERFLOW +#define EOVERFLOW ERANGE +#endif /* !defined(EOVERFLOW) */ + +/* + * Buffer size to hold the octal string representation of UINT128_MAX without + * nul-termination ("3777777777777777777777777777777777777777777"). + */ +#ifdef MAX_CONVERT_LENGTH +#undef MAX_CONVERT_LENGTH +#endif /* defined(MAX_CONVERT_LENGTH) */ +#define MAX_CONVERT_LENGTH 43 + +/* Format read states. */ +#define PRINT_S_DEFAULT 0 +#define PRINT_S_FLAGS 1 +#define PRINT_S_WIDTH 2 +#define PRINT_S_DOT 3 +#define PRINT_S_PRECISION 4 +#define PRINT_S_MOD 5 +#define PRINT_S_CONV 6 + +/* Format flags. */ +#define PRINT_F_MINUS (1 << 0) +#define PRINT_F_PLUS (1 << 1) +#define PRINT_F_SPACE (1 << 2) +#define PRINT_F_NUM (1 << 3) +#define PRINT_F_ZERO (1 << 4) +#define PRINT_F_QUOTE (1 << 5) +#define PRINT_F_UP (1 << 6) +#define PRINT_F_UNSIGNED (1 << 7) +#define PRINT_F_TYPE_G (1 << 8) +#define PRINT_F_TYPE_E (1 << 9) + +/* Conversion flags. */ +#define PRINT_C_CHAR 1 +#define PRINT_C_SHORT 2 +#define PRINT_C_LONG 3 +#define PRINT_C_LLONG 4 +#define PRINT_C_LDOUBLE 5 +#define PRINT_C_SIZE 6 +#define PRINT_C_PTRDIFF 7 +#define PRINT_C_INTMAX 8 + +#ifndef MAX +#define MAX(x, y) ((x >= y) ? x : y) +#endif /* !defined(MAX) */ +#ifndef CHARTOINT +#define CHARTOINT(ch) (ch - '0') +#endif /* !defined(CHARTOINT) */ +#ifndef ISDIGIT +#define ISDIGIT(ch) ('0' <= (unsigned char)ch && (unsigned char)ch <= '9') +#endif /* !defined(ISDIGIT) */ +#ifndef ISNAN +#define ISNAN(x) (x != x) +#endif /* !defined(ISNAN) */ +#ifndef ISINF +#define ISINF(x) ((x < -1 || x > 1) && x + x == x) +#endif /* !defined(ISINF) */ + +#ifdef OUTCHAR +#undef OUTCHAR +#endif /* defined(OUTCHAR) */ +#define OUTCHAR(str, len, size, ch) \ +do { \ + if (len + 1 < size) \ + str[len] = ch; \ + (len)++; \ +} while (/* CONSTCOND */ 0) + +static void fmtstr(char *, size_t *, size_t, const char *, int, int, int); +static void fmtint(char *, size_t *, size_t, INTMAX_T, int, int, int, int); +static void fmtflt(char *, size_t *, size_t, LDOUBLE, int, int, int, int *); +static void printsep(char *, size_t *, size_t); +static int getnumsep(int); +static int getexponent(LDOUBLE); +static int convert(UINTMAX_T, char *, size_t, int, int); +static UINTMAX_T cast(LDOUBLE); +static UINTMAX_T myround(LDOUBLE); +static LDOUBLE mypow10(int); + +/*extern int errno;*/ + +int +rpl_vsnprintf(char *str, size_t size, const char *format, va_list args) +{ + LDOUBLE fvalue; + INTMAX_T value; + unsigned char cvalue; + const char *strvalue; + INTMAX_T *intmaxptr; + PTRDIFF_T *ptrdiffptr; + SSIZE_T *sizeptr; + LLONG *llongptr; + long int *longptr; + int *intptr; + short int *shortptr; + signed char *charptr; + size_t len = 0; + int overflow = 0; + int base = 0; + int cflags = 0; + int flags = 0; + int width = 0; + int precision = -1; + int state = PRINT_S_DEFAULT; + char ch = *format++; + + /* + * C99 says: "If `n' is zero, nothing is written, and `s' may be a null + * pointer." (7.19.6.5, 2) We're forgiving and allow a NULL pointer + * even if a size larger than zero was specified. At least NetBSD's + * snprintf(3) does the same, as well as other versions of this file. + * (Though some of these versions will write to a non-NULL buffer even + * if a size of zero was specified, which violates the standard.) + */ + if (str == NULL && size != 0) + size = 0; + + while (ch != '\0') + switch (state) { + case PRINT_S_DEFAULT: + if (ch == '%') + state = PRINT_S_FLAGS; + else + OUTCHAR(str, len, size, ch); + ch = *format++; + break; + case PRINT_S_FLAGS: + switch (ch) { + case '-': + flags |= PRINT_F_MINUS; + ch = *format++; + break; + case '+': + flags |= PRINT_F_PLUS; + ch = *format++; + break; + case ' ': + flags |= PRINT_F_SPACE; + ch = *format++; + break; + case '#': + flags |= PRINT_F_NUM; + ch = *format++; + break; + case '0': + flags |= PRINT_F_ZERO; + ch = *format++; + break; + case '\'': /* SUSv2 flag (not in C99). */ + flags |= PRINT_F_QUOTE; + ch = *format++; + break; + default: + state = PRINT_S_WIDTH; + break; + } + break; + case PRINT_S_WIDTH: + if (ISDIGIT(ch)) { + ch = CHARTOINT(ch); + if (width > (INT_MAX - ch) / 10) { + overflow = 1; + goto out; + } + width = 10 * width + ch; + ch = *format++; + } else if (ch == '*') { + /* + * C99 says: "A negative field width argument is + * taken as a `-' flag followed by a positive + * field width." (7.19.6.1, 5) + */ + if ((width = va_arg(args, int)) < 0) { + flags |= PRINT_F_MINUS; + width = -width; + } + ch = *format++; + state = PRINT_S_DOT; + } else + state = PRINT_S_DOT; + break; + case PRINT_S_DOT: + if (ch == '.') { + state = PRINT_S_PRECISION; + ch = *format++; + } else + state = PRINT_S_MOD; + break; + case PRINT_S_PRECISION: + if (precision == -1) + precision = 0; + if (ISDIGIT(ch)) { + ch = CHARTOINT(ch); + if (precision > (INT_MAX - ch) / 10) { + overflow = 1; + goto out; + } + precision = 10 * precision + ch; + ch = *format++; + } else if (ch == '*') { + /* + * C99 says: "A negative precision argument is + * taken as if the precision were omitted." + * (7.19.6.1, 5) + */ + if ((precision = va_arg(args, int)) < 0) + precision = -1; + ch = *format++; + state = PRINT_S_MOD; + } else + state = PRINT_S_MOD; + break; + case PRINT_S_MOD: + switch (ch) { + case 'h': + ch = *format++; + if (ch == 'h') { /* It's a char. */ + ch = *format++; + cflags = PRINT_C_CHAR; + } else + cflags = PRINT_C_SHORT; + break; + case 'l': + ch = *format++; + if (ch == 'l') { /* It's a long long. */ + ch = *format++; + cflags = PRINT_C_LLONG; + } else + cflags = PRINT_C_LONG; + break; + case 'L': + cflags = PRINT_C_LDOUBLE; + ch = *format++; + break; + case 'j': + cflags = PRINT_C_INTMAX; + ch = *format++; + break; + case 't': + cflags = PRINT_C_PTRDIFF; + ch = *format++; + break; + case 'z': + cflags = PRINT_C_SIZE; + ch = *format++; + break; + } + state = PRINT_S_CONV; + break; + case PRINT_S_CONV: + switch (ch) { + case 'd': + /* FALLTHROUGH */ + case 'i': + switch (cflags) { + case PRINT_C_CHAR: + value = (signed char)va_arg(args, int); + break; + case PRINT_C_SHORT: + value = (short int)va_arg(args, int); + break; + case PRINT_C_LONG: + value = va_arg(args, long int); + break; + case PRINT_C_LLONG: + value = va_arg(args, LLONG); + break; + case PRINT_C_SIZE: + value = va_arg(args, SSIZE_T); + break; + case PRINT_C_INTMAX: + value = va_arg(args, INTMAX_T); + break; + case PRINT_C_PTRDIFF: + value = va_arg(args, PTRDIFF_T); + break; + default: + value = va_arg(args, int); + break; + } + fmtint(str, &len, size, value, 10, width, + precision, flags); + break; + case 'X': + flags |= PRINT_F_UP; + /* FALLTHROUGH */ + case 'x': + base = 16; + /* FALLTHROUGH */ + case 'o': + if (base == 0) + base = 8; + /* FALLTHROUGH */ + case 'u': + if (base == 0) + base = 10; + flags |= PRINT_F_UNSIGNED; + switch (cflags) { + case PRINT_C_CHAR: + value = (unsigned char)va_arg(args, + unsigned int); + break; + case PRINT_C_SHORT: + value = (unsigned short int)va_arg(args, + unsigned int); + break; + case PRINT_C_LONG: + value = va_arg(args, unsigned long int); + break; + case PRINT_C_LLONG: + value = va_arg(args, ULLONG); + break; + case PRINT_C_SIZE: + value = va_arg(args, size_t); + break; + case PRINT_C_INTMAX: + value = va_arg(args, UINTMAX_T); + break; + case PRINT_C_PTRDIFF: + value = va_arg(args, UPTRDIFF_T); + break; + default: + value = va_arg(args, unsigned int); + break; + } + fmtint(str, &len, size, value, base, width, + precision, flags); + break; + case 'A': + /* Not yet supported, we'll use "%F". */ + /* FALLTHROUGH */ + case 'E': + if (ch == 'E') + flags |= PRINT_F_TYPE_E; + /* FALLTHROUGH */ + case 'G': + if (ch == 'G') + flags |= PRINT_F_TYPE_G; + /* FALLTHROUGH */ + case 'F': + flags |= PRINT_F_UP; + /* FALLTHROUGH */ + case 'a': + /* Not yet supported, we'll use "%f". */ + /* FALLTHROUGH */ + case 'e': + if (ch == 'e') + flags |= PRINT_F_TYPE_E; + /* FALLTHROUGH */ + case 'g': + if (ch == 'g') + flags |= PRINT_F_TYPE_G; + /* FALLTHROUGH */ + case 'f': + if (cflags == PRINT_C_LDOUBLE) + fvalue = va_arg(args, LDOUBLE); + else + fvalue = va_arg(args, double); + fmtflt(str, &len, size, fvalue, width, + precision, flags, &overflow); + if (overflow) + goto out; + break; + case 'c': + cvalue = va_arg(args, int); + OUTCHAR(str, len, size, cvalue); + break; + case 's': + strvalue = va_arg(args, char *); + fmtstr(str, &len, size, strvalue, width, + precision, flags); + break; + case 'p': + /* + * C99 says: "The value of the pointer is + * converted to a sequence of printing + * characters, in an implementation-defined + * manner." (C99: 7.19.6.1, 8) + */ + if ((strvalue = (const char*)va_arg(args, void *)) == NULL) + /* + * We use the glibc format. BSD prints + * "0x0", SysV "0". + */ + fmtstr(str, &len, size, "(nil)", width, + -1, flags); + else { + /* + * We use the BSD/glibc format. SysV + * omits the "0x" prefix (which we emit + * using the PRINT_F_NUM flag). + */ + flags |= PRINT_F_NUM; + flags |= PRINT_F_UNSIGNED; + fmtint(str, &len, size, + (UINTPTR_T)strvalue, 16, width, + precision, flags); + } + break; + case 'n': + switch (cflags) { + case PRINT_C_CHAR: + charptr = va_arg(args, signed char *); + *charptr = len; + break; + case PRINT_C_SHORT: + shortptr = va_arg(args, short int *); + *shortptr = len; + break; + case PRINT_C_LONG: + longptr = va_arg(args, long int *); + *longptr = len; + break; + case PRINT_C_LLONG: + llongptr = va_arg(args, LLONG *); + *llongptr = len; + break; + case PRINT_C_SIZE: + /* + * C99 says that with the "z" length + * modifier, "a following `n' conversion + * specifier applies to a pointer to a + * signed integer type corresponding to + * size_t argument." (7.19.6.1, 7) + */ + sizeptr = va_arg(args, SSIZE_T *); + *sizeptr = len; + break; + case PRINT_C_INTMAX: + intmaxptr = va_arg(args, INTMAX_T *); + *intmaxptr = len; + break; + case PRINT_C_PTRDIFF: + ptrdiffptr = va_arg(args, PTRDIFF_T *); + *ptrdiffptr = len; + break; + default: + intptr = va_arg(args, int *); + *intptr = len; + break; + } + break; + case '%': /* Print a "%" character verbatim. */ + OUTCHAR(str, len, size, ch); + break; + default: /* Skip other characters. */ + break; + } + ch = *format++; + state = PRINT_S_DEFAULT; + base = cflags = flags = width = 0; + precision = -1; + break; + } +out: + if (len < size) + str[len] = '\0'; + else if (size > 0) + str[size - 1] = '\0'; + + if (overflow || len >= INT_MAX) { + errno = overflow ? EOVERFLOW : ERANGE; + return -1; + } + return (int)len; +} + +static void +fmtstr(char *str, size_t *len, size_t size, const char *value, int width, + int precision, int flags) +{ + int padlen, strln; /* Amount to pad. */ + int noprecision = (precision == -1); + + if (value == NULL) /* We're forgiving. */ + value = "(null)"; + + /* If a precision was specified, don't read the string past it. */ + for (strln = 0; value[strln] != '\0' && + (noprecision || strln < precision); strln++) + continue; + + if ((padlen = width - strln) < 0) + padlen = 0; + if (flags & PRINT_F_MINUS) /* Left justify. */ + padlen = -padlen; + + while (padlen > 0) { /* Leading spaces. */ + OUTCHAR(str, *len, size, ' '); + padlen--; + } + while ((noprecision || precision-- > 0) && *value != '\0') { + OUTCHAR(str, *len, size, *value); + value++; + } + while (padlen < 0) { /* Trailing spaces. */ + OUTCHAR(str, *len, size, ' '); + padlen++; + } +} + +static void +fmtint(char *str, size_t *len, size_t size, INTMAX_T value, int base, int width, + int precision, int flags) +{ + UINTMAX_T uvalue; + char iconvert[MAX_CONVERT_LENGTH]; + char sign = 0; + char hexprefix = 0; + int spadlen = 0; /* Amount to space pad. */ + int zpadlen = 0; /* Amount to zero pad. */ + int pos; + int separators = (flags & PRINT_F_QUOTE); + int noprecision = (precision == -1); + + if (flags & PRINT_F_UNSIGNED) + uvalue = value; + else { + uvalue = (value >= 0) ? value : -value; + if (value < 0) + sign = '-'; + else if (flags & PRINT_F_PLUS) /* Do a sign. */ + sign = '+'; + else if (flags & PRINT_F_SPACE) + sign = ' '; + } + + pos = convert(uvalue, iconvert, sizeof(iconvert), base, + flags & PRINT_F_UP); + + if (flags & PRINT_F_NUM && uvalue != 0) { + /* + * C99 says: "The result is converted to an `alternative form'. + * For `o' conversion, it increases the precision, if and only + * if necessary, to force the first digit of the result to be a + * zero (if the value and precision are both 0, a single 0 is + * printed). For `x' (or `X') conversion, a nonzero result has + * `0x' (or `0X') prefixed to it." (7.19.6.1, 6) + */ + switch (base) { + case 8: + if (precision <= pos) + precision = pos + 1; + break; + case 16: + hexprefix = (flags & PRINT_F_UP) ? 'X' : 'x'; + break; + } + } + + if (separators) /* Get the number of group separators we'll print. */ + separators = getnumsep(pos); + + zpadlen = precision - pos - separators; + spadlen = width /* Minimum field width. */ + - separators /* Number of separators. */ + - MAX(precision, pos) /* Number of integer digits. */ + - ((sign != 0) ? 1 : 0) /* Will we print a sign? */ + - ((hexprefix != 0) ? 2 : 0); /* Will we print a prefix? */ + + if (zpadlen < 0) + zpadlen = 0; + if (spadlen < 0) + spadlen = 0; + + /* + * C99 says: "If the `0' and `-' flags both appear, the `0' flag is + * ignored. For `d', `i', `o', `u', `x', and `X' conversions, if a + * precision is specified, the `0' flag is ignored." (7.19.6.1, 6) + */ + if (flags & PRINT_F_MINUS) /* Left justify. */ + spadlen = -spadlen; + else if (flags & PRINT_F_ZERO && noprecision) { + zpadlen += spadlen; + spadlen = 0; + } + while (spadlen > 0) { /* Leading spaces. */ + OUTCHAR(str, *len, size, ' '); + spadlen--; + } + if (sign != 0) /* Sign. */ + OUTCHAR(str, *len, size, sign); + if (hexprefix != 0) { /* A "0x" or "0X" prefix. */ + OUTCHAR(str, *len, size, '0'); + OUTCHAR(str, *len, size, hexprefix); + } + while (zpadlen > 0) { /* Leading zeros. */ + OUTCHAR(str, *len, size, '0'); + zpadlen--; + } + while (pos > 0) { /* The actual digits. */ + pos--; + OUTCHAR(str, *len, size, iconvert[pos]); + if (separators > 0 && pos > 0 && pos % 3 == 0) + printsep(str, len, size); + } + while (spadlen < 0) { /* Trailing spaces. */ + OUTCHAR(str, *len, size, ' '); + spadlen++; + } +} + +static void +fmtflt(char *str, size_t *len, size_t size, LDOUBLE fvalue, int width, + int precision, int flags, int *overflow) +{ + LDOUBLE ufvalue; + UINTMAX_T intpart; + UINTMAX_T fracpart; + UINTMAX_T mask; + const char *infnan = NULL; + char iconvert[MAX_CONVERT_LENGTH]; + char fconvert[MAX_CONVERT_LENGTH]; + char econvert[5]; /* "e-300" (without nul-termination). */ + char esign = 0; + char sign = 0; + int leadfraczeros = 0; + int exponent = 0; + int emitpoint = 0; + int omitzeros = 0; + int omitcount = 0; + int padlen = 0; + int epos = 0; + int fpos = 0; + int ipos = 0; + int separators = (flags & PRINT_F_QUOTE); + int estyle = (flags & PRINT_F_TYPE_E); +#if HAVE_LOCALECONV && HAVE_LCONV_DECIMAL_POINT + struct lconv *lc = localeconv(); +#endif /* HAVE_LOCALECONV && HAVE_LCONV_DECIMAL_POINT */ + + /* + * AIX' man page says the default is 0, but C99 and at least Solaris' + * and NetBSD's man pages say the default is 6, and sprintf(3) on AIX + * defaults to 6. + */ + if (precision == -1) + precision = 6; + + if (fvalue < 0.0) + sign = '-'; + else if (flags & PRINT_F_PLUS) /* Do a sign. */ + sign = '+'; + else if (flags & PRINT_F_SPACE) + sign = ' '; + + if (ISNAN(fvalue)) + infnan = (flags & PRINT_F_UP) ? "NAN" : "nan"; + else if (ISINF(fvalue)) + infnan = (flags & PRINT_F_UP) ? "INF" : "inf"; + + if (infnan != NULL) { + if (sign != 0) + iconvert[ipos++] = sign; + while (*infnan != '\0') + iconvert[ipos++] = *infnan++; + fmtstr(str, len, size, iconvert, width, ipos, flags); + return; + } + + /* "%e" (or "%E") or "%g" (or "%G") conversion. */ + if (flags & PRINT_F_TYPE_E || flags & PRINT_F_TYPE_G) { + if (flags & PRINT_F_TYPE_G) { + /* + * If the precision is zero, it is treated as one (cf. + * C99: 7.19.6.1, 8). + */ + if (precision == 0) + precision = 1; + /* + * For "%g" (and "%G") conversions, the precision + * specifies the number of significant digits, which + * includes the digits in the integer part. The + * conversion will or will not be using "e-style" (like + * "%e" or "%E" conversions) depending on the precision + * and on the exponent. However, the exponent can be + * affected by rounding the converted value, so we'll + * leave this decision for later. Until then, we'll + * assume that we're going to do an "e-style" conversion + * (in order to get the exponent calculated). For + * "e-style", the precision must be decremented by one. + */ + precision--; + /* + * For "%g" (and "%G") conversions, trailing zeros are + * removed from the fractional portion of the result + * unless the "#" flag was specified. + */ + if (!(flags & PRINT_F_NUM)) + omitzeros = 1; + } + exponent = getexponent(fvalue); + estyle = 1; + } + +again: + /* + * Sorry, we only support 9, 19, or 38 digits (that is, the number of + * digits of the 32-bit, the 64-bit, or the 128-bit UINTMAX_MAX value + * minus one) past the decimal point due to our conversion method. + */ + switch (sizeof(UINTMAX_T)) { + case 16: + if (precision > 38) + precision = 38; + break; + case 8: + if (precision > 19) + precision = 19; + break; + default: + if (precision > 9) + precision = 9; + break; + } + + ufvalue = (fvalue >= 0.0) ? fvalue : -fvalue; + if (estyle) /* We want exactly one integer digit. */ + ufvalue /= mypow10(exponent); + + if ((intpart = cast(ufvalue)) == UINTMAX_MAX) { + *overflow = 1; + return; + } + + /* + * Factor of ten with the number of digits needed for the fractional + * part. For example, if the precision is 3, the mask will be 1000. + */ + mask = mypow10(precision); + /* + * We "cheat" by converting the fractional part to integer by + * multiplying by a factor of ten. + */ + if ((fracpart = myround(mask * (ufvalue - intpart))) >= mask) { + /* + * For example, ufvalue = 2.99962, intpart = 2, and mask = 1000 + * (because precision = 3). Now, myround(1000 * 0.99962) will + * return 1000. So, the integer part must be incremented by one + * and the fractional part must be set to zero. + */ + intpart++; + fracpart = 0; + if (estyle && intpart == 10) { + /* + * The value was rounded up to ten, but we only want one + * integer digit if using "e-style". So, the integer + * part must be set to one and the exponent must be + * incremented by one. + */ + intpart = 1; + exponent++; + } + } + + /* + * Now that we know the real exponent, we can check whether or not to + * use "e-style" for "%g" (and "%G") conversions. If we don't need + * "e-style", the precision must be adjusted and the integer and + * fractional parts must be recalculated from the original value. + * + * C99 says: "Let P equal the precision if nonzero, 6 if the precision + * is omitted, or 1 if the precision is zero. Then, if a conversion + * with style `E' would have an exponent of X: + * + * - if P > X >= -4, the conversion is with style `f' (or `F') and + * precision P - (X + 1). + * + * - otherwise, the conversion is with style `e' (or `E') and precision + * P - 1." (7.19.6.1, 8) + * + * Note that we had decremented the precision by one. + */ + if (flags & PRINT_F_TYPE_G && estyle && + precision + 1 > exponent && exponent >= -4) { + precision -= exponent; + estyle = 0; + goto again; + } + + if (estyle) { + if (exponent < 0) { + exponent = -exponent; + esign = '-'; + } else + esign = '+'; + + /* + * Convert the exponent. The sizeof(econvert) is 5. So, the + * econvert buffer can hold e.g. "e+999" and "e-999". We don't + * support an exponent which contains more than three digits. + * Therefore, the following stores are safe. + */ + epos = convert(exponent, econvert, 3, 10, 0); + /* + * C99 says: "The exponent always contains at least two digits, + * and only as many more digits as necessary to represent the + * exponent." (7.19.6.1, 8) + */ + if (epos == 1) + econvert[epos++] = '0'; + econvert[epos++] = esign; + econvert[epos++] = (flags & PRINT_F_UP) ? 'E' : 'e'; + } + + /* Convert the integer part and the fractional part. */ + ipos = convert(intpart, iconvert, sizeof(iconvert), 10, 0); + if (fracpart != 0) /* convert() would return 1 if fracpart == 0. */ + fpos = convert(fracpart, fconvert, sizeof(fconvert), 10, 0); + + leadfraczeros = precision - fpos; + + if (omitzeros) { + if (fpos > 0) /* Omit trailing fractional part zeros. */ + while (omitcount < fpos && fconvert[omitcount] == '0') + omitcount++; + else { /* The fractional part is zero, omit it completely. */ + omitcount = precision; + leadfraczeros = 0; + } + precision -= omitcount; + } + + /* + * Print a decimal point if either the fractional part is non-zero + * and/or the "#" flag was specified. + */ + if (precision > 0 || flags & PRINT_F_NUM) + emitpoint = 1; + if (separators) /* Get the number of group separators we'll print. */ + separators = getnumsep(ipos); + + padlen = width /* Minimum field width. */ + - ipos /* Number of integer digits. */ + - epos /* Number of exponent characters. */ + - precision /* Number of fractional digits. */ + - separators /* Number of group separators. */ + - (emitpoint ? 1 : 0) /* Will we print a decimal point? */ + - ((sign != 0) ? 1 : 0); /* Will we print a sign character? */ + + if (padlen < 0) + padlen = 0; + + /* + * C99 says: "If the `0' and `-' flags both appear, the `0' flag is + * ignored." (7.19.6.1, 6) + */ + if (flags & PRINT_F_MINUS) /* Left justifty. */ + padlen = -padlen; + else if (flags & PRINT_F_ZERO && padlen > 0) { + if (sign != 0) { /* Sign. */ + OUTCHAR(str, *len, size, sign); + sign = 0; + } + while (padlen > 0) { /* Leading zeros. */ + OUTCHAR(str, *len, size, '0'); + padlen--; + } + } + while (padlen > 0) { /* Leading spaces. */ + OUTCHAR(str, *len, size, ' '); + padlen--; + } + if (sign != 0) /* Sign. */ + OUTCHAR(str, *len, size, sign); + while (ipos > 0) { /* Integer part. */ + ipos--; + OUTCHAR(str, *len, size, iconvert[ipos]); + if (separators > 0 && ipos > 0 && ipos % 3 == 0) + printsep(str, len, size); + } + if (emitpoint) { /* Decimal point. */ +#if HAVE_LOCALECONV && HAVE_LCONV_DECIMAL_POINT + if (lc->decimal_point != NULL && *lc->decimal_point != '\0') + OUTCHAR(str, *len, size, *lc->decimal_point); + else /* We'll always print some decimal point character. */ +#endif /* HAVE_LOCALECONV && HAVE_LCONV_DECIMAL_POINT */ + OUTCHAR(str, *len, size, '.'); + } + while (leadfraczeros > 0) { /* Leading fractional part zeros. */ + OUTCHAR(str, *len, size, '0'); + leadfraczeros--; + } + while (fpos > omitcount) { /* The remaining fractional part. */ + fpos--; + OUTCHAR(str, *len, size, fconvert[fpos]); + } + while (epos > 0) { /* Exponent. */ + epos--; + OUTCHAR(str, *len, size, econvert[epos]); + } + while (padlen < 0) { /* Trailing spaces. */ + OUTCHAR(str, *len, size, ' '); + padlen++; + } +} + +static void +printsep(char *str, size_t *len, size_t size) +{ +#if HAVE_LOCALECONV && HAVE_LCONV_THOUSANDS_SEP + struct lconv *lc = localeconv(); + int i; + + if (lc->thousands_sep != NULL) + for (i = 0; lc->thousands_sep[i] != '\0'; i++) + OUTCHAR(str, *len, size, lc->thousands_sep[i]); + else +#endif /* HAVE_LOCALECONV && HAVE_LCONV_THOUSANDS_SEP */ + OUTCHAR(str, *len, size, ','); +} + +static int +getnumsep(int digits) +{ + int separators = (digits - ((digits % 3 == 0) ? 1 : 0)) / 3; +#if HAVE_LOCALECONV && HAVE_LCONV_THOUSANDS_SEP + int strln; + struct lconv *lc = localeconv(); + + /* We support an arbitrary separator length (including zero). */ + if (lc->thousands_sep != NULL) { + for (strln = 0; lc->thousands_sep[strln] != '\0'; strln++) + continue; + separators *= strln; + } +#endif /* HAVE_LOCALECONV && HAVE_LCONV_THOUSANDS_SEP */ + return separators; +} + +static int +getexponent(LDOUBLE value) +{ + LDOUBLE tmp = (value >= 0.0) ? value : -value; + int exponent = 0; + + /* + * We check for LDOUBLE_MAX_10_EXP >= exponent >= LDOUBLE_MIN_10_EXP in + * order to work around possible endless loops which could happen (at + * least) in the second loop (at least) if we're called with an infinite + * value. However, we checked for infinity before calling this function + * using our ISINF() macro, so this might be somewhat paranoid. + */ + while (tmp < 1.0 && tmp > 0.0 && --exponent >= LDOUBLE_MIN_10_EXP) + tmp *= 10; + while (tmp >= 10.0 && ++exponent <= LDOUBLE_MAX_10_EXP) + tmp /= 10; + + return exponent; +} + +static int +convert(UINTMAX_T value, char *buf, size_t size, int base, int caps) +{ + const char *digits = caps ? "0123456789ABCDEF" : "0123456789abcdef"; + size_t pos = 0; + + /* We return an unterminated buffer with the digits in reverse order. */ + do { + buf[pos++] = digits[value % base]; + value /= base; + } while (value != 0 && pos < size); + + return (int)pos; +} + +static UINTMAX_T +cast(LDOUBLE value) +{ + UINTMAX_T result; + + /* + * We check for ">=" and not for ">" because if UINTMAX_MAX cannot be + * represented exactly as an LDOUBLE value (but is less than LDBL_MAX), + * it may be increased to the nearest higher representable value for the + * comparison (cf. C99: 6.3.1.4, 2). It might then equal the LDOUBLE + * value although converting the latter to UINTMAX_T would overflow. + */ + if (value >= UINTMAX_MAX) + return UINTMAX_MAX; + + result = value; + /* + * At least on NetBSD/sparc64 3.0.2 and 4.99.30, casting long double to + * an integer type converts e.g. 1.9 to 2 instead of 1 (which violates + * the standard). Sigh. + */ + return (result <= value) ? result : result - 1; +} + +static UINTMAX_T +myround(LDOUBLE value) +{ + UINTMAX_T intpart = cast(value); + + if (intpart == UINTMAX_MAX) + return UINTMAX_MAX; + + return ((value -= intpart) < 0.5) ? intpart : intpart + 1; +} + +static LDOUBLE +mypow10(int exponent) +{ + LDOUBLE result = 1; + + while (exponent > 0) { + result *= 10; + exponent--; + } + while (exponent < 0) { + result /= 10; + exponent++; + } + return result; +} +#endif /* !HAVE_VSNPRINTF */ + +#if !HAVE_VASPRINTF +#if NEED_MYMEMCPY +static void * +mymemcpy(void *dst, const void *src, size_t len) +{ + const char *from = (const char *)src; + char *to = (char*)dst; + + /* No need for optimization, we use this only to replace va_copy(3). */ + while (len-- > 0) + *to++ = *from++; + return dst; +} +#endif /* NEED_MYMEMCPY */ + +int +rpl_vasprintf(char **ret, const char *format, va_list ap) +{ + size_t size; + int len; + va_list aq; + + VA_COPY(aq, ap); +#if !HAVE_VSNPRINTF + len = rpl_vsnprintf(NULL, 0, format, aq); +#else + len = vsnprintf(NULL, 0, format, aq); +#endif + VA_END_COPY(aq); + if (len < 0 || (*ret = (char*)malloc(size = len + 1)) == NULL) + return -1; +#if !HAVE_VSNPRINTF + return rpl_vsnprintf(*ret, size, format, ap); +#else + return vsnprintf(*ret, size, format, ap); +#endif +} +#endif /* !HAVE_VASPRINTF */ + +#if !HAVE_SNPRINTF +#if HAVE_STDARG_H +int +rpl_snprintf(char *str, size_t size, const char *format, ...) +#else +int +rpl_snprintf(va_alist) va_dcl +#endif /* HAVE_STDARG_H */ +{ +#if !HAVE_STDARG_H + char *str; + size_t size; + char *format; +#endif /* HAVE_STDARG_H */ + va_list ap; + int len; + + VA_START(ap, format); + VA_SHIFT(ap, str, char *); + VA_SHIFT(ap, size, size_t); + VA_SHIFT(ap, format, const char *); +#if !HAVE_VSNPRINTF + len = rpl_vsnprintf(str, size, format, ap); +#else + len = vsnprintf(str, size, format, ap); +#endif + va_end(ap); + return len; +} +#endif /* !HAVE_SNPRINTF */ + +#if !HAVE_ASPRINTF +#if HAVE_STDARG_H +int +rpl_asprintf(char **ret, const char *format, ...) +#else +int +rpl_asprintf(va_alist) va_dcl +#endif /* HAVE_STDARG_H */ +{ +#if !HAVE_STDARG_H + char **ret; + char *format; +#endif /* HAVE_STDARG_H */ + va_list ap; + int len; + + VA_START(ap, format); + VA_SHIFT(ap, ret, char **); + VA_SHIFT(ap, format, const char *); +#if !HAVE_VASPRINTF + len = rpl_vasprintf(ret, format, ap); +#else + len = vasprintf(ret, format, ap); +#endif + va_end(ap); + return len; +} +#endif /* !HAVE_ASPRINTF */ +#else /* Dummy declaration to avoid empty translation unit warnings. */ +int main(int argc, char **argv); +#endif /* !HAVE_SNPRINTF || !HAVE_VSNPRINTF || !HAVE_ASPRINTF || [...] */ diff --git a/ExternData/Resources/C-Sources/modelica/stdint_msvc.h b/ExternData/Resources/C-Sources/modelica/stdint_msvc.h new file mode 100644 index 0000000..cb2acd9 --- /dev/null +++ b/ExternData/Resources/C-Sources/modelica/stdint_msvc.h @@ -0,0 +1,259 @@ +// ISO C9x compliant stdint.h for Microsoft Visual Studio +// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 +// +// Copyright (c) 2006-2013 Alexander Chemeris +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the product nor the names of its contributors may +// be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _MSC_VER // [ +#error "Use this header only with Microsoft Visual C++ compilers!" +#endif // _MSC_VER ] + +#ifndef _MSC_STDINT_H_ // [ +#define _MSC_STDINT_H_ + +#if _MSC_VER > 1000 +#pragma once +#endif + +#if _MSC_VER >= 1600 // [ +#include +#else // ] _MSC_VER >= 1600 [ + +#include + +// For Visual Studio 6 in C++ mode and for many Visual Studio versions when +// compiling for ARM we should wrap include with 'extern "C++" {}' +// or compiler give many errors like this: +// error C2733: second C linkage of overloaded function 'wmemchr' not allowed +#ifdef __cplusplus +extern "C" { +#endif +# include +#ifdef __cplusplus +} +#endif + +// Define _W64 macros to mark types changing their size, like intptr_t. +#ifndef _W64 +# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 +# define _W64 __w64 +# else +# define _W64 +# endif +#endif + + +// 7.18.1 Integer types + +// 7.18.1.1 Exact-width integer types + +// Visual Studio 6 and Embedded Visual C++ 4 doesn't +// realize that, e.g. char has the same size as __int8 +// so we give up on __intX for them. +#if (_MSC_VER < 1300) + typedef signed char int8_t; + typedef signed short int16_t; + typedef signed int int32_t; + typedef unsigned char uint8_t; + typedef unsigned short uint16_t; + typedef unsigned int uint32_t; +#else + typedef signed __int8 int8_t; + typedef signed __int16 int16_t; + typedef signed __int32 int32_t; + typedef unsigned __int8 uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; +#endif +typedef signed __int64 int64_t; +typedef unsigned __int64 uint64_t; + + +// 7.18.1.2 Minimum-width integer types +typedef int8_t int_least8_t; +typedef int16_t int_least16_t; +typedef int32_t int_least32_t; +typedef int64_t int_least64_t; +typedef uint8_t uint_least8_t; +typedef uint16_t uint_least16_t; +typedef uint32_t uint_least32_t; +typedef uint64_t uint_least64_t; + +// 7.18.1.3 Fastest minimum-width integer types +typedef int8_t int_fast8_t; +typedef int16_t int_fast16_t; +typedef int32_t int_fast32_t; +typedef int64_t int_fast64_t; +typedef uint8_t uint_fast8_t; +typedef uint16_t uint_fast16_t; +typedef uint32_t uint_fast32_t; +typedef uint64_t uint_fast64_t; + +// 7.18.1.4 Integer types capable of holding object pointers +#ifdef _WIN64 // [ + typedef signed __int64 intptr_t; + typedef unsigned __int64 uintptr_t; +#else // _WIN64 ][ + typedef _W64 signed int intptr_t; + typedef _W64 unsigned int uintptr_t; +#endif // _WIN64 ] + +// 7.18.1.5 Greatest-width integer types +typedef int64_t intmax_t; +typedef uint64_t uintmax_t; + + +// 7.18.2 Limits of specified-width integer types + +#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 + +// 7.18.2.1 Limits of exact-width integer types +#define INT8_MIN ((int8_t)_I8_MIN) +#define INT8_MAX _I8_MAX +#define INT16_MIN ((int16_t)_I16_MIN) +#define INT16_MAX _I16_MAX +#define INT32_MIN ((int32_t)_I32_MIN) +#define INT32_MAX _I32_MAX +#define INT64_MIN ((int64_t)_I64_MIN) +#define INT64_MAX _I64_MAX +#define UINT8_MAX _UI8_MAX +#define UINT16_MAX _UI16_MAX +#define UINT32_MAX _UI32_MAX +#define UINT64_MAX _UI64_MAX + +// 7.18.2.2 Limits of minimum-width integer types +#define INT_LEAST8_MIN INT8_MIN +#define INT_LEAST8_MAX INT8_MAX +#define INT_LEAST16_MIN INT16_MIN +#define INT_LEAST16_MAX INT16_MAX +#define INT_LEAST32_MIN INT32_MIN +#define INT_LEAST32_MAX INT32_MAX +#define INT_LEAST64_MIN INT64_MIN +#define INT_LEAST64_MAX INT64_MAX +#define UINT_LEAST8_MAX UINT8_MAX +#define UINT_LEAST16_MAX UINT16_MAX +#define UINT_LEAST32_MAX UINT32_MAX +#define UINT_LEAST64_MAX UINT64_MAX + +// 7.18.2.3 Limits of fastest minimum-width integer types +#define INT_FAST8_MIN INT8_MIN +#define INT_FAST8_MAX INT8_MAX +#define INT_FAST16_MIN INT16_MIN +#define INT_FAST16_MAX INT16_MAX +#define INT_FAST32_MIN INT32_MIN +#define INT_FAST32_MAX INT32_MAX +#define INT_FAST64_MIN INT64_MIN +#define INT_FAST64_MAX INT64_MAX +#define UINT_FAST8_MAX UINT8_MAX +#define UINT_FAST16_MAX UINT16_MAX +#define UINT_FAST32_MAX UINT32_MAX +#define UINT_FAST64_MAX UINT64_MAX + +// 7.18.2.4 Limits of integer types capable of holding object pointers +#ifdef _WIN64 // [ +# define INTPTR_MIN INT64_MIN +# define INTPTR_MAX INT64_MAX +# define UINTPTR_MAX UINT64_MAX +#else // _WIN64 ][ +# define INTPTR_MIN INT32_MIN +# define INTPTR_MAX INT32_MAX +# define UINTPTR_MAX UINT32_MAX +#endif // _WIN64 ] + +// 7.18.2.5 Limits of greatest-width integer types +#define INTMAX_MIN INT64_MIN +#define INTMAX_MAX INT64_MAX +#define UINTMAX_MAX UINT64_MAX + +// 7.18.3 Limits of other integer types + +#ifdef _WIN64 // [ +# define PTRDIFF_MIN _I64_MIN +# define PTRDIFF_MAX _I64_MAX +#else // _WIN64 ][ +# define PTRDIFF_MIN _I32_MIN +# define PTRDIFF_MAX _I32_MAX +#endif // _WIN64 ] + +#define SIG_ATOMIC_MIN INT_MIN +#define SIG_ATOMIC_MAX INT_MAX + +#ifndef SIZE_MAX // [ +# ifdef _WIN64 // [ +# define SIZE_MAX _UI64_MAX +# else // _WIN64 ][ +# define SIZE_MAX _UI32_MAX +# endif // _WIN64 ] +#endif // SIZE_MAX ] + +// WCHAR_MIN and WCHAR_MAX are also defined in +#ifndef WCHAR_MIN // [ +# define WCHAR_MIN 0 +#endif // WCHAR_MIN ] +#ifndef WCHAR_MAX // [ +# define WCHAR_MAX _UI16_MAX +#endif // WCHAR_MAX ] + +#define WINT_MIN 0 +#define WINT_MAX _UI16_MAX + +#endif // __STDC_LIMIT_MACROS ] + + +// 7.18.4 Limits of other integer types + +#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 + +// 7.18.4.1 Macros for minimum-width integer constants + +#define INT8_C(val) val##i8 +#define INT16_C(val) val##i16 +#define INT32_C(val) val##i32 +#define INT64_C(val) val##i64 + +#define UINT8_C(val) val##ui8 +#define UINT16_C(val) val##ui16 +#define UINT32_C(val) val##ui32 +#define UINT64_C(val) val##ui64 + +// 7.18.4.2 Macros for greatest-width integer constants +// These #ifndef's are needed to prevent collisions with . +// Check out Issue 9 for the details. +#ifndef INTMAX_C // [ +# define INTMAX_C INT64_C +#endif // INTMAX_C ] +#ifndef UINTMAX_C // [ +# define UINTMAX_C UINT64_C +#endif // UINTMAX_C ] + +#endif // __STDC_CONSTANT_MACROS ] + +#endif // _MSC_VER >= 1600 ] + +#endif // _MSC_STDINT_H_ ]