From 6cf09f344e9abf8b7ad707bafaa38960639b4ee4 Mon Sep 17 00:00:00 2001 From: Jeremy Bennett Date: Sat, 27 Apr 2019 20:18:25 +0100 Subject: [PATCH] Add scaling and generally clean up BEEBS This is a huge rewrite to get scaling pushed correctly into every benchmark. In the process we have also done the following: - Removed symbolic links to shared code. These just cause issues on other platforms. - Added working verify_benchmark code to all benchmarks. - Remove the src/template directory. It appears in the benchmark results and adds nothing useful for the user. - Corrected assorted bugs, particularly where it is assumed that int is 32-bits long. - Moved BEEBS versions of malloc, rand etc into a library in the main support directory. All benchmarks are now scaled, so that on a RI5CY processor with -O2 GCC, they all take around 4 million cycles with a board REPEAT_FACTOR of 1. ChangeLog: * config/riscv32/boards/ri5cyverilator/boardsupport.h: Change BOARD_REPEAT_FACTOR to 1. * configure: Regenerated. * configure.ac: Allow USER_CFLAGS and USER_LDFLAGS to be configured, remote Makefiles for src/ctl, src/matmult, src/sglib-arraysort, src/template and src/trio directories. * src/Makefile.am: Remove ctl, matmul, sglib-arraysort, template and trio SUBDIRS * src/Makefile.in: Regenerated. * src/aha-compress/Makefile.am: LDADD libbeebs. * src/aha-compress/Makefile.in: Regenerated. * src/aha-compress/compress_test.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. * src/aha-mont64/Makefile.am: LDADD libbeebs. * src/aha-mont64/Makefile.in: Regenerated. * src/aha-mont64/mont64.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. (verify_benchmark): Clean up return calculation. * src/bs/Makefile.am: LDADD libbeebs. * src/bs/Makefile.in: Regenerated. * src/bs/libbs.c: Include string.h, change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value, define NUMVALS. (DATA): Increase size of dataset (binary_search): Parameterize range. (verify_benchmark): Verify all result values using memcmp. (benchmark): Rewrite to make 5 calls to search, repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. * src/bubblesort/Makefile.am: LDADD libbeebs. * src/bubblesort/Makefile.in: Regenerated. * src/bubblesort/libbubblesort.c: Include string.h, change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR, incorporate array initialization into the loop. (initialise_benchmark): Move initialization into main benchmark loop. (verify_benchmark): Clean up array and test result using memcmp. * src/cnt/Makefile.am: LDADD libbeebs. * src/cnt/Makefile.in: Regenerated. * src/cnt/cnt.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR, add initialization into the loop and remove verification from this function. (InitSeed, RandomInteger): Make Seed long int, and update constants with L suffix. (initialize_benchmark): Move initialization into main benchmark loop. (verify_benchmark): Tidy up code. * src/compress/Makefile.am: LDADD libbeebs. * src/compress/Makefile.in: Regenerated. * src/compress/libcompress.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (verify_benchmark): Create version which actually verifies. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. * src/cover/Makefile.am: LDADD libbeebs. * src/cover/Makefile.in: Regenerated. * src/cover/libcover.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. (verify_benchmark): Tidy up. * src/crc/Makefile.am: LDADD libbeebs. * src/crc/Makefile.in: Regenerated. * src/crc/libcrc.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (verify_benchmark): Create version which actually verifies. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR, return result for verification. * src/crc32/Makefile.am: LDADD libbeebs. * src/crc32/Makefile.in: Regenerated. * src/crc32/crc_32.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (rand_beebs): Deleted. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR, return a result which fits in a 16-bit int. (verify_benchmark): Simplify and use 16-bit value. * src/ctl-stack/Makefile.am: LDADD libbeebs. * src/ctl-stack/Makefile.in: Regenerated. * src/ctl-stack/ctl.c: Change to actual file instead of symbolic link. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. (verify-benchmark): Tidy up and check memory not blown up. * src/ctl-stack/ctl.h: Change to actual file instead of symbolic link. * src/ctl-stack/stack.h: Change to actual file instead of symbolic link. * src/ctl-string/Makefile.am: LDADD libbeebs. * src/ctl-string/Makefile.in: Regenerated. * src/ctl-string/string.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (init_heap, malloc_beebs, free_beebs): Deleted. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR, include initialization code in the loop. (initialize_benchmark): Move in to main benchmark function. (verify_benchmark): Simplify and check memory usage. * src/ctl-vector/Makefile.am: LDADD libbeebs. * src/ctl-vector/Makefile.in: Regenerated. * src/ctl-vector/ctl.c:: Change to actual file instead of symbolic link. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. (initialize_benchmark): Move in to main benchmark function. (verify_benchmark): Simplify and check memory usage. * src/ctl-vector/ctl.h:: Change to actual file instead of symbolic link. * src/ctl-vector/vector.h: Change to actual file instead of symbolic link. * src/ctl/.gitignore: Deleted. * src/ctl/Makefile.am: Deleted. * src/ctl/Makefile.in: Deleted. * src/ctl/ctl.c: Deleted. * src/ctl/ctl.h: Deleted. * src/ctl/stack.h: Deleted. * src/ctl/vector.h: Deleted. * src/cubic/Makefile.am: LDADD libbeebs. * src/cubic/Makefile.in: Regenerated. * src/cubic/basicmath_small.c: Include string.h, change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value, add static variables at top level to capture results for verification. (verify_benchmark): Create version which actually verifies. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR, capture results for verification. * src/cubic/libcubic.c (void SolveCubic): Correct type casting throughout. * src/dijkstra/Makefile.am: LDADD libbeebs. * src/dijkstra/Makefile.in: Regenerated. * src/dijkstra/dijkstra_small.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. * src/dtoa/Makefile.am: LDADD libbeebs. * src/dtoa/Makefile.in: Regenerated. * src/dtoa/libdtoa.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (init_heap, malloc_beebs, free_beebs): Deleted. (initialise_benchmark): Contents moved into main benchmark function. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. (verify_benchmark): Simplify and check memory usage. * src/duff/Makefile.am: LDADD libbeebs. * src/duff/Makefile.in: Regenerated. * src/duff/libduff.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value, get rid of superfluous blank lines throughout. (initialise_benchmark): Contents moved into main benchmark function. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. * src/edn/Makefile.am: LDADD libbeebs. * src/edn/Makefile.in: Regenerated. * src/edn/libedn.c: Include string.h, change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR, move initialization into loop. (verify_benchmark): Tidy up and use memcmp to test vector. * src/expint/Makefile.am: LDADD libbeebs. * src/expint/Makefile.in: Regenerated. * src/expint/libexpint.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR, move initialization code into loop. (initialise_benchmark): Contents moved into main benchmark function. (verify_benchmark): Simplify. * src/fac/Makefile.am: LDADD libbeebs. * src/fac/Makefile.in: Regenerated. * src/fac/libfac.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (fac): Make return type long int, so works for 16-bit int. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. (verify_benchmark): Simplify. * src/fasta/Makefile.am: LDADD libbeebs. * src/fasta/Makefile.in: Regenerated. * src/fasta/libfasta.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (accumulate_probabilities): Change to write from input genelist to output genelist, copying content as well as probability. (repeat_fasta): Record result in repeat_res; (random_fasta): Clean up code. (verify_benchmark): Create version which actually verifies. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR, reworking so result can be verified. * src/fdct/Makefile.am: LDADD libbeebs. * src/fdct/Makefile.in: Regenerated. * src/fdct/libfdct.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. * src/fibcall/Makefile.am: LDADD libbeebs. * src/fibcall/Makefile.in: Regenerated. * src/fibcall/libfibcall.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. (verify_benchmark): Simplify. * src/fir/Makefile.am: LDADD libbeebs. * src/fir/Makefile.in: Regenerated. * src/fir/libfir.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (verify_benchmark): Create version which actually verifies. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. * src/frac/Makefile.am: LDADD libbeebs. * src/frac/Makefile.in: Regenerated. * src/frac/libfrac.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (frac): Change to use long int args, so works for 16-bit ints. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR, return result which works for 16-bit ints. (verify_benchmark): Change to work for 16-bit ints. * src/huffbench/Makefile.am: LDADD libbeebs. * src/huffbench/Makefile.in: Regenerated. * src/huffbench/libhuffbench.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (init_heap, malloc_beebs, free_beebs): Deleted. (TEST_SiZE): Change to #define, so can be used to size arrays. (verify_benchmark): Create version which actually verifies. (initialise_benchmark): Contents moved into main benchmark function. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR, do initialization in loop, capture data for verification. * src/insertsort/Makefile.am: LDADD libbeebs. * src/insertsort/Makefile.in: Regenerated. * src/insertsort/libinsertsort.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR, move initialization into loop and simplify using memcpy. (initialise_benchmark): Contents moved into main benchmark function. (verify_benchmark): Simplify using memcpy. * src/janne_complex/Makefile.am: LDADD libbeebs. * src/janne_complex/Makefile.in: Regenerated. * src/janne_complex/libjanne_complex.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR, move initialization into loop and simplify using memcpy. (initialise_benchmark): Contents moved into main benchmark function. (verify_benchmark): Simplify. * src/jfdctint/Makefile.am: LDADD libbeebs. * src/jfdctint/Makefile.in: Regenerated. * src/jfdctint/libjfdctint.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value, include string.h and stdint.h, correctly define type for DCTELEM and INT32, so both are always 32-bits. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR, move initialization into loop and simplify using memcpy. (initialise_benchmark): Contents moved into main benchmark function. (verify_benchmark): Simplify using memcpy. * src/lcdnum/Makefile.am: LDADD libbeebs. * src/lcdnum/Makefile.in: Regenerated. * src/lcdnum/liblcdnum.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (out_vals): Created to capture results. (verify_benchmark): Create version which actually verifies. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR and capture results for verification. * src/levenshtein/Makefile.am: LDADD libbeebs. * src/levenshtein/Makefile.in: Regenerated. * src/levenshtein/liblevenshtein.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. (verify_benchmark): Simplify. * src/ludcmp/Makefile.am: LDADD libbeebs. * src/ludcmp/Makefile.in: Regenerated. * src/ludcmp/libludcmp.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. (verify_benchmark): Tidy up. * src/matmult-float/Makefile.am: LDADD libbeebs. * src/matmult-float/Makefile.in: Regenerated. * src/matmult-float/matmult-float.c: Replace symbolic link to matmult.c and rename, change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. (verify_benchmark): Simplify using memcpy. * src/matmult-float/matmult.c: Symbolic link deleted. * src/matmult-int/Makefile.am: LDADD libbeebs. * src/matmult-int/Makefile.in: Regenerated. * src/matmult-int/matmult-int.c: Replace symbolic link to matmult.c and rename, change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. (verify_benchmark): Simplify using memcpy. * src/matmult/.gitignore: Deleted. * src/matmult/Makefile.am: Deleted. * src/matmult/Makefile.in: Deleted. * src/matmult/matmult.c: Deleted. * src/mergesort/Makefile.am: LDADD libbeebs. * src/mergesort/Makefile.in: Regenerated. * src/mergesort/libmergesort.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (rand_beebs): Deleted. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR, correct function table to use addresses. (verify_benchmark): Simplify using memcpy. * src/miniz/Makefile.am: LDADD libbeebs. * src/miniz/Makefile.in: Regenerated. * src/miniz/miniz.c: Include beebsc.h (init_heap, malloc_beebs, realloc_beebs, free_beebs): Deleted. * src/miniz/miniz_b.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (verify_benchmark): Create version which at least checks for heap overflow. (benchmark): Repeat set to 1, since this benchmark fails. * src/minver/Makefile.am: LDADD libbeebs. * src/minver/Makefile.in: Regenerated. * src/minver/libminver.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value, include math.h and string.h (a_ref): Array created and initialized. (b): Array initialized. (minver_fabs): Make function static. (mmul, minver): Clean up layout. (verify_benchmark): Create version which actually verifies. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR, record results for verifying. * src/nbody/Makefile.am: LDADD libbeebs. * src/nbody/Makefile.in: Regenerated. * src/nbody/nbody.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. * src/ndes/Makefile.am: LDADD libbeebs. * src/ndes/Makefile.in: Regenerated. * src/ndes/libndes.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR, initialize values in loop. (initialise_benchmark): Contents moved into main benchmark function. * src/nettle-aes/Makefile.am: LDADD libbeebs. * src/nettle-aes/Makefile.in: Regenerated. * src/nettle-aes/nettle-aes.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. * src/nettle-arcfour/Makefile.am: LDADD libbeebs. * src/nettle-arcfour/Makefile.in: Regenerated. * src/nettle-arcfour/arcfour.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. * src/nettle-cast128/Makefile.am: LDADD libbeebs. * src/nettle-cast128/Makefile.in: Regenerated. * src/nettle-cast128/cast128.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. * src/nettle-des/Makefile.am: LDADD libbeebs. * src/nettle-des/Makefile.in: Regenerated. * src/nettle-des/des.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. * src/nettle-md5/Makefile.am: LDADD libbeebs. * src/nettle-md5/Makefile.in: Regenerated. * src/nettle-md5/md5.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. * src/nettle-sha256/Makefile.am: LDADD libbeebs. * src/nettle-sha256/Makefile.in: Regenerated. * src/nettle-sha256/nettle-sha256.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. * src/newlib-exp/Makefile.am: LDADD libbeebs. * src/newlib-exp/Makefile.in: Regenerated. * src/newlib-exp/ef_exp.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (verify_benchmark): Create version which actually verifies. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. * src/newlib-log/Makefile.am: LDADD libbeebs. * src/newlib-log/Makefile.in: Regenerated. * src/newlib-log/ef_log.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (verify_benchmark): Create version which actually verifies. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. * src/newlib-mod/Makefile.am: LDADD libbeebs. * src/newlib-mod/Makefile.in: Regenerated. * src/newlib-mod/ef_mod.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (verify_benchmark): Create version which actually verifies. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. * src/newlib-sqrt/Makefile.am: LDADD libbeebs. * src/newlib-sqrt/Makefile.in: Regenerated. * src/newlib-sqrt/ef_sqrt.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. * src/ns/Makefile.am: LDADD libbeebs. * src/ns/Makefile.in: Regenerated. * src/ns/libns.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value, remove superfluous blank lines throughout. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. (verify_benchmark): Create version which actually verifies. * src/nsichneu/Makefile.am: LDADD libbeebs. * src/nsichneu/Makefile.in: Regenerated. * src/nsichneu/libnsichneu.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. * src/picojpeg/Makefile.am: LDADD libbeebs. * src/picojpeg/Makefile.in: Regenerated. * src/picojpeg/libpicojpeg.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value, remove trailing whitespace throughout. * src/picojpeg/picojpeg.h: Remove trailing whitespace throughout. * src/picojpeg/picojpeg_test.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. (verify_benchmark): Create version which actually verifies. * src/prime/Makefile.am: LDADD libbeebs. * src/prime/Makefile.in: Regenerated. * src/prime/libprime.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. (verify_benchmark): Simplify. * src/qrduino/Makefile.am: LDADD libbeebs. * src/qrduino/Makefile.in: Regenerated. * src/qrduino/qrframe.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (init_heap, malloc_beebs, calloc_beebs, free_beebs): Deleted. * src/qrduino/qrtest.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. (verify_benchmark): Simplify using memcpy. * src/qsort/Makefile.am: LDADD libbeebs. * src/qsort/Makefile.in: Regenerated. * src/qsort/libqsort.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (arr_ref): Created and initialized. (void sort): Fixed to work for 0 based arrays. (verify_benchmark): Create version which actually verifies. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. * src/qurt/Makefile.am: LDADD libbeebs. * src/qurt/Makefile.in: Regenerated. * src/qurt/libqurt.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (verify_benchmark): Create version which actually verifies. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. * src/recursion/Makefile.am: LDADD libbeebs. * src/recursion/Makefile.in: Regenerated. * src/recursion/librecursion.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. (verify_benchmark): Simplify. * src/rijndael/Makefile.am: LDADD libbeebs. * src/rijndael/Makefile.in: Regenerated. * src/rijndael/aesxam.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (rand_beebs): Deleted. (verify_benchmark): Create version which actually verifies. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. * src/select/Makefile.am: LDADD libbeebs. * src/select/Makefile.in: Regenerated. * src/select/libselect.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value, include math.h and string.h. (arr_ref): Array created and initialized. (SWAP): Macro deleted. (swap): Created. (select): Rewritten to match text book, for zero based vectors and using the swap function. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR, initialize data in loop. (initialise_benchmark): Move contents into main benchmark function. (verify_benchmark): Create version which actually verifies. * src/sglib-arraybinsearch/Makefile.am: LDADD libbeebs. * src/sglib-arraybinsearch/Makefile.in: Regenerated. * src/sglib-arraybinsearch/arraybinsearch.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. (verify_benchmark): Simplify. * src/sglib-arrayheapsort/Makefile.am: LDADD libbeebs. * src/sglib-arrayheapsort/Makefile.in: Regenerated. * src/sglib-arrayheapsort/arrayheapsort.c: Convert from symbolic link to arraysort and rename. (verify_benchmark): Create version which actually verifies. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. * src/sglib-arrayheapsort/arraysort.c: Symbolic link deleted. * src/sglib-arrayheapsort/sglib.h: Convert from symbolic link. * src/sglib-arrayquicksort/Makefile.am: LDADD libbeebs. * src/sglib-arrayquicksort/Makefile.in: Regenerated. * src/sglib-arrayquicksort/arrayquicksort.c: Convert from symbolic link to arraysort and rename. * src/sglib-arrayquicksort/arraysort.c: Symbolic link deleted. (verify_benchmark): Create version which actually verifies. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. * src/sglib-arrayquicksort/sglib.h: Convert from symbolic link. * src/sglib-arraysort/.gitignore: Deleted. * src/sglib-arraysort/Makefile.am: Deleted. * src/sglib-arraysort/Makefile.in: Deleted. * src/sglib-arraysort/sglib.h: Deleted. * src/sglib-dllist/Makefile.am: LDADD libbeebs. * src/sglib-dllist/Makefile.in: Regenerated. * src/sglib-dllist/dllist.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (init_heap, malloc_beebs, free_beebs): Deleted. (verify_benchmark): Create version which actually verifies. (initialise_benchmark): Move contents into main benchmark function. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR, initialize heap each time rount the loop. * src/sglib-hashtable/Makefile.am: LDADD libbeebs. * src/sglib-hashtable/Makefile.in: Regenerated. * src/sglib-hashtable/hashtable.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (init_heap, malloc_beebs, free_beebs): Deleted. (verify_benchmark): Create version which actually verifies. (initialise_benchmark): Move contents into main benchmark function. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR, initialize heap each time rount the loop. * src/sglib-listinsertsort/Makefile.am: LDADD libbeebs. * src/sglib-listinsertsort/Makefile.in: Regenerated. * src/sglib-listinsertsort/listinsertsort.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (init_heap, malloc_beebs, free_beebs): Deleted. (verify_benchmark): Simplify and also check for heap overrun. (benchmark): Simplify and repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. * src/sglib-listsort/Makefile.am: LDADD libbeebs. * src/sglib-listsort/Makefile.in: Regenerated. * src/sglib-listsort/listsort.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (init_heap, malloc_beebs, free_beebs): Deleted. (verify_benchmark): Simplify and also check for heap overrun. (benchmark): Simplify and repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. * src/sglib-queue/Makefile.am: LDADD libbeebs. * src/sglib-queue/Makefile.in: Regenerated. * src/sglib-queue/queue.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (verify_benchmark): Simplify. (benchmark): Simplify and repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. * src/sglib-rbtree/Makefile.am: LDADD libbeebs. * src/sglib-rbtree/Makefile.in: Regenerated. * src/sglib-rbtree/rbtree.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (init_heap, malloc_beebs, free_beebs): Deleted. (verify_benchmark): Simplify and also check for heap overrun. (benchmark): Simplify and repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. * src/slre/Makefile.am: LDADD libbeebs. * src/slre/Makefile.in: Regenerated. * src/slre/libslre.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. (verify_benchmark): Simplify. * src/sqrt/Makefile.am: LDADD libbeebs. * src/sqrt/Makefile.in: Regenerated. * src/sqrt/libsqrt.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR, return 16-bit result. (verify_benchmark): Simplify to work with 16-bit integers. * src/st/Makefile.am: LDADD libbeebs. * src/st/Makefile.in: Regenerated. * src/st/libst.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. (verify_benchmark): Simplify and make more reliable. * src/statemate/Makefile.am: LDADD libbeebs. * src/statemate/Makefile.in: Regenerated. * src/statemate/libstatemate.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR, initialize in loop. (initialise_benchmark): Move contents into main benchmark function. (verify-benchmark): Tidy up. * src/stb_perlin/Makefile.am: LDADD libbeebs. * src/stb_perlin/Makefile.in: Regenerated. * src/stb_perlin/libstb_perlin.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (verify_benchmark): Create version which actually verifies. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. * src/stringsearch1/Makefile.am: LDADD libbeebs. * src/stringsearch1/Makefile.in: Regenerated. * src/stringsearch1/stringsearch1.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. (verify_benchmark): Simplify. * src/strstr/Makefile.am: LDADD libbeebs. * src/strstr/Makefile.in: Regenerated. * src/strstr/libstrstr.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. * src/tarai/Makefile.am: LDADD libbeebs. * src/tarai/Makefile.in: Regenerated. * src/tarai/libtarai.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. (verify_benchmark): Simplify. * src/template/.gitignore: Deleted. * src/template/Makefile.am: Deleted. * src/template/Makefile.in: Deleted. * src/template/libtemplate.c: Deleted. * src/trio-snprintf/Makefile.am: LDADD libbeebs. * src/trio-snprintf/Makefile.in: Regenerated. * src/trio-snprintf/trio.c: Convert from symbolic link. * src/trio-snprintf/trio.h: Convert from symbolic link * src/trio-snprintf/trio_test.c: Convert from symbolic link, change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value.q (verify_benchmark): Improved. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR, capture all outputs. * src/trio-snprintf/triodef.h: Convert from symbolic link * src/trio-snprintf/triop.h: Convert from symbolic link * src/trio-snprintf/triostr.c: Convert from symbolic link. (struct _trio_string_t): (internal_string_alloc): * src/trio-snprintf/triostr.h: Convert from symbolic link * src/trio-sscanf/Makefile.am: LDADD libbeebs. * src/trio-sscanf/Makefile.in: Regenerated. * src/trio-sscanf/trio.c: Convert from symbolic link. * src/trio-sscanf/trio.h: Convert from symbolic link. * src/trio-sscanf/trio_test.c: Convert from symbolic link, change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value.q (verify_benchmark): Improved. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR, capture all inputs. * src/trio-sscanf/triodef.h: Convert from symbolic link. * src/trio-sscanf/triop.h: Convert from symbolic link. * src/trio-sscanf/triostr.c: Convert from symbolic link. * src/trio-sscanf/triostr.h: Convert from symbolic link. * src/trio/.gitignore: Deleted. * src/trio/Makefile.am: Deleted. * src/trio/Makefile.in: Deleted. * src/trio/trio.c: Deleted. * src/trio/trio.h: Deleted. * src/trio/trio_test.c: Deleted. * src/trio/triodef.h: Deleted. * src/trio/triop.h: Deleted. * src/trio/triostr.c: Deleted. * src/trio/triostr.h: Deleted. * src/ud/Makefile.am: LDADD libbeebs. * src/ud/Makefile.in: Regenerated. * src/ud/libud.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (verify_benchmark): Create version which actually verifies. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. * src/whetstone/Makefile.am: LDADD libbeebs. * src/whetstone/Makefile.in: Regenerated. * src/whetstone/libwhetstone.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (verify_benchmark): Create version which actually verifies. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. * src/wikisort/Makefile.am: LDADD libbeebs. * src/wikisort/Makefile.in: Regenerated. * src/wikisort/libwikisort.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. (rand_beebs): Deleted. (verify_benchmark): Create version which actually verifies. (benchmark): Repeat according to LOCAL_SCALE_FACTOR and REPEAT_FACTOR, correct use of addresses in function table. * support/Makefile.am: Created libbeebs.la, with associated source files. * support/Makefile.in: Regenerated. * support/beebsc.c: Created. * support/beebsc.h: Created. * support/main.c (main): Remove loop for calling benchmark, all scaling now in individual benchmarks. * support/support.h: Include beebsc.h --- ChangeLog | 729 ++ .../boards/ri5cyverilator/boardsupport.h | 2 +- configure | 13 +- configure.ac | 11 +- src/Makefile.am | 5 - src/Makefile.in | 5 - src/aha-compress/Makefile.am | 3 +- src/aha-compress/Makefile.in | 4 +- src/aha-compress/compress_test.c | 66 +- src/aha-mont64/Makefile.am | 3 +- src/aha-mont64/Makefile.in | 4 +- src/aha-mont64/mont64.c | 146 +- src/bs/Makefile.am | 3 +- src/bs/Makefile.in | 7 +- src/bs/libbs.c | 80 +- src/bubblesort/Makefile.am | 3 +- src/bubblesort/Makefile.in | 4 +- src/bubblesort/libbubblesort.c | 62 +- src/cnt/Makefile.am | 3 +- src/cnt/Makefile.in | 7 +- src/cnt/cnt.c | 37 +- src/compress/Makefile.am | 3 +- src/compress/Makefile.in | 4 +- src/compress/libcompress.c | 75 +- src/cover/Makefile.am | 1 + src/cover/Makefile.in | 2 + src/cover/libcover.c | 25 +- src/crc/Makefile.am | 3 +- src/crc/Makefile.in | 7 +- src/crc/libcrc.c | 26 +- src/crc32/Makefile.am | 1 + src/crc32/Makefile.in | 2 + src/crc32/crc_32.c | 41 +- src/ctl-stack/Makefile.am | 3 +- src/ctl-stack/Makefile.in | 4 +- src/ctl-stack/ctl.c | 135 +- src/ctl-stack/ctl.h | 75 +- src/ctl-stack/stack.h | 121 +- src/ctl-string/Makefile.am | 3 +- src/ctl-string/Makefile.in | 4 +- src/ctl-string/string.c | 117 +- src/ctl-vector/Makefile.am | 3 +- src/ctl-vector/Makefile.in | 4 +- src/ctl-vector/ctl.c | 136 +- src/ctl-vector/ctl.h | 75 +- src/ctl-vector/vector.h | 240 +- src/ctl/.gitignore | 1 - src/ctl/Makefile.am | 26 - src/ctl/Makefile.in | 480 - src/ctl/ctl.c | 203 - src/ctl/ctl.h | 74 - src/ctl/stack.h | 120 - src/ctl/vector.h | 239 - src/cubic/Makefile.am | 1 + src/cubic/Makefile.in | 2 + src/cubic/basicmath_small.c | 74 +- src/cubic/libcubic.c | 33 +- src/dijkstra/Makefile.am | 3 +- src/dijkstra/Makefile.in | 4 +- src/dijkstra/dijkstra_small.c | 23 +- src/dtoa/Makefile.am | 3 +- src/dtoa/Makefile.in | 7 +- src/dtoa/libdtoa.c | 68 +- src/duff/Makefile.am | 3 +- src/duff/Makefile.in | 7 +- src/duff/libduff.c | 59 +- src/edn/Makefile.am | 3 +- src/edn/Makefile.in | 7 +- src/edn/libedn.c | 180 +- src/expint/Makefile.am | 3 +- src/expint/Makefile.in | 4 +- src/expint/libexpint.c | 22 +- src/fac/Makefile.am | 3 +- src/fac/Makefile.in | 7 +- src/fac/libfac.c | 32 +- src/fasta/Makefile.am | 1 + src/fasta/Makefile.in | 2 + src/fasta/libfasta.c | 91 +- src/fdct/Makefile.am | 3 +- src/fdct/Makefile.in | 7 +- src/fdct/libfdct.c | 12 +- src/fibcall/Makefile.am | 3 +- src/fibcall/Makefile.in | 4 +- src/fibcall/libfibcall.c | 20 +- src/fir/Makefile.am | 3 +- src/fir/Makefile.in | 7 +- src/fir/libfir.c | 28 +- src/frac/Makefile.am | 3 +- src/frac/Makefile.in | 7 +- src/frac/libfrac.c | 27 +- src/huffbench/Makefile.am | 3 +- src/huffbench/Makefile.in | 4 +- src/huffbench/libhuffbench.c | 92 +- src/insertsort/Makefile.am | 3 +- src/insertsort/Makefile.in | 4 +- src/insertsort/libinsertsort.c | 55 +- src/janne_complex/Makefile.am | 3 +- src/janne_complex/Makefile.in | 4 +- src/janne_complex/libjanne_complex.c | 32 +- src/jfdctint/Makefile.am | 3 +- src/jfdctint/Makefile.in | 4 +- src/jfdctint/libjfdctint.c | 63 +- src/lcdnum/Makefile.am | 3 +- src/lcdnum/Makefile.in | 4 +- src/lcdnum/liblcdnum.c | 43 +- src/levenshtein/Makefile.am | 3 +- src/levenshtein/Makefile.in | 4 +- src/levenshtein/liblevenshtein.c | 27 +- src/ludcmp/Makefile.am | 3 +- src/ludcmp/Makefile.in | 4 +- src/ludcmp/libludcmp.c | 107 +- src/matmult-float/Makefile.am | 3 +- src/matmult-float/Makefile.in | 20 +- src/matmult-float/matmult-float.c | 212 + src/matmult-float/matmult.c | 1 - src/matmult-int/Makefile.am | 5 +- src/matmult-int/Makefile.in | 22 +- src/matmult-int/matmult-int.c | 265 + src/matmult-int/matmult.c | 1 - src/matmult/.gitignore | 1 - src/matmult/Makefile.am | 26 - src/matmult/Makefile.in | 480 - src/matmult/matmult.c | 228 - src/mergesort/Makefile.am | 3 +- src/mergesort/Makefile.in | 4 +- src/mergesort/libmergesort.c | 153 +- src/miniz/Makefile.am | 3 +- src/miniz/Makefile.in | 4 +- src/miniz/miniz.c | 81 +- src/miniz/miniz_b.c | 15 +- src/minver/Makefile.am | 4 +- src/minver/Makefile.in | 7 +- src/minver/libminver.c | 294 +- src/nbody/Makefile.am | 1 + src/nbody/Makefile.in | 2 + src/nbody/nbody.c | 22 +- src/ndes/Makefile.am | 3 +- src/ndes/Makefile.in | 7 +- src/ndes/libndes.c | 21 +- src/nettle-aes/Makefile.am | 3 +- src/nettle-aes/Makefile.in | 4 +- src/nettle-aes/nettle-aes.c | 15 +- src/nettle-arcfour/Makefile.am | 3 +- src/nettle-arcfour/Makefile.in | 4 +- src/nettle-arcfour/arcfour.c | 21 +- src/nettle-cast128/Makefile.am | 3 +- src/nettle-cast128/Makefile.in | 4 +- src/nettle-cast128/cast128.c | 11 +- src/nettle-des/Makefile.am | 3 +- src/nettle-des/Makefile.in | 4 +- src/nettle-des/des.c | 13 +- src/nettle-md5/Makefile.am | 3 +- src/nettle-md5/Makefile.in | 4 +- src/nettle-md5/md5.c | 12 +- src/nettle-sha256/Makefile.am | 3 +- src/nettle-sha256/Makefile.in | 4 +- src/nettle-sha256/nettle-sha256.c | 20 +- src/newlib-exp/Makefile.am | 6 +- src/newlib-exp/Makefile.in | 8 +- src/newlib-exp/ef_exp.c | 27 +- src/newlib-log/Makefile.am | 4 +- src/newlib-log/Makefile.in | 8 +- src/newlib-log/ef_log.c | 27 +- src/newlib-mod/Makefile.am | 6 +- src/newlib-mod/Makefile.in | 8 +- src/newlib-mod/ef_mod.c | 30 +- src/newlib-sqrt/Makefile.am | 3 +- src/newlib-sqrt/Makefile.in | 4 +- src/newlib-sqrt/ef_sqrt.c | 23 +- src/ns/Makefile.am | 3 +- src/ns/Makefile.in | 7 +- src/ns/libns.c | 563 +- src/nsichneu/Makefile.am | 3 +- src/nsichneu/Makefile.in | 4 +- src/nsichneu/libnsichneu.c | 5290 ++++++----- src/picojpeg/Makefile.am | 3 +- src/picojpeg/Makefile.in | 4 +- src/picojpeg/libpicojpeg.c | 310 +- src/picojpeg/picojpeg.h | 20 +- src/picojpeg/picojpeg_test.c | 183 +- src/prime/Makefile.am | 1 + src/prime/Makefile.in | 2 + src/prime/libprime.c | 24 +- src/qrduino/Makefile.am | 10 +- src/qrduino/Makefile.in | 12 +- src/qrduino/qrframe.c | 66 +- src/qrduino/qrtest.c | 55 +- src/qsort/Makefile.am | 1 + src/qsort/Makefile.in | 2 + src/qsort/libqsort.c | 39 +- src/qurt/Makefile.am | 6 +- src/qurt/Makefile.in | 10 +- src/qurt/libqurt.c | 30 +- src/recursion/Makefile.am | 3 +- src/recursion/Makefile.in | 4 +- src/recursion/librecursion.c | 19 +- src/rijndael/Makefile.am | 3 +- src/rijndael/Makefile.in | 4 +- src/rijndael/aesxam.c | 135 +- src/select/Makefile.am | 4 +- src/select/Makefile.in | 7 +- src/select/libselect.c | 162 +- src/sglib-arraybinsearch/Makefile.am | 3 +- src/sglib-arraybinsearch/Makefile.in | 4 +- src/sglib-arraybinsearch/arraybinsearch.c | 35 +- src/sglib-arrayheapsort/Makefile.am | 5 +- src/sglib-arrayheapsort/Makefile.in | 22 +- .../arrayheapsort.c} | 43 +- src/sglib-arrayheapsort/arraysort.c | 1 - src/sglib-arrayheapsort/sglib.h | 1966 ++++- src/sglib-arrayquicksort/Makefile.am | 5 +- src/sglib-arrayquicksort/Makefile.in | 22 +- src/sglib-arrayquicksort/arrayquicksort.c | 84 + src/sglib-arrayquicksort/arraysort.c | 1 - src/sglib-arrayquicksort/sglib.h | 1966 ++++- src/sglib-arraysort/.gitignore | 1 - src/sglib-arraysort/Makefile.am | 26 - src/sglib-arraysort/Makefile.in | 480 - src/sglib-arraysort/sglib.h | 1965 ----- src/sglib-dllist/Makefile.am | 3 +- src/sglib-dllist/Makefile.in | 4 +- src/sglib-dllist/dllist.c | 111 +- src/sglib-hashtable/Makefile.am | 3 +- src/sglib-hashtable/Makefile.in | 4 +- src/sglib-hashtable/hashtable.c | 107 +- src/sglib-listinsertsort/Makefile.am | 3 +- src/sglib-listinsertsort/Makefile.in | 4 +- src/sglib-listinsertsort/listinsertsort.c | 111 +- src/sglib-listsort/Makefile.am | 3 +- src/sglib-listsort/Makefile.in | 4 +- src/sglib-listsort/listsort.c | 107 +- src/sglib-queue/Makefile.am | 3 +- src/sglib-queue/Makefile.in | 4 +- src/sglib-queue/queue.c | 65 +- src/sglib-rbtree/Makefile.am | 3 +- src/sglib-rbtree/Makefile.in | 4 +- src/sglib-rbtree/rbtree.c | 100 +- src/slre/Makefile.am | 3 +- src/slre/Makefile.in | 7 +- src/slre/libslre.c | 34 +- src/sqrt/Makefile.am | 3 +- src/sqrt/Makefile.in | 7 +- src/sqrt/libsqrt.c | 25 +- src/st/Makefile.am | 3 +- src/st/Makefile.in | 7 +- src/st/libst.c | 84 +- src/statemate/Makefile.am | 3 +- src/statemate/Makefile.in | 4 +- src/statemate/libstatemate.c | 26 +- src/stb_perlin/Makefile.am | 3 +- src/stb_perlin/Makefile.in | 4 +- src/stb_perlin/libstb_perlin.c | 95 +- src/stringsearch1/Makefile.am | 3 +- src/stringsearch1/Makefile.in | 4 +- src/stringsearch1/stringsearch1.c | 24 +- src/strstr/Makefile.am | 3 +- src/strstr/Makefile.in | 4 +- src/strstr/libstrstr.c | 24 +- src/tarai/Makefile.am | 1 + src/tarai/Makefile.in | 2 + src/tarai/libtarai.c | 14 +- src/template/.gitignore | 1 - src/template/Makefile.am | 53 - src/template/Makefile.in | 759 -- src/template/libtemplate.c | 57 - src/trio-snprintf/Makefile.am | 3 +- src/trio-snprintf/Makefile.in | 4 +- src/trio-snprintf/trio.c | 7759 +++++++++++++++- src/trio-snprintf/trio.h | 261 +- src/trio-snprintf/trio_test.c | 76 +- src/trio-snprintf/triodef.h | 355 +- src/trio-snprintf/triop.h | 492 +- src/trio-snprintf/triostr.c | 2405 ++++- src/trio-snprintf/triostr.h | 700 +- src/trio-sscanf/Makefile.am | 3 +- src/trio-sscanf/Makefile.in | 4 +- src/trio-sscanf/trio.c | 7759 +++++++++++++++- src/trio-sscanf/trio.h | 261 +- src/trio-sscanf/trio_test.c | 76 +- src/trio-sscanf/triodef.h | 355 +- src/trio-sscanf/triop.h | 492 +- src/trio-sscanf/triostr.c | 2405 ++++- src/trio-sscanf/triostr.h | 700 +- src/trio/.gitignore | 1 - src/trio/Makefile.am | 26 - src/trio/Makefile.in | 480 - src/trio/trio.c | 7839 ----------------- src/trio/trio.h | 259 - src/trio/trio_test.c | 97 - src/trio/triodef.h | 354 - src/trio/triop.h | 491 -- src/trio/triostr.c | 2404 ----- src/trio/triostr.h | 699 -- src/ud/Makefile.am | 3 +- src/ud/Makefile.in | 7 +- src/ud/libud.c | 62 +- src/whetstone/Makefile.am | 1 + src/whetstone/Makefile.in | 2 + src/whetstone/libwhetstone.c | 21 +- src/wikisort/Makefile.am | 1 + src/wikisort/Makefile.in | 2 + src/wikisort/libwikisort.c | 199 +- support/Makefile.am | 17 +- support/Makefile.in | 37 +- support/beebsc.c | 177 + support/beebsc.h | 50 + support/main.c | 9 +- support/support.h | 4 + 308 files changed, 35939 insertions(+), 23791 deletions(-) mode change 120000 => 100644 src/ctl-stack/ctl.c mode change 120000 => 100644 src/ctl-stack/ctl.h mode change 120000 => 100644 src/ctl-stack/stack.h mode change 120000 => 100644 src/ctl-vector/ctl.c mode change 120000 => 100644 src/ctl-vector/ctl.h mode change 120000 => 100644 src/ctl-vector/vector.h delete mode 100644 src/ctl/.gitignore delete mode 100644 src/ctl/Makefile.am delete mode 100644 src/ctl/Makefile.in delete mode 100644 src/ctl/ctl.c delete mode 100644 src/ctl/ctl.h delete mode 100644 src/ctl/stack.h delete mode 100644 src/ctl/vector.h create mode 100644 src/matmult-float/matmult-float.c delete mode 120000 src/matmult-float/matmult.c create mode 100644 src/matmult-int/matmult-int.c delete mode 120000 src/matmult-int/matmult.c delete mode 100644 src/matmult/.gitignore delete mode 100644 src/matmult/Makefile.am delete mode 100644 src/matmult/Makefile.in delete mode 100644 src/matmult/matmult.c rename src/{sglib-arraysort/arraysort.c => sglib-arrayheapsort/arrayheapsort.c} (65%) delete mode 120000 src/sglib-arrayheapsort/arraysort.c mode change 120000 => 100644 src/sglib-arrayheapsort/sglib.h create mode 100644 src/sglib-arrayquicksort/arrayquicksort.c delete mode 120000 src/sglib-arrayquicksort/arraysort.c mode change 120000 => 100644 src/sglib-arrayquicksort/sglib.h delete mode 100644 src/sglib-arraysort/.gitignore delete mode 100644 src/sglib-arraysort/Makefile.am delete mode 100644 src/sglib-arraysort/Makefile.in delete mode 100644 src/sglib-arraysort/sglib.h delete mode 100644 src/template/.gitignore delete mode 100644 src/template/Makefile.am delete mode 100644 src/template/Makefile.in delete mode 100644 src/template/libtemplate.c mode change 120000 => 100644 src/trio-snprintf/trio.c mode change 120000 => 100644 src/trio-snprintf/trio.h mode change 120000 => 100644 src/trio-snprintf/trio_test.c mode change 120000 => 100644 src/trio-snprintf/triodef.h mode change 120000 => 100644 src/trio-snprintf/triop.h mode change 120000 => 100644 src/trio-snprintf/triostr.c mode change 120000 => 100644 src/trio-snprintf/triostr.h mode change 120000 => 100644 src/trio-sscanf/trio.c mode change 120000 => 100644 src/trio-sscanf/trio.h mode change 120000 => 100644 src/trio-sscanf/trio_test.c mode change 120000 => 100644 src/trio-sscanf/triodef.h mode change 120000 => 100644 src/trio-sscanf/triop.h mode change 120000 => 100644 src/trio-sscanf/triostr.c mode change 120000 => 100644 src/trio-sscanf/triostr.h delete mode 100644 src/trio/.gitignore delete mode 100644 src/trio/Makefile.am delete mode 100644 src/trio/Makefile.in delete mode 100644 src/trio/trio.c delete mode 100644 src/trio/trio.h delete mode 100644 src/trio/trio_test.c delete mode 100644 src/trio/triodef.h delete mode 100644 src/trio/triop.h delete mode 100644 src/trio/triostr.c delete mode 100644 src/trio/triostr.h create mode 100644 support/beebsc.c create mode 100644 support/beebsc.h diff --git a/ChangeLog b/ChangeLog index 71094e59..abaf2247 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,732 @@ +2019-04-27 Jeremy Bennett + + This is a huge rewrite to get scaling pushed correctly into every + benchmark. In the process we have also done the following: + + - Removed symbolic links to shared code. These just cause issues + on other platforms. + + - Remove the src/template directory. It appears in the benchmark + results and adds nothing useful for the user. + + - Added working verify_benchmark code to all benchmarks. + + - Corrected assorted bugs, particularly where it is assumed that + int is 32-bits long. + + - Moved BEEBS versions of malloc, rand etc into a library in the + main support directory. + + All benchmarks are now scaled, so that on a RI5CY processor with + -O2 GCC, they all take around 4 million cycles with a board + REPEAT_FACTOR of 1. + + * config/riscv32/boards/ri5cyverilator/boardsupport.h: Change + BOARD_REPEAT_FACTOR to 1. + * configure: Regenerated. + * configure.ac: Allow USER_CFLAGS and USER_LDFLAGS to be + configured, remote Makefiles for src/ctl, src/matmult, + src/sglib-arraysort, src/template and src/trio directories. + * src/Makefile.am: Remove ctl, matmul, sglib-arraysort, template + and trio SUBDIRS + * src/Makefile.in: + Regenerated. + * src/aha-compress/Makefile.am: LDADD libbeebs. + * src/aha-compress/Makefile.in: Regenerated. + * src/aha-compress/compress_test.c: Change SCALE_FACTOR to + LOCAL_SCALE_FACTOR and update value. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR. + * src/aha-mont64/Makefile.am: LDADD libbeebs. + * src/aha-mont64/Makefile.in: Regenerated. + * src/aha-mont64/mont64.c: Change SCALE_FACTOR to + LOCAL_SCALE_FACTOR and update value. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR. + (verify_benchmark): Clean up return calculation. + * src/bs/Makefile.am: LDADD libbeebs. + * src/bs/Makefile.in: Regenerated. + * src/bs/libbs.c: Include string.h, change SCALE_FACTOR to + LOCAL_SCALE_FACTOR and update value, define NUMVALS. + (DATA): Increase size of dataset + (binary_search): Parameterize range. + (verify_benchmark): Verify all result values using memcmp. + (benchmark): Rewrite to make 5 calls to search, repeat according + to LOCAL_SCALE_FACTOR and REPEAT_FACTOR. + * src/bubblesort/Makefile.am: LDADD libbeebs. + * src/bubblesort/Makefile.in: Regenerated. + * src/bubblesort/libbubblesort.c: Include string.h, change + SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR, incorporate array initialization into the loop. + (initialise_benchmark): Move initialization into main benchmark + loop. + (verify_benchmark): Clean up array and test result using memcmp. + * src/cnt/Makefile.am: LDADD libbeebs. + * src/cnt/Makefile.in: Regenerated. + * src/cnt/cnt.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and + update value. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR, add initialization into the loop and remove + verification from this function. + (InitSeed, RandomInteger): Make Seed long int, and update + constants with L suffix. + (initialize_benchmark): Move initialization into main benchmark + loop. + (verify_benchmark): Tidy up code. + * src/compress/Makefile.am: LDADD libbeebs. + * src/compress/Makefile.in: Regenerated. + * src/compress/libcompress.c: Change SCALE_FACTOR to + LOCAL_SCALE_FACTOR and update value. + (verify_benchmark): Create version which actually verifies. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR. + * src/cover/Makefile.am: LDADD libbeebs. + * src/cover/Makefile.in: Regenerated. + * src/cover/libcover.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR + and update value. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR. + (verify_benchmark): Tidy up. + * src/crc/Makefile.am: LDADD libbeebs. + * src/crc/Makefile.in: Regenerated. + * src/crc/libcrc.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and + update value. + (verify_benchmark): Create version which actually verifies. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR, return result for verification. + * src/crc32/Makefile.am: LDADD libbeebs. + * src/crc32/Makefile.in: Regenerated. + * src/crc32/crc_32.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR + and update value. + (rand_beebs): Deleted. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR, return a result which fits in a 16-bit int. + (verify_benchmark): Simplify and use 16-bit value. + * src/ctl-stack/Makefile.am: LDADD libbeebs. + * src/ctl-stack/Makefile.in: Regenerated. + * src/ctl-stack/ctl.c: Change to actual file instead of symbolic + link. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR. + (verify-benchmark): Tidy up and check memory not blown up. + * src/ctl-stack/ctl.h: Change to actual file instead of symbolic + link. + * src/ctl-stack/stack.h: Change to actual file instead of symbolic + link. + * src/ctl-string/Makefile.am: LDADD libbeebs. + * src/ctl-string/Makefile.in: Regenerated. + * src/ctl-string/string.c: Change SCALE_FACTOR to + LOCAL_SCALE_FACTOR and update value. + (init_heap, malloc_beebs, free_beebs): Deleted. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR, include initialization code in the loop. + (initialize_benchmark): Move in to main benchmark function. + (verify_benchmark): Simplify and check memory usage. + * src/ctl-vector/Makefile.am: LDADD libbeebs. + * src/ctl-vector/Makefile.in: Regenerated. + * src/ctl-vector/ctl.c:: Change to actual file instead of symbolic + link. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR. + (initialize_benchmark): Move in to main benchmark function. + (verify_benchmark): Simplify and check memory usage. + * src/ctl-vector/ctl.h:: Change to actual file instead of symbolic + link. + * src/ctl-vector/vector.h: Change to actual file instead of + symbolic link. + * src/ctl/.gitignore: Deleted. + * src/ctl/Makefile.am: Deleted. + * src/ctl/Makefile.in: Deleted. + * src/ctl/ctl.c: Deleted. + * src/ctl/ctl.h: Deleted. + * src/ctl/stack.h: Deleted. + * src/ctl/vector.h: Deleted. + * src/cubic/Makefile.am: LDADD libbeebs. + * src/cubic/Makefile.in: Regenerated. + * src/cubic/basicmath_small.c: Include string.h, change + SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value, add static + variables at top level to capture results for verification. + (verify_benchmark): Create version which actually verifies. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR, capture results for verification. + * src/cubic/libcubic.c (void SolveCubic): Correct type casting + throughout. + * src/dijkstra/Makefile.am: LDADD libbeebs. + * src/dijkstra/Makefile.in: Regenerated. + * src/dijkstra/dijkstra_small.c: Change SCALE_FACTOR to + LOCAL_SCALE_FACTOR and update value. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR. + * src/dtoa/Makefile.am: LDADD libbeebs. + * src/dtoa/Makefile.in: Regenerated. + * src/dtoa/libdtoa.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR + and update value. + (init_heap, malloc_beebs, free_beebs): Deleted. + (initialise_benchmark): Contents moved into main benchmark + function. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR. + (verify_benchmark): Simplify and check memory usage. + * src/duff/Makefile.am: LDADD libbeebs. + * src/duff/Makefile.in: Regenerated. + * src/duff/libduff.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR + and update value, get rid of superfluous blank lines throughout. + (initialise_benchmark): Contents moved into main benchmark + function. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR. + * src/edn/Makefile.am: LDADD libbeebs. + * src/edn/Makefile.in: Regenerated. + * src/edn/libedn.c: Include string.h, change SCALE_FACTOR to + LOCAL_SCALE_FACTOR and update value. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR, move initialization into loop. + (verify_benchmark): Tidy up and use memcmp to test vector. + * src/expint/Makefile.am: LDADD libbeebs. + * src/expint/Makefile.in: Regenerated. + * src/expint/libexpint.c: Change SCALE_FACTOR to + LOCAL_SCALE_FACTOR and update value. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR, move initialization code into loop. + (initialise_benchmark): Contents moved into main benchmark + function. + (verify_benchmark): Simplify. + * src/fac/Makefile.am: LDADD libbeebs. + * src/fac/Makefile.in: Regenerated. + * src/fac/libfac.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and + update value. + (fac): Make return type long int, so works for 16-bit int. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR. + (verify_benchmark): Simplify. + * src/fasta/Makefile.am: LDADD libbeebs. + * src/fasta/Makefile.in: Regenerated. + * src/fasta/libfasta.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR + and update value. + (accumulate_probabilities): Change to write from input genelist to + output genelist, copying content as well as probability. + (repeat_fasta): Record result in repeat_res; + (random_fasta): Clean up code. + (verify_benchmark): Create version which actually verifies. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR, reworking so result can be verified. + * src/fdct/Makefile.am: LDADD libbeebs. + * src/fdct/Makefile.in: Regenerated. + * src/fdct/libfdct.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR + and update value. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR. + * src/fibcall/Makefile.am: LDADD libbeebs. + * src/fibcall/Makefile.in: Regenerated. + * src/fibcall/libfibcall.c: Change SCALE_FACTOR to + LOCAL_SCALE_FACTOR and update value. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR. + (verify_benchmark): Simplify. + * src/fir/Makefile.am: LDADD libbeebs. + * src/fir/Makefile.in: Regenerated. + * src/fir/libfir.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and + update value. + (verify_benchmark): Create version which actually verifies. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR. + * src/frac/Makefile.am: LDADD libbeebs. + * src/frac/Makefile.in: Regenerated. + * src/frac/libfrac.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR + and update value. + (frac): Change to use long int args, so works for 16-bit ints. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR, return result which works for 16-bit ints. + (verify_benchmark): Change to work for 16-bit ints. + * src/huffbench/Makefile.am: LDADD libbeebs. + * src/huffbench/Makefile.in: Regenerated. + * src/huffbench/libhuffbench.c: Change SCALE_FACTOR to + LOCAL_SCALE_FACTOR and update value. + (init_heap, malloc_beebs, free_beebs): Deleted. + (TEST_SiZE): Change to #define, so can be used to size arrays. + (verify_benchmark): Create version which actually verifies. + (initialise_benchmark): Contents moved into main benchmark + function. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR, do initialization in loop, capture data for + verification. + * src/insertsort/Makefile.am: LDADD libbeebs. + * src/insertsort/Makefile.in: Regenerated. + * src/insertsort/libinsertsort.c: Change SCALE_FACTOR to + LOCAL_SCALE_FACTOR and update value. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR, move initialization into loop and simplify using + memcpy. + (initialise_benchmark): Contents moved into main benchmark + function. + (verify_benchmark): Simplify using memcpy. + * src/janne_complex/Makefile.am: LDADD libbeebs. + * src/janne_complex/Makefile.in: Regenerated. + * src/janne_complex/libjanne_complex.c: Change SCALE_FACTOR to + LOCAL_SCALE_FACTOR and update value. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR, move initialization into loop and simplify using + memcpy. + (initialise_benchmark): Contents moved into main benchmark + function. + (verify_benchmark): Simplify. + * src/jfdctint/Makefile.am: LDADD libbeebs. + * src/jfdctint/Makefile.in: Regenerated. + * src/jfdctint/libjfdctint.c: Change SCALE_FACTOR to + LOCAL_SCALE_FACTOR and update value, include string.h and + stdint.h, correctly define type for DCTELEM and INT32, so both are + always 32-bits. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR, move initialization into loop and simplify using + memcpy. + (initialise_benchmark): Contents moved into main benchmark + function. + (verify_benchmark): Simplify using memcpy. + * src/lcdnum/Makefile.am: LDADD libbeebs. + * src/lcdnum/Makefile.in: Regenerated. + * src/lcdnum/liblcdnum.c: Change SCALE_FACTOR to + LOCAL_SCALE_FACTOR and update value. + (out_vals): Created to capture results. + (verify_benchmark): Create version which actually verifies. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR and capture results for verification. + * src/levenshtein/Makefile.am: LDADD libbeebs. + * src/levenshtein/Makefile.in: Regenerated. + * src/levenshtein/liblevenshtein.c: Change SCALE_FACTOR to + LOCAL_SCALE_FACTOR and update value. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR. + (verify_benchmark): Simplify. + * src/ludcmp/Makefile.am: LDADD libbeebs. + * src/ludcmp/Makefile.in: Regenerated. + * src/ludcmp/libludcmp.c: Change SCALE_FACTOR to + LOCAL_SCALE_FACTOR and update value. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR. + (verify_benchmark): Tidy up. + * src/matmult-float/Makefile.am: LDADD libbeebs. + * src/matmult-float/Makefile.in: Regenerated. + * src/matmult-float/matmult-float.c: Replace symbolic link to + matmult.c and rename, change SCALE_FACTOR to LOCAL_SCALE_FACTOR + and update value. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR. + (verify_benchmark): Simplify using memcpy. + * src/matmult-float/matmult.c: Symbolic link deleted. + * src/matmult-int/Makefile.am: LDADD libbeebs. + * src/matmult-int/Makefile.in: Regenerated. + * src/matmult-int/matmult-int.c: Replace symbolic link to + matmult.c and rename, change SCALE_FACTOR to LOCAL_SCALE_FACTOR + and update value. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR. + (verify_benchmark): Simplify using memcpy. + * src/matmult/.gitignore: Deleted. + * src/matmult/Makefile.am: Deleted. + * src/matmult/Makefile.in: Deleted. + * src/matmult/matmult.c: Deleted. + * src/mergesort/Makefile.am: LDADD libbeebs. + * src/mergesort/Makefile.in: Regenerated. + * src/mergesort/libmergesort.c: Change SCALE_FACTOR to + LOCAL_SCALE_FACTOR and update value. + (rand_beebs): Deleted. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR, correct function table to use addresses. + (verify_benchmark): Simplify using memcpy. + * src/miniz/Makefile.am: LDADD libbeebs. + * src/miniz/Makefile.in: Regenerated. + * src/miniz/miniz.c: Include beebsc.h + (init_heap, malloc_beebs, realloc_beebs, free_beebs): Deleted. + * src/miniz/miniz_b.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR + and update value. + (verify_benchmark): Create version which at least checks for heap + overflow. + (benchmark): Repeat set to 1, since this benchmark fails. + * src/minver/Makefile.am: LDADD libbeebs. + * src/minver/Makefile.in: Regenerated. + * src/minver/libminver.c: Change SCALE_FACTOR to + LOCAL_SCALE_FACTOR and update value, include math.h and string.h + (a_ref): Array created and initialized. + (b): Array initialized. + (minver_fabs): Make function static. + (mmul, minver): Clean up layout. + (verify_benchmark): Create version which actually verifies. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR, record results for verifying. + * src/nbody/Makefile.am: LDADD libbeebs. + * src/nbody/Makefile.in: Regenerated. + * src/nbody/nbody.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and + update value. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR. + * src/ndes/Makefile.am: LDADD libbeebs. + * src/ndes/Makefile.in: Regenerated. + * src/ndes/libndes.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR + and update value. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR, initialize values in loop. + (initialise_benchmark): Contents moved into main benchmark + function. + * src/nettle-aes/Makefile.am: LDADD libbeebs. + * src/nettle-aes/Makefile.in: Regenerated. + * src/nettle-aes/nettle-aes.c: Change SCALE_FACTOR to + LOCAL_SCALE_FACTOR and update value. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR. + * src/nettle-arcfour/Makefile.am: LDADD libbeebs. + * src/nettle-arcfour/Makefile.in: Regenerated. + * src/nettle-arcfour/arcfour.c: Change SCALE_FACTOR to + LOCAL_SCALE_FACTOR and update value. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR. + * src/nettle-cast128/Makefile.am: LDADD libbeebs. + * src/nettle-cast128/Makefile.in: Regenerated. + * src/nettle-cast128/cast128.c: Change SCALE_FACTOR to + LOCAL_SCALE_FACTOR and update value. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR. + * src/nettle-des/Makefile.am: LDADD libbeebs. + * src/nettle-des/Makefile.in: Regenerated. + * src/nettle-des/des.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR + and update value. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR. + * src/nettle-md5/Makefile.am: LDADD libbeebs. + * src/nettle-md5/Makefile.in: Regenerated. + * src/nettle-md5/md5.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR + and update value. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR. + * src/nettle-sha256/Makefile.am: LDADD libbeebs. + * src/nettle-sha256/Makefile.in: Regenerated. + * src/nettle-sha256/nettle-sha256.c: Change SCALE_FACTOR to + LOCAL_SCALE_FACTOR and update value. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR. + * src/newlib-exp/Makefile.am: LDADD libbeebs. + * src/newlib-exp/Makefile.in: Regenerated. + * src/newlib-exp/ef_exp.c: Change SCALE_FACTOR to + LOCAL_SCALE_FACTOR and update value. + (verify_benchmark): Create version which actually verifies. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR. + * src/newlib-log/Makefile.am: LDADD libbeebs. + * src/newlib-log/Makefile.in: Regenerated. + * src/newlib-log/ef_log.c: Change SCALE_FACTOR to + LOCAL_SCALE_FACTOR and update value. + (verify_benchmark): Create version which actually verifies. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR. + * src/newlib-mod/Makefile.am: LDADD libbeebs. + * src/newlib-mod/Makefile.in: Regenerated. + * src/newlib-mod/ef_mod.c: Change SCALE_FACTOR to + LOCAL_SCALE_FACTOR and update value. + (verify_benchmark): Create version which actually verifies. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR. + * src/newlib-sqrt/Makefile.am: LDADD libbeebs. + * src/newlib-sqrt/Makefile.in: Regenerated. + * src/newlib-sqrt/ef_sqrt.c: Change SCALE_FACTOR to + LOCAL_SCALE_FACTOR and update value. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR. + * src/ns/Makefile.am: LDADD libbeebs. + * src/ns/Makefile.in: Regenerated. + * src/ns/libns.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and + update value, remove superfluous blank lines throughout. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR. + (verify_benchmark): Create version which actually verifies. + * src/nsichneu/Makefile.am: LDADD libbeebs. + * src/nsichneu/Makefile.in: Regenerated. + * src/nsichneu/libnsichneu.c: Change SCALE_FACTOR to + LOCAL_SCALE_FACTOR and update value. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR. + * src/picojpeg/Makefile.am: LDADD libbeebs. + * src/picojpeg/Makefile.in: Regenerated. + * src/picojpeg/libpicojpeg.c: Change SCALE_FACTOR to + LOCAL_SCALE_FACTOR and update value, remove trailing whitespace + throughout. + * src/picojpeg/picojpeg.h: Remove trailing whitespace throughout. + * src/picojpeg/picojpeg_test.c: Change SCALE_FACTOR to + LOCAL_SCALE_FACTOR and update value. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR. + (verify_benchmark): Create version which actually verifies. + * src/prime/Makefile.am: LDADD libbeebs. + * src/prime/Makefile.in: Regenerated. + * src/prime/libprime.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR + and update value. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR. + (verify_benchmark): Simplify. + * src/qrduino/Makefile.am: LDADD libbeebs. + * src/qrduino/Makefile.in: Regenerated. + * src/qrduino/qrframe.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR + and update value. + (init_heap, malloc_beebs, calloc_beebs, free_beebs): Deleted. + * src/qrduino/qrtest.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR + and update value. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR. + (verify_benchmark): Simplify using memcpy. + * src/qsort/Makefile.am: LDADD libbeebs. + * src/qsort/Makefile.in: Regenerated. + * src/qsort/libqsort.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR + and update value. + (arr_ref): Created and initialized. + (void sort): Fixed to work for 0 based arrays. + (verify_benchmark): Create version which actually verifies. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR. + * src/qurt/Makefile.am: LDADD libbeebs. + * src/qurt/Makefile.in: Regenerated. + * src/qurt/libqurt.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR + and update value. + (verify_benchmark): Create version which actually verifies. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR. + * src/recursion/Makefile.am: LDADD libbeebs. + * src/recursion/Makefile.in: Regenerated. + * src/recursion/librecursion.c: Change SCALE_FACTOR to + LOCAL_SCALE_FACTOR and update value. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR. + (verify_benchmark): Simplify. + * src/rijndael/Makefile.am: LDADD libbeebs. + * src/rijndael/Makefile.in: Regenerated. + * src/rijndael/aesxam.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR + and update value. + (rand_beebs): Deleted. + (verify_benchmark): Create version which actually verifies. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR. + * src/select/Makefile.am: LDADD libbeebs. + * src/select/Makefile.in: Regenerated. + * src/select/libselect.c: Change SCALE_FACTOR to + LOCAL_SCALE_FACTOR and update value, include math.h and string.h. + (arr_ref): Array created and initialized. + (SWAP): Macro deleted. + (swap): Created. + (select): Rewritten to match text book, for zero based vectors and + using the swap function. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR, initialize data in loop. + (initialise_benchmark): Move contents into main benchmark + function. + (verify_benchmark): Create version which actually verifies. + * src/sglib-arraybinsearch/Makefile.am: LDADD libbeebs. + * src/sglib-arraybinsearch/Makefile.in: Regenerated. + * src/sglib-arraybinsearch/arraybinsearch.c: Change SCALE_FACTOR + to LOCAL_SCALE_FACTOR and update value. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR. + (verify_benchmark): Simplify. + * src/sglib-arrayheapsort/Makefile.am: LDADD libbeebs. + * src/sglib-arrayheapsort/Makefile.in: Regenerated. + * src/sglib-arrayheapsort/arrayheapsort.c: Convert from symbolic + link to arraysort and rename. + (verify_benchmark): Create version which actually verifies. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR. + * src/sglib-arrayheapsort/arraysort.c: Symbolic link deleted. + * src/sglib-arrayheapsort/sglib.h: Convert from symbolic link. + * src/sglib-arrayquicksort/Makefile.am: LDADD libbeebs. + * src/sglib-arrayquicksort/Makefile.in: Regenerated. + * src/sglib-arrayquicksort/arrayquicksort.c: Convert from symbolic + link to arraysort and rename. + * src/sglib-arrayquicksort/arraysort.c: Symbolic link deleted. + (verify_benchmark): Create version which actually verifies. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR. + * src/sglib-arrayquicksort/sglib.h: Convert from symbolic link. + * src/sglib-arraysort/.gitignore: Deleted. + * src/sglib-arraysort/Makefile.am: Deleted. + * src/sglib-arraysort/Makefile.in: Deleted. + * src/sglib-arraysort/sglib.h: Deleted. + * src/sglib-dllist/Makefile.am: LDADD libbeebs. + * src/sglib-dllist/Makefile.in: Regenerated. + * src/sglib-dllist/dllist.c: Change SCALE_FACTOR to + LOCAL_SCALE_FACTOR and update value. + (init_heap, malloc_beebs, free_beebs): Deleted. + (verify_benchmark): Create version which actually verifies. + (initialise_benchmark): Move contents into main benchmark + function. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR, initialize heap each time rount the loop. + * src/sglib-hashtable/Makefile.am: LDADD libbeebs. + * src/sglib-hashtable/Makefile.in: Regenerated. + * src/sglib-hashtable/hashtable.c: Change SCALE_FACTOR to + LOCAL_SCALE_FACTOR and update value. + (init_heap, malloc_beebs, free_beebs): Deleted. + (verify_benchmark): Create version which actually verifies. + (initialise_benchmark): Move contents into main benchmark + function. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR, initialize heap each time rount the loop. + * src/sglib-listinsertsort/Makefile.am: LDADD libbeebs. + * src/sglib-listinsertsort/Makefile.in: Regenerated. + * src/sglib-listinsertsort/listinsertsort.c: Change SCALE_FACTOR + to LOCAL_SCALE_FACTOR and update value. + (init_heap, malloc_beebs, free_beebs): Deleted. + (verify_benchmark): Simplify and also check for heap overrun. + (benchmark): Simplify and repeat according to LOCAL_SCALE_FACTOR + and REPEAT_FACTOR. + * src/sglib-listsort/Makefile.am: LDADD libbeebs. + * src/sglib-listsort/Makefile.in: Regenerated. + * src/sglib-listsort/listsort.c: Change SCALE_FACTOR to + LOCAL_SCALE_FACTOR and update value. + (init_heap, malloc_beebs, free_beebs): Deleted. + (verify_benchmark): Simplify and also check for heap overrun. + (benchmark): Simplify and repeat according to LOCAL_SCALE_FACTOR + and REPEAT_FACTOR. + * src/sglib-queue/Makefile.am: LDADD libbeebs. + * src/sglib-queue/Makefile.in: Regenerated. + * src/sglib-queue/queue.c: Change SCALE_FACTOR to + LOCAL_SCALE_FACTOR and update value. + (verify_benchmark): Simplify. + (benchmark): Simplify and repeat according to LOCAL_SCALE_FACTOR + and REPEAT_FACTOR. + * src/sglib-rbtree/Makefile.am: LDADD libbeebs. + * src/sglib-rbtree/Makefile.in: Regenerated. + * src/sglib-rbtree/rbtree.c: Change SCALE_FACTOR to + LOCAL_SCALE_FACTOR and update value. + (init_heap, malloc_beebs, free_beebs): Deleted. + (verify_benchmark): Simplify and also check for heap overrun. + (benchmark): Simplify and repeat according to LOCAL_SCALE_FACTOR + and REPEAT_FACTOR. + * src/slre/Makefile.am: LDADD libbeebs. + * src/slre/Makefile.in: Regenerated. + * src/slre/libslre.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR + and update value. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR. + (verify_benchmark): Simplify. + * src/sqrt/Makefile.am: LDADD libbeebs. + * src/sqrt/Makefile.in: Regenerated. + * src/sqrt/libsqrt.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR + and update value. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR, return 16-bit result. + (verify_benchmark): Simplify to work with 16-bit integers. + * src/st/Makefile.am: LDADD libbeebs. + * src/st/Makefile.in: Regenerated. + * src/st/libst.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and + update value. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR. + (verify_benchmark): Simplify and make more reliable. + * src/statemate/Makefile.am: LDADD libbeebs. + * src/statemate/Makefile.in: Regenerated. + * src/statemate/libstatemate.c: Change SCALE_FACTOR to + LOCAL_SCALE_FACTOR and update value. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR, initialize in loop. + (initialise_benchmark): Move contents into main benchmark + function. + (verify-benchmark): Tidy up. + * src/stb_perlin/Makefile.am: LDADD libbeebs. + * src/stb_perlin/Makefile.in: Regenerated. + * src/stb_perlin/libstb_perlin.c: Change SCALE_FACTOR to + LOCAL_SCALE_FACTOR and update value. + (verify_benchmark): Create version which actually verifies. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR. + * src/stringsearch1/Makefile.am: LDADD libbeebs. + * src/stringsearch1/Makefile.in: Regenerated. + * src/stringsearch1/stringsearch1.c: Change SCALE_FACTOR to + LOCAL_SCALE_FACTOR and update value. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR. + (verify_benchmark): Simplify. + * src/strstr/Makefile.am: LDADD libbeebs. + * src/strstr/Makefile.in: Regenerated. + * src/strstr/libstrstr.c: Change SCALE_FACTOR to + LOCAL_SCALE_FACTOR and update value. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR. + * src/tarai/Makefile.am: LDADD libbeebs. + * src/tarai/Makefile.in: Regenerated. + * src/tarai/libtarai.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR + and update value. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR. + (verify_benchmark): Simplify. + * src/template/.gitignore: Deleted. + * src/template/Makefile.am: Deleted. + * src/template/Makefile.in: Deleted. + * src/template/libtemplate.c: Deleted. + * src/trio-snprintf/Makefile.am: LDADD libbeebs. + * src/trio-snprintf/Makefile.in: Regenerated. + * src/trio-snprintf/trio.c: Convert from symbolic link. + * src/trio-snprintf/trio.h: Convert from symbolic link + * src/trio-snprintf/trio_test.c: Convert from symbolic link, + change SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value.q + (verify_benchmark): Improved. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR, capture all outputs. + * src/trio-snprintf/triodef.h: Convert from symbolic link + * src/trio-snprintf/triop.h: Convert from symbolic link + * src/trio-snprintf/triostr.c: Convert from symbolic link. + (struct _trio_string_t): + (internal_string_alloc): + * src/trio-snprintf/triostr.h: Convert from symbolic link + * src/trio-sscanf/Makefile.am: LDADD libbeebs. + * src/trio-sscanf/Makefile.in: Regenerated. + * src/trio-sscanf/trio.c: Convert from symbolic link. + * src/trio-sscanf/trio.h: Convert from symbolic link. + * src/trio-sscanf/trio_test.c: Convert from symbolic link, change + SCALE_FACTOR to LOCAL_SCALE_FACTOR and update value.q + (verify_benchmark): Improved. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR, capture all inputs. + * src/trio-sscanf/triodef.h: Convert from symbolic link. + * src/trio-sscanf/triop.h: Convert from symbolic link. + * src/trio-sscanf/triostr.c: Convert from symbolic link. + * src/trio-sscanf/triostr.h: Convert from symbolic link. + * src/trio/.gitignore: Deleted. + * src/trio/Makefile.am: Deleted. + * src/trio/Makefile.in: Deleted. + * src/trio/trio.c: Deleted. + * src/trio/trio.h: Deleted. + * src/trio/trio_test.c: Deleted. + * src/trio/triodef.h: Deleted. + * src/trio/triop.h: Deleted. + * src/trio/triostr.c: Deleted. + * src/trio/triostr.h: Deleted. + * src/ud/Makefile.am: LDADD libbeebs. + * src/ud/Makefile.in: Regenerated. + * src/ud/libud.c: Change SCALE_FACTOR to LOCAL_SCALE_FACTOR and + update value. + (verify_benchmark): Create version which actually verifies. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR. + * src/whetstone/Makefile.am: LDADD libbeebs. + * src/whetstone/Makefile.in: Regenerated. + * src/whetstone/libwhetstone.c: Change SCALE_FACTOR to + LOCAL_SCALE_FACTOR and update value. + (verify_benchmark): Create version which actually verifies. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR. + * src/wikisort/Makefile.am: LDADD libbeebs. + * src/wikisort/Makefile.in: Regenerated. + * src/wikisort/libwikisort.c: Change SCALE_FACTOR to + LOCAL_SCALE_FACTOR and update value. + (rand_beebs): Deleted. + (verify_benchmark): Create version which actually verifies. + (benchmark): Repeat according to LOCAL_SCALE_FACTOR and + REPEAT_FACTOR, correct use of addresses in function table. + * support/Makefile.am: Created libbeebs.la, with associated source + files. + * support/Makefile.in: Regenerated. + * support/beebsc.c: Created. + * support/beebsc.h: Created. + * support/main.c (main): Remove loop for calling benchmark, all + scaling now in individual benchmarks. + * support/support.h: Include beebsc.h + 2019-04-24 Jeremy Bennett * Makefile.in: Regenerated. diff --git a/config/riscv32/boards/ri5cyverilator/boardsupport.h b/config/riscv32/boards/ri5cyverilator/boardsupport.h index 1a037e2c..af557b7a 100644 --- a/config/riscv32/boards/ri5cyverilator/boardsupport.h +++ b/config/riscv32/boards/ri5cyverilator/boardsupport.h @@ -17,4 +17,4 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -#define BOARD_REPEAT_FACTOR 32 +#define BOARD_REPEAT_FACTOR 1 diff --git a/configure b/configure index 5835ad79..2f42a39b 100755 --- a/configure +++ b/configure @@ -5126,8 +5126,10 @@ else fi -# Architecture, board and chip specific and user CFLAGS and LDFLAGS -CFLAGS="$CFLAGS $ARCH_CFLAGS $CHIP_CFLAGS $BOARD_CFLAGS $USER_CFLAGS" +# Architecture, board and chip specific and user CFLAGS and LDFLAGS. Note that +# we always compile with debug info, although this can be overridden by +# USER_CFLAGS +CFLAGS="$CFLAGS $ARCH_CFLAGS $CHIP_CFLAGS $BOARD_CFLAGS -g3 $USER_CFLAGS" LDFLAGS="$LDFLAGS $ARCH_LDFLAGS $CHIP_LDFLAGS $BOARD_LDFLAGS $USER_LDFLAGS" case `pwd` in @@ -15267,7 +15269,7 @@ ac_config_headers="$ac_config_headers config.h" # Generate makefiles -ac_config_files="$ac_config_files Makefile doc/Makefile src/Makefile src/aha-compress/Makefile src/aha-mont64/Makefile src/bs/Makefile src/bubblesort/Makefile src/cnt/Makefile src/compress/Makefile src/cover/Makefile src/crc/Makefile src/crc32/Makefile src/ctl/Makefile src/ctl-stack/Makefile src/ctl-string/Makefile src/ctl-vector/Makefile src/cubic/Makefile src/dijkstra/Makefile src/dtoa/Makefile src/duff/Makefile src/edn/Makefile src/expint/Makefile src/fac/Makefile src/fasta/Makefile src/fdct/Makefile src/fibcall/Makefile src/fir/Makefile src/frac/Makefile src/huffbench/Makefile src/insertsort/Makefile src/janne_complex/Makefile src/jfdctint/Makefile src/lcdnum/Makefile src/levenshtein/Makefile src/ludcmp/Makefile src/matmult/Makefile src/matmult-float/Makefile src/matmult-int/Makefile src/mergesort/Makefile src/miniz/Makefile src/minver/Makefile src/nbody/Makefile src/ndes/Makefile src/nettle-aes/Makefile src/nettle-arcfour/Makefile src/nettle-cast128/Makefile src/nettle-des/Makefile src/nettle-md5/Makefile src/nettle-sha256/Makefile src/newlib-exp/Makefile src/newlib-log/Makefile src/newlib-mod/Makefile src/newlib-sqrt/Makefile src/ns/Makefile src/nsichneu/Makefile src/picojpeg/Makefile src/prime/Makefile src/qrduino/Makefile src/qsort/Makefile src/qurt/Makefile src/recursion/Makefile src/rijndael/Makefile src/select/Makefile src/sglib-arraybinsearch/Makefile src/sglib-arrayheapsort/Makefile src/sglib-arrayquicksort/Makefile src/sglib-arraysort/Makefile src/sglib-dllist/Makefile src/sglib-hashtable/Makefile src/sglib-listinsertsort/Makefile src/sglib-listsort/Makefile src/sglib-queue/Makefile src/sglib-rbtree/Makefile src/slre/Makefile src/sqrt/Makefile src/st/Makefile src/statemate/Makefile src/stb_perlin/Makefile src/stringsearch1/Makefile src/strstr/Makefile src/tarai/Makefile src/template/Makefile src/trio/Makefile src/trio-snprintf/Makefile src/trio-sscanf/Makefile src/ud/Makefile src/whetstone/Makefile src/wikisort/Makefile support/Makefile testsuite/Makefile testsuite/beebs.test/Makefile testsuite/config/Makefile testsuite/lib/Makefile" +ac_config_files="$ac_config_files Makefile doc/Makefile src/Makefile src/aha-compress/Makefile src/aha-mont64/Makefile src/bs/Makefile src/bubblesort/Makefile src/cnt/Makefile src/compress/Makefile src/cover/Makefile src/crc/Makefile src/crc32/Makefile src/ctl-stack/Makefile src/ctl-string/Makefile src/ctl-vector/Makefile src/cubic/Makefile src/dijkstra/Makefile src/dtoa/Makefile src/duff/Makefile src/edn/Makefile src/expint/Makefile src/fac/Makefile src/fasta/Makefile src/fdct/Makefile src/fibcall/Makefile src/fir/Makefile src/frac/Makefile src/huffbench/Makefile src/insertsort/Makefile src/janne_complex/Makefile src/jfdctint/Makefile src/lcdnum/Makefile src/levenshtein/Makefile src/ludcmp/Makefile src/matmult-float/Makefile src/matmult-int/Makefile src/mergesort/Makefile src/miniz/Makefile src/minver/Makefile src/nbody/Makefile src/ndes/Makefile src/nettle-aes/Makefile src/nettle-arcfour/Makefile src/nettle-cast128/Makefile src/nettle-des/Makefile src/nettle-md5/Makefile src/nettle-sha256/Makefile src/newlib-exp/Makefile src/newlib-log/Makefile src/newlib-mod/Makefile src/newlib-sqrt/Makefile src/ns/Makefile src/nsichneu/Makefile src/picojpeg/Makefile src/prime/Makefile src/qrduino/Makefile src/qsort/Makefile src/qurt/Makefile src/recursion/Makefile src/rijndael/Makefile src/select/Makefile src/sglib-arraybinsearch/Makefile src/sglib-arrayheapsort/Makefile src/sglib-arrayquicksort/Makefile src/sglib-dllist/Makefile src/sglib-hashtable/Makefile src/sglib-listinsertsort/Makefile src/sglib-listsort/Makefile src/sglib-queue/Makefile src/sglib-rbtree/Makefile src/slre/Makefile src/sqrt/Makefile src/st/Makefile src/statemate/Makefile src/stb_perlin/Makefile src/stringsearch1/Makefile src/strstr/Makefile src/tarai/Makefile src/trio-snprintf/Makefile src/trio-sscanf/Makefile src/ud/Makefile src/whetstone/Makefile src/wikisort/Makefile support/Makefile testsuite/Makefile testsuite/beebs.test/Makefile testsuite/config/Makefile testsuite/lib/Makefile" # And spit it all out @@ -16643,7 +16645,6 @@ do "src/cover/Makefile") CONFIG_FILES="$CONFIG_FILES src/cover/Makefile" ;; "src/crc/Makefile") CONFIG_FILES="$CONFIG_FILES src/crc/Makefile" ;; "src/crc32/Makefile") CONFIG_FILES="$CONFIG_FILES src/crc32/Makefile" ;; - "src/ctl/Makefile") CONFIG_FILES="$CONFIG_FILES src/ctl/Makefile" ;; "src/ctl-stack/Makefile") CONFIG_FILES="$CONFIG_FILES src/ctl-stack/Makefile" ;; "src/ctl-string/Makefile") CONFIG_FILES="$CONFIG_FILES src/ctl-string/Makefile" ;; "src/ctl-vector/Makefile") CONFIG_FILES="$CONFIG_FILES src/ctl-vector/Makefile" ;; @@ -16666,7 +16667,6 @@ do "src/lcdnum/Makefile") CONFIG_FILES="$CONFIG_FILES src/lcdnum/Makefile" ;; "src/levenshtein/Makefile") CONFIG_FILES="$CONFIG_FILES src/levenshtein/Makefile" ;; "src/ludcmp/Makefile") CONFIG_FILES="$CONFIG_FILES src/ludcmp/Makefile" ;; - "src/matmult/Makefile") CONFIG_FILES="$CONFIG_FILES src/matmult/Makefile" ;; "src/matmult-float/Makefile") CONFIG_FILES="$CONFIG_FILES src/matmult-float/Makefile" ;; "src/matmult-int/Makefile") CONFIG_FILES="$CONFIG_FILES src/matmult-int/Makefile" ;; "src/mergesort/Makefile") CONFIG_FILES="$CONFIG_FILES src/mergesort/Makefile" ;; @@ -16697,7 +16697,6 @@ do "src/sglib-arraybinsearch/Makefile") CONFIG_FILES="$CONFIG_FILES src/sglib-arraybinsearch/Makefile" ;; "src/sglib-arrayheapsort/Makefile") CONFIG_FILES="$CONFIG_FILES src/sglib-arrayheapsort/Makefile" ;; "src/sglib-arrayquicksort/Makefile") CONFIG_FILES="$CONFIG_FILES src/sglib-arrayquicksort/Makefile" ;; - "src/sglib-arraysort/Makefile") CONFIG_FILES="$CONFIG_FILES src/sglib-arraysort/Makefile" ;; "src/sglib-dllist/Makefile") CONFIG_FILES="$CONFIG_FILES src/sglib-dllist/Makefile" ;; "src/sglib-hashtable/Makefile") CONFIG_FILES="$CONFIG_FILES src/sglib-hashtable/Makefile" ;; "src/sglib-listinsertsort/Makefile") CONFIG_FILES="$CONFIG_FILES src/sglib-listinsertsort/Makefile" ;; @@ -16712,8 +16711,6 @@ do "src/stringsearch1/Makefile") CONFIG_FILES="$CONFIG_FILES src/stringsearch1/Makefile" ;; "src/strstr/Makefile") CONFIG_FILES="$CONFIG_FILES src/strstr/Makefile" ;; "src/tarai/Makefile") CONFIG_FILES="$CONFIG_FILES src/tarai/Makefile" ;; - "src/template/Makefile") CONFIG_FILES="$CONFIG_FILES src/template/Makefile" ;; - "src/trio/Makefile") CONFIG_FILES="$CONFIG_FILES src/trio/Makefile" ;; "src/trio-snprintf/Makefile") CONFIG_FILES="$CONFIG_FILES src/trio-snprintf/Makefile" ;; "src/trio-sscanf/Makefile") CONFIG_FILES="$CONFIG_FILES src/trio-sscanf/Makefile" ;; "src/ud/Makefile") CONFIG_FILES="$CONFIG_FILES src/ud/Makefile" ;; diff --git a/configure.ac b/configure.ac index 47b86869..03674305 100644 --- a/configure.ac +++ b/configure.ac @@ -1309,8 +1309,10 @@ test -f $srcdir/config/$arch/boards/$board/calibration && \ AM_CONDITIONAL([CALIBRATION], [test x$HAVE_CALIBRATION == xyes]) -# Architecture, board and chip specific and user CFLAGS and LDFLAGS -CFLAGS="$CFLAGS $ARCH_CFLAGS $CHIP_CFLAGS $BOARD_CFLAGS $USER_CFLAGS" +# Architecture, board and chip specific and user CFLAGS and LDFLAGS. Note that +# we always compile with debug info, although this can be overridden by +# USER_CFLAGS +CFLAGS="$CFLAGS $ARCH_CFLAGS $CHIP_CFLAGS $BOARD_CFLAGS -g3 $USER_CFLAGS" LDFLAGS="$LDFLAGS $ARCH_LDFLAGS $CHIP_LDFLAGS $BOARD_LDFLAGS $USER_LDFLAGS" LT_INIT @@ -1378,7 +1380,6 @@ AC_CONFIG_FILES([Makefile \ src/cover/Makefile \ src/crc/Makefile \ src/crc32/Makefile \ - src/ctl/Makefile \ src/ctl-stack/Makefile \ src/ctl-string/Makefile \ src/ctl-vector/Makefile \ @@ -1401,7 +1402,6 @@ AC_CONFIG_FILES([Makefile \ src/lcdnum/Makefile \ src/levenshtein/Makefile \ src/ludcmp/Makefile \ - src/matmult/Makefile \ src/matmult-float/Makefile \ src/matmult-int/Makefile \ src/mergesort/Makefile \ @@ -1432,7 +1432,6 @@ AC_CONFIG_FILES([Makefile \ src/sglib-arraybinsearch/Makefile \ src/sglib-arrayheapsort/Makefile \ src/sglib-arrayquicksort/Makefile \ - src/sglib-arraysort/Makefile \ src/sglib-dllist/Makefile \ src/sglib-hashtable/Makefile \ src/sglib-listinsertsort/Makefile \ @@ -1447,8 +1446,6 @@ AC_CONFIG_FILES([Makefile \ src/stringsearch1/Makefile \ src/strstr/Makefile \ src/tarai/Makefile \ - src/template/Makefile \ - src/trio/Makefile \ src/trio-snprintf/Makefile \ src/trio-sscanf/Makefile \ src/ud/Makefile \ diff --git a/src/Makefile.am b/src/Makefile.am index a05c3c0e..6737a532 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -34,7 +34,6 @@ SUBDIRS = aha-compress \ cover \ crc \ crc32 \ - ctl \ ctl-stack \ ctl-string \ ctl-vector \ @@ -57,7 +56,6 @@ SUBDIRS = aha-compress \ lcdnum \ levenshtein \ ludcmp \ - matmult \ matmult-float \ matmult-int \ mergesort \ @@ -88,7 +86,6 @@ SUBDIRS = aha-compress \ sglib-arraybinsearch \ sglib-arrayheapsort \ sglib-arrayquicksort \ - sglib-arraysort \ sglib-dllist \ sglib-hashtable \ sglib-listinsertsort \ @@ -103,8 +100,6 @@ SUBDIRS = aha-compress \ stringsearch1 \ strstr \ tarai \ - template \ - trio \ trio-snprintf \ trio-sscanf \ ud \ diff --git a/src/Makefile.in b/src/Makefile.in index dc94676a..7ee23910 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -353,7 +353,6 @@ SUBDIRS = aha-compress \ cover \ crc \ crc32 \ - ctl \ ctl-stack \ ctl-string \ ctl-vector \ @@ -376,7 +375,6 @@ SUBDIRS = aha-compress \ lcdnum \ levenshtein \ ludcmp \ - matmult \ matmult-float \ matmult-int \ mergesort \ @@ -407,7 +405,6 @@ SUBDIRS = aha-compress \ sglib-arraybinsearch \ sglib-arrayheapsort \ sglib-arrayquicksort \ - sglib-arraysort \ sglib-dllist \ sglib-hashtable \ sglib-listinsertsort \ @@ -422,8 +419,6 @@ SUBDIRS = aha-compress \ stringsearch1 \ strstr \ tarai \ - template \ - trio \ trio-snprintf \ trio-sscanf \ ud \ diff --git a/src/aha-compress/Makefile.am b/src/aha-compress/Makefile.am index eab6662f..e6c598ad 100644 --- a/src/aha-compress/Makefile.am +++ b/src/aha-compress/Makefile.am @@ -33,6 +33,7 @@ libaha_compress_la_SOURCES = compress_test.c aha_compress_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libaha-compress.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) endif diff --git a/src/aha-compress/Makefile.in b/src/aha-compress/Makefile.in index 900b75ab..91e03a65 100644 --- a/src/aha-compress/Makefile.in +++ b/src/aha-compress/Makefile.in @@ -171,6 +171,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_AHA_COMPRESS_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_AHA_COMPRESS_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_AHA_COMPRESS_TRUE@ libaha-compress.la \ +@ENABLED_BENCHMARK_AHA_COMPRESS_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_AHA_COMPRESS_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_AHA_COMPRESS_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_AHA_COMPRESS_TRUE@ $(am__DEPENDENCIES_1) @@ -394,7 +395,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_AHA_COMPRESS_TRUE@aha_compress_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_AHA_COMPRESS_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_AHA_COMPRESS_TRUE@ libaha-compress.la \ -@ENABLED_BENCHMARK_AHA_COMPRESS_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_AHA_COMPRESS_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_AHA_COMPRESS_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/aha-compress/compress_test.c b/src/aha-compress/compress_test.c index be3f7c4f..d90630cf 100644 --- a/src/aha-compress/compress_test.c +++ b/src/aha-compress/compress_test.c @@ -27,7 +27,7 @@ /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) +#define LOCAL_SCALE_FACTOR 251 /* Code from GLS. Nine insns in the loop, giving 9*32 + 3 = 291 insns worst case (mask = all 1's, not counting subroutine linkage). */ @@ -160,34 +160,42 @@ initialise_benchmark (void) int benchmark (void) { - int errors = 0, n, i; - unsigned int r; - - n = sizeof(test)/sizeof(test[0]); - - for (i = 0; i < n; i += 3) { - r = compress1(test[i], test[i+1]); - if (r != test[i+2]) - errors = 1; - } - - for (i = 0; i < n; i += 3) { - r = compress2(test[i], test[i+1]); - if (r != test[i+2]) - errors = 1; - } - - for (i = 0; i < n; i += 3) { - r = compress3(test[i], test[i+1]); - if (r != test[i+2]) - errors = 1; - } - - for (i = 0; i < n; i += 3) { - r = compress4(test[i], test[i+1]); - if (r != test[i+2]) - errors = 1; - } + int i; + int errors; + + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + { + int n, i; + unsigned int r; + + errors = 0; + + n = sizeof(test)/sizeof(test[0]); + + for (i = 0; i < n; i += 3) { + r = compress1(test[i], test[i+1]); + if (r != test[i+2]) + errors = 1; + } + + for (i = 0; i < n; i += 3) { + r = compress2(test[i], test[i+1]); + if (r != test[i+2]) + errors = 1; + } + + for (i = 0; i < n; i += 3) { + r = compress3(test[i], test[i+1]); + if (r != test[i+2]) + errors = 1; + } + + for (i = 0; i < n; i += 3) { + r = compress4(test[i], test[i+1]); + if (r != test[i+2]) + errors = 1; + } + } return errors; } diff --git a/src/aha-mont64/Makefile.am b/src/aha-mont64/Makefile.am index 00076d8b..2d836d73 100644 --- a/src/aha-mont64/Makefile.am +++ b/src/aha-mont64/Makefile.am @@ -35,6 +35,7 @@ libaha_mont64_la_SOURCES = mont64.c aha_mont64_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libaha-mont64.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) endif diff --git a/src/aha-mont64/Makefile.in b/src/aha-mont64/Makefile.in index 366b3c52..f1a83e4b 100644 --- a/src/aha-mont64/Makefile.in +++ b/src/aha-mont64/Makefile.in @@ -172,6 +172,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_AHA_MONT64_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_AHA_MONT64_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_AHA_MONT64_TRUE@ libaha-mont64.la \ +@ENABLED_BENCHMARK_AHA_MONT64_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_AHA_MONT64_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_AHA_MONT64_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_AHA_MONT64_TRUE@ $(am__DEPENDENCIES_1) @@ -395,7 +396,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_AHA_MONT64_TRUE@aha_mont64_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_AHA_MONT64_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_AHA_MONT64_TRUE@ libaha-mont64.la \ -@ENABLED_BENCHMARK_AHA_MONT64_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_AHA_MONT64_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_AHA_MONT64_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/aha-mont64/mont64.c b/src/aha-mont64/mont64.c index a414f882..a51573d5 100644 --- a/src/aha-mont64/mont64.c +++ b/src/aha-mont64/mont64.c @@ -28,7 +28,7 @@ /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) +#define LOCAL_SCALE_FACTOR 315 /* Computes a*b mod m using Montgomery multiplication (MM). a, b, and m are unsigned numbers with a, b < m < 2**64, and m odd. The code does @@ -195,77 +195,82 @@ void xbinGCD(uint64 a, uint64 b, volatile uint64 *pu, volatile uint64 *pv) static uint64 in_a, in_b, in_m; int benchmark() { - uint64 a, b, m, hr, p1hi, p1lo, p1, p, abar, bbar; - uint64 phi, plo; - volatile uint64 rinv, mprime; - int errors = 0; - - m = in_m; // Must be odd. - b = in_b; // Must be smaller than m. - a = in_a; // Must be smaller than m. - - /* The simple calculation: This computes (a*b)**4 (mod m) correctly for all a, - b, m < 2**64. */ - - mulul64(a, b, &p1hi, &p1lo); // Compute a*b (mod m). - p1 = modul64(p1hi, p1lo, m); - mulul64(p1, p1, &p1hi, &p1lo); // Compute (a*b)**2 (mod m). - p1 = modul64(p1hi, p1lo, m); - mulul64(p1, p1, &p1hi, &p1lo); // Compute (a*b)**4 (mod m). - p1 = modul64(p1hi, p1lo, m); - - /* The MM method uses a quantity r that is the smallest power of 2 - that is larger than m, and hence also larger than a and b. Here we - deal with a variable hr that is just half of r. This is because r can - be as large as 2**64, which doesn't fit in one 64-bit word. So we - deal with hr, where 2**63 <= hr <= 1, and make the appropriate - adjustments wherever it is used. - We fix r at 2**64, and its log base 2 at 64. It doesn't hurt if - they are too big, it's just that some quantities (e.g., mprime) come - out larger than they would otherwise be. */ - - hr = 0x8000000000000000LL; - - /* Now, for the MM method, first compute the quantities that are - functions of only r and m, and hence are relatively constant. These - quantities can be used repeatedly, without change, when raising a - number to a large power modulo m. - First use the extended GCD algorithm to compute two numbers rinv - and mprime, such that - - r*rinv - m*mprime = 1 - - Reading this nodulo m, clearly r*rinv = 1 (mod m), i.e., rinv is the - multiplicative inverse of r modulo m. It is needed to convert the - result of MM back to a normal number. The other calculated number, - mprime, is used in the MM algorithm. */ - - xbinGCD(hr, m, &rinv, &mprime); // xbinGCD, in effect, doubles hr. - - /* Do a partial check of the results. It is partial because the - multiplications here give only the low-order half (64 bits) of the - products. */ - - if (2*hr*rinv - m*mprime != 1) { - errors = 1; - } + int i; + int errors; + + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) { + uint64 a, b, m, hr, p1hi, p1lo, p1, p, abar, bbar; + uint64 phi, plo; + volatile uint64 rinv, mprime; + errors = 0; + + m = in_m; // Must be odd. + b = in_b; // Must be smaller than m. + a = in_a; // Must be smaller than m. + + /* The simple calculation: This computes (a*b)**4 (mod m) correctly for all a, + b, m < 2**64. */ + + mulul64(a, b, &p1hi, &p1lo); // Compute a*b (mod m). + p1 = modul64(p1hi, p1lo, m); + mulul64(p1, p1, &p1hi, &p1lo); // Compute (a*b)**2 (mod m). + p1 = modul64(p1hi, p1lo, m); + mulul64(p1, p1, &p1hi, &p1lo); // Compute (a*b)**4 (mod m). + p1 = modul64(p1hi, p1lo, m); + + /* The MM method uses a quantity r that is the smallest power of 2 + that is larger than m, and hence also larger than a and b. Here we + deal with a variable hr that is just half of r. This is because r can + be as large as 2**64, which doesn't fit in one 64-bit word. So we + deal with hr, where 2**63 <= hr <= 1, and make the appropriate + adjustments wherever it is used. + We fix r at 2**64, and its log base 2 at 64. It doesn't hurt if + they are too big, it's just that some quantities (e.g., mprime) come + out larger than they would otherwise be. */ + + hr = 0x8000000000000000LL; + + /* Now, for the MM method, first compute the quantities that are + functions of only r and m, and hence are relatively constant. These + quantities can be used repeatedly, without change, when raising a + number to a large power modulo m. + First use the extended GCD algorithm to compute two numbers rinv + and mprime, such that + + r*rinv - m*mprime = 1 + + Reading this nodulo m, clearly r*rinv = 1 (mod m), i.e., rinv is the + multiplicative inverse of r modulo m. It is needed to convert the + result of MM back to a normal number. The other calculated number, + mprime, is used in the MM algorithm. */ + + xbinGCD(hr, m, &rinv, &mprime); // xbinGCD, in effect, doubles hr. + + /* Do a partial check of the results. It is partial because the + multiplications here give only the low-order half (64 bits) of the + products. */ + + if (2*hr*rinv - m*mprime != 1) { + errors = 1; + } - /* Compute abar = a*r(mod m) and bbar = b*r(mod m). That is, abar = - (a << 64)%m, and bbar = (b << 64)%m. */ + /* Compute abar = a*r(mod m) and bbar = b*r(mod m). That is, abar = + (a << 64)%m, and bbar = (b << 64)%m. */ - abar = modul64(a, 0, m); - bbar = modul64(b, 0, m); + abar = modul64(a, 0, m); + bbar = modul64(b, 0, m); - p = montmul(abar, bbar, m, mprime); /* Compute a*b (mod m). */ - p = montmul(p, p, m, mprime); /* Compute (a*b)**2 (mod m). */ - p = montmul(p, p, m, mprime); /* Compute (a*b)**4 (mod m). */ + p = montmul(abar, bbar, m, mprime); /* Compute a*b (mod m). */ + p = montmul(p, p, m, mprime); /* Compute (a*b)**2 (mod m). */ + p = montmul(p, p, m, mprime); /* Compute (a*b)**4 (mod m). */ - /* Convert p back to a normal number by p = (p*rinv)%m. */ + /* Convert p back to a normal number by p = (p*rinv)%m. */ - mulul64(p, rinv, &phi, &plo); - p = modul64(phi, plo, m); - if (p != p1) - errors = 1; + mulul64(p, rinv, &phi, &plo); + p = modul64(phi, plo, m); + if (p != p1) + errors = 1; + } return errors; } @@ -278,9 +283,8 @@ void initialise_benchmark() } // r is the number of errors therefore if r = 0 then output a 1 for correct + int verify_benchmark(int r) { - if (r != 0) - return 0; - return 1; -} \ No newline at end of file + return 0 == r; +} diff --git a/src/bs/Makefile.am b/src/bs/Makefile.am index 0570bd6b..31fe79fc 100644 --- a/src/bs/Makefile.am +++ b/src/bs/Makefile.am @@ -35,6 +35,7 @@ libbs_la_SOURCES = libbs.c bs_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libbs.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) endif diff --git a/src/bs/Makefile.in b/src/bs/Makefile.in index e3776727..a1e96055 100644 --- a/src/bs/Makefile.in +++ b/src/bs/Makefile.in @@ -169,7 +169,9 @@ bs_OBJECTS = $(am_bs_OBJECTS) am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_BS_TRUE@bs_DEPENDENCIES = $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_BS_TRUE@ $(top_builddir)/support/libsupport.la \ -@ENABLED_BENCHMARK_BS_TRUE@ libbs.la $(am__DEPENDENCIES_1) \ +@ENABLED_BENCHMARK_BS_TRUE@ libbs.la \ +@ENABLED_BENCHMARK_BS_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_BS_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_BS_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_BS_TRUE@ $(am__DEPENDENCIES_1) AM_V_P = $(am__v_P_@AM_V@) @@ -391,7 +393,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_BS_TRUE@bs_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_BS_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_BS_TRUE@ libbs.la \ -@ENABLED_BENCHMARK_BS_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_BS_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_BS_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/bs/libbs.c b/src/bs/libbs.c index a2b867b7..dd846285 100644 --- a/src/bs/libbs.c +++ b/src/bs/libbs.c @@ -1,5 +1,3 @@ - - /* This file is part of the Bristol/Embecosm Embedded Benchmark Suite. This program is free software: you can redistribute it and/or modify @@ -57,11 +55,12 @@ /* */ /*************************************************************************/ +#include #include "support.h" /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) +#define LOCAL_SCALE_FACTOR 9568 struct DATA { @@ -69,21 +68,30 @@ struct DATA { int value; } ; -struct DATA data[15] = { {1, 100}, - {5,200}, - {6, 300}, - {7, 700}, - {8, 900}, - {9, 250}, - {10, 400}, - {11, 600}, - {12, 800}, - {13, 1500}, - {14, 1200}, - {15, 110}, - {16, 140}, - {17, 133}, - {18, 10} }; +#define NUMVALS 100 + +struct DATA data[NUMVALS] = { + { 2, 1440 }, { 6, 130 }, { 9, 1960 }, { 12, 1750 }, { 13, 270 }, + { 15, 600 }, { 18, 790 }, { 19, 990 }, { 20, 400 }, { 23, 1300 }, + { 27, 880 }, { 29, 350 }, { 30, 1070 }, { 33, 70 }, { 39, 580 }, + { 40, 360 }, { 42, 320 }, { 43, 1430 }, { 45, 800 }, { 47, 510 }, + { 48, 850 }, { 50, 70 }, { 53, 1500 }, { 55, 1680 }, { 57, 980 }, + { 58, 570 }, { 59, 1230 }, { 61, 1930 }, { 63, 1710 }, { 64, 1640 }, + { 71, 1140 }, { 72, 680 }, { 73, 710 }, { 74, 460 }, { 77, 130 }, + { 79, 110 }, { 83, 1700 }, { 84, 610 }, { 85, 1540 }, { 86, 210 }, + { 89, 1290 }, { 92, 1480 }, { 94, 50 }, { 95, 930 }, { 99, 760 }, + { 101, 990 }, { 102, 190 }, { 104, 1160 }, { 105, 1860 }, { 106, 1960 }, + { 108, 1910 }, { 109, 1610 }, { 111, 1390 }, { 114, 1800 }, { 116, 1860 }, + { 117, 400 }, { 118, 1200 }, { 119, 930 }, { 120, 930 }, { 123, 430 }, + { 124, 130 }, { 125, 740 }, { 126, 870 }, { 129, 1840 }, { 132, 1220 }, + { 133, 350 }, { 136, 1690 }, { 137, 150 }, { 139, 1440 }, { 140, 1160 }, + { 141, 1740 }, { 142, 560 }, { 144, 760 }, { 145, 240 }, { 146, 480 }, + { 147, 1730 }, { 148, 1500 }, { 149, 1660 }, { 152, 310 }, { 153, 1970 }, + { 155, 840 }, { 158, 680 }, { 160, 500 }, { 161, 320 }, { 168, 760 }, + { 171, 1240 }, { 173, 310 }, { 174, 960 }, { 175, 1460 }, { 179, 1750 }, + { 181, 1710 }, { 183, 240 }, { 184, 1650 }, { 185, 1450 }, { 189, 170 }, + { 190, 330 }, { 194, 880 }, { 198, 400 }, { 199, 590 }, { 200, 1540 } +}; int binary_search(int x) @@ -91,7 +99,7 @@ binary_search(int x) int fvalue, mid, up, low ; low = 0; - up = 14; + up = NUMVALS - 1; fvalue = -1 /* all data are positive */ ; while (low <= up) { mid = (low + up) >> 1; @@ -110,13 +118,14 @@ binary_search(int x) return fvalue; } - -/* This benchmark does not support verification */ +int res [5]; /* Result for verification */ int -verify_benchmark (int res __attribute ((unused)) ) +verify_benchmark (int r __attribute ((unused)) ) { - return -1; + static int exp[5] = { 1440, 850, 990, 1730, 1540 }; + + return 0 == memcmp (res, exp, 5 * sizeof (res[0])); } @@ -129,7 +138,28 @@ initialise_benchmark (void) int benchmark() { - binary_search(8); + int i; + + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + { + volatile int v; + + v = 2; + v = binary_search (2); + res[0] = v; + v = 48; + v = binary_search (48); + res[1] = v; + v = 101; + v = binary_search (101); + res[2] = v; + v = 147; + v = binary_search (147); + res[3] = v; + v = 200; + v = binary_search (200); + res[4] = v; + } + return 0; } - diff --git a/src/bubblesort/Makefile.am b/src/bubblesort/Makefile.am index 328a307f..c76cec39 100644 --- a/src/bubblesort/Makefile.am +++ b/src/bubblesort/Makefile.am @@ -35,6 +35,7 @@ libbubblesort_la_SOURCES = libbubblesort.c bubblesort_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libbubblesort.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) endif diff --git a/src/bubblesort/Makefile.in b/src/bubblesort/Makefile.in index 112690c5..fbd55a41 100644 --- a/src/bubblesort/Makefile.in +++ b/src/bubblesort/Makefile.in @@ -172,6 +172,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_BUBBLESORT_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_BUBBLESORT_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_BUBBLESORT_TRUE@ libbubblesort.la \ +@ENABLED_BENCHMARK_BUBBLESORT_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_BUBBLESORT_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_BUBBLESORT_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_BUBBLESORT_TRUE@ $(am__DEPENDENCIES_1) @@ -395,7 +396,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_BUBBLESORT_TRUE@bubblesort_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_BUBBLESORT_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_BUBBLESORT_TRUE@ libbubblesort.la \ -@ENABLED_BENCHMARK_BUBBLESORT_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_BUBBLESORT_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_BUBBLESORT_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/bubblesort/libbubblesort.c b/src/bubblesort/libbubblesort.c index b6a96683..34a15385 100644 --- a/src/bubblesort/libbubblesort.c +++ b/src/bubblesort/libbubblesort.c @@ -19,13 +19,14 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ +#include + #include "support.h" /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 4) +#define LOCAL_SCALE_FACTOR 64 -#define WORSTCASE 1 #define FALSE 0 #define TRUE 1 #define NUMELEMS 100 @@ -48,27 +49,24 @@ void BubbleSort(int Array[]); int benchmark() { - BubbleSort(Array); + int i; + + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + { + int Index; + + for (Index = 0; Index < NUMELEMS; Index ++) + Array[Index] = -Index; + + BubbleSort(Array); + } + return 0; } void initialise_benchmark() -/* - * Initializes given array with randomly generated integers. - */ { - int Index, fact; - -#ifdef WORSTCASE - factor = -1; -#else - factor = 1; -#endif - -fact = factor; -for (Index = 0; Index < NUMELEMS; Index ++) - Array[Index] = Index*fact; } @@ -102,21 +100,19 @@ void BubbleSort(int Array[]) } int verify_benchmark(int result) { - int expected[NUMELEMS] = {-99, -98, -97, -96, -95, -94, -93, -92, - -91, -90, -89, -88, -87, -86, -85, -84, -83, -82, - -81, -80, -79, -78, -77, -76, -75, -74, -73, -72, - -71, -70, -69, -68, -67, -66, -65, -64, -63, -62, - -61, -60, -59, -58, -57, -56, -55, -54, -53, -52, - -51, -50, -49, -48, -47, -46, -45, -44, -43, -42, - -41, -40, -39, -38, -37, -36, -35, -34, -33, -32, - -31, -30, -29, -28, -27, -26, -25, -24, -23, -22, - -21, -20, -19, -18, -17, -16, -15, -14, -13, -12, - -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0}; - int i; - for (i=0; i> 0) +#define LOCAL_SCALE_FACTOR 944 /* $Id: cnt.c,v 1.3 2005/04/04 11:34:58 csg Exp $ */ @@ -77,7 +77,7 @@ int RandomInteger(void); // Globals -int Seed; +long int Seed; /* Must be at least 32-bit */ matrix Array; @@ -90,13 +90,21 @@ int Postotal, Negtotal, Poscnt, Negcnt; int benchmark (void) { + int res; + int i; + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + { + InitSeed(); + Initialize(Array); + res = Test(Array); + } //printf("\n *** MATRIX SUM AND COUNT BENCHMARK TEST ***\n\n"); //printf("RESULTS OF THE TEST:\n"); - return Test(Array); + return res; } @@ -145,7 +153,7 @@ int InitSeed (void) { - Seed = 0; + Seed = 0L; return 0; @@ -245,30 +253,15 @@ int RandomInteger(void) { - Seed = ((Seed * 133) + 81) % 8095; + Seed = ((Seed * 133L) + 81L) % 8095L; - return Seed; + return (int) Seed; } void initialise_benchmark() { - InitSeed(); - Initialize(Array); } int verify_benchmark(int nt) { - int expected_negtotal = 396675; - if (expected_negtotal != nt) - return 0; - return 1; - + return 396675 == nt; } - - - - - - - - - diff --git a/src/compress/Makefile.am b/src/compress/Makefile.am index e50e5949..734434f8 100644 --- a/src/compress/Makefile.am +++ b/src/compress/Makefile.am @@ -42,7 +42,8 @@ libcompress_la_SOURCES = libcompress.c compress_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libcompress.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) diff --git a/src/compress/Makefile.in b/src/compress/Makefile.in index 6fe911b4..ca2992c8 100644 --- a/src/compress/Makefile.in +++ b/src/compress/Makefile.in @@ -179,6 +179,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_COMPRESS_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_COMPRESS_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_COMPRESS_TRUE@ libcompress.la \ +@ENABLED_BENCHMARK_COMPRESS_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_COMPRESS_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_COMPRESS_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_COMPRESS_TRUE@ $(am__DEPENDENCIES_1) @@ -401,7 +402,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_COMPRESS_TRUE@compress_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_COMPRESS_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_COMPRESS_TRUE@ libcompress.la \ -@ENABLED_BENCHMARK_COMPRESS_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_COMPRESS_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_COMPRESS_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/compress/libcompress.c b/src/compress/libcompress.c index 2ed61d21..b6f69918 100644 --- a/src/compress/libcompress.c +++ b/src/compress/libcompress.c @@ -1,5 +1,3 @@ - - /* BEEBS compress benchmark Copyright (C) 2014 Embecosm Limited and University of Bristol @@ -51,7 +49,7 @@ // This scale factor will be changed to equalise the runtime of the // benchmarks -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) +#define LOCAL_SCALE_FACTOR 1278 /* #define DO_TRACING */ @@ -226,40 +224,6 @@ void output( code_int code ); void writebytes( char *buf, int n ); -/* This benchmark does not support verification */ - -int -verify_benchmark (int res __attribute ((unused)) ) -{ - return -1; -} - - -void -initialise_benchmark (void) -{ -} - - - -int benchmark() -{ - int count = IN_COUNT; - - maxbits = BITS; - maxmaxcode = 1 << maxbits; - - InCnt = count; - apsim_InCnt = IN_COUNT + 3; - InBuff = (unsigned char *)orig_text_buffer; - OutBuff = (unsigned char *)comp_text_buffer; - - compress(); - return 0; -} - - - static int offset; long int in_count = 1; /* length of input */ long int bytes_out; /* length of compressed output */ @@ -539,3 +503,40 @@ void output( code_int code ) offset = 0; } } + + +int +verify_benchmark (int res) +{ + return (0 == exit_stat) && (3 == res); +} + + +void +initialise_benchmark (void) +{ +} + + + +int benchmark() +{ + int i; + + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + { + int count = IN_COUNT; + + maxbits = BITS; + maxmaxcode = 1 << maxbits; + + InCnt = IN_COUNT; + apsim_InCnt = IN_COUNT + 3; + InBuff = (unsigned char *)orig_text_buffer; + OutBuff = (unsigned char *)comp_text_buffer; + + compress(); + } + + return bytes_out; +} diff --git a/src/cover/Makefile.am b/src/cover/Makefile.am index f255922f..4620c8af 100644 --- a/src/cover/Makefile.am +++ b/src/cover/Makefile.am @@ -34,6 +34,7 @@ libcover_la_SOURCES = libcover.c cover_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libcover.la \ + $(top_builddir)/support/libbeebsc.la \ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) diff --git a/src/cover/Makefile.in b/src/cover/Makefile.in index 5724bb9a..9c13ab28 100644 --- a/src/cover/Makefile.in +++ b/src/cover/Makefile.in @@ -171,6 +171,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_COVER_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_COVER_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_COVER_TRUE@ libcover.la \ +@ENABLED_BENCHMARK_COVER_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_COVER_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_COVER_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_COVER_TRUE@ $(am__DEPENDENCIES_1) @@ -393,6 +394,7 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_COVER_TRUE@cover_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_COVER_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_COVER_TRUE@ libcover.la \ +@ENABLED_BENCHMARK_COVER_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_COVER_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/cover/libcover.c b/src/cover/libcover.c index d102ed9c..811fef2a 100644 --- a/src/cover/libcover.c +++ b/src/cover/libcover.c @@ -24,7 +24,7 @@ /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) +#define LOCAL_SCALE_FACTOR 4333 int swi120(int c) { @@ -260,22 +260,21 @@ initialise_benchmark (void) int benchmark() { - volatile int cnt=0; + volatile int cnt; + int i; - cnt=swi10(cnt); - cnt=swi50(cnt); - cnt=swi120(cnt); - - /* printf("cnt: %d\n", cnt); */ - - return cnt; + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + { + cnt = 0; + cnt=swi10(cnt); + cnt=swi50(cnt); + cnt=swi120(cnt); + } + return cnt; } int verify_benchmark(int r) { - int expected = 180; - if (r != expected) - return 0; - return 1; + return 180 == r; } diff --git a/src/crc/Makefile.am b/src/crc/Makefile.am index e87fe3cd..faf432b0 100644 --- a/src/crc/Makefile.am +++ b/src/crc/Makefile.am @@ -34,7 +34,8 @@ libcrc_la_SOURCES = libcrc.c crc_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libcrc.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) diff --git a/src/crc/Makefile.in b/src/crc/Makefile.in index 303217f0..980acb7f 100644 --- a/src/crc/Makefile.in +++ b/src/crc/Makefile.in @@ -169,7 +169,9 @@ crc_OBJECTS = $(am_crc_OBJECTS) am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_CRC_TRUE@crc_DEPENDENCIES = $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_CRC_TRUE@ $(top_builddir)/support/libsupport.la \ -@ENABLED_BENCHMARK_CRC_TRUE@ libcrc.la $(am__DEPENDENCIES_1) \ +@ENABLED_BENCHMARK_CRC_TRUE@ libcrc.la \ +@ENABLED_BENCHMARK_CRC_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_CRC_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_CRC_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_CRC_TRUE@ $(am__DEPENDENCIES_1) AM_V_P = $(am__v_P_@AM_V@) @@ -391,7 +393,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_CRC_TRUE@crc_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_CRC_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_CRC_TRUE@ libcrc.la \ -@ENABLED_BENCHMARK_CRC_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_CRC_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_CRC_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/crc/libcrc.c b/src/crc/libcrc.c index b28dfa37..8d1479b6 100644 --- a/src/crc/libcrc.c +++ b/src/crc/libcrc.c @@ -1,5 +1,3 @@ - - /* BEEBS crc benchmark Copyright (C) 2014 Embecosm Limited and University of Bristol @@ -25,7 +23,7 @@ /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) +#define LOCAL_SCALE_FACTOR 2229 /* $Id: crc.c,v 1.2 2005/04/04 11:34:58 csg Exp $ */ @@ -145,9 +143,9 @@ unsigned short icrc(unsigned short crc, unsigned long len, /* This benchmark does not support verification */ int -verify_benchmark (int res __attribute ((unused)) ) +verify_benchmark (int res) { - return -1; + return 61727 == res; } @@ -162,16 +160,14 @@ int benchmark(void) { unsigned short i1,i2; unsigned long n; + int i; - n=40; - i1=icrc(0,n,(short)0,1); - i2=icrc(i1,n+2,(short)0,1); - - /* Silence compiler warning about unused variables. */ - (void) i2; + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + { + n=40; + i1=icrc(0,n,(short)0,1); + i2=icrc(i1,n+2,(short)0,1); + } - return 0; + return i2; } - - - diff --git a/src/crc32/Makefile.am b/src/crc32/Makefile.am index 5b0ab434..d86122df 100644 --- a/src/crc32/Makefile.am +++ b/src/crc32/Makefile.am @@ -35,6 +35,7 @@ libcrc32_la_SOURCES = crc_32.c crc32_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libcrc32.la \ + $(top_builddir)/support/libbeebsc.la \ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) endif diff --git a/src/crc32/Makefile.in b/src/crc32/Makefile.in index 5faa0805..13481798 100644 --- a/src/crc32/Makefile.in +++ b/src/crc32/Makefile.in @@ -171,6 +171,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_CRC32_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_CRC32_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_CRC32_TRUE@ libcrc32.la \ +@ENABLED_BENCHMARK_CRC32_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_CRC32_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_CRC32_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_CRC32_TRUE@ $(am__DEPENDENCIES_1) @@ -393,6 +394,7 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_CRC32_TRUE@crc32_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_CRC32_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_CRC32_TRUE@ libcrc32.la \ +@ENABLED_BENCHMARK_CRC32_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_CRC32_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/crc32/crc_32.c b/src/crc32/crc_32.c index ad53ddd6..548cbc53 100644 --- a/src/crc32/crc_32.c +++ b/src/crc32/crc_32.c @@ -1,4 +1,3 @@ - /* This file is part of the Bristol/Embecosm Embedded Benchmark Suite. This program is free software: you can redistribute it and/or modify @@ -23,7 +22,7 @@ /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 5) +#define LOCAL_SCALE_FACTOR 145 #include @@ -150,25 +149,6 @@ const static UNS_32_BITS crc_32_tab[] = { /* CRC polynomial 0xedb88320 */ }; -/* Yield a sequence of random numbers in the range [0, 2^15-1]. - - The seed is always initialized to zero. long int is guaranteed to be at - least 32 bits. The seed only ever uses 31 bits (so is positive). - - For BEEBS this gets round different operating systems using different - multipliers and offsets and RAND_MAX variations. */ - -static int -rand_beebs () -{ - static long int seed = 0; - - seed = (seed * 1103515245L + 12345) & ((1UL << 31) - 1); - return (int) (seed >> 16); - -} - - DWORD crc32pseudo() { int i; @@ -190,21 +170,24 @@ initialise_benchmark (void) } - int benchmark() { + int i; DWORD r; - r = crc32pseudo(); - return (int)r; + + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + { + srand_beebs (0); + r = crc32pseudo(); + } + + return (int) (r % 32768); } + int verify_benchmark(int r) { - int expected = 1207487004; - - if (r != expected) - return 0; - return 1; + return 11433 == r; } diff --git a/src/ctl-stack/Makefile.am b/src/ctl-stack/Makefile.am index a02126c8..19569293 100644 --- a/src/ctl-stack/Makefile.am +++ b/src/ctl-stack/Makefile.am @@ -35,7 +35,8 @@ libctl_stack_la_SOURCES = ctl.c ctl.h stack.h ctl_stack_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libctl-stack.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) libctl_stack_la_CPPFLAGS = -DCTL_STACK ${AM_CPPFLAGS} endif diff --git a/src/ctl-stack/Makefile.in b/src/ctl-stack/Makefile.in index f8b2b398..e42314e7 100644 --- a/src/ctl-stack/Makefile.in +++ b/src/ctl-stack/Makefile.in @@ -172,6 +172,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_CTL_STACK_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_CTL_STACK_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_CTL_STACK_TRUE@ libctl-stack.la \ +@ENABLED_BENCHMARK_CTL_STACK_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_CTL_STACK_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_CTL_STACK_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_CTL_STACK_TRUE@ $(am__DEPENDENCIES_1) @@ -395,7 +396,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_CTL_STACK_TRUE@ctl_stack_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_CTL_STACK_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_CTL_STACK_TRUE@ libctl-stack.la \ -@ENABLED_BENCHMARK_CTL_STACK_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_CTL_STACK_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_CTL_STACK_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) @ENABLED_BENCHMARK_CTL_STACK_TRUE@libctl_stack_la_CPPFLAGS = -DCTL_STACK ${AM_CPPFLAGS} all: all-am diff --git a/src/ctl-stack/ctl.c b/src/ctl-stack/ctl.c deleted file mode 120000 index 3f16ee40..00000000 --- a/src/ctl-stack/ctl.c +++ /dev/null @@ -1 +0,0 @@ -../ctl/ctl.c \ No newline at end of file diff --git a/src/ctl-stack/ctl.c b/src/ctl-stack/ctl.c new file mode 100644 index 00000000..66e7876d --- /dev/null +++ b/src/ctl-stack/ctl.c @@ -0,0 +1,134 @@ +/* -*- mode: C++; c-file-style: "gnu-mode" -*- */ +/* BEEBS vector benchmark + + Copyright (C) 2013 Embecosm Limited and University of Bristol + + Contributor: James Pallister + + This file is part of the Bristol/Embecosm Embedded Benchmark Suite. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include "support.h" + +/* This scale factor will be changed to equalise the runtime of the + benchmarks. */ +#define LOCAL_SCALE_FACTOR 446 + +typedef struct { + int a, b; +} pair; + +/* BEEBS heap is just an array */ + +#define HEAP_SIZE 8192 +static char heap[HEAP_SIZE]; + +#include "stack.h" + +/* Create stack functions for different types. */ +MAKE_STACK(int) +MAKE_STACK(pair) + +/* Container types. */ +typedef ctl_intStack int_container; +typedef ctl_pairStack pair_container; + +#define CTL_INIT(type) ctl_ ## type ## StackInit () +#define CTL_PUSH(type, stk, val) ctl_ ## type ## StackPush (stk, val) +#define CTL_POP(type, stk, res) ctl_ ## type ## StackPop (stk, res) +#define CTL_FREE(type, stk) ctl_ ## type ## StackFree (stk) + +/* There's no DELETE for stacks. */ +#define CTL_DELETE(type, vec, a, b) do { } while (0) + + +static int init; +static int lim; +static int fact; +static int begin; +static int end; +static int end2; + +int +benchmark (void) +{ + int j; + long int cnt; + + for (j = 0; j < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); j++) + { + int_container *v; + pair_container *v2; + int i; + + cnt=0; + init = 1; + lim = 100; + fact = 11; + begin = 4; + end = 50; + end2 = 8; + init_heap_beebs ((void *) heap, HEAP_SIZE); + + v = CTL_INIT (int); + + for (i = init; i <= lim; ++i) + CTL_PUSH (int, v, i * fact); + + CTL_DELETE (int, v, begin, end); + + while(v->size > 0) + { + int k; + + CTL_POP (int, v, &k); + + cnt += k; + } + + CTL_FREE (int, v); + + v2 = CTL_INIT (pair); + + for (i = init; i <= lim; ++i) + { + pair p = {i, i*i}; + CTL_PUSH (pair, v2, p); + } + + CTL_DELETE (pair, v2, begin, end2); + + while(v2->size > 0) + { + pair k; + + CTL_POP (pair, v2, &k); + + cnt += k.a*k.b; + } + + CTL_FREE (pair, v2); + } + + return (int) (cnt % 32768L); +} + +void initialise_benchmark() { +} + +int verify_benchmark(int r) +{ + return (31778 == r) && check_heap_beebs ((void *) heap); +} diff --git a/src/ctl-stack/ctl.h b/src/ctl-stack/ctl.h deleted file mode 120000 index dd995e54..00000000 --- a/src/ctl-stack/ctl.h +++ /dev/null @@ -1 +0,0 @@ -../ctl/ctl.h \ No newline at end of file diff --git a/src/ctl-stack/ctl.h b/src/ctl-stack/ctl.h new file mode 100644 index 00000000..f5935ebe --- /dev/null +++ b/src/ctl-stack/ctl.h @@ -0,0 +1,74 @@ +/* This file is part of the Bristol/Embecosm Embedded Benchmark Suite. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/***************************************************************************** + * FILE: ctl.h * + * AUTHOR: Toni Schornboeck * + ***************************************************************************** + * Das zentrale File der CTL * + ***************************************************************************** + * Diese Datei darf frei unter der * + * GPL (http://www.gnu.org/copyleft/gpl.html) verwendet werden. * + *****************************************************************************/ + +#ifndef CTL_STANDARD_HEADER__ +#define CTL_STANDARD_HEADER__ +#include +#include +#include +#include +#include + +#ifndef CTL_SIZE +#define CTL_SIZE 100 +#endif + +#ifndef CTL_GROWFACTOR +#define CTL_GROWFACTOR 0.7 +#endif + +#ifdef CTL_NORANGECHECK +#define CTL_RANGE(x) if(0) +#else +#define CTL_RANGE(x) if(x) +#endif + +#define CTL_OUT_OF_MEMORY 100 +#define CTL_WRONG_VALUE 101 +#define CTL_OUT_OF_RANGE 102 +#define CTL_NOT_FOUND 103 + +struct CTL_STRUCT { + size_t BlockSize; +}; +typedef struct CTL_STRUCT ctl_struct; + +unsigned int ctl_errno; +unsigned int ctl_warning; + +int ctl_SetBlockSize(ctl_struct* its, size_t BlockSize) +{ + if(BlockSize<1) + { + ctl_errno=CTL_WRONG_VALUE; + return 1; + } + its->BlockSize=BlockSize; + return 0; +} + +#define CTL_GROW_ALLOC_SIZE(its) its->BlockSize=((size_t)(its->alloc+its->alloc*CTL_GROWFACTOR)) + +#endif diff --git a/src/ctl-stack/stack.h b/src/ctl-stack/stack.h deleted file mode 120000 index 7a30bc93..00000000 --- a/src/ctl-stack/stack.h +++ /dev/null @@ -1 +0,0 @@ -../ctl/stack.h \ No newline at end of file diff --git a/src/ctl-stack/stack.h b/src/ctl-stack/stack.h new file mode 100644 index 00000000..d114ed0a --- /dev/null +++ b/src/ctl-stack/stack.h @@ -0,0 +1,120 @@ +/* This file is part of the Bristol/Embecosm Embedded Benchmark Suite. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/***************************************************************************** + * FILE: stack.h * + * AUTHOR: Toni Schornboeck * + ***************************************************************************** + * Implementierung eines FixedSize Stack fuer die CTL * + ***************************************************************************** + * Diese Datei darf frei unter der * + * GPL (http://www.gnu.org/copyleft/gpl.html) verwendet werden. * + *****************************************************************************/ + +#include "ctl.h" + +#define MAKE_STACK(type) \ +struct CTL_##type##STACK { \ + type* value; \ + size_t size; \ + size_t first; \ + size_t alloc; \ +}; \ + \ +typedef struct CTL_##type##STACK ctl_##type##Stack; \ + \ +ctl_##type##Stack* ctl_##type##StackInitSize(int BlockSize)\ +{ \ + ctl_##type##Stack* s=malloc_beebs(sizeof(ctl_##type##Stack));\ + if(!s) \ + { \ + return NULL; \ + } \ + s->alloc = BlockSize; \ + s->value = malloc_beebs(BlockSize*sizeof(type));\ + if(!s->value) \ + { \ + return NULL; \ + } \ + s->first = 0; \ + s->size = 0; \ + return s; \ +} \ + \ +ctl_##type##Stack* ctl_##type##StackInit(void) \ +{ \ + return ctl_##type##StackInitSize(CTL_SIZE); \ +} \ + \ +ctl_##type##Stack* ctl_##type##StackInitCopy(ctl_##type##Stack* stack)\ +{ \ + ctl_##type##Stack* s=malloc_beebs(sizeof(ctl_##type##Stack));\ + if(!s) \ + { \ + return NULL; \ + } \ + s->alloc = stack->alloc; \ + s->value = malloc_beebs(stack->alloc*sizeof(type));\ + if(!s->value) \ + { \ + return NULL; \ + } \ + s->first = stack->first; \ + s->size = stack->size; \ + return s; \ +} \ + \ +void ctl_##type##StackFree(ctl_##type##Stack* s) \ +{ \ + free_beebs(s->value); \ + free_beebs(s); \ +} \ + \ +int ctl_##type##StackPush(ctl_##type##Stack* s, type value)\ +{ \ + if(++s->size>s->alloc) \ + { \ + s->size=s->alloc; \ + } \ + if(++s->first==s->size) \ + { \ + s->first=0; \ + } \ + s->value[s->first]=value; \ + return 0; \ +} \ + \ +int ctl_##type##StackPop(ctl_##type##Stack* s, type* value)\ +{ \ + if(s->size==0) \ + { \ + ctl_errno=CTL_OUT_OF_RANGE; \ + return 1; \ + } \ + \ + if(value)*value=s->value[s->first]; \ + --s->size; \ + if(s->size) \ + { \ + if(!s->first) \ + { \ + s->first=s->size-1; \ + return 0; \ + } \ + --s->first; \ + } \ + return 0; \ +} + diff --git a/src/ctl-string/Makefile.am b/src/ctl-string/Makefile.am index 310c9918..c0c34094 100644 --- a/src/ctl-string/Makefile.am +++ b/src/ctl-string/Makefile.am @@ -34,6 +34,7 @@ libctl_string_la_SOURCES = string.c ctl_string_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libctl-string.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) endif diff --git a/src/ctl-string/Makefile.in b/src/ctl-string/Makefile.in index a37ae047..215207e0 100644 --- a/src/ctl-string/Makefile.in +++ b/src/ctl-string/Makefile.in @@ -172,6 +172,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_CTL_STRING_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_CTL_STRING_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_CTL_STRING_TRUE@ libctl-string.la \ +@ENABLED_BENCHMARK_CTL_STRING_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_CTL_STRING_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_CTL_STRING_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_CTL_STRING_TRUE@ $(am__DEPENDENCIES_1) @@ -395,7 +396,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_CTL_STRING_TRUE@ctl_string_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_CTL_STRING_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_CTL_STRING_TRUE@ libctl-string.la \ -@ENABLED_BENCHMARK_CTL_STRING_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_CTL_STRING_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_CTL_STRING_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/ctl-string/string.c b/src/ctl-string/string.c index 1457ae0f..4e360710 100644 --- a/src/ctl-string/string.c +++ b/src/ctl-string/string.c @@ -29,7 +29,7 @@ /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) +#define LOCAL_SCALE_FACTOR 422 #ifndef CTL_SIZE #define CTL_SIZE 100 @@ -60,51 +60,9 @@ unsigned int ctl_warning; /* BEEBS heap is just an array */ -#include - #define HEAP_SIZE 8192 static char heap[HEAP_SIZE]; -static void *heap_ptr; -static void *heap_end; - -/* Initialize the BEEBS heap pointers */ - -static void -init_heap () -{ - heap_ptr = (void *) heap; - heap_end = heap_ptr + HEAP_SIZE; -} - -/* BEEBS version of malloc. - - This is primarily to reduce library and OS dependencies. Malloc is - generally not used in embedded code, or if it is, only in well defined - contexts to pre-allocate a fixed amount of memory. So this simplistic - implementation is just fine. */ - -static void * -malloc_beebs (size_t size) -{ - void *new_ptr = heap_ptr; - - if (((heap_ptr + size) > heap_end) || (0 == size)) - return NULL; - else - { - heap_ptr += size; - return new_ptr; - } -} - -/* BEEBS version of free. - For our simplified version of memory handling, free can just do nothing. */ - -static void -free_beebs (void *ptr) -{ -} int ctl_SetBlockSize(ctl_struct* its, size_t BlockSize) { @@ -449,48 +407,53 @@ static const char *in5; int benchmark (void) { - ctl_string *s; - ctl_string *s2; - int cnt = 0; + volatile int cnt = 0; + int i; - s = ctl_StringInit(); - s2 = ctl_StringInit(); - - ctl_StringSet(s, in1); - ctl_StringAppend(s, in2); - ctl_StringSet(s2, in3); - ctl_StringSetString(s, s2); - - while(ctl_StringCmpNoCase(s, in4)) - { - ctl_StringAppend(s, in5); - cnt++; - } - - ctl_StringFree(s); - ctl_StringFree(s2); + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + { + static const char a[] = "This is a string"; + static const char b[] = "This is a str2"; + static const char c[] = "aaa"; + static const char d[] = "AaaAaAaaaaaAAaaaAAaaAaA"; + static const char e[] = "a"; + + ctl_string *s; + ctl_string *s2; + cnt = 0; + + in1 = a; + in2 = b; + in3 = c; + in4 = d; + in5 = e; + init_heap_beebs ((void *) heap, HEAP_SIZE); + + s = ctl_StringInit(); + s2 = ctl_StringInit(); + + ctl_StringSet(s, in1); + ctl_StringAppend(s, in2); + ctl_StringSet(s2, in3); + ctl_StringSetString(s, s2); + + while(ctl_StringCmpNoCase(s, in4)) + { + ctl_StringAppend(s, in5); + cnt++; + } + + ctl_StringFree(s); + ctl_StringFree(s2); + } return cnt; } void initialise_benchmark() { - static const char a[] = "This is a string"; - static const char b[] = "This is a str2"; - static const char c[] = "aaa"; - static const char d[] = "AaaAaAaaaaaAAaaaAAaaAaA"; - static const char e[] = "a"; - in1 = a; - in2 = b; - in3 = c; - in4 = d; - in5 = e; - init_heap (); } int verify_benchmark(int r) { - int expected = 21; - if (r != expected) - return 0; - return 1; + return (21 == r) && check_heap_beebs ((void *) heap); } diff --git a/src/ctl-vector/Makefile.am b/src/ctl-vector/Makefile.am index b29d13cc..52ff06ad 100644 --- a/src/ctl-vector/Makefile.am +++ b/src/ctl-vector/Makefile.am @@ -35,7 +35,8 @@ libctl_vector_la_SOURCES = ctl.c ctl.h vector.h ctl_vector_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libctl-vector.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) libctl_vector_la_CPPFLAGS = -DCTL_VECTOR ${AM_CPPFLAGS} endif diff --git a/src/ctl-vector/Makefile.in b/src/ctl-vector/Makefile.in index 4b94a078..0bb811fb 100644 --- a/src/ctl-vector/Makefile.in +++ b/src/ctl-vector/Makefile.in @@ -172,6 +172,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_CTL_VECTOR_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_CTL_VECTOR_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_CTL_VECTOR_TRUE@ libctl-vector.la \ +@ENABLED_BENCHMARK_CTL_VECTOR_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_CTL_VECTOR_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_CTL_VECTOR_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_CTL_VECTOR_TRUE@ $(am__DEPENDENCIES_1) @@ -395,7 +396,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_CTL_VECTOR_TRUE@ctl_vector_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_CTL_VECTOR_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_CTL_VECTOR_TRUE@ libctl-vector.la \ -@ENABLED_BENCHMARK_CTL_VECTOR_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_CTL_VECTOR_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_CTL_VECTOR_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) @ENABLED_BENCHMARK_CTL_VECTOR_TRUE@libctl_vector_la_CPPFLAGS = -DCTL_VECTOR ${AM_CPPFLAGS} all: all-am diff --git a/src/ctl-vector/ctl.c b/src/ctl-vector/ctl.c deleted file mode 120000 index 3f16ee40..00000000 --- a/src/ctl-vector/ctl.c +++ /dev/null @@ -1 +0,0 @@ -../ctl/ctl.c \ No newline at end of file diff --git a/src/ctl-vector/ctl.c b/src/ctl-vector/ctl.c new file mode 100644 index 00000000..4694d0ec --- /dev/null +++ b/src/ctl-vector/ctl.c @@ -0,0 +1,135 @@ +/* -*- mode: C++; c-file-style: "gnu-mode" -*- */ +/* BEEBS vector benchmark + + Copyright (C) 2013 Embecosm Limited and University of Bristol + + Contributor: James Pallister + + This file is part of the Bristol/Embecosm Embedded Benchmark Suite. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include "support.h" + +/* This scale factor will be changed to equalise the runtime of the + benchmarks. */ +#define LOCAL_SCALE_FACTOR 234 + +typedef struct { + int a, b; +} pair; + +/* BEEBS heap is just an array */ + +#include + +#define HEAP_SIZE 8192 +static char heap[HEAP_SIZE]; + +#include "vector.h" + +/* Create vector functions for different types. */ +MAKE_VECTOR(int) +MAKE_VECTOR(pair) + +/* Container types. */ +typedef ctl_intVector int_container; +typedef ctl_pairVector pair_container; + +#define CTL_INIT(type) ctl_##type##VectorInit () +#define CTL_PUSH(type, vec, val) ctl_ ## type ## VectorPush_Back(vec, val) +#define CTL_DELETE(type, vec, a, b) ctl_ ## type ## VectorDelete(vec, a, b) +#define CTL_POP(type, vec, res) ctl_ ## type ## VectorPop_Back(vec, res) +#define CTL_FREE(type, vec) ctl_ ## type ## VectorFree(vec) + +static int init; +static int lim; +static int fact; +static int begin; +static int end; +static int end2; + +int +benchmark (void) +{ + int j; + long int cnt; + + for (j = 0; j < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); j++) + { + int_container *v; + pair_container *v2; + + int i; + cnt=0; + init = 1; + lim = 100; + fact = 11; + begin = 4; + end = 50; + end2 = 8; + init_heap_beebs ((void *) heap, HEAP_SIZE); + + v = CTL_INIT (int); + + for (i = init; i <= lim; ++i) + CTL_PUSH (int, v, i * fact); + + CTL_DELETE (int, v, begin, end); + + while(v->size > 0) + { + int k; + + CTL_POP (int, v, &k); + + cnt += k; + } + + CTL_FREE (int, v); + + v2 = CTL_INIT (pair); + + for (i = init; i <= lim; ++i) + { + pair p = {i, i*i}; + CTL_PUSH (pair, v2, p); + } + + CTL_DELETE (pair, v2, begin, end2); + + while(v2->size > 0) + { + pair k; + + CTL_POP (pair, v2, &k); + + cnt += k.a*k.b; + } + + CTL_FREE (pair, v2); + } + + return (int) (cnt % 32768L); +} + +void initialise_benchmark() { +} + +int verify_benchmark(int r) +{ + return (26667 == r) & check_heap_beebs ((void *) heap); +} + + diff --git a/src/ctl-vector/ctl.h b/src/ctl-vector/ctl.h deleted file mode 120000 index dd995e54..00000000 --- a/src/ctl-vector/ctl.h +++ /dev/null @@ -1 +0,0 @@ -../ctl/ctl.h \ No newline at end of file diff --git a/src/ctl-vector/ctl.h b/src/ctl-vector/ctl.h new file mode 100644 index 00000000..f5935ebe --- /dev/null +++ b/src/ctl-vector/ctl.h @@ -0,0 +1,74 @@ +/* This file is part of the Bristol/Embecosm Embedded Benchmark Suite. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/***************************************************************************** + * FILE: ctl.h * + * AUTHOR: Toni Schornboeck * + ***************************************************************************** + * Das zentrale File der CTL * + ***************************************************************************** + * Diese Datei darf frei unter der * + * GPL (http://www.gnu.org/copyleft/gpl.html) verwendet werden. * + *****************************************************************************/ + +#ifndef CTL_STANDARD_HEADER__ +#define CTL_STANDARD_HEADER__ +#include +#include +#include +#include +#include + +#ifndef CTL_SIZE +#define CTL_SIZE 100 +#endif + +#ifndef CTL_GROWFACTOR +#define CTL_GROWFACTOR 0.7 +#endif + +#ifdef CTL_NORANGECHECK +#define CTL_RANGE(x) if(0) +#else +#define CTL_RANGE(x) if(x) +#endif + +#define CTL_OUT_OF_MEMORY 100 +#define CTL_WRONG_VALUE 101 +#define CTL_OUT_OF_RANGE 102 +#define CTL_NOT_FOUND 103 + +struct CTL_STRUCT { + size_t BlockSize; +}; +typedef struct CTL_STRUCT ctl_struct; + +unsigned int ctl_errno; +unsigned int ctl_warning; + +int ctl_SetBlockSize(ctl_struct* its, size_t BlockSize) +{ + if(BlockSize<1) + { + ctl_errno=CTL_WRONG_VALUE; + return 1; + } + its->BlockSize=BlockSize; + return 0; +} + +#define CTL_GROW_ALLOC_SIZE(its) its->BlockSize=((size_t)(its->alloc+its->alloc*CTL_GROWFACTOR)) + +#endif diff --git a/src/ctl-vector/vector.h b/src/ctl-vector/vector.h deleted file mode 120000 index 1f897e46..00000000 --- a/src/ctl-vector/vector.h +++ /dev/null @@ -1 +0,0 @@ -../ctl/vector.h \ No newline at end of file diff --git a/src/ctl-vector/vector.h b/src/ctl-vector/vector.h new file mode 100644 index 00000000..6b968e05 --- /dev/null +++ b/src/ctl-vector/vector.h @@ -0,0 +1,239 @@ +/* This file is part of the Bristol/Embecosm Embedded Benchmark Suite. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/***************************************************************************** + * FILE: vector.h * + * AUTHOR: Toni Schornboeck * + ***************************************************************************** + * Implementierung eines vectors (dynamisches array) fuer die CTL * + ***************************************************************************** + * Diese Datei darf frei unter der * + * GPL (http://www.gnu.org/copyleft/gpl.html) verwendet werden. * + *****************************************************************************/ + +#include "ctl.h" +#include "beebsc.h" + +#define MAKE_VECTOR(type) \ +struct CTL_##type##VECTOR { \ + size_t BlockSize; \ + type* value; \ + size_t size; \ + size_t alloc; \ +}; \ + \ +typedef struct CTL_##type##VECTOR ctl_##type##Vector; \ + \ +ctl_##type##Vector* ctl_##type##VectorInitSize(int BlockSize)\ +{ \ + ctl_##type##Vector* s=malloc_beebs(sizeof(ctl_##type##Vector));\ + if(!s) \ + { \ + return NULL; \ + } \ + s->BlockSize = BlockSize; \ + s->value = malloc_beebs(s->BlockSize*sizeof(type)); \ + if(!s->value) \ + { \ + ctl_errno = CTL_OUT_OF_MEMORY; \ + s->size = 0; \ + s->alloc = 0; \ + return NULL; \ + } \ + s->alloc = s->BlockSize; \ + s->size = 0; \ + return s; \ +} \ + \ +ctl_##type##Vector* ctl_##type##VectorInit(void) \ +{ \ + return ctl_##type##VectorInitSize(CTL_SIZE); \ +} \ + \ +ctl_##type##Vector* ctl_##type##VectorInitCopy(ctl_##type##Vector* vector)\ +{ \ + ctl_##type##Vector* s=malloc_beebs(sizeof(ctl_##type##Vector));\ + if(!s) \ + { \ + return NULL; \ + } \ + s->BlockSize = vector->BlockSize; \ + s->value = malloc_beebs(vector->alloc*sizeof(type)); \ + if(!s->value) \ + { \ + ctl_errno = CTL_OUT_OF_MEMORY; \ + s->size = 0; \ + s->alloc = 0; \ + return NULL; \ + } \ + memmove(s->value,vector->value,vector->size*sizeof(type));\ + s->alloc = vector->alloc; \ + s->size = vector->size; \ + return s; \ +} \ + \ +void ctl_##type##VectorFree(ctl_##type##Vector* s) \ +{ \ + free_beebs(s->value); \ + free_beebs(s); \ +} \ + \ +int ctl_##type##VectorPush_Back(ctl_##type##Vector* s, type push)\ +{ \ + if(s->alloc <= s->size) \ + { \ + type* secure; \ + s->alloc+=s->BlockSize; \ + secure=malloc_beebs(s->alloc*sizeof(type)); \ + if(!secure) \ + { \ + ctl_errno = CTL_OUT_OF_MEMORY; \ + s->alloc-=s->BlockSize; \ + return 1; \ + } \ + memcpy(secure, s->value, s->size*sizeof(type)); \ + CTL_GROW_ALLOC_SIZE(s); \ + s->value=secure; \ + } \ + s->value[s->size]=push; \ + ++s->size; \ + return 0; \ +} \ + \ +int ctl_##type##VectorPop_Back(ctl_##type##Vector* s, type* value)\ +{ \ + CTL_RANGE(s->size == 0) \ + { \ + ctl_errno = CTL_OUT_OF_RANGE; \ + return 0; \ + } \ + --s->size; \ + if(!value) \ + return 0; \ + *value = s->value[s->size]; \ + return 0; \ +} \ + \ +int ctl_##type##VectorSet(ctl_##type##Vector* s, type* vector, size_t size)\ +{ \ + if(s->value==vector && s->size==size) \ + return 0; \ + if(s->allocBlockSize+1)*s->BlockSize; \ + type* secure; \ + secure=malloc_beebs(alloc*sizeof(type)); \ + if(!secure) \ + { \ + ctl_errno = CTL_OUT_OF_MEMORY; \ + return 1; \ + } \ + memcpy(secure, s->value, s->size*sizeof(type)); \ + s->value=secure; \ + s->alloc=alloc; \ + } \ + s->size=size; \ + memmove(s->value,vector,size*sizeof(type)); \ + return 1; \ +} \ + \ +int ctl_##type##VectorSetVector(ctl_##type##Vector* s, ctl_##type##Vector* vector)\ +{ \ + if(s==vector) \ + return 0; \ + if(s->allocsize) \ + { \ + size_t alloc=(vector->size/s->BlockSize+1)*s->BlockSize;\ + type* secure; \ + secure=malloc_beebs(alloc*sizeof(type)); \ + if(!secure) \ + { \ + ctl_errno = CTL_OUT_OF_MEMORY; \ + return 1; \ + } \ + memcpy(secure, s->value, s->size*sizeof(type)); \ + s->alloc=alloc; \ + s->value=secure; \ + } \ + memmove(s->value,vector->value,vector->size*sizeof(type));\ + s->size=vector->size; \ + return 0; \ +} \ + \ +int ctl_##type##VectorSetAt(ctl_##type##Vector* s, size_t pos, type value)\ +{ \ + CTL_RANGE(pos>=s->size) \ + { \ + ctl_errno=CTL_OUT_OF_RANGE; \ + return 1; \ + } \ + s->value[pos]=value; \ + return 0; \ +} \ + \ +int ctl_##type##VectorInsert(ctl_##type##Vector* s, size_t pos, type value)\ +{ \ + CTL_RANGE(pos>=s->size) \ + { \ + ctl_errno=CTL_WRONG_VALUE; \ + return ctl_errno; \ + } \ + if(s->size>=s->alloc) \ + { \ + type* secure; \ + s->alloc+=s->BlockSize; \ + secure=malloc_beebs(s->alloc*sizeof(type)); \ + if(!secure) \ + { \ + s->alloc-=s->BlockSize; \ + ctl_errno=CTL_OUT_OF_MEMORY; \ + return 1; \ + } \ + memcpy(secure, s->value, s->size*sizeof(type)); \ + s->alloc+=s->BlockSize; \ + CTL_GROW_ALLOC_SIZE(s); \ + s->value=secure; \ + } \ + memmove(&s->value[pos+1],&s->value[pos],(s->size-pos)*sizeof(type));\ + ++s->size; \ + s->value[pos]=value; \ + return 0; \ +} \ + \ +int ctl_##type##VectorDelete(ctl_##type##Vector* s, size_t begin, size_t end)\ +{ \ + CTL_RANGE(begin>end) \ + { \ + ctl_errno=CTL_WRONG_VALUE; \ + return 1; \ + } \ + s->size-=(end-begin); \ + memmove(&s->value[begin],&s->value[end],s->size*sizeof(type));\ + return 0; \ +} \ + \ +int ctl_##type##VectorShrink(ctl_##type##Vector* s) \ +{ \ + type* secure; \ + secure=malloc_beebs(s->size*sizeof(type)); \ + if(!secure) \ + { \ + ctl_errno=CTL_OUT_OF_MEMORY; \ + return 1; \ + } \ + memcpy(secure, s->value, s->size*sizeof(type)); \ + s->value=secure; \ + return 0; \ +} diff --git a/src/ctl/.gitignore b/src/ctl/.gitignore deleted file mode 100644 index 9be55659..00000000 --- a/src/ctl/.gitignore +++ /dev/null @@ -1 +0,0 @@ -ctl diff --git a/src/ctl/Makefile.am b/src/ctl/Makefile.am deleted file mode 100644 index fa0e0e78..00000000 --- a/src/ctl/Makefile.am +++ /dev/null @@ -1,26 +0,0 @@ -# Makefile.am for distributing ctl -# -# Copyright (C) 2013 Embecosm Limited and University of Bristol -# -# This file is part of the Bristol/Embecosm Embedded Benchmark Suite. -# -# Contributor: James Pallister -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# SPDX-License-Identifier: GPL-3.0-or-later - -# Not a benchmark per se, but the base software for other benchmarks. - -EXTRA_DIST = ctl.c ctl.h stack.h vector.h diff --git a/src/ctl/Makefile.in b/src/ctl/Makefile.in deleted file mode 100644 index e13d7fd4..00000000 --- a/src/ctl/Makefile.in +++ /dev/null @@ -1,480 +0,0 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2014 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -# Makefile.am for distributing ctl -# -# Copyright (C) 2013 Embecosm Limited and University of Bristol -# -# This file is part of the Bristol/Embecosm Embedded Benchmark Suite. -# -# Contributor: James Pallister -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# SPDX-License-Identifier: GPL-3.0-or-later - -# Not a benchmark per se, but the base software for other benchmarks. -VPATH = @srcdir@ -am__is_gnu_make = { \ - if test -z '$(MAKELEVEL)'; then \ - false; \ - elif test -n '$(MAKE_HOST)'; then \ - true; \ - elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ - true; \ - else \ - false; \ - fi; \ -} -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -target_triplet = @target@ -subdir = src/ctl -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ - $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ - $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ - $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -SOURCES = -DIST_SOURCES = -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -am__DIST_COMMON = $(srcdir)/Makefile.in -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AR = @AR@ -ARCH = @ARCH@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -BENCHMARKS = @BENCHMARKS@ -BOARD = @BOARD@ -CC = @CC@ -CCAS = @CCAS@ -CCASDEPMODE = @CCASDEPMODE@ -CCASFLAGS = @CCASFLAGS@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CHIP = @CHIP@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEJAGNU = @DEJAGNU@ -DEPDIR = @DEPDIR@ -DLLTOOL = @DLLTOOL@ -DSYMUTIL = @DSYMUTIL@ -DUMMY_COMPILERRT = @DUMMY_COMPILERRT@ -DUMMY_CRT0 = @DUMMY_CRT0@ -DUMMY_LIBC = @DUMMY_LIBC@ -DUMMY_LIBGCC = @DUMMY_LIBGCC@ -DUMMY_LIBM = @DUMMY_LIBM@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LIBTOOL_DEPS = @LIBTOOL_DEPS@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MKDIR_P = @MKDIR_P@ -NM = @NM@ -NMEDIT = @NMEDIT@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -RANLIB = @RANLIB@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -VERSION = @VERSION@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target = @target@ -target_alias = @target_alias@ -target_cpu = @target_cpu@ -target_os = @target_os@ -target_vendor = @target_vendor@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -EXTRA_DIST = ctl.c ctl.h stack.h vector.h -all: all-am - -.SUFFIXES: -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/ctl/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu src/ctl/Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs -tags TAGS: - -ctags CTAGS: - -cscope cscopelist: - - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile -installdirs: -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic clean-libtool mostlyclean-am - -distclean: distclean-am - -rm -f Makefile -distclean-am: clean-am distclean-generic - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-generic mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: - -.MAKE: install-am install-strip - -.PHONY: all all-am check check-am clean clean-generic clean-libtool \ - cscopelist-am ctags-am distclean distclean-generic \ - distclean-libtool distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags-am uninstall uninstall-am - -.PRECIOUS: Makefile - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/src/ctl/ctl.c b/src/ctl/ctl.c deleted file mode 100644 index 8972d60e..00000000 --- a/src/ctl/ctl.c +++ /dev/null @@ -1,203 +0,0 @@ -/* -*- mode: C++; c-file-style: "gnu-mode" -*- */ -/* BEEBS vector benchmark - - Copyright (C) 2013 Embecosm Limited and University of Bristol - - Contributor: James Pallister - - This file is part of the Bristol/Embecosm Embedded Benchmark Suite. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#include "support.h" - -/* This scale factor will be changed to equalise the runtime of the - benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) - -typedef struct { - int a, b; -} pair; - -/* BEEBS heap is just an array */ - -#include - -#define HEAP_SIZE 8192 -static char heap[HEAP_SIZE]; -static void *heap_ptr; -static void *heap_end; - -/* Initialize the BEEBS heap pointers */ - -static void -init_heap () -{ - heap_ptr = (void *) heap; - heap_end = heap_ptr + HEAP_SIZE; -} - -/* BEEBS version of malloc. - - This is primarily to reduce library and OS dependencies. Malloc is - generally not used in embedded code, or if it is, only in well defined - contexts to pre-allocate a fixed amount of memory. So this simplistic - implementation is just fine. */ - -static void * -malloc_beebs (size_t size) -{ - void *new_ptr = heap_ptr; - - if (((heap_ptr + size) > heap_end) || (0 == size)) - return NULL; - else - { - heap_ptr += size; - return new_ptr; - } -} - -/* BEEBS version of free. - - For our simplified version of memory handling, free can just do nothing. */ - -static void -free_beebs (void *ptr) -{ -} - -#ifdef CTL_VECTOR -#include "vector.h" - -/* Create vector functions for different types. */ -MAKE_VECTOR(int) -MAKE_VECTOR(pair) - -/* Container types. */ -typedef ctl_intVector int_container; -typedef ctl_pairVector pair_container; - -#define CTL_INIT(type) ctl_##type##VectorInit () -#define CTL_PUSH(type, vec, val) ctl_ ## type ## VectorPush_Back(vec, val) -#define CTL_DELETE(type, vec, a, b) ctl_ ## type ## VectorDelete(vec, a, b) -#define CTL_POP(type, vec, res) ctl_ ## type ## VectorPop_Back(vec, res) -#define CTL_FREE(type, vec) ctl_ ## type ## VectorFree(vec) - -#elif defined CTL_STACK -#include "stack.h" - -/* Create stack functions for different types. */ -MAKE_STACK(int) -MAKE_STACK(pair) - -/* Container types. */ -typedef ctl_intStack int_container; -typedef ctl_pairStack pair_container; - -#define CTL_INIT(type) ctl_ ## type ## StackInit () -#define CTL_PUSH(type, stk, val) ctl_ ## type ## StackPush (stk, val) -#define CTL_POP(type, stk, res) ctl_ ## type ## StackPop (stk, res) -#define CTL_FREE(type, stk) ctl_ ## type ## StackFree (stk) - -/* There's no DELETE for stacks. */ -#define CTL_DELETE(type, vec, a, b) do { } while (0) - - -#else -#error "Expected CTL_VECTOR or CTL_STACK to be defined" -#endif - -static int init; -static int lim; -static int fact; -static int begin; -static int end; -static int end2; - -int -benchmark (void) -{ - int_container *v; - pair_container *v2; - - int cnt=0, i; - - v = CTL_INIT (int); - - for (i = init; i <= lim; ++i) - CTL_PUSH (int, v, i * fact); - - CTL_DELETE (int, v, begin, end); - - while(v->size > 0) - { - int k; - - CTL_POP (int, v, &k); - - cnt += k; - } - - CTL_FREE (int, v); - - v2 = CTL_INIT (pair); - - for (i = init; i <= lim; ++i) - { - pair p = {i, i*i}; - CTL_PUSH (pair, v2, p); - } - - CTL_DELETE (pair, v2, begin, end2); - - while(v2->size > 0) - { - pair k; - - CTL_POP (pair, v2, &k); - - cnt += k.a*k.b; - } - - CTL_FREE (pair, v2); - - return cnt; -} - -void initialise_benchmark() { - init = 1; - lim = 100; - fact = 11; - begin = 4; - end = 50; - end2 = 8; - init_heap (); -} - -int verify_benchmark(int r) -{ -#ifdef CTL_VECTOR - int expected = 25542939; -#elif defined CTL_STACK - int expected = 25558050; -#else -#error "Expected CTL_VECTOR or CTL_STACK to be defined" -#endif - if (r != expected) - return 0; - return 1; -} - - diff --git a/src/ctl/ctl.h b/src/ctl/ctl.h deleted file mode 100644 index f5935ebe..00000000 --- a/src/ctl/ctl.h +++ /dev/null @@ -1,74 +0,0 @@ -/* This file is part of the Bristol/Embecosm Embedded Benchmark Suite. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/***************************************************************************** - * FILE: ctl.h * - * AUTHOR: Toni Schornboeck * - ***************************************************************************** - * Das zentrale File der CTL * - ***************************************************************************** - * Diese Datei darf frei unter der * - * GPL (http://www.gnu.org/copyleft/gpl.html) verwendet werden. * - *****************************************************************************/ - -#ifndef CTL_STANDARD_HEADER__ -#define CTL_STANDARD_HEADER__ -#include -#include -#include -#include -#include - -#ifndef CTL_SIZE -#define CTL_SIZE 100 -#endif - -#ifndef CTL_GROWFACTOR -#define CTL_GROWFACTOR 0.7 -#endif - -#ifdef CTL_NORANGECHECK -#define CTL_RANGE(x) if(0) -#else -#define CTL_RANGE(x) if(x) -#endif - -#define CTL_OUT_OF_MEMORY 100 -#define CTL_WRONG_VALUE 101 -#define CTL_OUT_OF_RANGE 102 -#define CTL_NOT_FOUND 103 - -struct CTL_STRUCT { - size_t BlockSize; -}; -typedef struct CTL_STRUCT ctl_struct; - -unsigned int ctl_errno; -unsigned int ctl_warning; - -int ctl_SetBlockSize(ctl_struct* its, size_t BlockSize) -{ - if(BlockSize<1) - { - ctl_errno=CTL_WRONG_VALUE; - return 1; - } - its->BlockSize=BlockSize; - return 0; -} - -#define CTL_GROW_ALLOC_SIZE(its) its->BlockSize=((size_t)(its->alloc+its->alloc*CTL_GROWFACTOR)) - -#endif diff --git a/src/ctl/stack.h b/src/ctl/stack.h deleted file mode 100644 index d114ed0a..00000000 --- a/src/ctl/stack.h +++ /dev/null @@ -1,120 +0,0 @@ -/* This file is part of the Bristol/Embecosm Embedded Benchmark Suite. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/***************************************************************************** - * FILE: stack.h * - * AUTHOR: Toni Schornboeck * - ***************************************************************************** - * Implementierung eines FixedSize Stack fuer die CTL * - ***************************************************************************** - * Diese Datei darf frei unter der * - * GPL (http://www.gnu.org/copyleft/gpl.html) verwendet werden. * - *****************************************************************************/ - -#include "ctl.h" - -#define MAKE_STACK(type) \ -struct CTL_##type##STACK { \ - type* value; \ - size_t size; \ - size_t first; \ - size_t alloc; \ -}; \ - \ -typedef struct CTL_##type##STACK ctl_##type##Stack; \ - \ -ctl_##type##Stack* ctl_##type##StackInitSize(int BlockSize)\ -{ \ - ctl_##type##Stack* s=malloc_beebs(sizeof(ctl_##type##Stack));\ - if(!s) \ - { \ - return NULL; \ - } \ - s->alloc = BlockSize; \ - s->value = malloc_beebs(BlockSize*sizeof(type));\ - if(!s->value) \ - { \ - return NULL; \ - } \ - s->first = 0; \ - s->size = 0; \ - return s; \ -} \ - \ -ctl_##type##Stack* ctl_##type##StackInit(void) \ -{ \ - return ctl_##type##StackInitSize(CTL_SIZE); \ -} \ - \ -ctl_##type##Stack* ctl_##type##StackInitCopy(ctl_##type##Stack* stack)\ -{ \ - ctl_##type##Stack* s=malloc_beebs(sizeof(ctl_##type##Stack));\ - if(!s) \ - { \ - return NULL; \ - } \ - s->alloc = stack->alloc; \ - s->value = malloc_beebs(stack->alloc*sizeof(type));\ - if(!s->value) \ - { \ - return NULL; \ - } \ - s->first = stack->first; \ - s->size = stack->size; \ - return s; \ -} \ - \ -void ctl_##type##StackFree(ctl_##type##Stack* s) \ -{ \ - free_beebs(s->value); \ - free_beebs(s); \ -} \ - \ -int ctl_##type##StackPush(ctl_##type##Stack* s, type value)\ -{ \ - if(++s->size>s->alloc) \ - { \ - s->size=s->alloc; \ - } \ - if(++s->first==s->size) \ - { \ - s->first=0; \ - } \ - s->value[s->first]=value; \ - return 0; \ -} \ - \ -int ctl_##type##StackPop(ctl_##type##Stack* s, type* value)\ -{ \ - if(s->size==0) \ - { \ - ctl_errno=CTL_OUT_OF_RANGE; \ - return 1; \ - } \ - \ - if(value)*value=s->value[s->first]; \ - --s->size; \ - if(s->size) \ - { \ - if(!s->first) \ - { \ - s->first=s->size-1; \ - return 0; \ - } \ - --s->first; \ - } \ - return 0; \ -} - diff --git a/src/ctl/vector.h b/src/ctl/vector.h deleted file mode 100644 index 61215073..00000000 --- a/src/ctl/vector.h +++ /dev/null @@ -1,239 +0,0 @@ -/* This file is part of the Bristol/Embecosm Embedded Benchmark Suite. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/***************************************************************************** - * FILE: vector.h * - * AUTHOR: Toni Schornboeck * - ***************************************************************************** - * Implementierung eines vectors (dynamisches array) fuer die CTL * - ***************************************************************************** - * Diese Datei darf frei unter der * - * GPL (http://www.gnu.org/copyleft/gpl.html) verwendet werden. * - *****************************************************************************/ - -#include "ctl.h" - - -#define MAKE_VECTOR(type) \ -struct CTL_##type##VECTOR { \ - size_t BlockSize; \ - type* value; \ - size_t size; \ - size_t alloc; \ -}; \ - \ -typedef struct CTL_##type##VECTOR ctl_##type##Vector; \ - \ -ctl_##type##Vector* ctl_##type##VectorInitSize(int BlockSize)\ -{ \ - ctl_##type##Vector* s=malloc_beebs(sizeof(ctl_##type##Vector));\ - if(!s) \ - { \ - return NULL; \ - } \ - s->BlockSize = BlockSize; \ - s->value = malloc_beebs(s->BlockSize*sizeof(type)); \ - if(!s->value) \ - { \ - ctl_errno = CTL_OUT_OF_MEMORY; \ - s->size = 0; \ - s->alloc = 0; \ - return NULL; \ - } \ - s->alloc = s->BlockSize; \ - s->size = 0; \ - return s; \ -} \ - \ -ctl_##type##Vector* ctl_##type##VectorInit(void) \ -{ \ - return ctl_##type##VectorInitSize(CTL_SIZE); \ -} \ - \ -ctl_##type##Vector* ctl_##type##VectorInitCopy(ctl_##type##Vector* vector)\ -{ \ - ctl_##type##Vector* s=malloc_beebs(sizeof(ctl_##type##Vector));\ - if(!s) \ - { \ - return NULL; \ - } \ - s->BlockSize = vector->BlockSize; \ - s->value = malloc_beebs(vector->alloc*sizeof(type)); \ - if(!s->value) \ - { \ - ctl_errno = CTL_OUT_OF_MEMORY; \ - s->size = 0; \ - s->alloc = 0; \ - return NULL; \ - } \ - memmove(s->value,vector->value,vector->size*sizeof(type));\ - s->alloc = vector->alloc; \ - s->size = vector->size; \ - return s; \ -} \ - \ -void ctl_##type##VectorFree(ctl_##type##Vector* s) \ -{ \ - free_beebs(s->value); \ - free_beebs(s); \ -} \ - \ -int ctl_##type##VectorPush_Back(ctl_##type##Vector* s, type push)\ -{ \ - if(s->alloc <= s->size) \ - { \ - type* secure; \ - s->alloc+=s->BlockSize; \ - secure=malloc_beebs(s->alloc*sizeof(type)); \ - if(!secure) \ - { \ - ctl_errno = CTL_OUT_OF_MEMORY; \ - s->alloc-=s->BlockSize; \ - return 1; \ - } \ - memcpy(secure, s->value, s->size*sizeof(type)); \ - CTL_GROW_ALLOC_SIZE(s); \ - s->value=secure; \ - } \ - s->value[s->size]=push; \ - ++s->size; \ - return 0; \ -} \ - \ -int ctl_##type##VectorPop_Back(ctl_##type##Vector* s, type* value)\ -{ \ - CTL_RANGE(s->size == 0) \ - { \ - ctl_errno = CTL_OUT_OF_RANGE; \ - return 0; \ - } \ - --s->size; \ - if(!value) \ - return 0; \ - *value = s->value[s->size]; \ - return 0; \ -} \ - \ -int ctl_##type##VectorSet(ctl_##type##Vector* s, type* vector, size_t size)\ -{ \ - if(s->value==vector && s->size==size) \ - return 0; \ - if(s->allocBlockSize+1)*s->BlockSize; \ - type* secure; \ - secure=malloc_beebs(alloc*sizeof(type)); \ - if(!secure) \ - { \ - ctl_errno = CTL_OUT_OF_MEMORY; \ - return 1; \ - } \ - memcpy(secure, s->value, s->size*sizeof(type)); \ - s->value=secure; \ - s->alloc=alloc; \ - } \ - s->size=size; \ - memmove(s->value,vector,size*sizeof(type)); \ - return 1; \ -} \ - \ -int ctl_##type##VectorSetVector(ctl_##type##Vector* s, ctl_##type##Vector* vector)\ -{ \ - if(s==vector) \ - return 0; \ - if(s->allocsize) \ - { \ - size_t alloc=(vector->size/s->BlockSize+1)*s->BlockSize;\ - type* secure; \ - secure=malloc_beebs(alloc*sizeof(type)); \ - if(!secure) \ - { \ - ctl_errno = CTL_OUT_OF_MEMORY; \ - return 1; \ - } \ - memcpy(secure, s->value, s->size*sizeof(type)); \ - s->alloc=alloc; \ - s->value=secure; \ - } \ - memmove(s->value,vector->value,vector->size*sizeof(type));\ - s->size=vector->size; \ - return 0; \ -} \ - \ -int ctl_##type##VectorSetAt(ctl_##type##Vector* s, size_t pos, type value)\ -{ \ - CTL_RANGE(pos>=s->size) \ - { \ - ctl_errno=CTL_OUT_OF_RANGE; \ - return 1; \ - } \ - s->value[pos]=value; \ - return 0; \ -} \ - \ -int ctl_##type##VectorInsert(ctl_##type##Vector* s, size_t pos, type value)\ -{ \ - CTL_RANGE(pos>=s->size) \ - { \ - ctl_errno=CTL_WRONG_VALUE; \ - return ctl_errno; \ - } \ - if(s->size>=s->alloc) \ - { \ - type* secure; \ - s->alloc+=s->BlockSize; \ - secure=malloc_beebs(s->alloc*sizeof(type)); \ - if(!secure) \ - { \ - s->alloc-=s->BlockSize; \ - ctl_errno=CTL_OUT_OF_MEMORY; \ - return 1; \ - } \ - memcpy(secure, s->value, s->size*sizeof(type)); \ - s->alloc+=s->BlockSize; \ - CTL_GROW_ALLOC_SIZE(s); \ - s->value=secure; \ - } \ - memmove(&s->value[pos+1],&s->value[pos],(s->size-pos)*sizeof(type));\ - ++s->size; \ - s->value[pos]=value; \ - return 0; \ -} \ - \ -int ctl_##type##VectorDelete(ctl_##type##Vector* s, size_t begin, size_t end)\ -{ \ - CTL_RANGE(begin>end) \ - { \ - ctl_errno=CTL_WRONG_VALUE; \ - return 1; \ - } \ - s->size-=(end-begin); \ - memmove(&s->value[begin],&s->value[end],s->size*sizeof(type));\ - return 0; \ -} \ - \ -int ctl_##type##VectorShrink(ctl_##type##Vector* s) \ -{ \ - type* secure; \ - secure=malloc_beebs(s->size*sizeof(type)); \ - if(!secure) \ - { \ - ctl_errno=CTL_OUT_OF_MEMORY; \ - return 1; \ - } \ - memcpy(secure, s->value, s->size*sizeof(type)); \ - s->value=secure; \ - return 0; \ -} diff --git a/src/cubic/Makefile.am b/src/cubic/Makefile.am index 8ef55cfa..37a9b0bf 100644 --- a/src/cubic/Makefile.am +++ b/src/cubic/Makefile.am @@ -35,6 +35,7 @@ libcubic_la_SOURCES = libcubic.c basicmath_small.c pi.h snipmath.h sniptype.h cubic_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libcubic.la \ + $(top_builddir)/support/libbeebsc.la \ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) \ $(LIBM) endif diff --git a/src/cubic/Makefile.in b/src/cubic/Makefile.in index 4abb0ae5..7aff3210 100644 --- a/src/cubic/Makefile.in +++ b/src/cubic/Makefile.in @@ -173,6 +173,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_CUBIC_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_CUBIC_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_CUBIC_TRUE@ libcubic.la \ +@ENABLED_BENCHMARK_CUBIC_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_CUBIC_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_CUBIC_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_CUBIC_TRUE@ $(am__DEPENDENCIES_1) $(LIBM) @@ -395,6 +396,7 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_CUBIC_TRUE@cubic_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_CUBIC_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_CUBIC_TRUE@ libcubic.la \ +@ENABLED_BENCHMARK_CUBIC_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_CUBIC_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) \ @ENABLED_BENCHMARK_CUBIC_TRUE@ $(LIBM) diff --git a/src/cubic/basicmath_small.c b/src/cubic/basicmath_small.c index a93f2723..5036e360 100644 --- a/src/cubic/basicmath_small.c +++ b/src/cubic/basicmath_small.c @@ -1,5 +1,3 @@ - - /* BEEBS cubic benchmark Contributor: James Pallister @@ -19,20 +17,30 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ +#include #include "support.h" #include "snipmath.h" /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 13) +#define LOCAL_SCALE_FACTOR 5 + -/* This benchmark does not support verification */ + +static int soln_cnt0; +static int soln_cnt1; +static double res0[3]; +static double res1; + int verify_benchmark (int res __attribute ((unused)) ) { - return -1; + static double exp_res0[3] = {2.0, 6.0, 2.5}; + return (3 == soln_cnt0) && (fabs (2.0 - res0[0]) < 1.0e-10) + && (fabs (6.0 - res0[1]) < 1.0e-10) && (fabs (2.5 - res0[2]) < 1.0e-10) + && (1 == soln_cnt1) && (fabs (2.5 - res1) < 1.0e-10); } @@ -42,35 +50,43 @@ initialise_benchmark (void) } - int benchmark(void) { - double a1 = 1.0, b1 = -10.5, c1 = 32.0, d1 = -30.0; - double a2 = 1.0, b2 = -4.5, c2 = 17.0, d2 = -30.0; - double a3 = 1.0, b3 = -3.5, c3 = 22.0, d3 = -31.0; - double a4 = 1.0, b4 = -13.7, c4 = 1.0, d4 = -35.0; - int solutions; - - double output[48] = {0}; - double *output_pos = &(output[0]); - - /* solve some cubic functions */ - /* should get 3 solutions: 2, 6 & 2.5 */ - SolveCubic(a1, b1, c1, d1, &solutions, output); - /* should get 1 solution: 2.5 */ - SolveCubic(a2, b2, c2, d2, &solutions, output); - SolveCubic(a3, b3, c3, d3, &solutions, output); - SolveCubic(a4, b4, c4, d4, &solutions, output); - /* Now solve some random equations */ - for(a1=1;a1<3;a1++) { - for(b1=10;b1>8;b1--) { - for(c1=5;c1<6;c1+=0.5) { + int i; + + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + { + double a1 = 1.0, b1 = -10.5, c1 = 32.0, d1 = -30.0; + double a2 = 1.0, b2 = -4.5, c2 = 17.0, d2 = -30.0; + double a3 = 1.0, b3 = -3.5, c3 = 22.0, d3 = -31.0; + double a4 = 1.0, b4 = -13.7, c4 = 1.0, d4 = -35.0; + int solutions; + + double output[48] = {0}; + double *output_pos = &(output[0]); + + /* solve some cubic functions */ + /* should get 3 solutions: 2, 6 & 2.5 */ + SolveCubic(a1, b1, c1, d1, &solutions, output); + soln_cnt0 = solutions; + memcpy(res0,output,3*sizeof(res0[0])); + /* should get 1 solution: 2.5 */ + SolveCubic(a2, b2, c2, d2, &solutions, output); + soln_cnt1 = solutions; + res1 = output[0]; + SolveCubic(a3, b3, c3, d3, &solutions, output); + SolveCubic(a4, b4, c4, d4, &solutions, output); + /* Now solve some random equations */ + for(a1=1;a1<3;a1++) { + for(b1=10;b1>8;b1--) { + for(c1=5;c1<6;c1+=0.5) { for(d1=-1;d1>-3;d1--) { - SolveCubic(a1, b1, c1, d1, &solutions, output_pos); + SolveCubic(a1, b1, c1, d1, &solutions, output_pos); } - } + } + } } - } + } return 0; } diff --git a/src/cubic/libcubic.c b/src/cubic/libcubic.c index b22f4a28..4f2b396e 100644 --- a/src/cubic/libcubic.c +++ b/src/cubic/libcubic.c @@ -35,34 +35,31 @@ void SolveCubic(double a, int *solutions, double *x) { - long double a1 = b/a, a2 = c/a, a3 = d/a; - long double Q = (a1*a1 - 3.0*a2)/9.0; - long double R = (2.0*a1*a1*a1 - 9.0*a1*a2 + 27.0*a3)/54.0; - double R2_Q3 = R*R - Q*Q*Q; + long double a1 = (long double) (b/a); + long double a2 = (long double) (c/a); + long double a3 = (long double) (d/a); + long double Q = (a1*a1 - 3.0L*a2)/9.0L; + long double R = (2.0L*a1*a1*a1 - 9.0L*a1*a2 + 27.0L*a3)/54.0L; + double R2_Q3 = (double) (R*R - Q*Q*Q); - double theta; + double theta; if (R2_Q3 <= 0) { *solutions = 3; - theta = acos(R/sqrt(Q*Q*Q)); - x[0] = -2.0*sqrt(Q)*cos(theta/3.0) - a1/3.0; - x[1] = -2.0*sqrt(Q)*cos((theta+2.0*PI)/3.0) - a1/3.0; - x[2] = -2.0*sqrt(Q)*cos((theta+4.0*PI)/3.0) - a1/3.0; + theta = acos(((double) R)/sqrt((double) (Q*Q*Q))); + x[0] = -2.0*sqrt((double) Q)*cos(theta/3.0) - a1/3.0; + x[1] = -2.0*sqrt((double) Q)*cos((theta+2.0*PI)/3.0) - a1/3.0; + x[2] = -2.0*sqrt((double) Q)*cos((theta+4.0*PI)/3.0) - a1/3.0; } else { *solutions = 1; - x[0] = pow(sqrt(R2_Q3)+fabs(R), 1/3.0); - x[0] += Q/x[0]; - x[0] *= (R < 0.0) ? 1 : -1; - x[0] -= a1/3.0; + x[0] = pow(sqrt(R2_Q3)+fabs((double) R), 1/3.0); + x[0] += ((double) Q)/x[0]; + x[0] *= (R < 0.0L) ? 1 : -1; + x[0] -= (double) (a1/3.0L); } } -#ifdef TEST - - -#endif /* TEST */ - /* vim: set ts=3 sw=3 et: */ diff --git a/src/dijkstra/Makefile.am b/src/dijkstra/Makefile.am index 29c1fae7..d93b4b6d 100644 --- a/src/dijkstra/Makefile.am +++ b/src/dijkstra/Makefile.am @@ -34,7 +34,8 @@ libdijkstra_la_SOURCES = dijkstra_small.c dijkstra_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libdijkstra.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) diff --git a/src/dijkstra/Makefile.in b/src/dijkstra/Makefile.in index 847dcef4..5e9eef36 100644 --- a/src/dijkstra/Makefile.in +++ b/src/dijkstra/Makefile.in @@ -172,6 +172,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_DIJKSTRA_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_DIJKSTRA_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_DIJKSTRA_TRUE@ libdijkstra.la \ +@ENABLED_BENCHMARK_DIJKSTRA_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_DIJKSTRA_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_DIJKSTRA_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_DIJKSTRA_TRUE@ $(am__DEPENDENCIES_1) @@ -394,7 +395,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_DIJKSTRA_TRUE@dijkstra_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_DIJKSTRA_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_DIJKSTRA_TRUE@ libdijkstra.la \ -@ENABLED_BENCHMARK_DIJKSTRA_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_DIJKSTRA_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_DIJKSTRA_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/dijkstra/dijkstra_small.c b/src/dijkstra/dijkstra_small.c index 66332f2c..7c5828b5 100644 --- a/src/dijkstra/dijkstra_small.c +++ b/src/dijkstra/dijkstra_small.c @@ -30,7 +30,7 @@ /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 9) +#define LOCAL_SCALE_FACTOR 6 #define NUM_NODES 10 #define NONE 9999 @@ -236,17 +236,22 @@ initialise_benchmark (void) int benchmark() { - int i,j; + int l; - output_count = 0; + for (l = 0; l < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); l++) + { + int i,j; + + output_count = 0; - /* finds 10 shortest paths between nodes */ - for(j = 0; j < NUM_NODES; j++) { - for (i=0; i < NUM_NODES; i++) { - output[output_count] = dijkstra(i,j); - output_count++; + /* finds 10 shortest paths between nodes */ + for(j = 0; j < NUM_NODES; j++) { + for (i=0; i < NUM_NODES; i++) { + output[output_count] = dijkstra(i,j); + output_count++; + } } - } + } return 0; } diff --git a/src/dtoa/Makefile.am b/src/dtoa/Makefile.am index 2fe681c2..4149a46a 100644 --- a/src/dtoa/Makefile.am +++ b/src/dtoa/Makefile.am @@ -34,7 +34,8 @@ libdtoa_la_SOURCES = libdtoa.c dtoa_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libdtoa.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) diff --git a/src/dtoa/Makefile.in b/src/dtoa/Makefile.in index cda02c8b..94014f39 100644 --- a/src/dtoa/Makefile.in +++ b/src/dtoa/Makefile.in @@ -170,7 +170,9 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_DTOA_TRUE@dtoa_DEPENDENCIES = \ @ENABLED_BENCHMARK_DTOA_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_DTOA_TRUE@ $(top_builddir)/support/libsupport.la \ -@ENABLED_BENCHMARK_DTOA_TRUE@ libdtoa.la $(am__DEPENDENCIES_1) \ +@ENABLED_BENCHMARK_DTOA_TRUE@ libdtoa.la \ +@ENABLED_BENCHMARK_DTOA_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_DTOA_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_DTOA_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_DTOA_TRUE@ $(am__DEPENDENCIES_1) AM_V_P = $(am__v_P_@AM_V@) @@ -392,7 +394,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_DTOA_TRUE@dtoa_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_DTOA_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_DTOA_TRUE@ libdtoa.la \ -@ENABLED_BENCHMARK_DTOA_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_DTOA_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_DTOA_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/dtoa/libdtoa.c b/src/dtoa/libdtoa.c index 87f1fff3..a2ac5618 100644 --- a/src/dtoa/libdtoa.c +++ b/src/dtoa/libdtoa.c @@ -212,7 +212,7 @@ /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) +#define LOCAL_SCALE_FACTOR 458 #ifndef Long @@ -551,47 +551,6 @@ extern "C" char *dtoa(double d, int mode, int ndigits, #define HEAP_SIZE 8192 static char heap[HEAP_SIZE]; -static void *heap_ptr; -static void *heap_end; - -/* Initialize the BEEBS heap pointers */ - -static void -init_heap (void) -{ - heap_ptr = (void *) heap; - heap_end = heap_ptr + HEAP_SIZE; -} - -/* BEEBS version of malloc. - - This is primarily to reduce library and OS dependencies. Malloc is - generally not used in embedded code, or if it is, only in well defined - contexts to pre-allocate a fixed amount of memory. So this simplistic - implementation is just fine. */ - -void * -malloc_beebs (size_t size) -{ - void *new_ptr = heap_ptr; - - if (((heap_ptr + size) > heap_end) || (0 == size)) - return NULL; - else - { - heap_ptr += size; - return new_ptr; - } -} - -/* BEEBS version of free. - - For our simplified version of memory handling, free can just do nothing. */ - -void -free_beebs (void *ptr) -{ -} struct Bigint { @@ -4292,29 +4251,30 @@ char *nums[] = {"238434.3459823", "23955.0", "0.01000000023123", "1.0", "5555.55 void initialise_benchmark (void) { - init_heap (); } int benchmark() { - volatile double sum=0; - int i; + int j; + volatile double sum; - for(i = 0; i < 5; ++i) - sum += strtod(nums[i], NULL); + for (j = 0; j < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); j++) + { + int i; + sum=0; - return (int)sum; + init_heap_beebs ((void *) heap, HEAP_SIZE); + + for(i = 0; i < 5; ++i) + sum += strtod(nums[i], NULL); + } + return (int)sum; } int verify_benchmark(int r) { - int expected = 267945; - if (r != expected) - return 0; - else { - return 1; - } + return (267945 == r) && check_heap_beebs ((void *) heap); } diff --git a/src/duff/Makefile.am b/src/duff/Makefile.am index ea4f9433..5bb0e881 100644 --- a/src/duff/Makefile.am +++ b/src/duff/Makefile.am @@ -34,7 +34,8 @@ libduff_la_SOURCES = libduff.c duff_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libduff.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) diff --git a/src/duff/Makefile.in b/src/duff/Makefile.in index 4797456c..d2984fe0 100644 --- a/src/duff/Makefile.in +++ b/src/duff/Makefile.in @@ -170,7 +170,9 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_DUFF_TRUE@duff_DEPENDENCIES = \ @ENABLED_BENCHMARK_DUFF_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_DUFF_TRUE@ $(top_builddir)/support/libsupport.la \ -@ENABLED_BENCHMARK_DUFF_TRUE@ libduff.la $(am__DEPENDENCIES_1) \ +@ENABLED_BENCHMARK_DUFF_TRUE@ libduff.la \ +@ENABLED_BENCHMARK_DUFF_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_DUFF_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_DUFF_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_DUFF_TRUE@ $(am__DEPENDENCIES_1) AM_V_P = $(am__v_P_@AM_V@) @@ -392,7 +394,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_DUFF_TRUE@duff_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_DUFF_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_DUFF_TRUE@ libduff.la \ -@ENABLED_BENCHMARK_DUFF_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_DUFF_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_DUFF_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/duff/libduff.c b/src/duff/libduff.c index ab6f8936..8ef26d19 100644 --- a/src/duff/libduff.c +++ b/src/duff/libduff.c @@ -28,101 +28,68 @@ /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) - +#define LOCAL_SCALE_FACTOR 4801 /* $Id: duff.c,v 1.2 2005/04/04 11:34:58 csg Exp $ */ - - /*---------------------------------------------------------------------- - * WCET Benchmark created by Jakob Engblom, Uppsala university, - * February 2000. - * - * The purpose of this benchmark is to force the compiler to emit an - * unstructured loop, which is usually problematic for WCET tools to - * handle. - * - * The execution time should be constant. - * - * The original code is "Duff's Device", see the Jargon File, e.g. at - * http://www.tf.hut.fi/cgi-bin/jargon. Created in the early 1980s - * as a way to express loop unrolling in C. - * - *----------------------------------------------------------------------*/ - - #define ARRAYSIZE 100 - #define INVOCATION_COUNT 43 /* exec time depends on this one! */ - - - void duffcopy( char *to, char *from, int count) - { - int n=(count+7)/8; - switch(count%8){ - case 0: do{ *to++ = *from++; - case 7: *to++ = *from++; - case 6: *to++ = *from++; - case 5: *to++ = *from++; - case 4: *to++ = *from++; - case 3: *to++ = *from++; - case 2: *to++ = *from++; - case 1: *to++ = *from++; - } while(--n>0); - } - } char source[ARRAYSIZE]; - char target[ARRAYSIZE]; int benchmark(void) { - duffcopy( source, target, INVOCATION_COUNT ); + int i; + + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + { + int j; + + for(j=0;j #include "support.h" /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) +#define LOCAL_SCALE_FACTOR 81 /* @@ -274,86 +274,114 @@ initialise_benchmark (void) int benchmark(void) { - short in_a[200] = {0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400, 0x0000, - 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400, 0x0000, 0x07ff, 0x0c00, - 0x0800, 0x0200, 0xf800, 0xf300, 0x0400, 0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, - 0xf800, 0xf300, 0x0400, 0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, - 0x0400, 0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400, 0x0000, - 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400, 0x0000, 0x07ff, 0x0c00, - 0x0800, 0x0200, 0xf800, 0xf300, 0x0400, 0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, - 0xf800, 0xf300, 0x0400, 0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, - 0x0400, 0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400, 0x0000, - 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400, 0x0000, 0x07ff, 0x0c00, - 0x0800, 0x0200, 0xf800, 0xf300, 0x0400, 0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, - 0xf800, 0xf300, 0x0400, 0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, - 0x0400, 0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400, 0x0000, - 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400, 0x0000, 0x07ff, 0x0c00, - 0x0800, 0x0200, 0xf800, 0xf300, 0x0400, 0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, - 0xf800, 0xf300, 0x0400, 0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, - 0x0400, 0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400, 0x0000, - 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400, 0x0000, 0x07ff, 0x0c00, - 0x0800, 0x0200, 0xf800, 0xf300, 0x0400, 0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, - 0xf800, 0xf300, 0x0400, 0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400 - }; - short in_b[200] = - {0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000, 0x0c60, - 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000, 0x0c60, 0x0c40, 0x0c20, - 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000, 0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, - 0xf400, 0xf200, 0xf000, 0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, - 0xf000, 0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000, 0x0c60, - 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000, 0x0c60, 0x0c40, 0x0c20, - 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000, 0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, - 0xf400, 0xf200, 0xf000, 0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, - 0xf000, 0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000, 0x0c60, - 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000, 0x0c60, 0x0c40, 0x0c20, - 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000, 0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, - 0xf400, 0xf200, 0xf000, 0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, - 0xf000, 0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000, 0x0c60, - 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000, 0x0c60, 0x0c40, 0x0c20, - 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000, 0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, - 0xf400, 0xf200, 0xf000, 0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, - 0xf000, 0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000, 0x0c60, - 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000, 0x0c60, 0x0c40, 0x0c20, - 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000, 0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, - 0xf400, 0xf200, 0xf000, 0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000 - }; - c = 0x3; - d = 0xAAAA; - e = 0xEEEE; - - for (int i=0; i<200; i++) + int j; + + for (j = 0; j < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); j++) + { + short in_a[200] = { + 0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400, + 0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400, + 0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400, + 0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400, + 0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400, + 0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400, + 0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400, + 0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400, + 0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400, + 0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400, + 0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400, + 0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400, + 0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400, + 0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400, + 0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400, + 0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400, + 0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400, + 0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400, + 0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400, + 0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400, + 0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400, + 0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400, + 0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400, + 0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400, + 0x0000, 0x07ff, 0x0c00, 0x0800, 0x0200, 0xf800, 0xf300, 0x0400 + }; + short in_b[200] = { + 0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000, + 0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000, + 0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000, + 0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000, + 0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000, + 0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000, + 0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000, + 0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000, + 0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000, + 0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000, + 0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000, + 0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000, + 0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000, + 0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000, + 0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000, + 0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000, + 0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000, + 0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000, + 0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000, + 0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000, + 0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000, + 0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000, + 0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000, + 0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000, + 0x0c60, 0x0c40, 0x0c20, 0x0c00, 0xf600, 0xf400, 0xf200, 0xf000 + }; + c = 0x3; + d = 0xAAAA; + e = 0xEEEE; + + for (int i=0; i<200; i++) { a[i] = in_a[i]; b[i] = in_b[i]; } - /* - * Declared as memory variable so it doesn't get optimized out - */ - - vec_mpy1(a, b, c); - c = mac(a, b, (long int) c, (long int *) output); - fir(a, b, output); - fir_no_red_ld(a, b, output); - d = latsynth(a, b, N, d); - iir1(a, b, &output[100], output); - e = codebook(d, 1, 17, e, d, a, c, 1); - jpegdct(a, b); - return 0; + /* + * Declared as memory variable so it doesn't get optimized out + */ + + vec_mpy1(a, b, c); + c = mac(a, b, (long int) c, (long int *) output); + fir(a, b, output); + fir_no_red_ld(a, b, output); + d = latsynth(a, b, N, d); + iir1(a, b, &output[100], output); + e = codebook(d, 1, 17, e, d, a, c, 1); + jpegdct(a, b); + } + return 0; } -#include int verify_benchmark(int unused) { - int i; - int exp_c = 10243; - int exp_d = -441886230; - int exp_e = -441886230; - long int exp_output[200] = {3760, 4269, 3126, 1030, 2453, -4601, 1981, -1056, 2621, 4269, 3058, 1030, 2378, -4601, 1902, -1056, 2548, 4269, 2988, 1030, 2300, -4601, 1822, -1056, 2474, 4269, 2917, 1030, 2220, -4601, 1738, -1056, 2398, 4269, 2844, 1030, 2140, -4601, 1655, -1056, 2321, 4269, 2770, 1030, 2058, -4601, 1569, -1056, 2242, 4269, 2152, 1030, 1683, -4601, 1627, -1056, 2030, 4269, 2080, 1030, 1611, -4601, 1555, -1056, 1958, 4269, 2008, 1030, 1539, -4601, 1483, -1056, 1886, 4269, 1935, 1030, 1466, -4601, 1410, -1056, 1813, 4269, 1862, 1030, 1393, -4601, 1337, -1056, 1740, 4269, 1789, 1030, 1320, -4601, 1264, -1056, 1667, 4269, 1716, 1030, 1968, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - for (i=0; i<200; i++) { - if (output[i] != exp_output[i]) - return 0; - } - if (c != exp_c || d != exp_d || e != exp_e) - return 0; - return 1; + long int exp_output[200] = + { 3760, 4269, 3126, 1030, 2453, -4601, 1981, -1056, 2621, 4269, + 3058, 1030, 2378, -4601, 1902, -1056, 2548, 4269, 2988, 1030, + 2300, -4601, 1822, -1056, 2474, 4269, 2917, 1030, 2220, -4601, + 1738, -1056, 2398, 4269, 2844, 1030, 2140, -4601, 1655, -1056, + 2321, 4269, 2770, 1030, 2058, -4601, 1569, -1056, 2242, 4269, + 2152, 1030, 1683, -4601, 1627, -1056, 2030, 4269, 2080, 1030, + 1611, -4601, 1555, -1056, 1958, 4269, 2008, 1030, 1539, -4601, + 1483, -1056, 1886, 4269, 1935, 1030, 1466, -4601, 1410, -1056, + 1813, 4269, 1862, 1030, 1393, -4601, 1337, -1056, 1740, 4269, + 1789, 1030, 1320, -4601, 1264, -1056, 1667, 4269, 1716, 1030, + 1968, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + + return (0 == memcmp (output, exp_output, 200 * sizeof (output[0]))) + && (10243 == c) && (-441886230 == d) && (-441886230 == e); } diff --git a/src/expint/Makefile.am b/src/expint/Makefile.am index d11a67a0..ecb27401 100644 --- a/src/expint/Makefile.am +++ b/src/expint/Makefile.am @@ -34,7 +34,8 @@ libexpint_la_SOURCES = libexpint.c expint_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libexpint.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) diff --git a/src/expint/Makefile.in b/src/expint/Makefile.in index 3527218d..80fb1916 100644 --- a/src/expint/Makefile.in +++ b/src/expint/Makefile.in @@ -171,6 +171,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_EXPINT_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_EXPINT_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_EXPINT_TRUE@ libexpint.la \ +@ENABLED_BENCHMARK_EXPINT_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_EXPINT_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_EXPINT_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_EXPINT_TRUE@ $(am__DEPENDENCIES_1) @@ -393,7 +394,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_EXPINT_TRUE@expint_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_EXPINT_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_EXPINT_TRUE@ libexpint.la \ -@ENABLED_BENCHMARK_EXPINT_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_EXPINT_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_EXPINT_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/expint/libexpint.c b/src/expint/libexpint.c index 23be9547..fc028fe2 100644 --- a/src/expint/libexpint.c +++ b/src/expint/libexpint.c @@ -33,7 +33,7 @@ /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) +#define LOCAL_SCALE_FACTOR 571 long int expint(int n, long int x); @@ -111,19 +111,27 @@ static int n, x; int benchmark (void) { + int i; + + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR) - 1; i++) + { + int v = i % 100; + n = 50 - (v / 2); + x = v % 2; + benchmark_result = expint(n,x); + } + + n = 50; + x = 1; benchmark_result = expint(n,x); + return benchmark_result; } void initialise_benchmark() { - n = 50; - x = 1; } int verify_benchmark(int r) { - int expected = 3883; - if (r != expected) - return 0; - return 1; + return 3883 == r; } diff --git a/src/fac/Makefile.am b/src/fac/Makefile.am index 99dd34df..f4c1e518 100644 --- a/src/fac/Makefile.am +++ b/src/fac/Makefile.am @@ -34,7 +34,8 @@ libfac_la_SOURCES = libfac.c fac_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libfac.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) diff --git a/src/fac/Makefile.in b/src/fac/Makefile.in index 2df27d6c..9745ee06 100644 --- a/src/fac/Makefile.in +++ b/src/fac/Makefile.in @@ -169,7 +169,9 @@ fac_OBJECTS = $(am_fac_OBJECTS) am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_FAC_TRUE@fac_DEPENDENCIES = $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_FAC_TRUE@ $(top_builddir)/support/libsupport.la \ -@ENABLED_BENCHMARK_FAC_TRUE@ libfac.la $(am__DEPENDENCIES_1) \ +@ENABLED_BENCHMARK_FAC_TRUE@ libfac.la \ +@ENABLED_BENCHMARK_FAC_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_FAC_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_FAC_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_FAC_TRUE@ $(am__DEPENDENCIES_1) AM_V_P = $(am__v_P_@AM_V@) @@ -391,7 +393,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_FAC_TRUE@fac_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_FAC_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_FAC_TRUE@ libfac.la \ -@ENABLED_BENCHMARK_FAC_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_FAC_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_FAC_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/fac/libfac.c b/src/fac/libfac.c index b036f12d..2afa5ec3 100644 --- a/src/fac/libfac.c +++ b/src/fac/libfac.c @@ -26,9 +26,9 @@ /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) +#define LOCAL_SCALE_FACTOR 9195 -int fac (int n) +long int fac (int n) { if (n == 0) return 1; @@ -46,20 +46,24 @@ initialise_benchmark (void) int benchmark (void) { - int i; - volatile int s = 0; - volatile int n; - - n = 10; - for (i = 0; i <= n; i++) - s += fac (i); - return s; + int j; + volatile long int s; + + for (j = 0; j < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); j++) + { + int i; + volatile int n; + + s = 0; + n = 10; + for (i = 0; i <= n; i++) + s += fac (i); + } + + return s % 65536L; } int verify_benchmark(int r) { - int expected = 4037914; - if (r != expected) - return 0; - return 1; + return (4037914L % 65536L) == r; } diff --git a/src/fasta/Makefile.am b/src/fasta/Makefile.am index b76bc18c..3beb0749 100644 --- a/src/fasta/Makefile.am +++ b/src/fasta/Makefile.am @@ -34,6 +34,7 @@ libfasta_la_SOURCES = libfasta.c fasta_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libfasta.la \ + $(top_builddir)/support/libbeebsc.la \ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) diff --git a/src/fasta/Makefile.in b/src/fasta/Makefile.in index e3512b19..6712db35 100644 --- a/src/fasta/Makefile.in +++ b/src/fasta/Makefile.in @@ -171,6 +171,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_FASTA_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_FASTA_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_FASTA_TRUE@ libfasta.la \ +@ENABLED_BENCHMARK_FASTA_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_FASTA_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_FASTA_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_FASTA_TRUE@ $(am__DEPENDENCIES_1) @@ -393,6 +394,7 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_FASTA_TRUE@fasta_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_FASTA_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_FASTA_TRUE@ libfasta.la \ +@ENABLED_BENCHMARK_FASTA_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_FASTA_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/fasta/libfasta.c b/src/fasta/libfasta.c index 06d6f87b..65fb3b21 100644 --- a/src/fasta/libfasta.c +++ b/src/fasta/libfasta.c @@ -68,7 +68,7 @@ #include "support.h" -#define SCALE_FACTOR (REPEAT_FACTOR >> 6) +#define LOCAL_SCALE_FACTOR 1 #define WIDTH 60 #define MIN(a,b) ((a) <= (b) ? (a) : (b)) @@ -79,6 +79,9 @@ typedef struct { char c; } aminoacid_t; +static char repeat_res[WIDTH]; +static char random_res[WIDTH + 1]; + static inline float myrandom (float max) { unsigned long const IM = 139968; unsigned long const IA = 3877; @@ -89,12 +92,15 @@ static inline float myrandom (float max) { return max * (long) last / IM; } -static inline void accumulate_probabilities (aminoacid_t *genelist, size_t len) { +static inline void accumulate_probabilities (const aminoacid_t *genelist_in, + aminoacid_t *genelist_out, + size_t len) { float cp = 0.0; size_t i; for (i = 0; i < len; i++) { - cp += genelist[i].p; - genelist[i].p = cp; + cp += genelist_in[i].p; + genelist_out[i].p = cp; + genelist_out[i].c = genelist_in[i].c; } } @@ -119,6 +125,7 @@ static void repeat_fasta (char const *s, size_t count) { if (pos >= len) pos -= len; count -= line; } while (count); + memcpy (repeat_res, s2, WIDTH); /* Since BEEBS uses alloca don't try to free! free (s2);*/ } @@ -133,31 +140,35 @@ static void repeat_fasta (char const *s, size_t count) { /* This is done count times. */ /* Between each WIDTH consecutive characters, the function prints a newline */ static void random_fasta (aminoacid_t const *genelist, size_t count) { + char buf[WIDTH + 1]; + do { + size_t line = MIN(WIDTH, count); + size_t pos = 0; do { - size_t line = MIN(WIDTH, count); - size_t pos = 0; - char buf[WIDTH + 1]; - do { - float r = myrandom (1.0); - size_t i = 0; - while (genelist[i].p < r) - ++i; /* Linear search */ - buf[pos++] = genelist[i].c; - } while (pos < line); - buf[line] = '\n'; - /*fwrite_unlocked (buf, 1, line + 1, stdout); */ - (void) buf; /* Silence compiler warning about unused 'buf'. */ - count -= line; - } while (count); + float r = myrandom (1.0); + size_t i = 0; + while (genelist[i].p < r) + ++i; /* Linear search */ + buf[pos++] = genelist[i].c; + } while (pos < line); + buf[line] = '\n'; + count -= line; + } while (count); + + memcpy (random_res, buf, WIDTH+1); } -/* This benchmark does not support verification */ - int verify_benchmark (int res __attribute ((unused)) ) { - return -1; + static const char *repeat_ref = + "GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGA"; + static const char *random_ref = + "ggaagtgaaaagataaatat\naaatgacgccacgtgtcgaataatggtctgaccaatgta\n"; + + return (0 == strncmp (repeat_res, repeat_ref, WIDTH)) + && (0 == strncmp (random_res, random_ref, WIDTH+1)); } @@ -169,9 +180,13 @@ initialise_benchmark (void) int benchmark () { - const int n = 1000; + int i; - static aminoacid_t iub[] = { + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + { + const int n = 1000; + + static const aminoacid_t iub_ref[15] = { { 0.27, 'a' }, { 0.12, 'c' }, { 0.12, 'g' }, @@ -188,16 +203,20 @@ int benchmark () { { 0.02, 'W' }, { 0.02, 'Y' }}; - static aminoacid_t homosapiens[] = { + aminoacid_t iub[15]; + + static const aminoacid_t homsap_ref[4] = { { 0.3029549426680, 'a' }, { 0.1979883004921, 'c' }, { 0.1975473066391, 'g' }, { 0.3015094502008, 't' }}; - accumulate_probabilities (iub, NELEMENTS(iub)); - accumulate_probabilities (homosapiens, NELEMENTS(homosapiens)); + aminoacid_t homsap[4]; + + accumulate_probabilities (iub_ref, iub, NELEMENTS(iub)); + accumulate_probabilities (homsap_ref, homsap, NELEMENTS(homsap)); - static char const *const alu ="\ + static char const *const alu ="\ GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGG\ GAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGA\ CCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAAT\ @@ -206,12 +225,14 @@ GCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGG\ AGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCC\ AGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA"; - /*fputs_unlocked (">ONE Homo sapiens alu\n", stdout);*/ - repeat_fasta (alu, 2 * n); - /*fputs_unlocked (">TWO IUB ambiguity codes\n", stdout);*/ - random_fasta (iub, 3 * n); - /*fputs_unlocked (">THREE Homo sapiens frequency\n", stdout);*/ - random_fasta (homosapiens, 5 * n); - return 0; + /*fputs_unlocked (">ONE Homo sapiens alu\n", stdout);*/ + repeat_fasta (alu, 2 * n); + /*fputs_unlocked (">TWO IUB ambiguity codes\n", stdout);*/ + random_fasta (iub, 3 * n); + /*fputs_unlocked (">THREE Homo sapiens frequency\n", stdout);*/ + random_fasta (homsap, 5 * n); + } + + return 0; } diff --git a/src/fdct/Makefile.am b/src/fdct/Makefile.am index f6566d73..6c1e6255 100644 --- a/src/fdct/Makefile.am +++ b/src/fdct/Makefile.am @@ -34,7 +34,8 @@ libfdct_la_SOURCES = libfdct.c fdct_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libfdct.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) diff --git a/src/fdct/Makefile.in b/src/fdct/Makefile.in index da517500..35cb93b1 100644 --- a/src/fdct/Makefile.in +++ b/src/fdct/Makefile.in @@ -170,7 +170,9 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_FDCT_TRUE@fdct_DEPENDENCIES = \ @ENABLED_BENCHMARK_FDCT_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_FDCT_TRUE@ $(top_builddir)/support/libsupport.la \ -@ENABLED_BENCHMARK_FDCT_TRUE@ libfdct.la $(am__DEPENDENCIES_1) \ +@ENABLED_BENCHMARK_FDCT_TRUE@ libfdct.la \ +@ENABLED_BENCHMARK_FDCT_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_FDCT_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_FDCT_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_FDCT_TRUE@ $(am__DEPENDENCIES_1) AM_V_P = $(am__v_P_@AM_V@) @@ -392,7 +394,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_FDCT_TRUE@fdct_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_FDCT_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_FDCT_TRUE@ libfdct.la \ -@ENABLED_BENCHMARK_FDCT_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_FDCT_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_FDCT_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/fdct/libfdct.c b/src/fdct/libfdct.c index dfa617e5..b4b0d5e3 100644 --- a/src/fdct/libfdct.c +++ b/src/fdct/libfdct.c @@ -63,7 +63,7 @@ /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) +#define LOCAL_SCALE_FACTOR 2538 #ifdef IO #include "libp.c" @@ -292,10 +292,14 @@ initialise_benchmark (void) #include int benchmark() { - /* Need to reinitialize the input data each time */ + int i; + + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + { + memcpy (block, block_ref, 64 * sizeof (block[0])); + fdct(block, 8); + } - memcpy (block, block_ref, 64 * sizeof (block[0])); - fdct(block, 8); return 0; } diff --git a/src/fibcall/Makefile.am b/src/fibcall/Makefile.am index 425f5933..64829321 100644 --- a/src/fibcall/Makefile.am +++ b/src/fibcall/Makefile.am @@ -34,7 +34,8 @@ libfibcall_la_SOURCES = libfibcall.c fibcall_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libfibcall.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) diff --git a/src/fibcall/Makefile.in b/src/fibcall/Makefile.in index bde626e1..9b26d5dc 100644 --- a/src/fibcall/Makefile.in +++ b/src/fibcall/Makefile.in @@ -172,6 +172,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_FIBCALL_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_FIBCALL_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_FIBCALL_TRUE@ libfibcall.la \ +@ENABLED_BENCHMARK_FIBCALL_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_FIBCALL_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_FIBCALL_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_FIBCALL_TRUE@ $(am__DEPENDENCIES_1) @@ -394,7 +395,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_FIBCALL_TRUE@fibcall_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_FIBCALL_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_FIBCALL_TRUE@ libfibcall.la \ -@ENABLED_BENCHMARK_FIBCALL_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_FIBCALL_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_FIBCALL_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/fibcall/libfibcall.c b/src/fibcall/libfibcall.c index a4f2179c..3bafa8b6 100644 --- a/src/fibcall/libfibcall.c +++ b/src/fibcall/libfibcall.c @@ -1,4 +1,3 @@ - /* BEEBS fibcall benchmark Copyright (C) 2014 Embecosm Limited and University of Bristol @@ -24,7 +23,7 @@ /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR << 5)) +#define LOCAL_SCALE_FACTOR 19137 /* $Id: fibcall.c,v 1.2 2005/04/04 11:34:58 csg Exp $ */ @@ -99,19 +98,18 @@ int benchmark() { int a; int r; + int i; + + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + { + a = 30; + r = fib(a); + } - a = 30; - r = fib(a); return r; } int verify_benchmark(int r) { - int exp = 832040; - if (r != exp) - return 0; - return 1; + return 832040 == r; } - - - diff --git a/src/fir/Makefile.am b/src/fir/Makefile.am index ecbf0e99..2159ce12 100644 --- a/src/fir/Makefile.am +++ b/src/fir/Makefile.am @@ -34,7 +34,8 @@ libfir_la_SOURCES = libfir.c fir_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libfir.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) diff --git a/src/fir/Makefile.in b/src/fir/Makefile.in index 11a61c22..8191f114 100644 --- a/src/fir/Makefile.in +++ b/src/fir/Makefile.in @@ -169,7 +169,9 @@ fir_OBJECTS = $(am_fir_OBJECTS) am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_FIR_TRUE@fir_DEPENDENCIES = $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_FIR_TRUE@ $(top_builddir)/support/libsupport.la \ -@ENABLED_BENCHMARK_FIR_TRUE@ libfir.la $(am__DEPENDENCIES_1) \ +@ENABLED_BENCHMARK_FIR_TRUE@ libfir.la \ +@ENABLED_BENCHMARK_FIR_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_FIR_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_FIR_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_FIR_TRUE@ $(am__DEPENDENCIES_1) AM_V_P = $(am__v_P_@AM_V@) @@ -391,7 +393,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_FIR_TRUE@fir_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_FIR_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_FIR_TRUE@ libfir.la \ -@ENABLED_BENCHMARK_FIR_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_FIR_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_FIR_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/fir/libfir.c b/src/fir/libfir.c index af8d5049..a6a7df77 100644 --- a/src/fir/libfir.c +++ b/src/fir/libfir.c @@ -1,5 +1,3 @@ - - /* BEEBS fir benchmark MDH WCET BENCHMARK SUITE. @@ -22,11 +20,13 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ +#include + #include "support.h" /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) +#define LOCAL_SCALE_FACTOR 5 #define LOOPS 1 @@ -113,7 +113,10 @@ const long in_data[701]={ 0x77, 0x6c, 0x75, 0x41, 0x49, 0x4f, 0x3b, 0xb, 0x54, 0x37, 0 }; -long out_data[720]={ +// To match size of input +#define OUTSIZE 720 + +long out_ref[OUTSIZE]={ 0x3, 0xfffffffa, 0xfffffffd, 0x1d, 0x58, 0x89, 0x87, 0x56, 0x20, 0x7, 0x7, 0x4, 0xfffffff9, 0x0, 0x28, 0x5b, 0x6b, 0x4f, 0x2b, 0x21, 0x2d, 0x30, 0x27, 0x27, 0x37, 0x47, 0x42, 0x27, 0x8, 0xfffffff4, @@ -186,10 +189,7 @@ long out_data[720]={ 0x6f, 0x6a, 0x66, 0x5c, 0x4b, 0x3a, 0x33, 0x36, 0x38, 0x2c, 0 }; -// To match size of input -#define OUTSIZE 720 - - +static long output[OUTSIZE]; /*-------------------------------------------------- *--- Prototypes @@ -273,12 +273,10 @@ void fir_filter_int(const long* in,long* out,long in_len, -/* This benchmark does not support verification */ - int verify_benchmark (int res __attribute ((unused)) ) { - return -1; + return 0 == memcmp (out_ref, output, OUTSIZE); } @@ -291,10 +289,10 @@ initialise_benchmark (void) int benchmark (void) { - long output[OUTSIZE]; + int i; + + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + fir_filter_int(in_data,output,700,fir_int,35,285); - fir_filter_int(in_data,output,700,fir_int,35,285); return 0; } - - diff --git a/src/frac/Makefile.am b/src/frac/Makefile.am index bc16903b..53724569 100644 --- a/src/frac/Makefile.am +++ b/src/frac/Makefile.am @@ -34,7 +34,8 @@ libfrac_la_SOURCES = libfrac.c frac_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libfrac.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) diff --git a/src/frac/Makefile.in b/src/frac/Makefile.in index b0a48727..efaeeef6 100644 --- a/src/frac/Makefile.in +++ b/src/frac/Makefile.in @@ -170,7 +170,9 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_FRAC_TRUE@frac_DEPENDENCIES = \ @ENABLED_BENCHMARK_FRAC_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_FRAC_TRUE@ $(top_builddir)/support/libsupport.la \ -@ENABLED_BENCHMARK_FRAC_TRUE@ libfrac.la $(am__DEPENDENCIES_1) \ +@ENABLED_BENCHMARK_FRAC_TRUE@ libfrac.la \ +@ENABLED_BENCHMARK_FRAC_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_FRAC_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_FRAC_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_FRAC_TRUE@ $(am__DEPENDENCIES_1) AM_V_P = $(am__v_P_@AM_V@) @@ -392,7 +394,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_FRAC_TRUE@frac_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_FRAC_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_FRAC_TRUE@ libfrac.la \ -@ENABLED_BENCHMARK_FRAC_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_FRAC_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_FRAC_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/frac/libfrac.c b/src/frac/libfrac.c index bd2ec539..d15174f1 100644 --- a/src/frac/libfrac.c +++ b/src/frac/libfrac.c @@ -1,4 +1,3 @@ - /* BEEBS frac benchmark Copyright (C) 2014 Embecosm Limited and University of Bristol @@ -24,7 +23,7 @@ /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) +#define LOCAL_SCALE_FACTOR 28 #include @@ -39,7 +38,7 @@ #define MIN 3.0e-10 double -frac(double v, int *n, int *d, double error) +frac(double v, long int *n, long int *d, double error) { /* given a number, v, this function outputs two integers, @@ -127,21 +126,23 @@ initialise_benchmark (void) int benchmark() { - double error = 1.0e-10; - int n,d,i; + long int n,d,i; + int j; + + for (j = 0; j < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); j++) + { + double error = 1.0e-10; - n = 0; - for(i = 0; i < 10; ++i) - frac(nums[i], &n, &d, error); + n = 0; + for(i = 0; i < 10; ++i) + frac(nums[i], &n, &d, error); + } - return d; + return (int) (d % 32768L); } int verify_benchmark(int r) { - int expected = 1000000; - if (r != expected) - return 0; - return 1; + return 16960 == r; } diff --git a/src/huffbench/Makefile.am b/src/huffbench/Makefile.am index cba97506..8ffdbcdf 100644 --- a/src/huffbench/Makefile.am +++ b/src/huffbench/Makefile.am @@ -34,7 +34,8 @@ libhuffbench_la_SOURCES = libhuffbench.c huffbench_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libhuffbench.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) diff --git a/src/huffbench/Makefile.in b/src/huffbench/Makefile.in index 6961a461..3a7d223a 100644 --- a/src/huffbench/Makefile.in +++ b/src/huffbench/Makefile.in @@ -172,6 +172,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_HUFFBENCH_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_HUFFBENCH_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_HUFFBENCH_TRUE@ libhuffbench.la \ +@ENABLED_BENCHMARK_HUFFBENCH_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_HUFFBENCH_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_HUFFBENCH_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_HUFFBENCH_TRUE@ $(am__DEPENDENCIES_1) @@ -395,7 +396,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_HUFFBENCH_TRUE@huffbench_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_HUFFBENCH_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_HUFFBENCH_TRUE@ libhuffbench.la \ -@ENABLED_BENCHMARK_HUFFBENCH_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_HUFFBENCH_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_HUFFBENCH_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/huffbench/libhuffbench.c b/src/huffbench/libhuffbench.c index 886733d6..3b4e7616 100644 --- a/src/huffbench/libhuffbench.c +++ b/src/huffbench/libhuffbench.c @@ -58,56 +58,13 @@ /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) +#define LOCAL_SCALE_FACTOR 13 /* BEEBS heap is just an array */ -#include - #define HEAP_SIZE 8192 static char heap[HEAP_SIZE]; -static void *heap_ptr; -static void *heap_end; - -/* Initialize the BEEBS heap pointers */ - -static void -init_heap (void) -{ - heap_ptr = (void *) heap; - heap_end = heap_ptr + HEAP_SIZE; -} - -/* BEEBS version of malloc. - - This is primarily to reduce library and OS dependencies. Malloc is - generally not used in embedded code, or if it is, only in well defined - contexts to pre-allocate a fixed amount of memory. So this simplistic - implementation is just fine. */ - -static void * -malloc_beebs (size_t size) -{ - void *new_ptr = heap_ptr; - - if (((heap_ptr + size) > heap_end) || (0 == size)) - return NULL; - else - { - heap_ptr += size; - return new_ptr; - } -} - -/* BEEBS version of free. - - For our simplified version of memory handling, free can just do nothing. */ - -static void -free_beebs (void *ptr) -{ -} // embedded random number generator; ala Park and Miller static long seed = 1325; @@ -137,7 +94,7 @@ static size_t random4() } -static const int TEST_SIZE = 500; +#define TEST_SIZE 500 typedef unsigned long bits32; typedef unsigned char byte; @@ -488,34 +445,57 @@ void compdecomp(byte * data, size_t data_len) } -/* This benchmark does not support verification */ +static byte res_data[TEST_SIZE]; int verify_benchmark (int res __attribute ((unused)) ) { - return -1; + static const byte *ref_data = "\ +FRMGNMVOMWDGSYBXUPUTK5QUWE32ZOECYJVJGOCW\ +MI1YK2I04CPLGAYLECL243JLEXWDLPAHFG3G2PFV\ +3ERJTVNIJD1VIRP1OXSD3APUEFDJZXFPZ4SUSIFS\ +5TGNW2UR4NEM3LAOX1VBD0DM302CQRLJASXFCUJN\ +1GEVHENYUCDYQPTLQMERDCFTXDFF1CRYEINYGJHI\ +EZKISDYOVAZLNELHBCPALQBDO5HIMPQ5PU53W45H\ +CMR00C0LPHMP3PIUSVJAT04T5OXPRFJOU0VBFJ1R\ +HYLHXWW0YKJFQ1TMKIM1UPN355LWPOOFJCZ2NXHR\ +J0WDOZ3040LNYAXJSX1MNVQIS2ZMKAJPL1W24YIB\ +3UTUMMQI3WOE4MZYN4GLE2NX45W4TRRWKYS53CIL\ +ZRLEVCPJLLEPYGGE4ZUQXNB4O0FVCTABJGSL40VW\ +J1YPXG2ZNSQZXLCGSZ1QUK1YBWB41EN5WEZFR3HQ\ +JQICXCYIBUTSJBN11CVN"; + + return (0 == memcmp (res_data, ref_data, sizeof (ref_data))) + && check_heap_beebs ((void *) heap); } void initialise_benchmark (void) { - init_heap (); } int benchmark() { - // initialization - byte * test_data = generate_test_data(TEST_SIZE); + byte * test_data; + int i; + + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + { + // initialization + seed = 1325; + init_heap_beebs ((void *) heap, HEAP_SIZE); + test_data = generate_test_data(TEST_SIZE); - // what we're timing - compdecomp(test_data,TEST_SIZE); + // what we're timing + compdecomp(test_data,TEST_SIZE); + } - // release resources - free_beebs(test_data); + // Copy for validation + memcpy (res_data, test_data, TEST_SIZE); - // done - return 0; + // done + return 0; } diff --git a/src/insertsort/Makefile.am b/src/insertsort/Makefile.am index 657b4381..7585bbd6 100644 --- a/src/insertsort/Makefile.am +++ b/src/insertsort/Makefile.am @@ -34,7 +34,8 @@ libinsertsort_la_SOURCES = libinsertsort.c insertsort_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libinsertsort.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) diff --git a/src/insertsort/Makefile.in b/src/insertsort/Makefile.in index e3422dab..8043c45a 100644 --- a/src/insertsort/Makefile.in +++ b/src/insertsort/Makefile.in @@ -172,6 +172,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_INSERTSORT_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_INSERTSORT_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_INSERTSORT_TRUE@ libinsertsort.la \ +@ENABLED_BENCHMARK_INSERTSORT_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_INSERTSORT_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_INSERTSORT_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_INSERTSORT_TRUE@ $(am__DEPENDENCIES_1) @@ -395,7 +396,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_INSERTSORT_TRUE@insertsort_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_INSERTSORT_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_INSERTSORT_TRUE@ libinsertsort.la \ -@ENABLED_BENCHMARK_INSERTSORT_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_INSERTSORT_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_INSERTSORT_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/insertsort/libinsertsort.c b/src/insertsort/libinsertsort.c index b3eeb508..63f8007b 100644 --- a/src/insertsort/libinsertsort.c +++ b/src/insertsort/libinsertsort.c @@ -62,52 +62,51 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ +#include #include "support.h" /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) +#define LOCAL_SCALE_FACTOR 10443 unsigned int a[11]; /* assume all data is positive */ int benchmark (void) { - int i,j, temp; - i = 2; - while(i <= 10){ - j = i; - while (a[j] < a[j-1]) - { - temp = a[j]; - a[j] = a[j-1]; - a[j-1] = temp; - j--; + static const unsigned int a_ref[11] = { + 0, 11, 10, 9, 8 ,7, 6, 5, 4, 3, 2 + }; + + int k; + + for (k = 0; k < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); k++) + { + int i,j, temp; + + memcpy (a, a_ref, 11 * sizeof (a[0])); + i = 2; + + while(i <= 10){ + j = i; + while (a[j] < a[j-1]) + { + temp = a[j]; + a[j] = a[j-1]; + a[j-1] = temp; + j--; + } + i++; } - i++; } + return 0; } void initialise_benchmark() { - a[0] = 0; - a[1] = 11; - a[2] = 10; - a[3] = 9; - a[4] = 8; - a[5] = 7; - a[6] = 6; - a[7] = 5; - a[8] = 4; - a[9] = 3; - a[10]= 2; } int verify_benchmark(int unused) { - int i; int expected[] = {0,2,3,4,5,6,7,8,9,10,11}; - for (i=0; i<11; i++) - if (a[i] != expected[i]) - return 0; - return 1; + return 0 == memcmp (a, expected, 11 * sizeof (a[0])); } diff --git a/src/janne_complex/Makefile.am b/src/janne_complex/Makefile.am index 360c5954..d4a3e01a 100644 --- a/src/janne_complex/Makefile.am +++ b/src/janne_complex/Makefile.am @@ -34,7 +34,8 @@ libjanne_complex_la_SOURCES = libjanne_complex.c janne_complex_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libjanne_complex.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) diff --git a/src/janne_complex/Makefile.in b/src/janne_complex/Makefile.in index 31e33ea5..9bf15931 100644 --- a/src/janne_complex/Makefile.in +++ b/src/janne_complex/Makefile.in @@ -173,6 +173,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_JANNE_COMPLEX_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_JANNE_COMPLEX_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_JANNE_COMPLEX_TRUE@ libjanne_complex.la \ +@ENABLED_BENCHMARK_JANNE_COMPLEX_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_JANNE_COMPLEX_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_JANNE_COMPLEX_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_JANNE_COMPLEX_TRUE@ $(am__DEPENDENCIES_1) @@ -396,7 +397,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_JANNE_COMPLEX_TRUE@janne_complex_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_JANNE_COMPLEX_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_JANNE_COMPLEX_TRUE@ libjanne_complex.la \ -@ENABLED_BENCHMARK_JANNE_COMPLEX_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_JANNE_COMPLEX_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_JANNE_COMPLEX_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/janne_complex/libjanne_complex.c b/src/janne_complex/libjanne_complex.c index 0e215c9a..190a01ce 100644 --- a/src/janne_complex/libjanne_complex.c +++ b/src/janne_complex/libjanne_complex.c @@ -23,7 +23,7 @@ /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) +#define LOCAL_SCALE_FACTOR 23119 /*---------------------------------------------------------------------- @@ -78,27 +78,31 @@ static int a, b; int benchmark() { - /* a = [1..30] b = [1..30] */ - int answer = 0; - /* if(answer) - {a = 1; b = 1;} - else - {a = 30; b = 30;} */ - answer = complex(a, b); + volatile int answer = 0; + int i; + + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + { + /* a = [1..30] b = [1..30] */ + answer = 0; + a = 1; + b = 1; + /* if(answer) + {a = 1; b = 1;} + else + {a = 30; b = 30;} */ + answer = complex(a, b); + } + return answer; } void initialise_benchmark() { - a = 1; - b = 1; } int verify_benchmark(int r) { - int exp = 1; - if (r != exp) - return 0; - return 1; + return 1 == r; } diff --git a/src/jfdctint/Makefile.am b/src/jfdctint/Makefile.am index 108882de..fb3f311d 100644 --- a/src/jfdctint/Makefile.am +++ b/src/jfdctint/Makefile.am @@ -34,7 +34,8 @@ libjfdctint_la_SOURCES = libjfdctint.c jfdctint_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libjfdctint.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) diff --git a/src/jfdctint/Makefile.in b/src/jfdctint/Makefile.in index 76578214..6383c3b6 100644 --- a/src/jfdctint/Makefile.in +++ b/src/jfdctint/Makefile.in @@ -172,6 +172,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_JFDCTINT_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_JFDCTINT_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_JFDCTINT_TRUE@ libjfdctint.la \ +@ENABLED_BENCHMARK_JFDCTINT_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_JFDCTINT_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_JFDCTINT_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_JFDCTINT_TRUE@ $(am__DEPENDENCIES_1) @@ -394,7 +395,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_JFDCTINT_TRUE@jfdctint_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_JFDCTINT_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_JFDCTINT_TRUE@ libjfdctint.la \ -@ENABLED_BENCHMARK_JFDCTINT_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_JFDCTINT_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_JFDCTINT_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/jfdctint/libjfdctint.c b/src/jfdctint/libjfdctint.c index 25948ccb..06ddc8eb 100644 --- a/src/jfdctint/libjfdctint.c +++ b/src/jfdctint/libjfdctint.c @@ -21,11 +21,13 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ +#include +#include #include "support.h" /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) +#define LOCAL_SCALE_FACTOR 1199 /********************************************************************** Functions to be timed @@ -38,8 +40,8 @@ #define DCTSIZE 8 #define BITS_IN_JSAMPLE 8 #define MULTIPLY16C16(var,const) ((var) * (const)) -#define DCTELEM int -#define INT32 int +#define DCTELEM int32_t +#define INT32 int32_t #define GLOBAL #define RIGHT_SHIFT(x,shft) ((x) >> (shft)) #define ONE ((INT32) 1) @@ -332,29 +334,52 @@ jpeg_fdct_islow () int benchmark (void) { - jpeg_fdct_islow(); + int j; + + for (j = 0; j < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); j++) + { + int i; + long int seed; + + /* Worst case settings */ + /* Set array to random values */ + seed = 1L; + + for (i = 0; i < 64; i++) { + seed = ((seed * 133L) + 81L) % 65535l; + data[i] = (int) seed; + } + + jpeg_fdct_islow(); + } + return 0; } void initialise_benchmark() { - int i, seed; - - /* Worst case settings */ - /* Set array to random values */ - seed = 1; - for (i = 0; i < 64; i++) { - seed = ((seed * 133) + 81) % 65535; - data[i] = seed; - } } int verify_benchmark(int unused) { - DCTELEM exp[] = {1956823, 184557, -39350, -94393, -77163, 5995, 162871, -3428, 31856, 57575, -49784, 43664, 63854, -9784, 11398, -23444, 13102, 59509, 63748, -34407, -57064, 11667, 37414, 41934, 20234, 25212, -44504, 25562, -46366, -4562, -40816, -64820, -203745, -15884, -134082, -126104, 66045, 23372, -87152, -147968, 41739, -20979, -36653, 23706, 613, 41593, 34760, -60639, 30493, -10396, 13944, -13980, 52343, -40116, -55093, 37532, 61998, -22500, 25991, -57098, -18228, 47265, -48356, 38613}; - int i; - for (i=0; i<64; ++i) - if (data[i] != exp[i]) - return 0; - return 1; + DCTELEM exp[64] = { + 1956823, 184557, -39350, -94393, + -77163, 5995, 162871, -3428, + 31856, 57575, -49784, 43664, + 63854, -9784, 11398, -23444, + 13102, 59509, 63748, -34407, + -57064, 11667, 37414, 41934, + 20234, 25212, -44504, 25562, + -46366, -4562, -40816, -64820, + -203745, -15884, -134082, -126104, + 66045, 23372, -87152, -147968, + 41739, -20979, -36653, 23706, + 613, 41593, 34760, -60639, + 30493, -10396, 13944, -13980, + 52343, -40116, -55093, 37532, + 61998, -22500, 25991, -57098, + -18228, 47265, -48356, 38613 }; + + return 0 == memcmp (data, exp, 64 * sizeof (data[0])); + } diff --git a/src/lcdnum/Makefile.am b/src/lcdnum/Makefile.am index 366418fc..c1aa6e83 100644 --- a/src/lcdnum/Makefile.am +++ b/src/lcdnum/Makefile.am @@ -34,7 +34,8 @@ liblcdnum_la_SOURCES = liblcdnum.c lcdnum_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ liblcdnum.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) diff --git a/src/lcdnum/Makefile.in b/src/lcdnum/Makefile.in index 0646b3c7..f3895c5e 100644 --- a/src/lcdnum/Makefile.in +++ b/src/lcdnum/Makefile.in @@ -171,6 +171,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_LCDNUM_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_LCDNUM_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_LCDNUM_TRUE@ liblcdnum.la \ +@ENABLED_BENCHMARK_LCDNUM_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_LCDNUM_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_LCDNUM_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_LCDNUM_TRUE@ $(am__DEPENDENCIES_1) @@ -393,7 +394,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_LCDNUM_TRUE@lcdnum_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_LCDNUM_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_LCDNUM_TRUE@ liblcdnum.la \ -@ENABLED_BENCHMARK_LCDNUM_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_LCDNUM_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_LCDNUM_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/lcdnum/liblcdnum.c b/src/lcdnum/liblcdnum.c index 3c004447..43cb6760 100644 --- a/src/lcdnum/liblcdnum.c +++ b/src/lcdnum/liblcdnum.c @@ -1,5 +1,3 @@ - - /* BEEBS lcdnum benchmark Copyright (C) 2014 Embecosm Limited and University of Bristol @@ -21,11 +19,12 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ +#include #include "support.h" /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) +#define LOCAL_SCALE_FACTOR 13650 /* MDH WCET BENCHMARK SUITE. */ @@ -76,16 +75,16 @@ unsigned char num_to_lcd(unsigned char a) return 0; } -volatile unsigned char IN; -volatile unsigned char OUT; - - -/* This benchmark does not support verification */ +unsigned char out_vals[16]; int verify_benchmark (int res __attribute ((unused)) ) { - return -1; + static const unsigned char out_ref[16] = + { 0x00, 0x24, 0x5d, 0x6d, 0x2e, 0x5d, 0x7b, 0x25, + 0x7f, 0x6f, 0x3f, 0x7a, 0x53, 0x7c, 0x5b, 0x1b }; + + return 0 == memcmp (out_vals, out_ref, 16); } @@ -98,21 +97,21 @@ initialise_benchmark (void) int benchmark(void) { - int i; - unsigned char a; - /*volatile*/ int n; /* JG */ + int j; - n = 10; - for(i=0; i< n; i++) + for (j = 0; j < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); j++) { - a = IN; /* scan port */ - if(i<5) - { - a = a &0x0F; - OUT = num_to_lcd(a); - } + int i; + + for (i = 0; i < 16; i++) + { + volatile unsigned char in = (unsigned char) i; + volatile unsigned char out; + + out = num_to_lcd (in); + out_vals[i] = out; + } } + return 0; } - - diff --git a/src/levenshtein/Makefile.am b/src/levenshtein/Makefile.am index 9e6ba4a1..b6ae2773 100644 --- a/src/levenshtein/Makefile.am +++ b/src/levenshtein/Makefile.am @@ -34,7 +34,8 @@ liblevenshtein_la_SOURCES = liblevenshtein.c levenshtein_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ liblevenshtein.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) diff --git a/src/levenshtein/Makefile.in b/src/levenshtein/Makefile.in index ce798a44..422a9308 100644 --- a/src/levenshtein/Makefile.in +++ b/src/levenshtein/Makefile.in @@ -173,6 +173,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_LEVENSHTEIN_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_LEVENSHTEIN_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_LEVENSHTEIN_TRUE@ liblevenshtein.la \ +@ENABLED_BENCHMARK_LEVENSHTEIN_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_LEVENSHTEIN_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_LEVENSHTEIN_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_LEVENSHTEIN_TRUE@ $(am__DEPENDENCIES_1) @@ -396,7 +397,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_LEVENSHTEIN_TRUE@levenshtein_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_LEVENSHTEIN_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_LEVENSHTEIN_TRUE@ liblevenshtein.la \ -@ENABLED_BENCHMARK_LEVENSHTEIN_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_LEVENSHTEIN_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_LEVENSHTEIN_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/levenshtein/liblevenshtein.c b/src/levenshtein/liblevenshtein.c index eb6433d1..629a976f 100644 --- a/src/levenshtein/liblevenshtein.c +++ b/src/levenshtein/liblevenshtein.c @@ -1,4 +1,3 @@ - /* BEEBS levenshtein benchmark c: levenhstein.c @@ -42,7 +41,7 @@ /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) +#define LOCAL_SCALE_FACTOR 86 #include @@ -87,25 +86,27 @@ initialise_benchmark (void) } - int benchmark() { - int i, j; - volatile unsigned sum = 0; + int k; + volatile unsigned sum; - for(i = 0; i < 5; ++i) - for(j = 0; j < 5; ++j) - sum += levenshtein_distance(strings[i], strings[j]); + for (k = 0; k < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); k++) + { + int i, j; + sum = 0; - return sum; + for(i = 0; i < 5; ++i) + for(j = 0; j < 5; ++j) + sum += levenshtein_distance(strings[i], strings[j]); + } + return sum; } + int verify_benchmark(int r) { - int exp = 122; - if (r != exp) - return 0; - return 1; + return 122 == r; } diff --git a/src/ludcmp/Makefile.am b/src/ludcmp/Makefile.am index 3898d31e..8adcdaa6 100644 --- a/src/ludcmp/Makefile.am +++ b/src/ludcmp/Makefile.am @@ -34,7 +34,8 @@ libludcmp_la_SOURCES = libludcmp.c ludcmp_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libludcmp.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) diff --git a/src/ludcmp/Makefile.in b/src/ludcmp/Makefile.in index 0276d5ea..9ef9e9d4 100644 --- a/src/ludcmp/Makefile.in +++ b/src/ludcmp/Makefile.in @@ -171,6 +171,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_LUDCMP_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_LUDCMP_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_LUDCMP_TRUE@ libludcmp.la \ +@ENABLED_BENCHMARK_LUDCMP_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_LUDCMP_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_LUDCMP_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_LUDCMP_TRUE@ $(am__DEPENDENCIES_1) @@ -393,7 +394,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_LUDCMP_TRUE@ludcmp_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_LUDCMP_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_LUDCMP_TRUE@ libludcmp.la \ -@ENABLED_BENCHMARK_LUDCMP_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_LUDCMP_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_LUDCMP_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/ludcmp/libludcmp.c b/src/ludcmp/libludcmp.c index 4b3c2894..ad52809d 100644 --- a/src/ludcmp/libludcmp.c +++ b/src/ludcmp/libludcmp.c @@ -1,4 +1,3 @@ - /* BEEBS ludcmp benchmark MDH WCET BENCHMARK SUITE. @@ -78,7 +77,7 @@ /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) +#define LOCAL_SCALE_FACTOR 135 /* NOTE: These arrays were all originally size 5 in every dimension. However, the code below is either broken, or very smart in how is @@ -161,38 +160,90 @@ initialise_benchmark (void) int benchmark (void) { - int i, j/*, nmax = 50*/, n = 5; - float eps, w; - - eps = 1.0e-6; - - for (i = 0; i <= n; i++) { - w = 0.0; - for (j = 0; j <= n; j++) { - a[i][j] = (i + 1) + (j + 1); - if (i == j) - a[i][j] *= 10.0; - w += a[i][j]; - } - b[i] = w; - } + int k; + + for (k = 0; k < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); k++) + { + int i, j/*, nmax = 50*/, n = 5; + float eps, w; + + eps = 1.0e-6; + + for (i = 0; i <= n; i++) { + w = 0.0; + for (j = 0; j <= n; j++) { + a[i][j] = (i + 1) + (j + 1); + if (i == j) + a[i][j] *= 10.0; + w += a[i][j]; + } + b[i] = w; + } + + chkerr = ludcmp( /* nmax, */ n, eps); + } - chkerr = ludcmp( /* nmax, */ n, eps); return 0; } int verify_benchmark(int unused) { - float exp_a[8][9] = {{20.000000000000000000000000000000, 3.000000000000000000000000000000, 4.000000000000000000000000000000, 5.000000000000000000000000000000, 6.000000000000000000000000000000, 7.000000000000000000000000000000, 0.000000000000000000000000000000, 0.000000000000000000000000000000, 0.000000000000000000000000000000}, -{0.150000005960464477539062500000, 39.549999237060546875000000000000, 4.400000095367431640625000000000, 5.250000000000000000000000000000, 6.099999904632568359375000000000, 6.949999809265136718750000000000, 0.000000000000000000000000000000, 0.000000000000000000000000000000, 0.000000000000000000000000000000}, -{0.200000002980232238769531250000, 0.111251585185527801513671875000, 58.710494995117187500000000000000, 5.415929317474365234375000000000, 6.121365547180175781250000000000, 6.826801300048828125000000000000, 0.000000000000000000000000000000, 0.000000000000000000000000000000, 0.000000000000000000000000000000}, -{0.250000000000000000000000000000, 0.132743358612060546875000000000, 0.092248059809207916259765625000, 77.553489685058593750000000000000, 6.125581741333007812500000000000, 6.697674274444580078125000000000, 0.000000000000000000000000000000, 0.000000000000000000000000000000, 0.000000000000000000000000000000}, -{0.300000011920928955078125000000, 0.154235139489173889160156250000, 0.104263566434383392333984375000, 0.078985251486301422119140625000, 96.137092590332031250000000000000, 6.587261199951171875000000000000, 0.000000000000000000000000000000, 0.000000000000000000000000000000, 0.000000000000000000000000000000}, -{0.349999994039535522460937500000, 0.175726920366287231445312500000, 0.116279065608978271484375000000, 0.086361996829509735107421875000, 0.068519458174705505371093750000, 114.505111694335937500000000000000, 0.000000000000000000000000000000, 0.000000000000000000000000000000, 0.000000000000000000000000000000}, -{0.000000000000000000000000000000, 0.000000000000000000000000000000, 0.000000000000000000000000000000, 0.000000000000000000000000000000, 0.000000000000000000000000000000, 0.000000000000000000000000000000, 0.000000000000000000000000000000, 0.000000000000000000000000000000, 0.000000000000000000000000000000}, -{0.000000000000000000000000000000, 0.000000000000000000000000000000, 0.000000000000000000000000000000, 0.000000000000000000000000000000, 0.000000000000000000000000000000, 0.000000000000000000000000000000, 0.000000000000000000000000000000, 0.000000000000000000000000000000, 0.000000000000000000000000000000}}; - float exp_b[] = {45.000000, 69.000000, 93.000000, 117.000000, 141.000000, 165.000000}; - float exp_x[] = {1, 1, 0.999999821186065673828125, 1, 1.00000011920928955078125, 1}; + float exp_a[8][9] = { + { 20.000000000000000000000000000000, 3.000000000000000000000000000000, + 4.000000000000000000000000000000, 5.000000000000000000000000000000, + 6.000000000000000000000000000000, 7.000000000000000000000000000000, + 0.000000000000000000000000000000, 0.000000000000000000000000000000, + 0.000000000000000000000000000000 + }, + { 0.150000005960464477539062500000, 39.549999237060546875000000000000, + 4.400000095367431640625000000000, 5.250000000000000000000000000000, + 6.099999904632568359375000000000, 6.949999809265136718750000000000, + 0.000000000000000000000000000000, 0.000000000000000000000000000000, + 0.000000000000000000000000000000 + }, + { 0.200000002980232238769531250000, 0.111251585185527801513671875000, + 58.710494995117187500000000000000, 5.415929317474365234375000000000, + 6.121365547180175781250000000000, 6.826801300048828125000000000000, + 0.000000000000000000000000000000, 0.000000000000000000000000000000, + 0.000000000000000000000000000000 + }, + { 0.250000000000000000000000000000, 0.132743358612060546875000000000, + 0.092248059809207916259765625000, 77.553489685058593750000000000000, + 6.125581741333007812500000000000, 6.697674274444580078125000000000, + 0.000000000000000000000000000000, 0.000000000000000000000000000000, + 0.000000000000000000000000000000 + }, + { 0.300000011920928955078125000000, 0.154235139489173889160156250000, + 0.104263566434383392333984375000, 0.078985251486301422119140625000, + 96.137092590332031250000000000000, 6.587261199951171875000000000000, + 0.000000000000000000000000000000, 0.000000000000000000000000000000, + 0.000000000000000000000000000000 + }, + { 0.349999994039535522460937500000, 0.175726920366287231445312500000, + 0.116279065608978271484375000000, 0.086361996829509735107421875000, + 0.068519458174705505371093750000, 114.505111694335937500000000000000, + 0.000000000000000000000000000000, 0.000000000000000000000000000000, + 0.000000000000000000000000000000 + }, + { 0.000000000000000000000000000000, 0.000000000000000000000000000000, + 0.000000000000000000000000000000, 0.000000000000000000000000000000, + 0.000000000000000000000000000000, 0.000000000000000000000000000000, + 0.000000000000000000000000000000, 0.000000000000000000000000000000, + 0.000000000000000000000000000000 + }, + { 0.000000000000000000000000000000, 0.000000000000000000000000000000, + 0.000000000000000000000000000000, 0.000000000000000000000000000000, + 0.000000000000000000000000000000, 0.000000000000000000000000000000, + 0.000000000000000000000000000000, 0.000000000000000000000000000000, + 0.000000000000000000000000000000 + } }; + + float exp_b[] = { + 45.000000, 69.000000, 93.000000, 117.000000, 141.000000, 165.000000 + }; + float exp_x[] = { + 1, 1, 0.999999821186065673828125, 1, 1.00000011920928955078125, 1 + }; int i, j; for (i=0; i<6; i++) { if (b[i] != exp_b[i]) diff --git a/src/matmult-float/Makefile.am b/src/matmult-float/Makefile.am index 6470dcbf..9bb29930 100644 --- a/src/matmult-float/Makefile.am +++ b/src/matmult-float/Makefile.am @@ -30,11 +30,12 @@ noinst_LTLIBRARIES = libmatmult-float.la matmult_float_SOURCES = -libmatmult_float_la_SOURCES = matmult.c +libmatmult_float_la_SOURCES = matmult-float.c matmult_float_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libmatmult-float.la \ + $(top_builddir)/support/libbeebsc.la \ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) libmatmult_float_la_CPPFLAGS = -DMATMULT_FLOAT ${AM_CPPFLAGS} diff --git a/src/matmult-float/Makefile.in b/src/matmult-float/Makefile.in index fb8805db..c4a9eaba 100644 --- a/src/matmult-float/Makefile.in +++ b/src/matmult-float/Makefile.in @@ -155,8 +155,8 @@ CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libmatmult_float_la_LIBADD = -am__libmatmult_float_la_SOURCES_DIST = matmult.c -@ENABLED_BENCHMARK_MATMULT_FLOAT_TRUE@am_libmatmult_float_la_OBJECTS = libmatmult_float_la-matmult.lo +am__libmatmult_float_la_SOURCES_DIST = matmult-float.c +@ENABLED_BENCHMARK_MATMULT_FLOAT_TRUE@am_libmatmult_float_la_OBJECTS = libmatmult_float_la-matmult-float.lo libmatmult_float_la_OBJECTS = $(am_libmatmult_float_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -172,6 +172,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_MATMULT_FLOAT_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_MATMULT_FLOAT_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_MATMULT_FLOAT_TRUE@ libmatmult-float.la \ +@ENABLED_BENCHMARK_MATMULT_FLOAT_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_MATMULT_FLOAT_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_MATMULT_FLOAT_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_MATMULT_FLOAT_TRUE@ $(am__DEPENDENCIES_1) @@ -391,10 +392,11 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_MATMULT_FLOAT_TRUE@LIBM = $(if $(DUMMY_LIBM),$(DUMMY_LIBM),-lm) @ENABLED_BENCHMARK_MATMULT_FLOAT_TRUE@noinst_LTLIBRARIES = libmatmult-float.la @ENABLED_BENCHMARK_MATMULT_FLOAT_TRUE@matmult_float_SOURCES = -@ENABLED_BENCHMARK_MATMULT_FLOAT_TRUE@libmatmult_float_la_SOURCES = matmult.c +@ENABLED_BENCHMARK_MATMULT_FLOAT_TRUE@libmatmult_float_la_SOURCES = matmult-float.c @ENABLED_BENCHMARK_MATMULT_FLOAT_TRUE@matmult_float_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_MATMULT_FLOAT_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_MATMULT_FLOAT_TRUE@ libmatmult-float.la \ +@ENABLED_BENCHMARK_MATMULT_FLOAT_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_MATMULT_FLOAT_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) @ENABLED_BENCHMARK_MATMULT_FLOAT_TRUE@libmatmult_float_la_CPPFLAGS = -DMATMULT_FLOAT ${AM_CPPFLAGS} @@ -506,7 +508,7 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmatmult_float_la-matmult.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmatmult_float_la-matmult-float.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -529,12 +531,12 @@ distclean-compile: @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< -libmatmult_float_la-matmult.lo: matmult.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmatmult_float_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmatmult_float_la-matmult.lo -MD -MP -MF $(DEPDIR)/libmatmult_float_la-matmult.Tpo -c -o libmatmult_float_la-matmult.lo `test -f 'matmult.c' || echo '$(srcdir)/'`matmult.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmatmult_float_la-matmult.Tpo $(DEPDIR)/libmatmult_float_la-matmult.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='matmult.c' object='libmatmult_float_la-matmult.lo' libtool=yes @AMDEPBACKSLASH@ +libmatmult_float_la-matmult-float.lo: matmult-float.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmatmult_float_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmatmult_float_la-matmult-float.lo -MD -MP -MF $(DEPDIR)/libmatmult_float_la-matmult-float.Tpo -c -o libmatmult_float_la-matmult-float.lo `test -f 'matmult-float.c' || echo '$(srcdir)/'`matmult-float.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmatmult_float_la-matmult-float.Tpo $(DEPDIR)/libmatmult_float_la-matmult-float.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='matmult-float.c' object='libmatmult_float_la-matmult-float.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmatmult_float_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmatmult_float_la-matmult.lo `test -f 'matmult.c' || echo '$(srcdir)/'`matmult.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmatmult_float_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmatmult_float_la-matmult-float.lo `test -f 'matmult-float.c' || echo '$(srcdir)/'`matmult-float.c mostlyclean-libtool: -rm -f *.lo diff --git a/src/matmult-float/matmult-float.c b/src/matmult-float/matmult-float.c new file mode 100644 index 00000000..662c66fd --- /dev/null +++ b/src/matmult-float/matmult-float.c @@ -0,0 +1,212 @@ +/* BEEBS matmult benchmark + + Copyright (C) 2014 Embecosm Limited and University of Bristol + + Contributor James Pallister + + This file is part of the Bristol/Embecosm Embedded Benchmark Suite. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* Original code from: WCET Benchmarks, + http://www.mrtc.mdh.se/projects/wcet/benchmarks.html + Permission to license under GPL obtained by email from Björn Lisper + */ + +/* $Id: matmult.c,v 1.2 2005/04/04 11:34:58 csg Exp $ */ + +/* matmult.c */ +/* was mm.c! */ + + +/*----------------------------------------------------------------------* + * To make this program compile under our assumed embedded environment, + * we had to make several changes: + * - Declare all functions in ANSI style, not K&R. + * this includes adding return types in all cases! + * - Declare function prototypes + * - Disable all output + * - Disable all UNIX-style includes + * + * This is a program that was developed from mm.c to matmult.c by + * Thomas Lundqvist at Chalmers. + *----------------------------------------------------------------------*/ + +#include +#include +#include "support.h" +/* This scale factor will be changed to equalise the runtime of the + benchmarks. */ + +#define LOCAL_SCALE_FACTOR 20 +#define UPPERLIMIT 10 +typedef float matrix [UPPERLIMIT][UPPERLIMIT]; +#define RANDOM_VALUE ((float) RandomInteger () / 10.0) +#define ZERO 0.0 +#define MOD_SIZE 255 + +int +values_match (float v1, float v2) +{ + if (v1 != v2) + { + int exp; + float diff; + + /* Ignore the least significant bit of the mantissa + * to account for any loss of precision due to floating point + * operations */ + frexpf(v1, &exp); + diff = fabsf(v1 - v2); + /* TODO: Fix for big endian */ + if (diff > (1 << exp)) { + return 0; + } + } + + return 1; +} + + +/* + * MATRIX MULTIPLICATION BENCHMARK PROGRAM: + * This program multiplies 2 square matrices resulting in a 3rd + * matrix. It tests a compiler's speed in handling multidimensional + * arrays and simple arithmetic. + */ + + + + +int Seed; +matrix ArrayA_ref, ArrayA, ArrayB_ref, ArrayB, ResultArray; + +void Multiply(matrix A, matrix B, matrix Res); +void InitSeed(void); +void Test(matrix A, matrix B, matrix Res); +void Initialize(matrix Array); +int RandomInteger(void); + +int benchmark() +{ + int i; + + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + { + memcpy (ArrayA, ArrayA_ref, + UPPERLIMIT * UPPERLIMIT * sizeof (ArrayA[0][0])); + memcpy (ArrayB, ArrayB_ref, + UPPERLIMIT * UPPERLIMIT * sizeof (ArrayA[0][0])); + + Test(ArrayA, ArrayB, ResultArray); + } + + return 0; +} + + +/* + * Initializes the seed used in the random number generator. + */ +void InitSeed(void) +{ + Seed = 0; +} + +/* + * Runs a multiplication test on an array. Calculates and prints the + * time it takes to multiply the matrices. + */ +void Test(matrix A, matrix B, matrix Res) +{ + Multiply(A, B, Res); +} + +/* + * Generates random integers between 0 and 8095 + */ +int RandomInteger(void) +{ + Seed = ((Seed * 133) + 81) % MOD_SIZE; + return (Seed); +} + +/* + * Multiplies arrays A and B and stores the result in ResultArray. + */ +void Multiply(matrix A, matrix B, matrix Res) +{ + register int Outer, Inner, Index; + + for (Outer = 0; Outer < UPPERLIMIT; Outer++) + for (Inner = 0; Inner < UPPERLIMIT; Inner++) + { + Res [Outer][Inner] = ZERO; + for (Index = 0; Index < UPPERLIMIT; Index++) + Res[Outer][Inner] += A[Outer][Index] * B[Index][Inner]; + } +} + +void initialise_benchmark() { + InitSeed(); + int OuterIndex, InnerIndex; + + for (OuterIndex = 0; OuterIndex < UPPERLIMIT; OuterIndex++) + for (InnerIndex = 0; InnerIndex < UPPERLIMIT; InnerIndex++) + ArrayA_ref[OuterIndex][InnerIndex] = RANDOM_VALUE; + for (OuterIndex = 0; OuterIndex < UPPERLIMIT; OuterIndex++) + for (InnerIndex = 0; InnerIndex < UPPERLIMIT; InnerIndex++) + ArrayB_ref[OuterIndex][InnerIndex] = RANDOM_VALUE; +} + +int verify_benchmark(int unused) +{ + int i, j; + matrix exp = { + { 949.950073, 860.760010, 1184.940186, 971.279968, 1180.799927, + 887.309937, 1281.239990, 613.529968, 1144.799927, 612.809998, + }, + { 989.550049, 758.339966, 1288.259888, 760.320007, 832.500000, + 739.890015, 1381.860107, 969.119995, 1147.049927, 698.940002, + }, + { 809.099976, 644.309937, 1241.190063, 959.130005, 677.700012, + 763.109924, 1251.989990, 551.880005, 904.950012, 731.609924, + }, + { 1216.799927, 916.290039, 1371.059937, 563.669983, 1106.999878, + 603.090027, 1277.910034, 835.469971, 850.049927, 784.890015, + }, + { 668.700012, 477.360016, 1100.339966, 732.330017, 762.299988, + 647.910034, 841.139893, 408.329987, 931.049988, 562.409973, + }, + { 828.000000, 751.139954, 1537.109985, 715.320007, 949.950012, + 1004.940063, 1425.960083, 1079.369873, 1296.000000, 792.989990, + }, + { 1077.299927, 540.809998, 852.840027, 667.979980, 844.649963, + 733.859924, 985.139954, 775.979980, 903.150024, 596.609985, + }, + { 822.599976, 631.439941, 1133.010010, 238.769989, 667.799988, + 567.989990, 1093.859985, 884.070007, 552.599976, 630.539978, + }, + { 949.950073, 860.760010, 1184.940186, 971.279968, 1180.799927, + 887.309937, 1281.239990, 613.529968, 1144.799927, 612.809998, + }, + { 989.550049, 758.339966, 1288.259888, 760.320007, 832.500000, + 739.890015, 1381.860107, 969.119995, 1147.049927, 698.940002 + } }; + + return 0 == memcmp (ResultArray, exp, + UPPERLIMIT * UPPERLIMIT * sizeof (exp[0][0])); +} + +/* vim: set ts=3 sw=3 et: */ diff --git a/src/matmult-float/matmult.c b/src/matmult-float/matmult.c deleted file mode 120000 index 7bf5d6a2..00000000 --- a/src/matmult-float/matmult.c +++ /dev/null @@ -1 +0,0 @@ -../matmult/matmult.c \ No newline at end of file diff --git a/src/matmult-int/Makefile.am b/src/matmult-int/Makefile.am index 617df53b..42442466 100644 --- a/src/matmult-int/Makefile.am +++ b/src/matmult-int/Makefile.am @@ -30,12 +30,13 @@ noinst_LTLIBRARIES = libmatmult-int.la matmult_int_SOURCES = -libmatmult_int_la_SOURCES = matmult.c +libmatmult_int_la_SOURCES = matmult-int.c matmult_int_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libmatmult-int.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) libmatmult_int_la_CPPFLAGS = -DMATMULT_INT ${AM_CPPFLAGS} diff --git a/src/matmult-int/Makefile.in b/src/matmult-int/Makefile.in index 57f26caf..1f6021bd 100644 --- a/src/matmult-int/Makefile.in +++ b/src/matmult-int/Makefile.in @@ -155,8 +155,8 @@ CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libmatmult_int_la_LIBADD = -am__libmatmult_int_la_SOURCES_DIST = matmult.c -@ENABLED_BENCHMARK_MATMULT_INT_TRUE@am_libmatmult_int_la_OBJECTS = libmatmult_int_la-matmult.lo +am__libmatmult_int_la_SOURCES_DIST = matmult-int.c +@ENABLED_BENCHMARK_MATMULT_INT_TRUE@am_libmatmult_int_la_OBJECTS = libmatmult_int_la-matmult-int.lo libmatmult_int_la_OBJECTS = $(am_libmatmult_int_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -172,6 +172,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_MATMULT_INT_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_MATMULT_INT_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_MATMULT_INT_TRUE@ libmatmult-int.la \ +@ENABLED_BENCHMARK_MATMULT_INT_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_MATMULT_INT_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_MATMULT_INT_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_MATMULT_INT_TRUE@ $(am__DEPENDENCIES_1) @@ -391,11 +392,12 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_MATMULT_INT_TRUE@LIBM = $(if $(DUMMY_LIBM),$(DUMMY_LIBM),-lm) @ENABLED_BENCHMARK_MATMULT_INT_TRUE@noinst_LTLIBRARIES = libmatmult-int.la @ENABLED_BENCHMARK_MATMULT_INT_TRUE@matmult_int_SOURCES = -@ENABLED_BENCHMARK_MATMULT_INT_TRUE@libmatmult_int_la_SOURCES = matmult.c +@ENABLED_BENCHMARK_MATMULT_INT_TRUE@libmatmult_int_la_SOURCES = matmult-int.c @ENABLED_BENCHMARK_MATMULT_INT_TRUE@matmult_int_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_MATMULT_INT_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_MATMULT_INT_TRUE@ libmatmult-int.la \ -@ENABLED_BENCHMARK_MATMULT_INT_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_MATMULT_INT_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_MATMULT_INT_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) @ENABLED_BENCHMARK_MATMULT_INT_TRUE@libmatmult_int_la_CPPFLAGS = -DMATMULT_INT ${AM_CPPFLAGS} all: all-am @@ -506,7 +508,7 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmatmult_int_la-matmult.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmatmult_int_la-matmult-int.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -529,12 +531,12 @@ distclean-compile: @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< -libmatmult_int_la-matmult.lo: matmult.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmatmult_int_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmatmult_int_la-matmult.lo -MD -MP -MF $(DEPDIR)/libmatmult_int_la-matmult.Tpo -c -o libmatmult_int_la-matmult.lo `test -f 'matmult.c' || echo '$(srcdir)/'`matmult.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmatmult_int_la-matmult.Tpo $(DEPDIR)/libmatmult_int_la-matmult.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='matmult.c' object='libmatmult_int_la-matmult.lo' libtool=yes @AMDEPBACKSLASH@ +libmatmult_int_la-matmult-int.lo: matmult-int.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmatmult_int_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmatmult_int_la-matmult-int.lo -MD -MP -MF $(DEPDIR)/libmatmult_int_la-matmult-int.Tpo -c -o libmatmult_int_la-matmult-int.lo `test -f 'matmult-int.c' || echo '$(srcdir)/'`matmult-int.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmatmult_int_la-matmult-int.Tpo $(DEPDIR)/libmatmult_int_la-matmult-int.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='matmult-int.c' object='libmatmult_int_la-matmult-int.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmatmult_int_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmatmult_int_la-matmult.lo `test -f 'matmult.c' || echo '$(srcdir)/'`matmult.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmatmult_int_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmatmult_int_la-matmult-int.lo `test -f 'matmult-int.c' || echo '$(srcdir)/'`matmult-int.c mostlyclean-libtool: -rm -f *.lo diff --git a/src/matmult-int/matmult-int.c b/src/matmult-int/matmult-int.c new file mode 100644 index 00000000..6c85c2ca --- /dev/null +++ b/src/matmult-int/matmult-int.c @@ -0,0 +1,265 @@ +/* BEEBS matmult benchmark + + Copyright (C) 2014 Embecosm Limited and University of Bristol + + Contributor James Pallister + + This file is part of the Bristol/Embecosm Embedded Benchmark Suite. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* Original code from: WCET Benchmarks, + http://www.mrtc.mdh.se/projects/wcet/benchmarks.html + Permission to license under GPL obtained by email from Björn Lisper + */ + +/* $Id: matmult.c,v 1.2 2005/04/04 11:34:58 csg Exp $ */ + +/* matmult.c */ +/* was mm.c! */ + + +/*----------------------------------------------------------------------* + * To make this program compile under our assumed embedded environment, + * we had to make several changes: + * - Declare all functions in ANSI style, not K&R. + * this includes adding return types in all cases! + * - Declare function prototypes + * - Disable all output + * - Disable all UNIX-style includes + * + * This is a program that was developed from mm.c to matmult.c by + * Thomas Lundqvist at Chalmers. + *----------------------------------------------------------------------*/ + +#include +#include "support.h" + +/* This scale factor will be changed to equalise the runtime of the + benchmarks. */ +#define LOCAL_SCALE_FACTOR 47 +#define UPPERLIMIT 20 +#define RANDOM_VALUE (RandomInteger ()) +#define ZERO 0 +#define MOD_SIZE 8095 +typedef long matrix [UPPERLIMIT][UPPERLIMIT]; + +int +values_match (long v1, long v2) +{ + return (v1 == v2); +} + + +/* + * MATRIX MULTIPLICATION BENCHMARK PROGRAM: + * This program multiplies 2 square matrices resulting in a 3rd + * matrix. It tests a compiler's speed in handling multidimensional + * arrays and simple arithmetic. + */ + + + + +int Seed; +matrix ArrayA_ref, ArrayA, ArrayB_ref, ArrayB, ResultArray; + +void Multiply(matrix A, matrix B, matrix Res); +void InitSeed(void); +void Test(matrix A, matrix B, matrix Res); +void Initialize(matrix Array); +int RandomInteger(void); + +int benchmark() +{ + int i; + + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + { + memcpy (ArrayA, ArrayA_ref, + UPPERLIMIT * UPPERLIMIT * sizeof (ArrayA[0][0])); + memcpy (ArrayB, ArrayB_ref, + UPPERLIMIT * UPPERLIMIT * sizeof (ArrayA[0][0])); + + Test(ArrayA, ArrayB, ResultArray); + } + + return 0; +} + + +/* + * Initializes the seed used in the random number generator. + */ +void InitSeed(void) +{ + Seed = 0; +} + +/* + * Runs a multiplication test on an array. Calculates and prints the + * time it takes to multiply the matrices. + */ +void Test(matrix A, matrix B, matrix Res) +{ + Multiply(A, B, Res); +} + +/* + * Generates random integers between 0 and 8095 + */ +int RandomInteger(void) +{ + Seed = ((Seed * 133) + 81) % MOD_SIZE; + return (Seed); +} + +/* + * Multiplies arrays A and B and stores the result in ResultArray. + */ +void Multiply(matrix A, matrix B, matrix Res) +{ + register int Outer, Inner, Index; + + for (Outer = 0; Outer < UPPERLIMIT; Outer++) + for (Inner = 0; Inner < UPPERLIMIT; Inner++) + { + Res [Outer][Inner] = ZERO; + for (Index = 0; Index < UPPERLIMIT; Index++) + Res[Outer][Inner] += A[Outer][Index] * B[Index][Inner]; + } +} + +void initialise_benchmark() { + InitSeed(); + int OuterIndex, InnerIndex; + + for (OuterIndex = 0; OuterIndex < UPPERLIMIT; OuterIndex++) + for (InnerIndex = 0; InnerIndex < UPPERLIMIT; InnerIndex++) + ArrayA_ref[OuterIndex][InnerIndex] = RANDOM_VALUE; + for (OuterIndex = 0; OuterIndex < UPPERLIMIT; OuterIndex++) + for (InnerIndex = 0; InnerIndex < UPPERLIMIT; InnerIndex++) + ArrayB_ref[OuterIndex][InnerIndex] = RANDOM_VALUE; +} + +int verify_benchmark(int unused) +{ + int i, j; + matrix exp = { + { 291018000, 315000075, 279049970, 205074215, 382719905, + 302595865, 348060915, 308986330, 343160760, 307099935, + 292564810, 240954510, 232755815, 246511665, 328466830, + 263664375, 324016395, 334656070, 285978755, 345370360 + }, + { 252241835, 333432715, 299220275, 247745815, 422508990, + 316728505, 359662270, 277775280, 323336795, 320656600, + 249903690, 251499360, 242195700, 263484280, 348207635, + 289485100, 328607555, 300799835, 269351410, 305703460 + }, + { 304901010, 316252815, 263230275, 208939015, 421993740, + 335002930, 348571170, 280992155, 289749970, 259701175, + 295249990, 310900035, 250896625, 250154105, 315096035, + 236364800, 312879355, 312580685, 275998435, 344137885 + }, + { 286700525, 325985600, 253054970, 224361490, 353502130, + 306544290, 323492140, 259123905, 307731610, 282414410, + 281127810, 246936935, 207890815, 233789540, 339836730, + 277296350, 319925620, 307470895, 290537580, 292297535 + }, + { 272571255, 377663320, 304545985, 263001340, 375034885, + 325423710, 410620380, 313191730, 356989815, 308508355, + 218003850, 272487135, 266000220, 264734710, 367539620, + 304146675, 355295500, 276019740, 251415695, 301225235 + }, + { 272547900, 321522300, 288294345, 247748015, 389912855, + 331874890, 370798315, 315467255, 367554485, 311947660, + 258809685, 270536510, 256730515, 287143040, 363087030, + 285672775, 353670120, 304219695, 274897255, 324684660 + }, + { 233123995, 227142480, 212655155, 198592290, 345335250, + 302661845, 253374925, 233243305, 233750030, 224590040, + 200404820, 250791135, 234405760, 211723645, 280630165, + 185245875, 296423665, 276278575, 252368265, 278726535 + }, + { 277690535, 339615440, 320921550, 307114315, 400187215, + 334374655, 376286920, 295993530, 362988020, 356272700, + 293965465, 261574710, 259690975, 263037705, 416748985, + 274683275, 385571030, 402782385, 323927010, 362778710 + }, + { 267168970, 323401680, 279474330, 201934365, 362624300, + 330736145, 371793675, 299650280, 333646005, 264791490, + 215918320, 277512760, 264068435, 234555295, 321772515, + 217507025, 310372440, 317544750, 245525965, 343183435 + }, + { 281293570, 326519505, 233494705, 238516065, 297038200, + 266273420, 349521550, 259343530, 306032255, 266397915, + 210274920, 263743085, 231689610, 251949545, 293562740, + 226822900, 309225440, 286212000, 206108715, 236678985 + }, + { 288404350, 310319375, 282695670, 244150740, 426489380, + 387525790, 342018190, 326086505, 352250260, 319997735, + 300645835, 284822660, 271837440, 274000415, 361826730, + 252399600, 348582320, 375813820, 316588255, 322499110 + }, + { 273368780, 329706295, 288668335, 234501665, 381962610, + 343186285, 337520205, 259637405, 295755465, 284778105, + 205310525, 249598310, 256662470, 251533535, 336159770, + 249342150, 333559450, 329296590, 278254845, 300673860 + }, + { 318589575, 315522800, 260632295, 250009765, 337127730, + 312810490, 346698590, 260810030, 388289910, 337081285, + 283635410, 208148610, 234123865, 259653165, 370115255, + 243311450, 377808245, 358786770, 286839730, 321912835 + }, + { 229541925, 253967450, 223002545, 202302515, 303446955, + 268472740, 285580065, 211013405, 287677960, 279773910, + 227377310, 197461135, 222469715, 179536615, 306957380, + 178407075, 281051570, 279718120, 234868230, 288991535 + }, + { 290692955, 317729070, 297868235, 213450065, 469270935, + 375344910, 326987580, 334565680, 325300040, 290325655, + 254703825, 284914960, 245773820, 276641510, 323510795, + 271034400, 337424250, 360011440, 281515520, 331261535 + }, + { 287075125, 313194850, 269889345, 208109115, 420653930, + 331900290, 355440665, 318065155, 343785360, 302163035, + 308959360, 312666110, 268997740, 288557415, 370158305, + 205012650, 318198795, 384484520, 316450105, 378714460 + }, + { 278680580, 356815220, 307597060, 216073365, 390879235, + 358775185, 358895230, 306434180, 315569040, 272688130, + 249424325, 274584610, 273530970, 265450585, 325127920, + 312802050, 317134900, 298518590, 269975470, 332586535 + }, + { 245629780, 267021570, 234689035, 208808065, 366356035, + 267059560, 349348005, 270158755, 348048340, 291550930, + 272717800, 259714410, 236033845, 280627610, 335089770, + 176610475, 259339950, 322752840, 236218295, 329687310 + }, + { 226517370, 272306005, 271484080, 216145515, 400972075, + 288475645, 332969550, 338410905, 329052205, 330392265, + 306488095, 271979085, 232795960, 257593945, 339558165, + 202700275, 320622065, 386350450, 315344865, 329233410 + }, + { 224852610, 231292540, 236945875, 243273740, 336327040, + 305144680, 248261920, 191671605, 241699245, 263085200, + 198883715, 175742885, 202517850, 172427630, 296304160, + 209188850, 326546955, 252990460, 238844535, 289753485 + } }; + + return 0 == memcmp (ResultArray, exp, + UPPERLIMIT * UPPERLIMIT * sizeof (exp[0][0])); +} + +/* vim: set ts=3 sw=3 et: */ diff --git a/src/matmult-int/matmult.c b/src/matmult-int/matmult.c deleted file mode 120000 index 7bf5d6a2..00000000 --- a/src/matmult-int/matmult.c +++ /dev/null @@ -1 +0,0 @@ -../matmult/matmult.c \ No newline at end of file diff --git a/src/matmult/.gitignore b/src/matmult/.gitignore deleted file mode 100644 index d2da3eb8..00000000 --- a/src/matmult/.gitignore +++ /dev/null @@ -1 +0,0 @@ -matmult diff --git a/src/matmult/Makefile.am b/src/matmult/Makefile.am deleted file mode 100644 index 71ef8b29..00000000 --- a/src/matmult/Makefile.am +++ /dev/null @@ -1,26 +0,0 @@ -# Makefile.am for distributing matmult -# -# Copyright (C) 2013 Embecosm Limited and University of Bristol -# -# This file is part of the Bristol/Embecosm Embedded Benchmark Suite. -# -# Contributor: James Pallister -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# SPDX-License-Identifier: GPL-3.0-or-later - -# Not a benchmark per se, but the base software for other benchmarks. - -EXTRA_DIST = matmult.c diff --git a/src/matmult/Makefile.in b/src/matmult/Makefile.in deleted file mode 100644 index 515420fd..00000000 --- a/src/matmult/Makefile.in +++ /dev/null @@ -1,480 +0,0 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2014 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -# Makefile.am for distributing matmult -# -# Copyright (C) 2013 Embecosm Limited and University of Bristol -# -# This file is part of the Bristol/Embecosm Embedded Benchmark Suite. -# -# Contributor: James Pallister -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# SPDX-License-Identifier: GPL-3.0-or-later - -# Not a benchmark per se, but the base software for other benchmarks. -VPATH = @srcdir@ -am__is_gnu_make = { \ - if test -z '$(MAKELEVEL)'; then \ - false; \ - elif test -n '$(MAKE_HOST)'; then \ - true; \ - elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ - true; \ - else \ - false; \ - fi; \ -} -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -target_triplet = @target@ -subdir = src/matmult -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ - $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ - $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ - $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -SOURCES = -DIST_SOURCES = -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -am__DIST_COMMON = $(srcdir)/Makefile.in -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AR = @AR@ -ARCH = @ARCH@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -BENCHMARKS = @BENCHMARKS@ -BOARD = @BOARD@ -CC = @CC@ -CCAS = @CCAS@ -CCASDEPMODE = @CCASDEPMODE@ -CCASFLAGS = @CCASFLAGS@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CHIP = @CHIP@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEJAGNU = @DEJAGNU@ -DEPDIR = @DEPDIR@ -DLLTOOL = @DLLTOOL@ -DSYMUTIL = @DSYMUTIL@ -DUMMY_COMPILERRT = @DUMMY_COMPILERRT@ -DUMMY_CRT0 = @DUMMY_CRT0@ -DUMMY_LIBC = @DUMMY_LIBC@ -DUMMY_LIBGCC = @DUMMY_LIBGCC@ -DUMMY_LIBM = @DUMMY_LIBM@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LIBTOOL_DEPS = @LIBTOOL_DEPS@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MKDIR_P = @MKDIR_P@ -NM = @NM@ -NMEDIT = @NMEDIT@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -RANLIB = @RANLIB@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -VERSION = @VERSION@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target = @target@ -target_alias = @target_alias@ -target_cpu = @target_cpu@ -target_os = @target_os@ -target_vendor = @target_vendor@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -EXTRA_DIST = matmult.c -all: all-am - -.SUFFIXES: -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/matmult/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu src/matmult/Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs -tags TAGS: - -ctags CTAGS: - -cscope cscopelist: - - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile -installdirs: -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic clean-libtool mostlyclean-am - -distclean: distclean-am - -rm -f Makefile -distclean-am: clean-am distclean-generic - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-generic mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: - -.MAKE: install-am install-strip - -.PHONY: all all-am check check-am clean clean-generic clean-libtool \ - cscopelist-am ctags-am distclean distclean-generic \ - distclean-libtool distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags-am uninstall uninstall-am - -.PRECIOUS: Makefile - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/src/matmult/matmult.c b/src/matmult/matmult.c deleted file mode 100644 index 3daaab2e..00000000 --- a/src/matmult/matmult.c +++ /dev/null @@ -1,228 +0,0 @@ -/* BEEBS matmult benchmark - - Copyright (C) 2014 Embecosm Limited and University of Bristol - - Contributor James Pallister - - This file is part of the Bristol/Embecosm Embedded Benchmark Suite. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* Original code from: WCET Benchmarks, - http://www.mrtc.mdh.se/projects/wcet/benchmarks.html - Permission to license under GPL obtained by email from Björn Lisper - */ - -/* $Id: matmult.c,v 1.2 2005/04/04 11:34:58 csg Exp $ */ - -/* matmult.c */ -/* was mm.c! */ - - -/*----------------------------------------------------------------------* - * To make this program compile under our assumed embedded environment, - * we had to make several changes: - * - Declare all functions in ANSI style, not K&R. - * this includes adding return types in all cases! - * - Declare function prototypes - * - Disable all output - * - Disable all UNIX-style includes - * - * This is a program that was developed from mm.c to matmult.c by - * Thomas Lundqvist at Chalmers. - *----------------------------------------------------------------------*/ -#ifdef MATMULT_FLOAT -#include -#endif /* MATMULT_FLOAT */ - -#include "support.h" -/* This scale factor will be changed to equalise the runtime of the - benchmarks. */ -#ifdef MATMULT_FLOAT -#define SCALE_FACTOR (REPEAT_FACTOR >> 5) -#define UPPERLIMIT 10 -typedef float matrix [UPPERLIMIT][UPPERLIMIT]; -#define RANDOM_VALUE ((float) RandomInteger () / 10.0) -#define ZERO 0.0 -#define MOD_SIZE 255 - -int -values_match (float v1, float v2) -{ - if (v1 != v2) - { - int exp; - float diff; - - /* Ignore the least significant bit of the mantissa - * to account for any loss of precision due to floating point - * operations */ - frexpf(v1, &exp); - diff = fabsf(v1 - v2); - /* TODO: Fix for big endian */ - if (diff > (1 << exp)) { - return 0; - } - } - - return 1; -} - -#elif defined MATMULT_INT -#define SCALE_FACTOR (REPEAT_FACTOR >> 6) -#define UPPERLIMIT 20 -#define RANDOM_VALUE (RandomInteger ()) -#define ZERO 0 -#define MOD_SIZE 8095 -typedef long matrix [UPPERLIMIT][UPPERLIMIT]; - -int -values_match (long v1, long v2) -{ - return (v1 == v2); -} - -#else -#error "No SCALE_FACTOR defined" -#endif - -/* - * MATRIX MULTIPLICATION BENCHMARK PROGRAM: - * This program multiplies 2 square matrices resulting in a 3rd - * matrix. It tests a compiler's speed in handling multidimensional - * arrays and simple arithmetic. - */ - - - - -int Seed; -matrix ArrayA, ArrayB, ResultArray; - -void Multiply(matrix A, matrix B, matrix Res); -void InitSeed(void); -void Test(matrix A, matrix B, matrix Res); -void Initialize(matrix Array); -int RandomInteger(void); - -int benchmark() -{ - Test(ArrayA, ArrayB, ResultArray); - - return 0; -} - - -/* - * Initializes the seed used in the random number generator. - */ -void InitSeed(void) -{ - Seed = 0; -} - -/* - * Runs a multiplication test on an array. Calculates and prints the - * time it takes to multiply the matrices. - */ -void Test(matrix A, matrix B, matrix Res) -{ - Multiply(A, B, Res); -} - -/* - * Generates random integers between 0 and 8095 - */ -int RandomInteger(void) -{ - Seed = ((Seed * 133) + 81) % MOD_SIZE; - return (Seed); -} - -/* - * Multiplies arrays A and B and stores the result in ResultArray. - */ -void Multiply(matrix A, matrix B, matrix Res) -{ - register int Outer, Inner, Index; - - for (Outer = 0; Outer < UPPERLIMIT; Outer++) - for (Inner = 0; Inner < UPPERLIMIT; Inner++) - { - Res [Outer][Inner] = ZERO; - for (Index = 0; Index < UPPERLIMIT; Index++) - Res[Outer][Inner] += A[Outer][Index] * B[Index][Inner]; - } -} - -void initialise_benchmark() { - InitSeed(); - int OuterIndex, InnerIndex; - - for (OuterIndex = 0; OuterIndex < UPPERLIMIT; OuterIndex++) - for (InnerIndex = 0; InnerIndex < UPPERLIMIT; InnerIndex++) - ArrayA[OuterIndex][InnerIndex] = RANDOM_VALUE; - for (OuterIndex = 0; OuterIndex < UPPERLIMIT; OuterIndex++) - for (InnerIndex = 0; InnerIndex < UPPERLIMIT; InnerIndex++) - ArrayB[OuterIndex][InnerIndex] = RANDOM_VALUE; -} - -int verify_benchmark(int unused) -{ - int i, j; -#ifdef MATMULT_FLOAT - matrix exp = {{949.950073, 860.760010, 1184.940186, 971.279968, 1180.799927, 887.309937, 1281.239990, 613.529968, 1144.799927, 612.809998, }, - {989.550049, 758.339966, 1288.259888, 760.320007, 832.500000, 739.890015, 1381.860107, 969.119995, 1147.049927, 698.940002, }, - {809.099976, 644.309937, 1241.190063, 959.130005, 677.700012, 763.109924, 1251.989990, 551.880005, 904.950012, 731.609924, }, - {1216.799927, 916.290039, 1371.059937, 563.669983, 1106.999878, 603.090027, 1277.910034, 835.469971, 850.049927, 784.890015, }, - {668.700012, 477.360016, 1100.339966, 732.330017, 762.299988, 647.910034, 841.139893, 408.329987, 931.049988, 562.409973, }, - {828.000000, 751.139954, 1537.109985, 715.320007, 949.950012, 1004.940063, 1425.960083, 1079.369873, 1296.000000, 792.989990, }, - {1077.299927, 540.809998, 852.840027, 667.979980, 844.649963, 733.859924, 985.139954, 775.979980, 903.150024, 596.609985, }, - {822.599976, 631.439941, 1133.010010, 238.769989, 667.799988, 567.989990, 1093.859985, 884.070007, 552.599976, 630.539978, }, - {949.950073, 860.760010, 1184.940186, 971.279968, 1180.799927, 887.309937, 1281.239990, 613.529968, 1144.799927, 612.809998, }, - {989.550049, 758.339966, 1288.259888, 760.320007, 832.500000, 739.890015, 1381.860107, 969.119995, 1147.049927, 698.940002} - }; -#endif -#ifdef MATMULT_INT - matrix exp = { - {291018000, 315000075, 279049970, 205074215, 382719905, 302595865, 348060915, 308986330, 343160760, 307099935, 292564810, 240954510, 232755815, 246511665, 328466830, 263664375, 324016395, 334656070, 285978755, 345370360}, - {252241835, 333432715, 299220275, 247745815, 422508990, 316728505, 359662270, 277775280, 323336795, 320656600, 249903690, 251499360, 242195700, 263484280, 348207635, 289485100, 328607555, 300799835, 269351410, 305703460}, - {304901010, 316252815, 263230275, 208939015, 421993740, 335002930, 348571170, 280992155, 289749970, 259701175, 295249990, 310900035, 250896625, 250154105, 315096035, 236364800, 312879355, 312580685, 275998435, 344137885}, - {286700525, 325985600, 253054970, 224361490, 353502130, 306544290, 323492140, 259123905, 307731610, 282414410, 281127810, 246936935, 207890815, 233789540, 339836730, 277296350, 319925620, 307470895, 290537580, 292297535}, - {272571255, 377663320, 304545985, 263001340, 375034885, 325423710, 410620380, 313191730, 356989815, 308508355, 218003850, 272487135, 266000220, 264734710, 367539620, 304146675, 355295500, 276019740, 251415695, 301225235}, - {272547900, 321522300, 288294345, 247748015, 389912855, 331874890, 370798315, 315467255, 367554485, 311947660, 258809685, 270536510, 256730515, 287143040, 363087030, 285672775, 353670120, 304219695, 274897255, 324684660}, - {233123995, 227142480, 212655155, 198592290, 345335250, 302661845, 253374925, 233243305, 233750030, 224590040, 200404820, 250791135, 234405760, 211723645, 280630165, 185245875, 296423665, 276278575, 252368265, 278726535}, - {277690535, 339615440, 320921550, 307114315, 400187215, 334374655, 376286920, 295993530, 362988020, 356272700, 293965465, 261574710, 259690975, 263037705, 416748985, 274683275, 385571030, 402782385, 323927010, 362778710}, - {267168970, 323401680, 279474330, 201934365, 362624300, 330736145, 371793675, 299650280, 333646005, 264791490, 215918320, 277512760, 264068435, 234555295, 321772515, 217507025, 310372440, 317544750, 245525965, 343183435}, - {281293570, 326519505, 233494705, 238516065, 297038200, 266273420, 349521550, 259343530, 306032255, 266397915, 210274920, 263743085, 231689610, 251949545, 293562740, 226822900, 309225440, 286212000, 206108715, 236678985}, - {288404350, 310319375, 282695670, 244150740, 426489380, 387525790, 342018190, 326086505, 352250260, 319997735, 300645835, 284822660, 271837440, 274000415, 361826730, 252399600, 348582320, 375813820, 316588255, 322499110}, - {273368780, 329706295, 288668335, 234501665, 381962610, 343186285, 337520205, 259637405, 295755465, 284778105, 205310525, 249598310, 256662470, 251533535, 336159770, 249342150, 333559450, 329296590, 278254845, 300673860}, - {318589575, 315522800, 260632295, 250009765, 337127730, 312810490, 346698590, 260810030, 388289910, 337081285, 283635410, 208148610, 234123865, 259653165, 370115255, 243311450, 377808245, 358786770, 286839730, 321912835}, - {229541925, 253967450, 223002545, 202302515, 303446955, 268472740, 285580065, 211013405, 287677960, 279773910, 227377310, 197461135, 222469715, 179536615, 306957380, 178407075, 281051570, 279718120, 234868230, 288991535}, - {290692955, 317729070, 297868235, 213450065, 469270935, 375344910, 326987580, 334565680, 325300040, 290325655, 254703825, 284914960, 245773820, 276641510, 323510795, 271034400, 337424250, 360011440, 281515520, 331261535}, - {287075125, 313194850, 269889345, 208109115, 420653930, 331900290, 355440665, 318065155, 343785360, 302163035, 308959360, 312666110, 268997740, 288557415, 370158305, 205012650, 318198795, 384484520, 316450105, 378714460}, - {278680580, 356815220, 307597060, 216073365, 390879235, 358775185, 358895230, 306434180, 315569040, 272688130, 249424325, 274584610, 273530970, 265450585, 325127920, 312802050, 317134900, 298518590, 269975470, 332586535}, - {245629780, 267021570, 234689035, 208808065, 366356035, 267059560, 349348005, 270158755, 348048340, 291550930, 272717800, 259714410, 236033845, 280627610, 335089770, 176610475, 259339950, 322752840, 236218295, 329687310}, - {226517370, 272306005, 271484080, 216145515, 400972075, 288475645, 332969550, 338410905, 329052205, 330392265, 306488095, 271979085, 232795960, 257593945, 339558165, 202700275, 320622065, 386350450, 315344865, 329233410}, - {224852610, 231292540, 236945875, 243273740, 336327040, 305144680, 248261920, 191671605, 241699245, 263085200, 198883715, 175742885, 202517850, 172427630, 296304160, 209188850, 326546955, 252990460, 238844535, 289753485}, - }; -#endif - for (i=0; i> 10) +#define LOCAL_SCALE_FACTOR 10 #include #include @@ -50,32 +50,6 @@ */ -/* BEEBS fixes RAND_MAX to its lowest permitted value, 2^15-1 */ - -#ifdef RAND_MAX -#undef RAND_MAX -#endif -#define RAND_MAX ((1U << 15) - 1) - -/* Yield a sequence of random numbers in the range [0, 2^15-1]. - - The seed is always initialized to zero. long int is guaranteed to be at - least 32 bits. The seed only ever uses 31 bits (so is positive). - - For BEEBS this gets round different operating systems using different - multipliers and offsets and RAND_MAX variations. */ - -static int -rand_beebs () -{ - static long int seed = 0; - - seed = (seed * 1103515245L + 12345) & ((1UL << 31) - 1); - return (int) (seed >> 16); - -} - - long Min(const long a, const long b) { if (a < b) return a; return b; @@ -222,7 +196,7 @@ long TestingJittered(long index, long total) { } long TestingMostlyEqual(long index, long total) { - return 1000 + rand_beebs() * 1.0/RAND_MAX * 4; + return 1000L + (long) (rand_beebs() % 4); } @@ -236,66 +210,77 @@ initialise_benchmark (void) -int benchmark() { - long total, index, test_case; - Comparison compare = TestCompare; - - __typeof__(&TestingPathological) test_cases[] = { - TestingPathological, - TestingRandom, - TestingMostlyDescending, - TestingMostlyAscending, - TestingAscending, - TestingDescending, - TestingEqual, - TestingJittered, - TestingMostlyEqual - }; - - /* initialize the random-number generator. */ - /* The original code used srand here, but not needed since we are - using a fixed random number generator for reproducibility. - srand(0); - */ - /*srand(10141985);*/ /* in case you want the same random numbers */ - - - total = max_size; - for (test_case = 0; test_case < sizeof(test_cases)/sizeof(test_cases[0]); test_case++) { - - for (index = 0; index < total; index++) { - Test item; - - item.value = test_cases[test_case](index, total); - item.index = index; - - array1[index] = item; - } - - MergeSort(array1, total, compare); +int benchmark() +{ + long total, index, test_case; + Comparison compare = TestCompare; + + __typeof__(&TestingPathological) test_cases[9] = + { + &TestingPathological, + &TestingRandom, + &TestingMostlyDescending, + &TestingMostlyAscending, + &TestingAscending, + &TestingDescending, + &TestingEqual, + &TestingJittered, + &TestingMostlyEqual + }; + + int i; + + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + { + /* initialize the random-number generator. */ + /* The original code used srand here, we use a value that will fit in + a 16-bit unsigned int. */ + srand_beebs (0); + /*srand(10141985);*/ /* in case you want the same random numbers */ + + total = max_size; + for (test_case = 0; test_case < 9; test_case++) { + + for (index = 0; index < total; index++) { + Test item; + + item.value = test_cases[test_case](index, total); + item.index = index; + + array1[index] = item; } - return 0; + MergeSort(array1, total, compare); + } + } + + return 0; } int verify_benchmark(int unused) { - int i; - // x86 - // int exp_val[] = {1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1003, 1003, 1003, 1003, 1003, 1003, 1003, 1003, 1003, 1003, 1003, 1003, 1003, 1003, 1003, 1003}; - // int exp_index[] = {0, 9, 14, 16, 17, 19, 21, 29, 35, 36, 38, 42, 46, 49, 51, 65, 76, 77, 78, 80, 84, 85, 90, 97, 98, 5, 6, 8, 20, 23, 24, 26, 30, 34, 43, 44, 45, 47, 52, 53, 54, 56, 63, 71, 72, 86, 87, 91, 95, 1, 2, 3, 4, 10, 11, 12, 13, 28, 32, 37, 39, 41, 48, 50, 55, 57, 58, 60, 62, 64, 66, 68, 69, 70, 73, 75, 79, 81, 82, 83, 88, 92, 94, 99, 7, 15, 18, 22, 25, 27, 31, 33, 40, 59, 61, 67, 74, 89, 93, 96}; - // stm32 - int exp_val[] = {1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1003, 1003, 1003, 1003, 1003, 1003, 1003, 1003, 1003, 1003, 1003, 1003, 1003, 1003, 1003, 1003}; - int exp_index[] = {0, 9, 14, 16, 17, 19, 21, 29, 35, 36, 38, 42, 46, 49, 51, 65, 76, 77, 78, 80, 84, 85, 90, 97, 98, 5, 6, 8, 20, 23, 24, 26, 30, 34, 43, 44, 45, 47, 52, 53, 54, 56, 63, 71, 72, 86, 87, 91, 95, 1, 2, 3, 4, 10, 11, 12, 13, 28, 32, 37, 39, 41, 48, 50, 55, 57, 58, 60, 62, 64, 66, 68, 69, 70, 73, 75, 79, 81, 82, 83, 88, 92, 94, 99, 7, 15, 18, 22, 25, 27, 31, 33, 40, 59, 61, 67, 74, 89, 93, 96}; - for (i=0; i - -#define HEAP_SIZE 8192 -static char heap[HEAP_SIZE]; -static void *heap_ptr; -static void *heap_end; - -/* Initialize the BEEBS heap pointers */ - -void -init_heap (void) -{ - heap_ptr = (void *) heap; - heap_end = heap_ptr + HEAP_SIZE; -} - -/* BEEBS version of malloc. - - This is primarily to reduce library and OS dependencies. Malloc is - generally not used in embedded code, or if it is, only in well defined - contexts to pre-allocate a fixed amount of memory. So this simplistic - implementation is just fine. */ - -static void * -malloc_beebs (size_t size) -{ - void *new_ptr = heap_ptr; - - if (((heap_ptr + size) > heap_end) || (0 == size)) - return NULL; - else - { - heap_ptr += size; - return new_ptr; - } -} - -/* BEEBS version of realloc. - - This is primarily to reduce library and OS dependencies. We just have to - allocate new memory and copy stuff across. */ - -static void * -realloc_beebs (void *ptr, size_t size) -{ - void *new_ptr = heap_ptr; - - if (((heap_ptr + size) > heap_end) || (0 == size)) - return NULL; - else - { - heap_ptr += size; - - /* This is clunky, since we don't know the size of the original - pointer. However it is a read only action and we know it must - be big enough if we right off the end, or we couldn't have - allocated here. If the size is smaller, it doesn't matter. */ - - if (NULL != ptr) - { - int i; - - for (i = 0; i < size; i++) - ((char *) new_ptr)[i] = ((char *)ptr)[i]; - } - - return new_ptr; - } -} - -/* BEEBS version of free. - - For our simplified version of memory handling, free can just do nothing. */ - -static void -free_beebs (void *ptr) -{ -} +#include "beebsc.h" // ------------------- ZIP archive reading/writing diff --git a/src/miniz/miniz_b.c b/src/miniz/miniz_b.c index 77cfb7f8..65390d54 100644 --- a/src/miniz/miniz_b.c +++ b/src/miniz/miniz_b.c @@ -26,7 +26,7 @@ /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) +#define LOCAL_SCALE_FACTOR 402275 // Like compress() but with more control, level may range from 0 (storing) to 9 (max. compression) int mz_compress2(unsigned char *pDest, unsigned long *pDest_len, const unsigned char *pSource, unsigned long source_len, int level); @@ -39,26 +39,27 @@ const char *text="Since the ancients (as we are told by Pappas), made great acco unsigned char tocompress[1200]; unsigned char compressed[1200]; +/* Array for use by BEEBS malloc */ -/* This benchmark does not support verification */ +#define HEAP_SIZE 8192 +static char heap[HEAP_SIZE]; + +/* This benchmark does not support verification, other than of malloc */ int verify_benchmark (int res __attribute ((unused)) ) { - return -1; + return check_heap_beebs ((void *) heap); } -extern void init_heap (void); - void initialise_benchmark (void) { - init_heap (); /* Set up BEEBS heap */ + init_heap_beebs ((void *) heap, HEAP_SIZE); /* Set up BEEBS heap */ } - int benchmark() { volatile int cnt=0; diff --git a/src/minver/Makefile.am b/src/minver/Makefile.am index d085ac73..48d8d331 100644 --- a/src/minver/Makefile.am +++ b/src/minver/Makefile.am @@ -34,7 +34,9 @@ libminver_la_SOURCES = libminver.c minver_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libminver.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) \ + $(LIBM) diff --git a/src/minver/Makefile.in b/src/minver/Makefile.in index f43a6548..b5922ca5 100644 --- a/src/minver/Makefile.in +++ b/src/minver/Makefile.in @@ -171,9 +171,10 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_MINVER_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_MINVER_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_MINVER_TRUE@ libminver.la \ +@ENABLED_BENCHMARK_MINVER_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_MINVER_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_MINVER_TRUE@ $(am__DEPENDENCIES_1) \ -@ENABLED_BENCHMARK_MINVER_TRUE@ $(am__DEPENDENCIES_1) +@ENABLED_BENCHMARK_MINVER_TRUE@ $(am__DEPENDENCIES_1) $(LIBM) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false @@ -393,7 +394,9 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_MINVER_TRUE@minver_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_MINVER_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_MINVER_TRUE@ libminver.la \ -@ENABLED_BENCHMARK_MINVER_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_MINVER_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_MINVER_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) \ +@ENABLED_BENCHMARK_MINVER_TRUE@ $(LIBM) all: all-am diff --git a/src/minver/libminver.c b/src/minver/libminver.c index 5c536c02..e4718c86 100644 --- a/src/minver/libminver.c +++ b/src/minver/libminver.c @@ -63,24 +63,33 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ +#include +#include #include "support.h" /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) +#define LOCAL_SCALE_FACTOR 329 int minver(int row, int col, float eps); int mmul(int row_a, int col_a, int row_b, int col_b); -static float a[3][3] = { +static float a_ref[3][3] = { {3.0, -6.0, 7.0}, {9.0, 0.0, -5.0}, {5.0, -8.0, 6.0}, }; -float b[3][3], c[3][3], aa[3][3], a_i[3][3], e[3][3], det; +static float b[3][3] = { + {-3.0, 0.0, 2.0}, + { 3.0, -2.0, 0.0}, + { 0.0, 2.0, -3.0}, +}; + +static float a[3][3], c[3][3], d[3][3], det; -float minver_fabs(float n) +static float +minver_fabs(float n) { float f; @@ -89,139 +98,148 @@ float minver_fabs(float n) return f; } - -int mmul(int row_a, int col_a, int row_b, int col_b) +int +mmul(int row_a, int col_a, int row_b, int col_b) { - int i, j, k, row_c, col_c; - float w; - - row_c = row_a; - col_c = col_b; - - if(row_c < 1 || row_b < 1 || col_c < 1 || col_a != row_b) return(999); - for(i = 0; i < row_c; i++) - { - for(j = 0; j < col_c; j++) - { - w = 0.0; - for(k = 0; k < row_b; k++) - w += a[i][k] * b[k][j]; - c[i][j] = w; - } - } - return(0); - + int i, j, k, row_c, col_c; + float w; + + row_c = row_a; + col_c = col_b; + + if(row_c < 1 || row_b < 1 || col_c < 1 || col_a != row_b) return(999); + for(i = 0; i < row_c; i++) + { + for(j = 0; j < col_c; j++) + { + w = 0.0; + for(k = 0; k < row_b; k++) + w += a[i][k] * b[k][j]; + c[i][j] = w; + } + } + + return(0); } -/* Volatile global. Write defined, but otherwise unused local - variables here to avoid their definitions being optimised out. */ -volatile int data_sink = 0; -int minver(int row, int col, float eps) +int +minver(int row, int col, float eps) { - - int work[500], i, j, k, r, iw, s, t, u, v; - float w, wmax, pivot, api, w1; - - r = t = w = s = 0; - if(row < 2 || row > 500 || eps <= 0.0) return(999); - w1 = 1.0; - for(i = 0; i < row; i++) - work[i] = i; - for(k = 0; k < row; k++) - { - wmax = 0.0; - for(i = k; i < row; i++) - { - w = minver_fabs(a[i][k]); - if(w > wmax) - { - wmax = w; - r = i; - } - } - pivot = a[r][k]; - api = minver_fabs(pivot); - if(api <= eps) - { - det = w1; - return(1); - } - w1 *= pivot; - u = k * col; - v = r * col; - if(r != k) - { - w1 = -w; - iw = work[k]; - work[k] = work[r]; - work[r] = iw; - for(j = 0; j < row; j++) - { - s = u + j; - t = v + j; - w = a[k][j]; - a[k][j] = a[r][j]; - a[r][j] = w; - } - } - for(i = 0; i < row; i++) - a[k][i] /= pivot; - for(i = 0; i < row; i++) - { - if(i != k) - { - v = i * col; - s = v + k; - w = a[i][k]; - if(w != 0.0) - { - for(j = 0; j < row; j++) - if(j != k) a[i][j] -= w * a[k][j]; - a[i][k] = -w / pivot; - } - } - } - a[k][k] = 1.0 / pivot; - } - for(i = 0; i < row; i++) - { - while(1) - { - k = work[i]; - if(k == i) break; - iw = work[k]; - work[k] = work[i]; - work[i] = iw; - for(j = 0; j < row; j++) - { - u = j * col; - s = u + i; - t = u + k; - w = a[k][i]; - a[k][i] = a[k][k]; - a[k][k] = w; - } - } - } - det = w1; - - /* Silence compiler warnings about unused variables. */ - data_sink = t; - data_sink = s; - - return(0); + int work[500], i, j, k, r, iw, u, v; + float w, wmax, pivot, api, w1; + + r = w = 0; + if(row < 2 || row > 500 || eps <= 0.0) return(999); + w1 = 1.0; + for(i = 0; i < row; i++) + work[i] = i; + for(k = 0; k < row; k++) + { + wmax = 0.0; + for(i = k; i < row; i++) + { + w = minver_fabs(a[i][k]); + if(w > wmax) + { + wmax = w; + r = i; + } + } + pivot = a[r][k]; + api = minver_fabs(pivot); + if(api <= eps) + { + det = w1; + return(1); + } + w1 *= pivot; + u = k * col; + v = r * col; + if(r != k) + { + w1 = -w; + iw = work[k]; + work[k] = work[r]; + work[r] = iw; + for(j = 0; j < row; j++) + { + w = a[k][j]; + a[k][j] = a[r][j]; + a[r][j] = w; + } + } + for(i = 0; i < row; i++) + a[k][i] /= pivot; + for(i = 0; i < row; i++) + { + if(i != k) + { + v = i * col; + w = a[i][k]; + if(w != 0.0) + { + for(j = 0; j < row; j++) + if(j != k) a[i][j] -= w * a[k][j]; + a[i][k] = -w / pivot; + } + } + } + a[k][k] = 1.0 / pivot; + } + + for(i = 0; i < row; i++) + { + while(1) + { + k = work[i]; + if(k == i) break; + iw = work[k]; + work[k] = work[i]; + work[i] = iw; + for(j = 0; j < row; j++) + { + u = j * col; + w = a[k][i]; + a[k][i] = a[k][k]; + a[k][k] = w; + } + } + } + + det = w1; + + return(0); } - - -/* This benchmark does not support verification */ - int verify_benchmark (int res __attribute ((unused)) ) { - return -1; + int i, j; + float eps = 1.0e-6; + + static float c_exp[3][3] = { + { -27.0, 26.0, -15.0 }, + { -27.0, -10.0, 33.0 }, + { -39.0, 28.0, -8.0 } + }; + + static float d_exp[3][3] = { + { 0.133333325, -0.199999958, 0.2666665910}, + { -0.519999862, 0.113333330, 0.5266665220}, + { 0.479999840, -0.359999895, 0.0399999917} + }; + + /* Allow small errors in floating point */ + + for (i = 0; i < 3; i++) + for (j = 0; j < 3; j++) + if ((fabs(c[i][j] - c_exp[i][j]) > eps) + || (fabs(d[i][j] - d_exp[i][j]) > eps)) + return 0; + + return fabs (det + 16.6666718) <= eps; } @@ -234,22 +252,18 @@ initialise_benchmark (void) int benchmark (void) { - int i, j; - float eps; - - eps = 1.0e-6; + int i; - for(i = 0; i < 3; i++) - for(j = 0; j < 3; j++) - aa[i][j] = a[i][j]; + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + { + float eps = 1.0e-6; - minver(3, 3, eps); - for(i = 0; i < 3; i++) - for(j = 0; j < 3; j++) - a_i[i][j] = a[i][j]; + memcpy (a, a_ref, 3 * 3 * sizeof (a[0][0])); + minver(3, 3, eps); + memcpy (d, a, 3 * 3 * sizeof (a[0][0])); + memcpy (a, a_ref, 3 * 3 * sizeof (a[0][0])); + mmul(3, 3, 3, 3); + } - mmul(3, 3, 3, 3); return 0; } - - diff --git a/src/nbody/Makefile.am b/src/nbody/Makefile.am index 16b64441..b4caaa01 100644 --- a/src/nbody/Makefile.am +++ b/src/nbody/Makefile.am @@ -34,6 +34,7 @@ libnbody_la_SOURCES = nbody.c nbody_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libnbody.la \ + $(top_builddir)/support/libbeebsc.la \ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) \ $(LIBM) endif diff --git a/src/nbody/Makefile.in b/src/nbody/Makefile.in index 22c781b8..79d74d4b 100644 --- a/src/nbody/Makefile.in +++ b/src/nbody/Makefile.in @@ -171,6 +171,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_NBODY_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_NBODY_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_NBODY_TRUE@ libnbody.la \ +@ENABLED_BENCHMARK_NBODY_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_NBODY_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_NBODY_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_NBODY_TRUE@ $(am__DEPENDENCIES_1) $(LIBM) @@ -393,6 +394,7 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_NBODY_TRUE@nbody_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_NBODY_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_NBODY_TRUE@ libnbody.la \ +@ENABLED_BENCHMARK_NBODY_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_NBODY_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) \ @ENABLED_BENCHMARK_NBODY_TRUE@ $(LIBM) diff --git a/src/nbody/nbody.c b/src/nbody/nbody.c index 6c6b49b1..4157892e 100644 --- a/src/nbody/nbody.c +++ b/src/nbody/nbody.c @@ -1,4 +1,3 @@ - /* BEEBS nbody benchmark Copyright (C) 2014 Embecosm Limited and University of Bristol @@ -69,7 +68,7 @@ #include "support.h" -#define SCALE_FACTOR (REPEAT_FACTOR >> 8) +#define LOCAL_SCALE_FACTOR 1 #define PI 3.141592653589793 #define SOLAR_MASS ( 4 * PI * PI ) @@ -170,13 +169,18 @@ initialise_benchmark (void) int benchmark() { - int i; - offset_momentum(solar_bodies, BODIES_SIZE); - /*printf("%.9f\n", bodies_energy(solar_bodies, BODIES_SIZE));*/ - for (i = 0; i < 100; ++i) - bodies_energy(solar_bodies, BODIES_SIZE); - /*printf("%.9f\n", bodies_energy(solar_bodies, BODIES_SIZE));*/ - return 0; + int j; + + for (j = 0; j < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); j++) + { + int i; + offset_momentum(solar_bodies, BODIES_SIZE); + /*printf("%.9f\n", bodies_energy(solar_bodies, BODIES_SIZE));*/ + for (i = 0; i < 100; ++i) + bodies_energy(solar_bodies, BODIES_SIZE); + /*printf("%.9f\n", bodies_energy(solar_bodies, BODIES_SIZE));*/ + } + return 0; } int verify_benchmark(int unused) { diff --git a/src/ndes/Makefile.am b/src/ndes/Makefile.am index e5aed2ba..5b5c03eb 100644 --- a/src/ndes/Makefile.am +++ b/src/ndes/Makefile.am @@ -34,7 +34,8 @@ libndes_la_SOURCES = libndes.c ndes_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libndes.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) diff --git a/src/ndes/Makefile.in b/src/ndes/Makefile.in index 71317a93..228473a8 100644 --- a/src/ndes/Makefile.in +++ b/src/ndes/Makefile.in @@ -170,7 +170,9 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_NDES_TRUE@ndes_DEPENDENCIES = \ @ENABLED_BENCHMARK_NDES_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_NDES_TRUE@ $(top_builddir)/support/libsupport.la \ -@ENABLED_BENCHMARK_NDES_TRUE@ libndes.la $(am__DEPENDENCIES_1) \ +@ENABLED_BENCHMARK_NDES_TRUE@ libndes.la \ +@ENABLED_BENCHMARK_NDES_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_NDES_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_NDES_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_NDES_TRUE@ $(am__DEPENDENCIES_1) AM_V_P = $(am__v_P_@AM_V@) @@ -392,7 +394,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_NDES_TRUE@ndes_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_NDES_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_NDES_TRUE@ libndes.la \ -@ENABLED_BENCHMARK_NDES_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_NDES_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_NDES_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/ndes/libndes.c b/src/ndes/libndes.c index a63f98bf..c66bef67 100644 --- a/src/ndes/libndes.c +++ b/src/ndes/libndes.c @@ -25,7 +25,7 @@ /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) +#define LOCAL_SCALE_FACTOR 115 /* A read from this address will result in an known value of 1 */ /* #define KNOWN_VALUE (int)(*((char *)0x80200001)) Changed JG/Ebbe */ @@ -241,17 +241,22 @@ static int newkey, isw; int benchmark (void) { - des(inp, key, &newkey, isw, &out); + int i; + + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + { + inp.l = KNOWN_VALUE * 35; + inp.r = KNOWN_VALUE * 26; + key.l = KNOWN_VALUE * 2; + key.r = KNOWN_VALUE * 16; + newkey = value; + isw = value; + des(inp, key, &newkey, isw, &out); + } return 0; } void initialise_benchmark() { - inp.l = KNOWN_VALUE * 35; - inp.r = KNOWN_VALUE * 26; - key.l = KNOWN_VALUE * 2; - key.r = KNOWN_VALUE * 16; - newkey = value; - isw = value; } int verify_benchmark(int unused) { diff --git a/src/nettle-aes/Makefile.am b/src/nettle-aes/Makefile.am index 623e17ad..e01d8352 100644 --- a/src/nettle-aes/Makefile.am +++ b/src/nettle-aes/Makefile.am @@ -34,6 +34,7 @@ libnettle_aes_la_SOURCES = nettle-aes.c nettle_aes_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libnettle-aes.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) endif diff --git a/src/nettle-aes/Makefile.in b/src/nettle-aes/Makefile.in index 31bfb982..b8d04dde 100644 --- a/src/nettle-aes/Makefile.in +++ b/src/nettle-aes/Makefile.in @@ -172,6 +172,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_NETTLE_AES_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_NETTLE_AES_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_NETTLE_AES_TRUE@ libnettle-aes.la \ +@ENABLED_BENCHMARK_NETTLE_AES_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_NETTLE_AES_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_NETTLE_AES_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_NETTLE_AES_TRUE@ $(am__DEPENDENCIES_1) @@ -395,7 +396,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_NETTLE_AES_TRUE@nettle_aes_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_NETTLE_AES_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_NETTLE_AES_TRUE@ libnettle-aes.la \ -@ENABLED_BENCHMARK_NETTLE_AES_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_NETTLE_AES_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_NETTLE_AES_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/nettle-aes/nettle-aes.c b/src/nettle-aes/nettle-aes.c index 755b797b..3b1203f2 100644 --- a/src/nettle-aes/nettle-aes.c +++ b/src/nettle-aes/nettle-aes.c @@ -31,7 +31,7 @@ /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) +#define LOCAL_SCALE_FACTOR 66 // From nettle/macros.h @@ -1156,11 +1156,16 @@ initialise_benchmark (void) int benchmark (void) { - aes_set_encrypt_key(&encctx, 32, key); - aes_encrypt(&encctx, LEN, encrypted, plaintext); + int i; - aes_set_decrypt_key(&decctx, 32, key); - aes_decrypt(&decctx, LEN, decrypted, encrypted); + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + { + aes_set_encrypt_key(&encctx, 32, key); + aes_encrypt(&encctx, LEN, encrypted, plaintext); + + aes_set_decrypt_key(&decctx, 32, key); + aes_decrypt(&decctx, LEN, decrypted, encrypted); + } return 0; } diff --git a/src/nettle-arcfour/Makefile.am b/src/nettle-arcfour/Makefile.am index b84b985d..8c4e82ad 100644 --- a/src/nettle-arcfour/Makefile.am +++ b/src/nettle-arcfour/Makefile.am @@ -34,7 +34,8 @@ libnettle_arcfour_la_SOURCES = arcfour.c nettle_arcfour_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libnettle-arcfour.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) diff --git a/src/nettle-arcfour/Makefile.in b/src/nettle-arcfour/Makefile.in index 8870e4d7..19fe9f59 100644 --- a/src/nettle-arcfour/Makefile.in +++ b/src/nettle-arcfour/Makefile.in @@ -172,6 +172,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_NETTLE_ARCFOUR_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_NETTLE_ARCFOUR_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_NETTLE_ARCFOUR_TRUE@ libnettle-arcfour.la \ +@ENABLED_BENCHMARK_NETTLE_ARCFOUR_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_NETTLE_ARCFOUR_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_NETTLE_ARCFOUR_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_NETTLE_ARCFOUR_TRUE@ $(am__DEPENDENCIES_1) @@ -395,7 +396,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_NETTLE_ARCFOUR_TRUE@nettle_arcfour_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_NETTLE_ARCFOUR_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_NETTLE_ARCFOUR_TRUE@ libnettle-arcfour.la \ -@ENABLED_BENCHMARK_NETTLE_ARCFOUR_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_NETTLE_ARCFOUR_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_NETTLE_ARCFOUR_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/nettle-arcfour/arcfour.c b/src/nettle-arcfour/arcfour.c index 50943cab..79e66e16 100644 --- a/src/nettle-arcfour/arcfour.c +++ b/src/nettle-arcfour/arcfour.c @@ -1,4 +1,3 @@ - /* BEEBS nettle-arcfour benchmark Copyright (C) 2001, 2004 Niels Möller @@ -26,7 +25,7 @@ /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) +#define LOCAL_SCALE_FACTOR 321 static const uint8_t key[16] = { 0xf,0xe,0xd,0xc,0xb,0xa,0x9,0x8,0x7,0x6,0x5,0x4,0x3,0x2,0x1,0x0 @@ -99,12 +98,18 @@ initialise_benchmark (void) int benchmark (void) { - /* Encryption */ - arcfour_set_key(&arcfour_ctx, 16, key); - arcfour_crypt(&arcfour_ctx, 16, result, data); - /* Decryption */ - arcfour_set_key(&arcfour_ctx, 16, key); - arcfour_crypt(&arcfour_ctx, 16, result, result); + int i; + + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + { + /* Encryption */ + arcfour_set_key(&arcfour_ctx, 16, key); + arcfour_crypt(&arcfour_ctx, 16, result, data); + /* Decryption */ + arcfour_set_key(&arcfour_ctx, 16, key); + arcfour_crypt(&arcfour_ctx, 16, result, result); + } + return 0; } diff --git a/src/nettle-cast128/Makefile.am b/src/nettle-cast128/Makefile.am index 9beea895..7f44a739 100644 --- a/src/nettle-cast128/Makefile.am +++ b/src/nettle-cast128/Makefile.am @@ -34,7 +34,8 @@ libnettle_cast128_la_SOURCES = cast128.c nettle_cast128_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libnettle-cast128.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) endif diff --git a/src/nettle-cast128/Makefile.in b/src/nettle-cast128/Makefile.in index 6eef178e..71017afc 100644 --- a/src/nettle-cast128/Makefile.in +++ b/src/nettle-cast128/Makefile.in @@ -172,6 +172,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_NETTLE_CAST128_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_NETTLE_CAST128_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_NETTLE_CAST128_TRUE@ libnettle-cast128.la \ +@ENABLED_BENCHMARK_NETTLE_CAST128_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_NETTLE_CAST128_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_NETTLE_CAST128_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_NETTLE_CAST128_TRUE@ $(am__DEPENDENCIES_1) @@ -395,7 +396,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_NETTLE_CAST128_TRUE@nettle_cast128_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_NETTLE_CAST128_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_NETTLE_CAST128_TRUE@ libnettle-cast128.la \ -@ENABLED_BENCHMARK_NETTLE_CAST128_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_NETTLE_CAST128_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_NETTLE_CAST128_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/nettle-cast128/cast128.c b/src/nettle-cast128/cast128.c index 84bec19c..ed58d4d4 100644 --- a/src/nettle-cast128/cast128.c +++ b/src/nettle-cast128/cast128.c @@ -25,7 +25,7 @@ /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) +#define LOCAL_SCALE_FACTOR 2051 static const uint8_t key[16] = { 0xf,0xe,0xd,0xc,0xb,0xa,0x9,0x8,0x7,0x6,0x5,0x4,0x3,0x2,0x1,0x0 @@ -858,8 +858,13 @@ int initialise_benchmark() int benchmark (void) { - cast128_encrypt(&cast128_ctx, CAST128_KEY_SIZE, result, data); - cast128_decrypt(&cast128_ctx, CAST128_KEY_SIZE, result, result); + int i; + + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + { + cast128_encrypt(&cast128_ctx, CAST128_KEY_SIZE, result, data); + cast128_decrypt(&cast128_ctx, CAST128_KEY_SIZE, result, result); + } return 0; } diff --git a/src/nettle-des/Makefile.am b/src/nettle-des/Makefile.am index 39007cbc..b7191634 100644 --- a/src/nettle-des/Makefile.am +++ b/src/nettle-des/Makefile.am @@ -37,7 +37,8 @@ libnettle_des_la_SOURCES = des.c \ nettle_des_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libnettle-des.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) EXTRA_DIST = descore.README diff --git a/src/nettle-des/Makefile.in b/src/nettle-des/Makefile.in index 0e8e849c..a271a7d5 100644 --- a/src/nettle-des/Makefile.in +++ b/src/nettle-des/Makefile.in @@ -172,6 +172,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_NETTLE_DES_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_NETTLE_DES_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_NETTLE_DES_TRUE@ libnettle-des.la \ +@ENABLED_BENCHMARK_NETTLE_DES_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_NETTLE_DES_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_NETTLE_DES_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_NETTLE_DES_TRUE@ $(am__DEPENDENCIES_1) @@ -399,7 +400,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_NETTLE_DES_TRUE@nettle_des_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_NETTLE_DES_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_NETTLE_DES_TRUE@ libnettle-des.la \ -@ENABLED_BENCHMARK_NETTLE_DES_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_NETTLE_DES_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_NETTLE_DES_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) @ENABLED_BENCHMARK_NETTLE_DES_TRUE@EXTRA_DIST = descore.README all: all-am diff --git a/src/nettle-des/des.c b/src/nettle-des/des.c index c73e7e41..f201e57e 100644 --- a/src/nettle-des/des.c +++ b/src/nettle-des/des.c @@ -1,4 +1,3 @@ - /* BEEBS nettle-des benchmark Copyright (C) 1992 Dana L. How @@ -27,7 +26,7 @@ /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) +#define LOCAL_SCALE_FACTOR 1139 static const uint8_t data[16] = { 0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xa,0xb,0xc,0xd,0xe,0xf @@ -282,8 +281,14 @@ initialise_benchmark (void) int benchmark (void) { - des_encrypt(&des_ctx, 16, result, data); - des_decrypt(&des_ctx, 16, result, result); + int i; + + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + { + des_encrypt(&des_ctx, 16, result, data); + des_decrypt(&des_ctx, 16, result, result); + } + return 0; } diff --git a/src/nettle-md5/Makefile.am b/src/nettle-md5/Makefile.am index a83fe656..bb805072 100644 --- a/src/nettle-md5/Makefile.am +++ b/src/nettle-md5/Makefile.am @@ -34,6 +34,7 @@ libnettle_md5_la_SOURCES = md5.c nettle_md5_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libnettle-md5.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ +$(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) endif diff --git a/src/nettle-md5/Makefile.in b/src/nettle-md5/Makefile.in index ead92942..6b876826 100644 --- a/src/nettle-md5/Makefile.in +++ b/src/nettle-md5/Makefile.in @@ -172,6 +172,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_NETTLE_MD5_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_NETTLE_MD5_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_NETTLE_MD5_TRUE@ libnettle-md5.la \ +@ENABLED_BENCHMARK_NETTLE_MD5_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_NETTLE_MD5_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_NETTLE_MD5_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_NETTLE_MD5_TRUE@ $(am__DEPENDENCIES_1) @@ -395,7 +396,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_NETTLE_MD5_TRUE@nettle_md5_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_NETTLE_MD5_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_NETTLE_MD5_TRUE@ libnettle-md5.la \ -@ENABLED_BENCHMARK_NETTLE_MD5_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_NETTLE_MD5_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_NETTLE_MD5_TRUE@$(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/nettle-md5/md5.c b/src/nettle-md5/md5.c index bea9e3e5..4fec9dc0 100644 --- a/src/nettle-md5/md5.c +++ b/src/nettle-md5/md5.c @@ -26,7 +26,7 @@ /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) +#define LOCAL_SCALE_FACTOR 3666 static uint8_t input[64] = { 0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xa,0xb,0xc,0xd,0xe,0xf, @@ -175,8 +175,14 @@ initialise_benchmark (void) int benchmark (void) { - memcpy (digest, digest_ref, _MD5_DIGEST_LENGTH * sizeof (digest[0])); - _nettle_md5_compress(digest, input); + int i; + + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + { + memcpy (digest, digest_ref, _MD5_DIGEST_LENGTH * sizeof (digest[0])); + _nettle_md5_compress(digest, input); + } + return 0; } diff --git a/src/nettle-sha256/Makefile.am b/src/nettle-sha256/Makefile.am index 52523cee..1e3c2db2 100644 --- a/src/nettle-sha256/Makefile.am +++ b/src/nettle-sha256/Makefile.am @@ -34,6 +34,7 @@ libnettle_sha256_la_SOURCES = nettle-sha256.c nettle_sha256_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libnettle-sha256.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) endif diff --git a/src/nettle-sha256/Makefile.in b/src/nettle-sha256/Makefile.in index 1a05e990..714d90e0 100644 --- a/src/nettle-sha256/Makefile.in +++ b/src/nettle-sha256/Makefile.in @@ -173,6 +173,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_NETTLE_SHA256_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_NETTLE_SHA256_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_NETTLE_SHA256_TRUE@ libnettle-sha256.la \ +@ENABLED_BENCHMARK_NETTLE_SHA256_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_NETTLE_SHA256_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_NETTLE_SHA256_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_NETTLE_SHA256_TRUE@ $(am__DEPENDENCIES_1) @@ -396,7 +397,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_NETTLE_SHA256_TRUE@nettle_sha256_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_NETTLE_SHA256_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_NETTLE_SHA256_TRUE@ libnettle-sha256.la \ -@ENABLED_BENCHMARK_NETTLE_SHA256_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_NETTLE_SHA256_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_NETTLE_SHA256_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/nettle-sha256/nettle-sha256.c b/src/nettle-sha256/nettle-sha256.c index aa704b6f..c1b47396 100644 --- a/src/nettle-sha256/nettle-sha256.c +++ b/src/nettle-sha256/nettle-sha256.c @@ -31,7 +31,7 @@ /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) +#define LOCAL_SCALE_FACTOR 451 // From nettle/nettle-types.h @@ -442,17 +442,21 @@ verify_benchmark (int res __attribute ((unused)) ) void initialise_benchmark (void) { - memset (buffer, 0, sizeof(buffer)); } int benchmark (void) { - struct sha256_ctx ctx; - nettle_sha256.init (&ctx); - nettle_sha256.update (&ctx, sizeof (msg), msg); - nettle_sha256.digest (&ctx, nettle_sha256.digest_size, buffer); - return 0; -} + int i; + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + { + memset (buffer, 0, sizeof(buffer)); + struct sha256_ctx ctx; + nettle_sha256.init (&ctx); + nettle_sha256.update (&ctx, sizeof (msg), msg); + nettle_sha256.digest (&ctx, nettle_sha256.digest_size, buffer); + } + return 0; +} diff --git a/src/newlib-exp/Makefile.am b/src/newlib-exp/Makefile.am index b395c794..e00b2eaf 100644 --- a/src/newlib-exp/Makefile.am +++ b/src/newlib-exp/Makefile.am @@ -34,8 +34,8 @@ libnewlib_exp_la_SOURCES = ef_exp.c newlib_exp_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libnewlib-exp.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) - - + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) \ + $(LIBM) endif diff --git a/src/newlib-exp/Makefile.in b/src/newlib-exp/Makefile.in index a4c0512b..46381ccb 100644 --- a/src/newlib-exp/Makefile.in +++ b/src/newlib-exp/Makefile.in @@ -172,9 +172,11 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_NEWLIB_EXP_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_NEWLIB_EXP_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_NEWLIB_EXP_TRUE@ libnewlib-exp.la \ +@ENABLED_BENCHMARK_NEWLIB_EXP_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_NEWLIB_EXP_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_NEWLIB_EXP_TRUE@ $(am__DEPENDENCIES_1) \ -@ENABLED_BENCHMARK_NEWLIB_EXP_TRUE@ $(am__DEPENDENCIES_1) +@ENABLED_BENCHMARK_NEWLIB_EXP_TRUE@ $(am__DEPENDENCIES_1) \ +@ENABLED_BENCHMARK_NEWLIB_EXP_TRUE@ $(LIBM) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false @@ -395,7 +397,9 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_NEWLIB_EXP_TRUE@newlib_exp_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_NEWLIB_EXP_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_NEWLIB_EXP_TRUE@ libnewlib-exp.la \ -@ENABLED_BENCHMARK_NEWLIB_EXP_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_NEWLIB_EXP_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_NEWLIB_EXP_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) \ +@ENABLED_BENCHMARK_NEWLIB_EXP_TRUE@ $(LIBM) all: all-am diff --git a/src/newlib-exp/ef_exp.c b/src/newlib-exp/ef_exp.c index 30dbf56e..ca72371a 100644 --- a/src/newlib-exp/ef_exp.c +++ b/src/newlib-exp/ef_exp.c @@ -1,5 +1,3 @@ - - /* BEEBS newlib ef_exp implementation ==================================================== @@ -30,6 +28,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ +#include "math.h" #include "support.h" #include @@ -133,7 +132,7 @@ P5 = 4.1381369442e-08; /* 0x3331bb4c */ /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) +#define LOCAL_SCALE_FACTOR 9445 /* Tell the compiler not to optimize out calls in BENCHMARK. */ volatile float result = 0; @@ -145,7 +144,7 @@ volatile float result = 0; int verify_benchmark (int res __attribute ((unused)) ) { - return -1; + return fabs (233.204193 - result) < 1.0e-5; } @@ -158,12 +157,18 @@ initialise_benchmark (void) int benchmark (void) { - result = __ieee754_expf(1); - result = __ieee754_expf(2); - result = __ieee754_expf(3); - result = __ieee754_expf(4); - result = __ieee754_expf(5); - return 0; -} + int i; + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + { + result = 0.0; + result += __ieee754_expf(1); + result += __ieee754_expf(2); + result += __ieee754_expf(3); + result += __ieee754_expf(4); + result += __ieee754_expf(5); + } + + return 0; +} diff --git a/src/newlib-log/Makefile.am b/src/newlib-log/Makefile.am index 337cfb83..cb896b6e 100644 --- a/src/newlib-log/Makefile.am +++ b/src/newlib-log/Makefile.am @@ -34,7 +34,9 @@ libnewlib_log_la_SOURCES = ef_log.c newlib_log_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libnewlib-log.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) \ + $(LIBM) diff --git a/src/newlib-log/Makefile.in b/src/newlib-log/Makefile.in index 1c656186..b8febc33 100644 --- a/src/newlib-log/Makefile.in +++ b/src/newlib-log/Makefile.in @@ -172,9 +172,11 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_NEWLIB_LOG_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_NEWLIB_LOG_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_NEWLIB_LOG_TRUE@ libnewlib-log.la \ +@ENABLED_BENCHMARK_NEWLIB_LOG_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_NEWLIB_LOG_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_NEWLIB_LOG_TRUE@ $(am__DEPENDENCIES_1) \ -@ENABLED_BENCHMARK_NEWLIB_LOG_TRUE@ $(am__DEPENDENCIES_1) +@ENABLED_BENCHMARK_NEWLIB_LOG_TRUE@ $(am__DEPENDENCIES_1) \ +@ENABLED_BENCHMARK_NEWLIB_LOG_TRUE@ $(LIBM) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false @@ -395,7 +397,9 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_NEWLIB_LOG_TRUE@newlib_log_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_NEWLIB_LOG_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_NEWLIB_LOG_TRUE@ libnewlib-log.la \ -@ENABLED_BENCHMARK_NEWLIB_LOG_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_NEWLIB_LOG_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_NEWLIB_LOG_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) \ +@ENABLED_BENCHMARK_NEWLIB_LOG_TRUE@ $(LIBM) all: all-am diff --git a/src/newlib-log/ef_log.c b/src/newlib-log/ef_log.c index 4be10a62..ceb50033 100644 --- a/src/newlib-log/ef_log.c +++ b/src/newlib-log/ef_log.c @@ -1,5 +1,3 @@ - - /* BEEBS newlib ef_log implementation ==================================================== @@ -30,6 +28,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ +#include "math.h" #include "support.h" #include @@ -121,7 +120,7 @@ static const float zero = 0.0; /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) +#define LOCAL_SCALE_FACTOR 10308 /* Tell the compiler not to optimize out calls in BENCHMARK. */ volatile float result = 0; @@ -133,7 +132,7 @@ volatile float result = 0; int verify_benchmark (int res __attribute ((unused)) ) { - return -1; + return fabs (6.579251 - result) < 1.0e-5; } @@ -146,12 +145,18 @@ initialise_benchmark (void) int benchmark (void) { - result = __ieee754_logf(2); - result = __ieee754_logf(3); - result = __ieee754_logf(4); - result = __ieee754_logf(5); - result = __ieee754_logf(6); - return 0; -} + int i; + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + { + result = 0.0; + result += __ieee754_logf(2); + result += __ieee754_logf(3); + result += __ieee754_logf(4); + result += __ieee754_logf(5); + result += __ieee754_logf(6); + } + + return 0; +} diff --git a/src/newlib-mod/Makefile.am b/src/newlib-mod/Makefile.am index d5b084d5..0a1ba67d 100644 --- a/src/newlib-mod/Makefile.am +++ b/src/newlib-mod/Makefile.am @@ -34,8 +34,8 @@ libnewlib_mod_la_SOURCES = ef_mod.c newlib_mod_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libnewlib-mod.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) - - + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) \ + $(LIBM) endif diff --git a/src/newlib-mod/Makefile.in b/src/newlib-mod/Makefile.in index 02dd4006..95f0695a 100644 --- a/src/newlib-mod/Makefile.in +++ b/src/newlib-mod/Makefile.in @@ -172,9 +172,11 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_NEWLIB_MOD_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_NEWLIB_MOD_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_NEWLIB_MOD_TRUE@ libnewlib-mod.la \ +@ENABLED_BENCHMARK_NEWLIB_MOD_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_NEWLIB_MOD_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_NEWLIB_MOD_TRUE@ $(am__DEPENDENCIES_1) \ -@ENABLED_BENCHMARK_NEWLIB_MOD_TRUE@ $(am__DEPENDENCIES_1) +@ENABLED_BENCHMARK_NEWLIB_MOD_TRUE@ $(am__DEPENDENCIES_1) \ +@ENABLED_BENCHMARK_NEWLIB_MOD_TRUE@ $(LIBM) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false @@ -395,7 +397,9 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_NEWLIB_MOD_TRUE@newlib_mod_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_NEWLIB_MOD_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_NEWLIB_MOD_TRUE@ libnewlib-mod.la \ -@ENABLED_BENCHMARK_NEWLIB_MOD_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_NEWLIB_MOD_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_NEWLIB_MOD_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) \ +@ENABLED_BENCHMARK_NEWLIB_MOD_TRUE@ $(LIBM) all: all-am diff --git a/src/newlib-mod/ef_mod.c b/src/newlib-mod/ef_mod.c index a5f86490..78a20a90 100644 --- a/src/newlib-mod/ef_mod.c +++ b/src/newlib-mod/ef_mod.c @@ -1,5 +1,3 @@ - - /* BEEBS newlib ef_fmod implementation ==================================================== @@ -30,6 +28,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ +#include "math.h" #include "support.h" #include @@ -148,19 +147,16 @@ static const float one = 1.0, Zero[] = {0.0, -0.0,}; /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) +#define LOCAL_SCALE_FACTOR 10335 /* Tell the compiler not to optimize out calls in BENCHMARK. */ volatile float result = 0; - -/* This benchmark does not support verification */ - int verify_benchmark (int res __attribute ((unused)) ) { - return -1; + return fabs (21.8908005 - result) < 1.0e-5; } @@ -173,12 +169,18 @@ initialise_benchmark (void) int benchmark (void) { - result = __ieee754_fmodf(2.2353, 1234.5); - result = __ieee754_fmodf(3.2515, 2345.6); - result = __ieee754_fmodf(4.9346, 3456.7); - result = __ieee754_fmodf(5.2342, 4567.8); - result = __ieee754_fmodf(6.2352, 5678.9); - return 0; -} + int i; + + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + { + result = 0.0; + result += __ieee754_fmodf(2.2353, 1234.5); + result += __ieee754_fmodf(3.2515, 2345.6); + result += __ieee754_fmodf(4.9346, 3456.7); + result += __ieee754_fmodf(5.2342, 4567.8); + result += __ieee754_fmodf(6.2352, 5678.9); + } + return 0; +} diff --git a/src/newlib-sqrt/Makefile.am b/src/newlib-sqrt/Makefile.am index 05a579dc..7c56d7f9 100644 --- a/src/newlib-sqrt/Makefile.am +++ b/src/newlib-sqrt/Makefile.am @@ -34,7 +34,8 @@ libnewlib_sqrt_la_SOURCES = ef_sqrt.c newlib_sqrt_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libnewlib-sqrt.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) diff --git a/src/newlib-sqrt/Makefile.in b/src/newlib-sqrt/Makefile.in index 5ff5086c..35483773 100644 --- a/src/newlib-sqrt/Makefile.in +++ b/src/newlib-sqrt/Makefile.in @@ -173,6 +173,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_NEWLIB_SQRT_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_NEWLIB_SQRT_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_NEWLIB_SQRT_TRUE@ libnewlib-sqrt.la \ +@ENABLED_BENCHMARK_NEWLIB_SQRT_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_NEWLIB_SQRT_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_NEWLIB_SQRT_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_NEWLIB_SQRT_TRUE@ $(am__DEPENDENCIES_1) @@ -396,7 +397,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_NEWLIB_SQRT_TRUE@newlib_sqrt_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_NEWLIB_SQRT_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_NEWLIB_SQRT_TRUE@ libnewlib-sqrt.la \ -@ENABLED_BENCHMARK_NEWLIB_SQRT_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_NEWLIB_SQRT_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_NEWLIB_SQRT_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/newlib-sqrt/ef_sqrt.c b/src/newlib-sqrt/ef_sqrt.c index 043c1fb2..e4244c20 100644 --- a/src/newlib-sqrt/ef_sqrt.c +++ b/src/newlib-sqrt/ef_sqrt.c @@ -119,21 +119,27 @@ static const float one = 1.0, tiny=1.0e-30; /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) +#define LOCAL_SCALE_FACTOR 1828 /* Tell the compiler not to optimize out calls in BENCHMARK. */ volatile float result[6]; -static int a, b, c, d, e, f; +volatile int a, b, c, d, e, f; int benchmark (void) { - result[0] = __ieee754_sqrtf(a); - result[1] = __ieee754_sqrtf(b); - result[2] = __ieee754_sqrtf(c); - result[3] = __ieee754_sqrtf(d); - result[4] = __ieee754_sqrtf(e); - result[5] = __ieee754_sqrtf(f); + int i; + + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + { + result[0] = __ieee754_sqrtf(a); + result[1] = __ieee754_sqrtf(b); + result[2] = __ieee754_sqrtf(c); + result[3] = __ieee754_sqrtf(d); + result[4] = __ieee754_sqrtf(e); + result[5] = __ieee754_sqrtf(f); + } + return 0; } @@ -154,7 +160,6 @@ int verify_benchmark(int unused) 2.4494898319244384765625, 2.6457512378692626953125, 2.8284270763397216796875}; - //printf("{%f, %f, %f, %f, %f, %f};", result[0], result[1], result[2], result[3], result[4], result[5]); int i; for (i=0; i<6; i++) if (result[i] != exp[i]) diff --git a/src/ns/Makefile.am b/src/ns/Makefile.am index 251fb4af..16300e82 100644 --- a/src/ns/Makefile.am +++ b/src/ns/Makefile.am @@ -34,7 +34,8 @@ libns_la_SOURCES = libns.c ns_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libns.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) diff --git a/src/ns/Makefile.in b/src/ns/Makefile.in index 92cc8d2c..3be8a5b9 100644 --- a/src/ns/Makefile.in +++ b/src/ns/Makefile.in @@ -169,7 +169,9 @@ ns_OBJECTS = $(am_ns_OBJECTS) am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_NS_TRUE@ns_DEPENDENCIES = $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_NS_TRUE@ $(top_builddir)/support/libsupport.la \ -@ENABLED_BENCHMARK_NS_TRUE@ libns.la $(am__DEPENDENCIES_1) \ +@ENABLED_BENCHMARK_NS_TRUE@ libns.la \ +@ENABLED_BENCHMARK_NS_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_NS_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_NS_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_NS_TRUE@ $(am__DEPENDENCIES_1) AM_V_P = $(am__v_P_@AM_V@) @@ -391,7 +393,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_NS_TRUE@ns_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_NS_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_NS_TRUE@ libns.la \ -@ENABLED_BENCHMARK_NS_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_NS_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_NS_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/ns/libns.c b/src/ns/libns.c index 05c88c70..e9e55fb9 100644 --- a/src/ns/libns.c +++ b/src/ns/libns.c @@ -1,5 +1,3 @@ - - /* BEEBS ns benchmark Copyright (C) 2014 Embecosm Limited and University of Bristol @@ -25,7 +23,7 @@ /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 3) +#define LOCAL_SCALE_FACTOR 669 /* $Id: ns.c,v 1.2 2005/04/04 11:34:58 csg Exp $ */ @@ -45,1039 +43,503 @@ * Revision 1.2 2005/04/04 11:34:58 csg * again * - * Revision 1.1 2005/03/29 11:28:43 jgn - * New file. - * - * Revision 1.8 2001/05/07 10:05:37 ijae - * no message - * - * Revision 1.7 2001/04/25 12:48:15 ijae - * Corrected trace names. - * - * Revision 1.6 2001/04/25 12:17:47 ijae - * no message - * - * Revision 1.5 2001/04/25 12:11:31 ijae - * Compilable for V850 - * - * Revision 1.4 2001/04/25 12:09:55 ijae - * Now in target mode. - * - * Revision 1.3 2001/04/25 12:06:36 ijae - * Now 4D array. Compiles & runs on PC - * - * Revision 1.2 2001/04/25 11:59:38 ijae - * A bit more comments. - * - *-------------------------------------------------- */ - - - -/* -------------------------------------------------- * - - * Define TEST to check the # iterations in inner loop, - - * and that the right value is found and returned - - * -------------------------------------------------- */ - - - -//#define TEST - - - /* -------------------------------------------------- - * Array of keys and values, 4-dimensional just - * for the fun of it. - * -------------------------------------------------- */ - const int keys[5][5][5][5] = - { - // [0] - { - // [0][0] - { - {0,0,0,0,0}, - {0,0,0,0,0}, - {0,0,0,0,0}, - {0,0,0,0,0}, - {0,0,0,0,0} - }, - // [0][1] - { - {0,0,0,0,0}, - {0,0,0,0,0}, - {0,0,0,0,0}, - {0,0,0,0,0}, - {0,0,0,0,0} - }, - // [0][2] - { - {0,0,0,0,0}, - {0,0,0,0,0}, - {0,0,0,0,0}, - {0,0,0,0,0}, - {0,0,0,0,0} - }, - // [0][3] - { - {0,0,0,0,0}, - {0,0,0,0,0}, - {0,0,0,0,0}, - {0,0,0,0,0}, - {0,0,0,0,0} - }, - // [0][4] - { - {0,0,0,0,0}, - {0,0,0,0,0}, - {0,0,0,0,0}, - {0,0,0,0,0}, - {0,0,0,0,0} - } - }, - // [1] - { - // [1][0] - { - {1,1,1,1,1}, - {1,1,1,1,1}, - {1,1,1,1,1}, - {1,1,1,1,1}, - {1,1,1,1,1} - }, - // [1][1] - { - {1,1,1,1,1}, - {1,1,1,1,1}, - {1,1,1,1,1}, - {1,1,1,1,1}, - {1,1,1,1,1} - }, - // [1][2] - { - {1,1,1,1,1}, - {1,1,1,1,1}, - {1,1,1,1,1}, - {1,1,1,1,1}, - {1,1,1,1,1} - }, - // [1][3] - { - {1,1,1,1,1}, - {1,1,1,1,1}, - {1,1,1,1,1}, - {1,1,1,1,1}, - {1,1,1,1,1} - }, - // [1][4] - { - {1,1,1,1,1}, - {1,1,1,1,1}, - {1,1,1,1,1}, - {1,1,1,1,1}, - {1,1,1,1,1} - } - }, - // [2] - { - // [2][0] - { - {2,2,2,2,2}, - {2,2,2,2,2}, - {2,2,2,2,2}, - {2,2,2,2,2}, - {2,2,2,2,2} - }, - // [2][1] - { - {2,2,2,2,2}, - {2,2,2,2,2}, - {2,2,2,2,2}, - {2,2,2,2,2}, - {2,2,2,2,2} - }, - // [2][2] - { - {2,2,2,2,2}, - {2,2,2,2,2}, - {2,2,2,2,2}, - {2,2,2,2,2}, - {2,2,2,2,2} - }, - // [2][3] - { - {2,2,2,2,2}, - {2,2,2,2,2}, - {2,2,2,2,2}, - {2,2,2,2,2}, - {2,2,2,2,2} - }, - // [2][4] - { - {2,2,2,2,2}, - {2,2,2,2,2}, - {2,2,2,2,2}, - {2,2,2,2,2}, - {2,2,2,2,2} - } - }, - // [3] - { - // [3][0] - { - {3,3,3,3,3}, - {3,3,3,3,3}, - {3,3,3,3,3}, - {3,3,3,3,3}, - {3,3,3,3,3} - }, - // [3][1] - { - {3,3,3,3,3}, - {3,3,3,3,3}, - {3,3,3,3,3}, - {3,3,3,3,3}, - {3,3,3,3,3} - }, - // [3][2] - { - {3,3,3,3,3}, - {3,3,3,3,3}, - {3,3,3,3,3}, - {3,3,3,3,3}, - {3,3,3,3,3} - }, - // [3][3] - { - {3,3,3,3,3}, - {3,3,3,3,3}, - {3,3,3,3,3}, - {3,3,3,3,3}, - {3,3,3,3,3} - }, - // [3][4] - { - {3,3,3,3,3}, - {3,3,3,3,3}, - {3,3,3,3,3}, - {3,3,3,3,3}, - {3,3,3,3,3} - } - }, - // [4] - { - // [4][0] - { - {4,4,4,4,4}, - {4,4,4,4,4}, - {4,4,4,4,4}, - {4,4,4,4,4}, - {4,4,4,4,4} - }, - // [4][1] - { - {4,4,4,4,4}, - {4,4,4,4,4}, - {4,4,4,4,4}, - {4,4,4,4,4}, - {4,4,4,4,4} - }, - // [4][2] - { - {4,4,4,4,4}, - {4,4,4,4,4}, - {4,4,4,4,4}, - {4,4,4,4,4}, - {4,4,4,4,4} - }, - // [4][3] - { - {4,4,4,4,4}, - {4,4,4,4,4}, - {4,4,4,4,4}, - {4,4,4,4,4}, - {4,4,4,4,4} - }, - // [4][4] - { - {4,4,4,4,4}, - {4,4,4,4,4}, - {4,4,4,4,4}, - {4,4,4,4,4}, - - {4,4,4,4, - -#ifdef FIND_TARGET - - 400 - -#else - - 401 /* not searched for */ - -#endif - - } - + {4,4,4,4,401} } - } - }; - - - - - int answer[5][5][5][5] = - { - // [0] - { - // [0][0] - { - {123,123,123,123,123}, - {123,123,123,123,123}, - {123,123,123,123,123}, - {123,123,123,123,123}, - {123,123,123,123,123} - }, - // [0][1] - { - {123,123,123,123,123}, - {123,123,123,123,123}, - {123,123,123,123,123}, - {123,123,123,123,123}, - {123,123,123,123,123} - }, - // [0][2] - { - {123,123,123,123,123}, - {123,123,123,123,123}, - {123,123,123,123,123}, - {123,123,123,123,123}, - {123,123,123,123,123} - }, - // [0][3] - { - {123,123,123,123,123}, - {123,123,123,123,123}, - {123,123,123,123,123}, - {123,123,123,123,123}, - {123,123,123,123,123} - }, - // [0][4] - { - {123,123,123,123,123}, - {123,123,123,123,123}, - {123,123,123,123,123}, - {123,123,123,123,123}, - {123,123,123,123,123} - } - }, - // [1] - { - // [1][0] - { - {234,234,234,234,234}, - {234,234,234,234,234}, - {234,234,234,234,234}, - {234,234,234,234,234}, - {234,234,234,234,234} - }, - // [1][1] - { - {234,234,234,234,234}, - {234,234,234,234,234}, - {234,234,234,234,234}, - {234,234,234,234,234}, - {234,234,234,234,234} - }, - // [1][2] - { - {234,234,234,234,234}, - {234,234,234,234,234}, - {234,234,234,234,234}, - {234,234,234,234,234}, - {234,234,234,234,234} - }, - // [1][3] - { - {234,234,234,234,234}, - {234,234,234,234,234}, - {234,234,234,234,234}, - {234,234,234,234,234}, - {234,234,234,234,234} - }, - // [1][4] - { - {234,234,234,234,234}, - {234,234,234,234,234}, - {234,234,234,234,234}, - {234,234,234,234,234}, - {234,234,234,234,234} - } - }, - // [2] - { - // [2][0] - { - {345,345,345,345}, - {345,345,345,345}, - {345,345,345,345}, - {345,345,345,345}, - {345,345,345,345} - }, - // [2][1] - { - {345,345,345,345}, - {345,345,345,345}, - {345,345,345,345}, - {345,345,345,345}, - {345,345,345,345} - }, - // [2][2] - { - {345,345,345,345}, - {345,345,345,345}, - {345,345,345,345}, - {345,345,345,345}, - {345,345,345,345} - }, - // [2][3] - { - {345,345,345,345}, - {345,345,345,345}, - {345,345,345,345}, - {345,345,345,345}, - {345,345,345,345} - }, - // [2][4] - { - {345,345,345,345}, - {345,345,345,345}, - {345,345,345,345}, - {345,345,345,345}, - {345,345,345,345} - } - }, - // [3] - { - // [3][0] - { - {456,456,456,456,456}, - {456,456,456,456,456}, - {456,456,456,456,456}, - {456,456,456,456,456}, - {456,456,456,456,456} - }, - // [3][1] - { - {456,456,456,456,456}, - {456,456,456,456,456}, - {456,456,456,456,456}, - {456,456,456,456,456}, - {456,456,456,456,456} - }, - // [3][2] - { - {456,456,456,456,456}, - {456,456,456,456,456}, - {456,456,456,456,456}, - {456,456,456,456,456}, - {456,456,456,456,456} - }, - // [3][3] - { - {456,456,456,456,456}, - {456,456,456,456,456}, - {456,456,456,456,456}, - {456,456,456,456,456}, - {456,456,456,456,456} - }, - // [3][4] - { - {456,456,456,456,456}, - {456,456,456,456,456}, - {456,456,456,456,456}, - {456,456,456,456,456}, - {456,456,456,456,456} - } - }, - // [4] - { - // [4][0] - { - {567,567,567,567,567}, - {567,567,567,567,567}, - {567,567,567,567,567}, - {567,567,567,567,567}, - {567,567,567,567,567} - }, - // [4][1] - { - {567,567,567,567,567}, - {567,567,567,567,567}, - {567,567,567,567,567}, - {567,567,567,567,567}, - {567,567,567,567,567} - }, - // [4][2] - { - {567,567,567,567,567}, - {567,567,567,567,567}, - {567,567,567,567,567}, - {567,567,567,567,567}, - {567,567,567,567,567} - }, - // [4][3] - { - {567,567,567,567,567}, - {567,567,567,567,567}, - {567,567,567,567,567}, - {567,567,567,567,567}, - {567,567,567,567,567} - }, - // [4][4] - { - {567,567,567,567,567}, - {567,567,567,567,567}, - {567,567,567,567,567}, - {567,567,567,567,567}, - {567,567,567,567,1111} - } - } - }; - - - int foo(int x) - { - -#ifdef TEST - - int c = 0; /* counter for innerloop */ - -#endif - int i,j,k,l; - - for(i=0; i<5; i++) - for(j=0 ; j<5 ; j++) - for(k=0 ; k<5 ; k++) - for(l=0 ; l<5 ; l++) - { - -#ifdef TEST - - c++; - -#endif - if( keys[i][j][k][l] == x ) - { - -#ifdef TEST - - printf(" %d\n",c); - -#endif - return answer[i][j][k][l] + keys[i][j][k][l]; - } - } return -1; - } - - - - /* This benchmark does not support verification */ int -verify_benchmark (int res __attribute ((unused)) ) +verify_benchmark (int res) { - return -1; + return -1 == res; } @@ -1090,18 +552,11 @@ initialise_benchmark (void) int benchmark(void) { + volatile int r; + int i; -#ifdef TEST - - printf("result=%d\n",foo(400)); - -#else + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + r = foo (400); - foo(400); - -#endif - - return 0; + return r; } - - diff --git a/src/nsichneu/Makefile.am b/src/nsichneu/Makefile.am index 243cbaab..a0f1f124 100644 --- a/src/nsichneu/Makefile.am +++ b/src/nsichneu/Makefile.am @@ -34,7 +34,8 @@ libnsichneu_la_SOURCES = libnsichneu.c nsichneu_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libnsichneu.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) diff --git a/src/nsichneu/Makefile.in b/src/nsichneu/Makefile.in index 5ea0442a..e0ffe850 100644 --- a/src/nsichneu/Makefile.in +++ b/src/nsichneu/Makefile.in @@ -172,6 +172,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_NSICHNEU_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_NSICHNEU_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_NSICHNEU_TRUE@ libnsichneu.la \ +@ENABLED_BENCHMARK_NSICHNEU_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_NSICHNEU_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_NSICHNEU_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_NSICHNEU_TRUE@ $(am__DEPENDENCIES_1) @@ -394,7 +395,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_NSICHNEU_TRUE@nsichneu_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_NSICHNEU_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_NSICHNEU_TRUE@ libnsichneu.la \ -@ENABLED_BENCHMARK_NSICHNEU_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_NSICHNEU_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_NSICHNEU_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/nsichneu/libnsichneu.c b/src/nsichneu/libnsichneu.c index 066fa675..37b96a82 100644 --- a/src/nsichneu/libnsichneu.c +++ b/src/nsichneu/libnsichneu.c @@ -1,4 +1,3 @@ - /* BEEBS nsichneu benchmark Copyright (C) 2014 Embecosm Limited and University of Bristol @@ -24,7 +23,7 @@ /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 2) +#define LOCAL_SCALE_FACTOR 1339 /* $Id: nsichneu.c,v 1.3 2005/04/15 09:18:42 jgn Exp $ */ @@ -68,8 +67,6 @@ void trace(char *s) #endif - - volatile int P1_is_marked = 3; volatile long P1_marking_member_0[3]; volatile int P2_is_marked = 5; @@ -77,9 +74,6 @@ volatile long P2_marking_member_0[5]; volatile int P3_is_marked = 0; volatile long P3_marking_member_0[6]; - - - void initialise_benchmark (void) { @@ -89,4203 +83,4193 @@ initialise_benchmark (void) /**void NSicherNeu()**/ int benchmark() { - int dummy_i; -/* dummy_i = 17; Takes too much time */ - dummy_i = 2; + int j; - while (dummy_i > 0) { + for (j = 0; j < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); j++) + { + P1_is_marked = 3; + P2_is_marked = 5; + P3_is_marked = 0; - dummy_i--; /* Permutation for Place P1 : 0, 1, 2 */ /* Transition T1 */ if ( (P1_is_marked >= 3) && - (P3_is_marked + 3 <= 6) && - (P1_marking_member_0[1] == P1_marking_member_0[2]) ) { + (P3_is_marked + 3 <= 6) && + (P1_marking_member_0[1] == P1_marking_member_0[2]) ) { - long x; - long y; - long z; + long x; + long y; + long z; - x = P1_marking_member_0[0]; - y = P1_marking_member_0[1]; + x = P1_marking_member_0[0]; + y = P1_marking_member_0[1]; - /* Transition condition */ - if (x < y) { + /* Transition condition */ + if (x < y) { - /* demarking of input places */ - P1_is_marked -= 3; + /* demarking of input places */ + P1_is_marked -= 3; - /* preaction */ - z = x - y; + /* preaction */ + z = x - y; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = x; - P3_marking_member_0[P3_is_marked+1] = y; - P3_marking_member_0[P3_is_marked+2] = z; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = x; + P3_marking_member_0[P3_is_marked+1] = y; + P3_marking_member_0[P3_is_marked+2] = z; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P1 : 0, 2, 1 */ /* Transition T1 */ if ( (P1_is_marked >= 3) && - (P3_is_marked + 3 <= 6) && - (P1_marking_member_0[2] == P1_marking_member_0[1]) ) { + (P3_is_marked + 3 <= 6) && + (P1_marking_member_0[2] == P1_marking_member_0[1]) ) { - long x; - long y; - long z; + long x; + long y; + long z; - x = P1_marking_member_0[0]; - y = P1_marking_member_0[2]; + x = P1_marking_member_0[0]; + y = P1_marking_member_0[2]; - /* Transition condition */ - if ((x < y)) { + /* Transition condition */ + if ((x < y)) { - /* demarking of input places */ - P1_is_marked -= 3; + /* demarking of input places */ + P1_is_marked -= 3; - /* preaction */ - z = x - y; + /* preaction */ + z = x - y; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = x; - P3_marking_member_0[P3_is_marked+1] = y; - P3_marking_member_0[P3_is_marked+2] = z; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = x; + P3_marking_member_0[P3_is_marked+1] = y; + P3_marking_member_0[P3_is_marked+2] = z; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P1 : 1, 0, 2 */ /* Transition T1 */ if ( (P1_is_marked >= 3) && - (P3_is_marked + 3 <= 6) && - (P1_marking_member_0[0] == P1_marking_member_0[2]) ) { + (P3_is_marked + 3 <= 6) && + (P1_marking_member_0[0] == P1_marking_member_0[2]) ) { - long x; - long y; - long z; + long x; + long y; + long z; - x = P1_marking_member_0[1]; - y = P1_marking_member_0[0]; + x = P1_marking_member_0[1]; + y = P1_marking_member_0[0]; - /* Transition condition */ - if (x < y) { + /* Transition condition */ + if (x < y) { - /* demarking of input places */ - P1_is_marked -= 3; + /* demarking of input places */ + P1_is_marked -= 3; - /* preaction */ - z = x - y; + /* preaction */ + z = x - y; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = x; - P3_marking_member_0[P3_is_marked+1] = y; - P3_marking_member_0[P3_is_marked+2] = z; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = x; + P3_marking_member_0[P3_is_marked+1] = y; + P3_marking_member_0[P3_is_marked+2] = z; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P1 : 1, 2, 0 */ /* Transition T1 */ if ( (P1_is_marked >= 3) && - (P3_is_marked + 3 <= 6) && - (P1_marking_member_0[2] == P1_marking_member_0[0])) { + (P3_is_marked + 3 <= 6) && + (P1_marking_member_0[2] == P1_marking_member_0[0])) { - long x; - long y; - long z; + long x; + long y; + long z; - x = P1_marking_member_0[1]; - y = P1_marking_member_0[2]; + x = P1_marking_member_0[1]; + y = P1_marking_member_0[2]; - /* Transition condition */ - if ((x < y)) { + /* Transition condition */ + if ((x < y)) { - /* demarking of input places */ - P1_is_marked -= 3; + /* demarking of input places */ + P1_is_marked -= 3; - /* preaction */ - z = x - y; + /* preaction */ + z = x - y; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = x; - P3_marking_member_0[P3_is_marked+1] = y; - P3_marking_member_0[P3_is_marked+2] = z; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = x; + P3_marking_member_0[P3_is_marked+1] = y; + P3_marking_member_0[P3_is_marked+2] = z; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P1 : 2, 0, 1 */ /* Transition T1 */ if ( (P1_is_marked >= 3) && - (P3_is_marked + 3 <= 6) && - (P1_marking_member_0[0] == P1_marking_member_0[1]) ) { - long x; - long y; - long z; + (P3_is_marked + 3 <= 6) && + (P1_marking_member_0[0] == P1_marking_member_0[1]) ) { + long x; + long y; + long z; - x = P1_marking_member_0[2]; - y = P1_marking_member_0[0]; + x = P1_marking_member_0[2]; + y = P1_marking_member_0[0]; - /* Transition condition */ - if ((x < y)) { + /* Transition condition */ + if ((x < y)) { - /* demarking of input places */ - P1_is_marked -= 3; + /* demarking of input places */ + P1_is_marked -= 3; - /* preaction */ - z = x - y; + /* preaction */ + z = x - y; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = x; - P3_marking_member_0[P3_is_marked+1] = y; - P3_marking_member_0[P3_is_marked+2] = z; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = x; + P3_marking_member_0[P3_is_marked+1] = y; + P3_marking_member_0[P3_is_marked+2] = z; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P1 : 2, 1, 0 */ /* Transition T1 */ if ( (P1_is_marked >= 3) && - (P3_is_marked + 3 <= 6) && - (P1_marking_member_0[1] == P1_marking_member_0[0]) ) { - long x; - long y; - long z; + (P3_is_marked + 3 <= 6) && + (P1_marking_member_0[1] == P1_marking_member_0[0]) ) { + long x; + long y; + long z; - x = P1_marking_member_0[2]; - y = P1_marking_member_0[1]; + x = P1_marking_member_0[2]; + y = P1_marking_member_0[1]; - /* Transition condition */ - if ((x < y)) { + /* Transition condition */ + if ((x < y)) { - /* demarking of input places */ - P1_is_marked -= 3; + /* demarking of input places */ + P1_is_marked -= 3; - /* preaction */ - z = x - y; + /* preaction */ + z = x - y; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = x; - P3_marking_member_0[P3_is_marked+1] = y; - P3_marking_member_0[P3_is_marked+2] = z; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = x; + P3_marking_member_0[P3_is_marked+1] = y; + P3_marking_member_0[P3_is_marked+2] = z; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 0, 1, 2, 3 */ /* Transition T2 */ if ( (P2_is_marked >= 4) && - (((P3_is_marked + 3) <= 6)) && - ( ((P2_marking_member_0[1] == P2_marking_member_0[2])) && - ((P2_marking_member_0[1] == P2_marking_member_0[3])) ) ) { - long a; - long b; - long c; + (((P3_is_marked + 3) <= 6)) && + ( ((P2_marking_member_0[1] == P2_marking_member_0[2])) && + ((P2_marking_member_0[1] == P2_marking_member_0[3])) ) ) { + long a; + long b; + long c; - a = P2_marking_member_0[0]; - b = P2_marking_member_0[1]; + a = P2_marking_member_0[0]; + b = P2_marking_member_0[1]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_is_marked -= 4; + /* demarking of input places */ + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 0, 1, 3, 2 */ /* Transition T2 */ if ( (P2_is_marked >= 4) && - (((P3_is_marked + 3) <= 6)) && - ( (P2_marking_member_0[1] == P2_marking_member_0[3]) && - (P2_marking_member_0[1] == P2_marking_member_0[2]) ) ) { - long a; - long b; - long c; + (((P3_is_marked + 3) <= 6)) && + ( (P2_marking_member_0[1] == P2_marking_member_0[3]) && + (P2_marking_member_0[1] == P2_marking_member_0[2]) ) ) { + long a; + long b; + long c; - a = P2_marking_member_0[0]; - b = P2_marking_member_0[1]; + a = P2_marking_member_0[0]; + b = P2_marking_member_0[1]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_is_marked -= 4; + /* demarking of input places */ + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 0, 2, 1, 3 */ /* Transition T2 */ if ( (P2_is_marked >= 4) && - ((P3_is_marked + 3) <= 6) && - ( (P2_marking_member_0[2] == P2_marking_member_0[1]) && - (P2_marking_member_0[2] == P2_marking_member_0[3]) ) ) { - long a; - long b; - long c; + ((P3_is_marked + 3) <= 6) && + ( (P2_marking_member_0[2] == P2_marking_member_0[1]) && + (P2_marking_member_0[2] == P2_marking_member_0[3]) ) ) { + long a; + long b; + long c; - a = P2_marking_member_0[0]; - b = P2_marking_member_0[2]; + a = P2_marking_member_0[0]; + b = P2_marking_member_0[2]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_is_marked -= 4; + /* demarking of input places */ + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 0, 2, 3, 1 */ /* Transition T2 */ if ( (P2_is_marked >= 4) && - ((P3_is_marked + 3) <= 6) && - ( (P2_marking_member_0[2] == P2_marking_member_0[3]) && - (P2_marking_member_0[2] == P2_marking_member_0[1]) ) ) { - long a; - long b; - long c; + ((P3_is_marked + 3) <= 6) && + ( (P2_marking_member_0[2] == P2_marking_member_0[3]) && + (P2_marking_member_0[2] == P2_marking_member_0[1]) ) ) { + long a; + long b; + long c; - a = P2_marking_member_0[0]; - b = P2_marking_member_0[2]; + a = P2_marking_member_0[0]; + b = P2_marking_member_0[2]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_is_marked -= 4; + /* demarking of input places */ + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 0, 3, 1, 2 */ /* Transition T2 */ if ( (P2_is_marked >= 4) && - ((P3_is_marked + 3) <= 6) && - ( (P2_marking_member_0[3] == P2_marking_member_0[1]) && - (P2_marking_member_0[3] == P2_marking_member_0[2]) ) ) { - long a; - long b; - long c; + ((P3_is_marked + 3) <= 6) && + ( (P2_marking_member_0[3] == P2_marking_member_0[1]) && + (P2_marking_member_0[3] == P2_marking_member_0[2]) ) ) { + long a; + long b; + long c; - a = P2_marking_member_0[0]; - b = P2_marking_member_0[3]; + a = P2_marking_member_0[0]; + b = P2_marking_member_0[3]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_is_marked -= 4; + /* demarking of input places */ + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 0, 3, 2, 1 */ /* Transition T2 */ if ( (P2_is_marked >= 4) && - ((P3_is_marked + 3) <= 6) && - ( (P2_marking_member_0[3] == P2_marking_member_0[2]) && - (P2_marking_member_0[3] == P2_marking_member_0[1]) ) ) { - long a; - long b; - long c; + ((P3_is_marked + 3) <= 6) && + ( (P2_marking_member_0[3] == P2_marking_member_0[2]) && + (P2_marking_member_0[3] == P2_marking_member_0[1]) ) ) { + long a; + long b; + long c; - a = P2_marking_member_0[0]; - b = P2_marking_member_0[3]; + a = P2_marking_member_0[0]; + b = P2_marking_member_0[3]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_is_marked -= 4; + /* demarking of input places */ + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 1, 0, 2, 3 */ /* Transition T2 */ if ( (P2_is_marked >= 4) && - ((P3_is_marked + 3) <= 6) && - ( (P2_marking_member_0[0] == P2_marking_member_0[2]) && - (P2_marking_member_0[0] == P2_marking_member_0[3]) ) ) { - long a; - long b; - long c; + ((P3_is_marked + 3) <= 6) && + ( (P2_marking_member_0[0] == P2_marking_member_0[2]) && + (P2_marking_member_0[0] == P2_marking_member_0[3]) ) ) { + long a; + long b; + long c; - a = P2_marking_member_0[1]; - b = P2_marking_member_0[0]; + a = P2_marking_member_0[1]; + b = P2_marking_member_0[0]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_is_marked -= 4; + /* demarking of input places */ + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 1, 0, 3, 2 */ /* Transition T2 */ if ( (P2_is_marked >= 4) && - ((P3_is_marked + 3) <= 6) && - ( (P2_marking_member_0[0] == P2_marking_member_0[3]) && - (P2_marking_member_0[0] == P2_marking_member_0[2]) ) ) { - long a; - long b; - long c; + ((P3_is_marked + 3) <= 6) && + ( (P2_marking_member_0[0] == P2_marking_member_0[3]) && + (P2_marking_member_0[0] == P2_marking_member_0[2]) ) ) { + long a; + long b; + long c; - a = P2_marking_member_0[1]; - b = P2_marking_member_0[0]; + a = P2_marking_member_0[1]; + b = P2_marking_member_0[0]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_is_marked -= 4; + /* demarking of input places */ + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 1, 2, 0, 3 */ /* Transition T2 */ if ( (P2_is_marked >= 4) && - ((P3_is_marked + 3) <= 6) && - ( (P2_marking_member_0[2] == P2_marking_member_0[0]) && - (P2_marking_member_0[2] == P2_marking_member_0[3]) ) ) { - long a; - long b; - long c; + ((P3_is_marked + 3) <= 6) && + ( (P2_marking_member_0[2] == P2_marking_member_0[0]) && + (P2_marking_member_0[2] == P2_marking_member_0[3]) ) ) { + long a; + long b; + long c; - a = P2_marking_member_0[1]; - b = P2_marking_member_0[2]; + a = P2_marking_member_0[1]; + b = P2_marking_member_0[2]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_is_marked -= 4; + /* demarking of input places */ + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 1, 2, 3, 0 */ /* Transition T2 */ if ( (P2_is_marked >= 4) && - ((P3_is_marked + 3) <= 6) && - ( (P2_marking_member_0[2] == P2_marking_member_0[3]) && - (P2_marking_member_0[2] == P2_marking_member_0[0]) ) ) { - long a; - long b; - long c; - - a = P2_marking_member_0[1]; - b = P2_marking_member_0[2]; - - /* Transition condition */ - if ((b > a)) { - /* demarking of input places */ - P2_is_marked -= 4; - - /* preaction */ - c = a + b; - - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; - - } /* end of if (Transition condition) */ + ((P3_is_marked + 3) <= 6) && + ( (P2_marking_member_0[2] == P2_marking_member_0[3]) && + (P2_marking_member_0[2] == P2_marking_member_0[0]) ) ) { + long a; + long b; + long c; + + a = P2_marking_member_0[1]; + b = P2_marking_member_0[2]; + + /* Transition condition */ + if ((b > a)) { + /* demarking of input places */ + P2_is_marked -= 4; + + /* preaction */ + c = a + b; + + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; + + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 1, 3, 0, 2 */ /* Transition T2 */ if ( (P2_is_marked >= 4) && - ((P3_is_marked + 3) <= 6) && - ( (P2_marking_member_0[3] == P2_marking_member_0[0]) && - (P2_marking_member_0[3] == P2_marking_member_0[2]) ) ) { - long a; - long b; - long c; - - a = P2_marking_member_0[1]; - b = P2_marking_member_0[3]; - - /* Transition condition */ - if ((b > a)) { - /* demarking of input places */ - P2_is_marked -= 4; - - /* preaction */ - c = a + b; - - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; - - } /* end of if (Transition condition) */ + ((P3_is_marked + 3) <= 6) && + ( (P2_marking_member_0[3] == P2_marking_member_0[0]) && + (P2_marking_member_0[3] == P2_marking_member_0[2]) ) ) { + long a; + long b; + long c; + + a = P2_marking_member_0[1]; + b = P2_marking_member_0[3]; + + /* Transition condition */ + if ((b > a)) { + /* demarking of input places */ + P2_is_marked -= 4; + + /* preaction */ + c = a + b; + + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; + + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 1, 3, 2, 0 */ /* Transition T2 */ if ( (P2_is_marked >= 4) && - ((P3_is_marked + 3) <= 6) && - ( (P2_marking_member_0[3] == P2_marking_member_0[2]) && - (P2_marking_member_0[3] == P2_marking_member_0[0]) ) ) { - long a; - long b; - long c; + ((P3_is_marked + 3) <= 6) && + ( (P2_marking_member_0[3] == P2_marking_member_0[2]) && + (P2_marking_member_0[3] == P2_marking_member_0[0]) ) ) { + long a; + long b; + long c; - a = P2_marking_member_0[1]; - b = P2_marking_member_0[3]; + a = P2_marking_member_0[1]; + b = P2_marking_member_0[3]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_is_marked -= 4; + /* demarking of input places */ + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 2, 0, 1, 3 */ /* Transition T2 */ if ( (P2_is_marked >= 4) && - ((P3_is_marked + 3) <= 6) && - ( (P2_marking_member_0[0] == P2_marking_member_0[1]) && - (P2_marking_member_0[0] == P2_marking_member_0[3]) ) ) { - long a; - long b; - long c; - - a = P2_marking_member_0[2]; - b = P2_marking_member_0[0]; - - /* Transition condition */ - if ((b > a)) { - /* demarking of input places */ - P2_is_marked -= 4; - - /* preaction */ - c = a + b; - - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; - - } /* end of if (Transition condition) */ + ((P3_is_marked + 3) <= 6) && + ( (P2_marking_member_0[0] == P2_marking_member_0[1]) && + (P2_marking_member_0[0] == P2_marking_member_0[3]) ) ) { + long a; + long b; + long c; + + a = P2_marking_member_0[2]; + b = P2_marking_member_0[0]; + + /* Transition condition */ + if ((b > a)) { + /* demarking of input places */ + P2_is_marked -= 4; + + /* preaction */ + c = a + b; + + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; + + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 2, 0, 3, 1 */ /* Transition T2 */ if ( (P2_is_marked >= 4) && - ((P3_is_marked + 3) <= 6) && - ( (P2_marking_member_0[0] == P2_marking_member_0[3]) && - (P2_marking_member_0[0] == P2_marking_member_0[1]) ) ) { - long a; - long b; - long c; - - a = P2_marking_member_0[2]; - b = P2_marking_member_0[0]; - - /* Transition condition */ - if ((b > a)) { - /* demarking of input places */ - P2_is_marked -= 4; - - /* preaction */ - c = a + b; - - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; - - } /* end of if (Transition condition) */ + ((P3_is_marked + 3) <= 6) && + ( (P2_marking_member_0[0] == P2_marking_member_0[3]) && + (P2_marking_member_0[0] == P2_marking_member_0[1]) ) ) { + long a; + long b; + long c; + + a = P2_marking_member_0[2]; + b = P2_marking_member_0[0]; + + /* Transition condition */ + if ((b > a)) { + /* demarking of input places */ + P2_is_marked -= 4; + + /* preaction */ + c = a + b; + + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; + + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 2, 1, 0, 3 */ /* Transition T2 */ if ( (P2_is_marked >= 4) && - ((P3_is_marked + 3) <= 6) && - ( (P2_marking_member_0[1] == P2_marking_member_0[0]) && - (P2_marking_member_0[1] == P2_marking_member_0[3]) ) ) { - long a; - long b; - long c; - - a = P2_marking_member_0[2]; - b = P2_marking_member_0[1]; - - /* Transition condition */ - if ((b > a)) { - /* demarking of input places */ - P2_is_marked -= 4; - - /* preaction */ - c = a + b; - - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; - - } /* end of if (Transition condition) */ + ((P3_is_marked + 3) <= 6) && + ( (P2_marking_member_0[1] == P2_marking_member_0[0]) && + (P2_marking_member_0[1] == P2_marking_member_0[3]) ) ) { + long a; + long b; + long c; + + a = P2_marking_member_0[2]; + b = P2_marking_member_0[1]; + + /* Transition condition */ + if ((b > a)) { + /* demarking of input places */ + P2_is_marked -= 4; + + /* preaction */ + c = a + b; + + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; + + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 2, 1, 3, 0 */ /* Transition T2 */ if ( (P2_is_marked >= 4) && - ((P3_is_marked + 3) <= 6) && - ( (P2_marking_member_0[1] == P2_marking_member_0[3]) && - (P2_marking_member_0[1] == P2_marking_member_0[0]) ) ) { - long a; - long b; - long c; - - a = P2_marking_member_0[2]; - b = P2_marking_member_0[1]; - - /* Transition condition */ - if ((b > a)) { - /* demarking of input places */ - P2_is_marked -= 4; - - /* preaction */ - c = a + b; - - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; - - } /* end of if (Transition condition) */ + ((P3_is_marked + 3) <= 6) && + ( (P2_marking_member_0[1] == P2_marking_member_0[3]) && + (P2_marking_member_0[1] == P2_marking_member_0[0]) ) ) { + long a; + long b; + long c; + + a = P2_marking_member_0[2]; + b = P2_marking_member_0[1]; + + /* Transition condition */ + if ((b > a)) { + /* demarking of input places */ + P2_is_marked -= 4; + + /* preaction */ + c = a + b; + + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; + + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 2, 3, 0, 1 */ /* Transition T2 */ if ( (P2_is_marked >= 4) && - ((P3_is_marked + 3) <= 6) && - ( (P2_marking_member_0[3] == P2_marking_member_0[0]) && - (P2_marking_member_0[3] == P2_marking_member_0[1]) ) ) { - long a; - long b; - long c; - - a = P2_marking_member_0[2]; - b = P2_marking_member_0[3]; - - /* Transition condition */ - if ((b > a)) { - /* demarking of input places */ - P2_is_marked -= 4; - - /* preaction */ - c = a + b; - - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; - - } /* end of if (Transition condition) */ + ((P3_is_marked + 3) <= 6) && + ( (P2_marking_member_0[3] == P2_marking_member_0[0]) && + (P2_marking_member_0[3] == P2_marking_member_0[1]) ) ) { + long a; + long b; + long c; + + a = P2_marking_member_0[2]; + b = P2_marking_member_0[3]; + + /* Transition condition */ + if ((b > a)) { + /* demarking of input places */ + P2_is_marked -= 4; + + /* preaction */ + c = a + b; + + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; + + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 2, 3, 1, 0 */ /* Transition T2 */ if ( (P2_is_marked >= 4) && - ((P3_is_marked + 3) <= 6) && - ( (P2_marking_member_0[3] == P2_marking_member_0[1]) && - (P2_marking_member_0[3] == P2_marking_member_0[0]) ) ) { - long a; - long b; - long c; - - a = P2_marking_member_0[2]; - b = P2_marking_member_0[3]; - - /* Transition condition */ - if ((b > a)) { - /* demarking of input places */ - P2_is_marked -= 4; - - /* preaction */ - c = a + b; - - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; - - } /* end of if (Transition condition) */ + ((P3_is_marked + 3) <= 6) && + ( (P2_marking_member_0[3] == P2_marking_member_0[1]) && + (P2_marking_member_0[3] == P2_marking_member_0[0]) ) ) { + long a; + long b; + long c; + + a = P2_marking_member_0[2]; + b = P2_marking_member_0[3]; + + /* Transition condition */ + if ((b > a)) { + /* demarking of input places */ + P2_is_marked -= 4; + + /* preaction */ + c = a + b; + + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; + + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 3, 0, 1, 2 */ /* Transition T2 */ if ( (P2_is_marked >= 4) && - ((P3_is_marked + 3) <= 6) && - ( (P2_marking_member_0[0] == P2_marking_member_0[1]) && - (P2_marking_member_0[0] == P2_marking_member_0[2]) ) ) { - long a; - long b; - long c; + ((P3_is_marked + 3) <= 6) && + ( (P2_marking_member_0[0] == P2_marking_member_0[1]) && + (P2_marking_member_0[0] == P2_marking_member_0[2]) ) ) { + long a; + long b; + long c; - a = P2_marking_member_0[3]; - b = P2_marking_member_0[0]; + a = P2_marking_member_0[3]; + b = P2_marking_member_0[0]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_is_marked -= 4; + /* demarking of input places */ + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 3, 0, 2, 1 */ /* Transition T2 */ if ( (P2_is_marked >= 4) && - ( (P3_is_marked + 3) <= 6) && - ( ( P2_marking_member_0[0] == P2_marking_member_0[2]) && - ( P2_marking_member_0[0] == P2_marking_member_0[1]) ) ) { + ( (P3_is_marked + 3) <= 6) && + ( ( P2_marking_member_0[0] == P2_marking_member_0[2]) && + ( P2_marking_member_0[0] == P2_marking_member_0[1]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[3]; - b = P2_marking_member_0[0]; + a = P2_marking_member_0[3]; + b = P2_marking_member_0[0]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_is_marked -= 4; + /* demarking of input places */ + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 3, 1, 0, 2 */ /* Transition T2 */ if ( (P2_is_marked >= 4) && - ( (P3_is_marked + 3) <= 6) && - ( ( P2_marking_member_0[1] == P2_marking_member_0[0]) && - ( P2_marking_member_0[1] == P2_marking_member_0[2]) ) ) { + ( (P3_is_marked + 3) <= 6) && + ( ( P2_marking_member_0[1] == P2_marking_member_0[0]) && + ( P2_marking_member_0[1] == P2_marking_member_0[2]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[3]; - b = P2_marking_member_0[1]; + a = P2_marking_member_0[3]; + b = P2_marking_member_0[1]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_is_marked -= 4; + /* demarking of input places */ + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 3, 1, 2, 0 */ /* Transition T2 */ if ( (P2_is_marked >= 4) && - ( (P3_is_marked + 3) <= 6) && - ( ( P2_marking_member_0[1] == P2_marking_member_0[2]) && - ( P2_marking_member_0[1] == P2_marking_member_0[0]) ) ) { + ( (P3_is_marked + 3) <= 6) && + ( ( P2_marking_member_0[1] == P2_marking_member_0[2]) && + ( P2_marking_member_0[1] == P2_marking_member_0[0]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[3]; - b = P2_marking_member_0[1]; + a = P2_marking_member_0[3]; + b = P2_marking_member_0[1]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_is_marked -= 4; + /* demarking of input places */ + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 3, 2, 0, 1 */ /* Transition T2 */ if ( (P2_is_marked >= 4) && - ( (P3_is_marked + 3) <= 6) && - ( ( P2_marking_member_0[2] == P2_marking_member_0[0]) && - ( P2_marking_member_0[2] == P2_marking_member_0[1]) ) ) { + ( (P3_is_marked + 3) <= 6) && + ( ( P2_marking_member_0[2] == P2_marking_member_0[0]) && + ( P2_marking_member_0[2] == P2_marking_member_0[1]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[3]; - b = P2_marking_member_0[2]; + a = P2_marking_member_0[3]; + b = P2_marking_member_0[2]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_is_marked -= 4; + /* demarking of input places */ + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 3, 2, 1, 0 */ /* Transition T2 */ if ( (P2_is_marked >= 4) && - ( (P3_is_marked + 3) <= 6) && - ( ( P2_marking_member_0[2] == P2_marking_member_0[1]) && - ( P2_marking_member_0[2] == P2_marking_member_0[0]) ) ) { + ( (P3_is_marked + 3) <= 6) && + ( ( P2_marking_member_0[2] == P2_marking_member_0[1]) && + ( P2_marking_member_0[2] == P2_marking_member_0[0]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[3]; - b = P2_marking_member_0[2]; + a = P2_marking_member_0[3]; + b = P2_marking_member_0[2]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_is_marked -= 4; + /* demarking of input places */ + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 0, 1, 2, 4 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - ( ( P2_marking_member_0[1] == P2_marking_member_0[2]) && - ( P2_marking_member_0[1] == P2_marking_member_0[4]) ) ) { + ( (P3_is_marked + 3) <= 6) && + ( ( P2_marking_member_0[1] == P2_marking_member_0[2]) && + ( P2_marking_member_0[1] == P2_marking_member_0[4]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[0]; - b = P2_marking_member_0[1]; + a = P2_marking_member_0[0]; + b = P2_marking_member_0[1]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[3]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[3]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 0, 1, 3, 4 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - ( ( P2_marking_member_0[1] == P2_marking_member_0[3]) && - ( P2_marking_member_0[1] == P2_marking_member_0[4]) ) ) { + ( (P3_is_marked + 3) <= 6) && + ( ( P2_marking_member_0[1] == P2_marking_member_0[3]) && + ( P2_marking_member_0[1] == P2_marking_member_0[4]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[0]; - b = P2_marking_member_0[1]; + a = P2_marking_member_0[0]; + b = P2_marking_member_0[1]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[2]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[2]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 0, 1, 4, 2 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - ( ( P2_marking_member_0[1] == P2_marking_member_0[4]) && - ( P2_marking_member_0[1] == P2_marking_member_0[2]) ) ) { + ( (P3_is_marked + 3) <= 6) && + ( ( P2_marking_member_0[1] == P2_marking_member_0[4]) && + ( P2_marking_member_0[1] == P2_marking_member_0[2]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[0]; - b = P2_marking_member_0[1]; + a = P2_marking_member_0[0]; + b = P2_marking_member_0[1]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[3]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[3]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 0, 1, 4, 3 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - ( ( P2_marking_member_0[1] == P2_marking_member_0[4]) && - ( P2_marking_member_0[1] == P2_marking_member_0[3]) ) ) { + ( (P3_is_marked + 3) <= 6) && + ( ( P2_marking_member_0[1] == P2_marking_member_0[4]) && + ( P2_marking_member_0[1] == P2_marking_member_0[3]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[0]; - b = P2_marking_member_0[1]; + a = P2_marking_member_0[0]; + b = P2_marking_member_0[1]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[2]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[2]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 0, 2, 1, 4 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - ( ( P2_marking_member_0[2] == P2_marking_member_0[1]) && - ( P2_marking_member_0[2] == P2_marking_member_0[4]) ) ) { + ( (P3_is_marked + 3) <= 6) && + ( ( P2_marking_member_0[2] == P2_marking_member_0[1]) && + ( P2_marking_member_0[2] == P2_marking_member_0[4]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[0]; - b = P2_marking_member_0[2]; + a = P2_marking_member_0[0]; + b = P2_marking_member_0[2]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[3]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[3]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 0, 2, 3, 4 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - ( ( P2_marking_member_0[2] == P2_marking_member_0[3]) && - ( P2_marking_member_0[2] == P2_marking_member_0[4]) ) ) { + ( (P3_is_marked + 3) <= 6) && + ( ( P2_marking_member_0[2] == P2_marking_member_0[3]) && + ( P2_marking_member_0[2] == P2_marking_member_0[4]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[0]; - b = P2_marking_member_0[2]; + a = P2_marking_member_0[0]; + b = P2_marking_member_0[2]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[1]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[1]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 0, 2, 4, 1 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - ( ( P2_marking_member_0[2] == P2_marking_member_0[4]) && - ( P2_marking_member_0[2] == P2_marking_member_0[1]) ) ) { + ( (P3_is_marked + 3) <= 6) && + ( ( P2_marking_member_0[2] == P2_marking_member_0[4]) && + ( P2_marking_member_0[2] == P2_marking_member_0[1]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[0]; - b = P2_marking_member_0[2]; + a = P2_marking_member_0[0]; + b = P2_marking_member_0[2]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[3]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[3]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 0, 2, 4, 3 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - ( ( P2_marking_member_0[2] == P2_marking_member_0[4]) && - ( P2_marking_member_0[2] == P2_marking_member_0[3]) ) ) { + ( (P3_is_marked + 3) <= 6) && + ( ( P2_marking_member_0[2] == P2_marking_member_0[4]) && + ( P2_marking_member_0[2] == P2_marking_member_0[3]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[0]; - b = P2_marking_member_0[2]; + a = P2_marking_member_0[0]; + b = P2_marking_member_0[2]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[1]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[1]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 0, 3, 1, 4 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - ( ( P2_marking_member_0[3] == P2_marking_member_0[1]) && - ( P2_marking_member_0[3] == P2_marking_member_0[4]) ) ) { + ( (P3_is_marked + 3) <= 6) && + ( ( P2_marking_member_0[3] == P2_marking_member_0[1]) && + ( P2_marking_member_0[3] == P2_marking_member_0[4]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[0]; - b = P2_marking_member_0[3]; + a = P2_marking_member_0[0]; + b = P2_marking_member_0[3]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[2]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[2]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 0, 3, 2, 4 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - ( ( P2_marking_member_0[3] == P2_marking_member_0[2]) && - ( P2_marking_member_0[3] == P2_marking_member_0[4]) ) ) { + ( (P3_is_marked + 3) <= 6) && + ( ( P2_marking_member_0[3] == P2_marking_member_0[2]) && + ( P2_marking_member_0[3] == P2_marking_member_0[4]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[0]; - b = P2_marking_member_0[3]; + a = P2_marking_member_0[0]; + b = P2_marking_member_0[3]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[1]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[1]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 0, 3, 4, 1 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - ( ( P2_marking_member_0[3] == P2_marking_member_0[4]) && - ( P2_marking_member_0[3] == P2_marking_member_0[1]) ) ) { + ( (P3_is_marked + 3) <= 6) && + ( ( P2_marking_member_0[3] == P2_marking_member_0[4]) && + ( P2_marking_member_0[3] == P2_marking_member_0[1]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[0]; - b = P2_marking_member_0[3]; + a = P2_marking_member_0[0]; + b = P2_marking_member_0[3]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[2]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[2]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 0, 3, 4, 2 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - ( ( P2_marking_member_0[3] == P2_marking_member_0[4]) && - ( P2_marking_member_0[3] == P2_marking_member_0[2]) ) ) { + ( (P3_is_marked + 3) <= 6) && + ( ( P2_marking_member_0[3] == P2_marking_member_0[4]) && + ( P2_marking_member_0[3] == P2_marking_member_0[2]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[0]; - b = P2_marking_member_0[3]; + a = P2_marking_member_0[0]; + b = P2_marking_member_0[3]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[1]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[1]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 0, 4, 1, 2 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - ( ( P2_marking_member_0[4] == P2_marking_member_0[1]) && - ( P2_marking_member_0[4] == P2_marking_member_0[2]) ) ) { + ( (P3_is_marked + 3) <= 6) && + ( ( P2_marking_member_0[4] == P2_marking_member_0[1]) && + ( P2_marking_member_0[4] == P2_marking_member_0[2]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[0]; - b = P2_marking_member_0[4]; + a = P2_marking_member_0[0]; + b = P2_marking_member_0[4]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[3]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[3]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 0, 4, 1, 3 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - ( ( P2_marking_member_0[4] == P2_marking_member_0[1]) && - ( P2_marking_member_0[4] == P2_marking_member_0[3]) ) ) { + ( (P3_is_marked + 3) <= 6) && + ( ( P2_marking_member_0[4] == P2_marking_member_0[1]) && + ( P2_marking_member_0[4] == P2_marking_member_0[3]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[0]; - b = P2_marking_member_0[4]; + a = P2_marking_member_0[0]; + b = P2_marking_member_0[4]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[2]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[2]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 0, 4, 2, 1 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - ( ( P2_marking_member_0[4] == P2_marking_member_0[2]) && - ( P2_marking_member_0[4] == P2_marking_member_0[1]) ) ) { + ( (P3_is_marked + 3) <= 6) && + ( ( P2_marking_member_0[4] == P2_marking_member_0[2]) && + ( P2_marking_member_0[4] == P2_marking_member_0[1]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[0]; - b = P2_marking_member_0[4]; + a = P2_marking_member_0[0]; + b = P2_marking_member_0[4]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[3]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[3]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 0, 4, 2, 3 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - ( ( P2_marking_member_0[4] == P2_marking_member_0[2]) && - ( P2_marking_member_0[4] == P2_marking_member_0[3]) ) ) { + ( (P3_is_marked + 3) <= 6) && + ( ( P2_marking_member_0[4] == P2_marking_member_0[2]) && + ( P2_marking_member_0[4] == P2_marking_member_0[3]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[0]; - b = P2_marking_member_0[4]; + a = P2_marking_member_0[0]; + b = P2_marking_member_0[4]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[1]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[1]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 0, 4, 3, 1 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - ( ( P2_marking_member_0[4] == P2_marking_member_0[3]) && - ( P2_marking_member_0[4] == P2_marking_member_0[1]) ) ) { + ( (P3_is_marked + 3) <= 6) && + ( ( P2_marking_member_0[4] == P2_marking_member_0[3]) && + ( P2_marking_member_0[4] == P2_marking_member_0[1]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[0]; - b = P2_marking_member_0[4]; + a = P2_marking_member_0[0]; + b = P2_marking_member_0[4]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[2]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[2]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 0, 4, 3, 2 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - ( ( P2_marking_member_0[4] == P2_marking_member_0[3]) && - ( P2_marking_member_0[4] == P2_marking_member_0[2]) ) ) { + ( (P3_is_marked + 3) <= 6) && + ( ( P2_marking_member_0[4] == P2_marking_member_0[3]) && + ( P2_marking_member_0[4] == P2_marking_member_0[2]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[0]; - b = P2_marking_member_0[4]; + a = P2_marking_member_0[0]; + b = P2_marking_member_0[4]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[1]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[1]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 1, 0, 2, 4 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[0] == P2_marking_member_0[2]) && - ( P2_marking_member_0[0] == P2_marking_member_0[4]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[0] == P2_marking_member_0[2]) && + ( P2_marking_member_0[0] == P2_marking_member_0[4]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[1]; - b = P2_marking_member_0[0]; + a = P2_marking_member_0[1]; + b = P2_marking_member_0[0]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[3]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[3]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 1, 0, 3, 4 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[0] == P2_marking_member_0[3]) && - ( P2_marking_member_0[0] == P2_marking_member_0[4]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[0] == P2_marking_member_0[3]) && + ( P2_marking_member_0[0] == P2_marking_member_0[4]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[1]; - b = P2_marking_member_0[0]; + a = P2_marking_member_0[1]; + b = P2_marking_member_0[0]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[2]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[2]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 1, 0, 4, 2 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[0] == P2_marking_member_0[4]) && - ( P2_marking_member_0[0] == P2_marking_member_0[2]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[0] == P2_marking_member_0[4]) && + ( P2_marking_member_0[0] == P2_marking_member_0[2]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[1]; - b = P2_marking_member_0[0]; + a = P2_marking_member_0[1]; + b = P2_marking_member_0[0]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[3]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[3]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 1, 0, 4, 3 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[0] == P2_marking_member_0[4]) && - ( P2_marking_member_0[0] == P2_marking_member_0[3]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[0] == P2_marking_member_0[4]) && + ( P2_marking_member_0[0] == P2_marking_member_0[3]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[1]; - b = P2_marking_member_0[0]; + a = P2_marking_member_0[1]; + b = P2_marking_member_0[0]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[2]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[2]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 1, 2, 0, 4 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[2] == P2_marking_member_0[0]) && - ( P2_marking_member_0[2] == P2_marking_member_0[4]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[2] == P2_marking_member_0[0]) && + ( P2_marking_member_0[2] == P2_marking_member_0[4]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[1]; - b = P2_marking_member_0[2]; + a = P2_marking_member_0[1]; + b = P2_marking_member_0[2]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[3]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[3]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 1, 2, 3, 4 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[2] == P2_marking_member_0[3]) && - ( P2_marking_member_0[2] == P2_marking_member_0[4]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[2] == P2_marking_member_0[3]) && + ( P2_marking_member_0[2] == P2_marking_member_0[4]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[1]; - b = P2_marking_member_0[2]; + a = P2_marking_member_0[1]; + b = P2_marking_member_0[2]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_is_marked -= 4; + /* demarking of input places */ + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 1, 2, 4, 0 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[2] == P2_marking_member_0[4]) && - ( P2_marking_member_0[2] == P2_marking_member_0[0]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[2] == P2_marking_member_0[4]) && + ( P2_marking_member_0[2] == P2_marking_member_0[0]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[1]; - b = P2_marking_member_0[2]; + a = P2_marking_member_0[1]; + b = P2_marking_member_0[2]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[3]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[3]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 1, 2, 4, 3 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[2] == P2_marking_member_0[4]) && - ( P2_marking_member_0[2] == P2_marking_member_0[3]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[2] == P2_marking_member_0[4]) && + ( P2_marking_member_0[2] == P2_marking_member_0[3]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[1]; - b = P2_marking_member_0[2]; + a = P2_marking_member_0[1]; + b = P2_marking_member_0[2]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_is_marked -= 4; + /* demarking of input places */ + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 1, 3, 0, 4 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[3] == P2_marking_member_0[0]) && - ( P2_marking_member_0[3] == P2_marking_member_0[4]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[3] == P2_marking_member_0[0]) && + ( P2_marking_member_0[3] == P2_marking_member_0[4]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[1]; - b = P2_marking_member_0[3]; + a = P2_marking_member_0[1]; + b = P2_marking_member_0[3]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[2]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[2]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 1, 3, 2, 4 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[3] == P2_marking_member_0[2]) && - ( P2_marking_member_0[3] == P2_marking_member_0[4]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[3] == P2_marking_member_0[2]) && + ( P2_marking_member_0[3] == P2_marking_member_0[4]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[1]; - b = P2_marking_member_0[3]; + a = P2_marking_member_0[1]; + b = P2_marking_member_0[3]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_is_marked -= 4; + /* demarking of input places */ + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 1, 3, 4, 0 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[3] == P2_marking_member_0[4]) && - ( P2_marking_member_0[3] == P2_marking_member_0[0]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[3] == P2_marking_member_0[4]) && + ( P2_marking_member_0[3] == P2_marking_member_0[0]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[1]; - b = P2_marking_member_0[3]; + a = P2_marking_member_0[1]; + b = P2_marking_member_0[3]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[2]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[2]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 1, 3, 4, 2 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[3] == P2_marking_member_0[4]) && - ( P2_marking_member_0[3] == P2_marking_member_0[2]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[3] == P2_marking_member_0[4]) && + ( P2_marking_member_0[3] == P2_marking_member_0[2]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[1]; - b = P2_marking_member_0[3]; + a = P2_marking_member_0[1]; + b = P2_marking_member_0[3]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_is_marked -= 4; + /* demarking of input places */ + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 1, 4, 0, 2 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[4] == P2_marking_member_0[0]) && - ( P2_marking_member_0[4] == P2_marking_member_0[2]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[4] == P2_marking_member_0[0]) && + ( P2_marking_member_0[4] == P2_marking_member_0[2]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[1]; - b = P2_marking_member_0[4]; + a = P2_marking_member_0[1]; + b = P2_marking_member_0[4]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[3]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[3]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 1, 4, 0, 3 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[4] == P2_marking_member_0[0]) && - ( P2_marking_member_0[4] == P2_marking_member_0[3]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[4] == P2_marking_member_0[0]) && + ( P2_marking_member_0[4] == P2_marking_member_0[3]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[1]; - b = P2_marking_member_0[4]; + a = P2_marking_member_0[1]; + b = P2_marking_member_0[4]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[2]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[2]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 1, 4, 2, 0 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[4] == P2_marking_member_0[2]) && - ( P2_marking_member_0[4] == P2_marking_member_0[0]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[4] == P2_marking_member_0[2]) && + ( P2_marking_member_0[4] == P2_marking_member_0[0]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[1]; - b = P2_marking_member_0[4]; + a = P2_marking_member_0[1]; + b = P2_marking_member_0[4]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[3]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[3]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 1, 4, 2, 3 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[4] == P2_marking_member_0[2]) && - ( P2_marking_member_0[4] == P2_marking_member_0[3]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[4] == P2_marking_member_0[2]) && + ( P2_marking_member_0[4] == P2_marking_member_0[3]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[1]; - b = P2_marking_member_0[4]; + a = P2_marking_member_0[1]; + b = P2_marking_member_0[4]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_is_marked -= 4; + /* demarking of input places */ + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 1, 4, 3, 0 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[4] == P2_marking_member_0[3]) && - ( P2_marking_member_0[4] == P2_marking_member_0[0]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[4] == P2_marking_member_0[3]) && + ( P2_marking_member_0[4] == P2_marking_member_0[0]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[1]; - b = P2_marking_member_0[4]; + a = P2_marking_member_0[1]; + b = P2_marking_member_0[4]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[2]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[2]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 1, 4, 3, 2 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[4] == P2_marking_member_0[3]) && - ( P2_marking_member_0[4] == P2_marking_member_0[2]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[4] == P2_marking_member_0[3]) && + ( P2_marking_member_0[4] == P2_marking_member_0[2]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[1]; - b = P2_marking_member_0[4]; + a = P2_marking_member_0[1]; + b = P2_marking_member_0[4]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_is_marked -= 4; + /* demarking of input places */ + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 2, 0, 1, 4 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[0] == P2_marking_member_0[1]) && - ( P2_marking_member_0[0] == P2_marking_member_0[4]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[0] == P2_marking_member_0[1]) && + ( P2_marking_member_0[0] == P2_marking_member_0[4]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[2]; - b = P2_marking_member_0[0]; + a = P2_marking_member_0[2]; + b = P2_marking_member_0[0]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[3]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[3]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 2, 0, 3, 4 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[0] == P2_marking_member_0[3]) && - ( P2_marking_member_0[0] == P2_marking_member_0[4]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[0] == P2_marking_member_0[3]) && + ( P2_marking_member_0[0] == P2_marking_member_0[4]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[2]; - b = P2_marking_member_0[0]; + a = P2_marking_member_0[2]; + b = P2_marking_member_0[0]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[1]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[1]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 2, 0, 4, 1 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[0] == P2_marking_member_0[4]) && - ( P2_marking_member_0[0] == P2_marking_member_0[1]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[0] == P2_marking_member_0[4]) && + ( P2_marking_member_0[0] == P2_marking_member_0[1]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[2]; - b = P2_marking_member_0[0]; + a = P2_marking_member_0[2]; + b = P2_marking_member_0[0]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[3]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[3]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 2, 0, 4, 3 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[0] == P2_marking_member_0[4]) && - ( P2_marking_member_0[0] == P2_marking_member_0[3]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[0] == P2_marking_member_0[4]) && + ( P2_marking_member_0[0] == P2_marking_member_0[3]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[2]; - b = P2_marking_member_0[0]; + a = P2_marking_member_0[2]; + b = P2_marking_member_0[0]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[1]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[1]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 2, 1, 0, 4 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[1] == P2_marking_member_0[0]) && - ( P2_marking_member_0[1] == P2_marking_member_0[4]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[1] == P2_marking_member_0[0]) && + ( P2_marking_member_0[1] == P2_marking_member_0[4]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[2]; - b = P2_marking_member_0[1]; + a = P2_marking_member_0[2]; + b = P2_marking_member_0[1]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[3]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[3]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 2, 1, 3, 4 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[1] == P2_marking_member_0[3]) && - ( P2_marking_member_0[1] == P2_marking_member_0[4]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[1] == P2_marking_member_0[3]) && + ( P2_marking_member_0[1] == P2_marking_member_0[4]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[2]; - b = P2_marking_member_0[1]; + a = P2_marking_member_0[2]; + b = P2_marking_member_0[1]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_is_marked -= 4; + /* demarking of input places */ + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 2, 1, 4, 0 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[1] == P2_marking_member_0[4]) && - ( P2_marking_member_0[1] == P2_marking_member_0[0]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[1] == P2_marking_member_0[4]) && + ( P2_marking_member_0[1] == P2_marking_member_0[0]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[2]; - b = P2_marking_member_0[1]; + a = P2_marking_member_0[2]; + b = P2_marking_member_0[1]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[3]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[3]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 2, 1, 4, 3 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[1] == P2_marking_member_0[4]) && - ( P2_marking_member_0[1] == P2_marking_member_0[3]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[1] == P2_marking_member_0[4]) && + ( P2_marking_member_0[1] == P2_marking_member_0[3]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[2]; - b = P2_marking_member_0[1]; + a = P2_marking_member_0[2]; + b = P2_marking_member_0[1]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_is_marked -= 4; + /* demarking of input places */ + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 2, 3, 0, 4 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[3] == P2_marking_member_0[0]) && - ( P2_marking_member_0[3] == P2_marking_member_0[4]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[3] == P2_marking_member_0[0]) && + ( P2_marking_member_0[3] == P2_marking_member_0[4]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[2]; - b = P2_marking_member_0[3]; + a = P2_marking_member_0[2]; + b = P2_marking_member_0[3]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[1]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[1]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 2, 3, 1, 4 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[3] == P2_marking_member_0[1]) && - ( P2_marking_member_0[3] == P2_marking_member_0[4]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[3] == P2_marking_member_0[1]) && + ( P2_marking_member_0[3] == P2_marking_member_0[4]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[2]; - b = P2_marking_member_0[3]; + a = P2_marking_member_0[2]; + b = P2_marking_member_0[3]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_is_marked -= 4; + /* demarking of input places */ + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 2, 3, 4, 0 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[3] == P2_marking_member_0[4]) && - ( P2_marking_member_0[3] == P2_marking_member_0[0]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[3] == P2_marking_member_0[4]) && + ( P2_marking_member_0[3] == P2_marking_member_0[0]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[2]; - b = P2_marking_member_0[3]; + a = P2_marking_member_0[2]; + b = P2_marking_member_0[3]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[1]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[1]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 2, 3, 4, 1 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[3] == P2_marking_member_0[4]) && - ( P2_marking_member_0[3] == P2_marking_member_0[1]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[3] == P2_marking_member_0[4]) && + ( P2_marking_member_0[3] == P2_marking_member_0[1]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[2]; - b = P2_marking_member_0[3]; + a = P2_marking_member_0[2]; + b = P2_marking_member_0[3]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_is_marked -= 4; + /* demarking of input places */ + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 2, 4, 0, 1 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[4] == P2_marking_member_0[0]) && - ( P2_marking_member_0[4] == P2_marking_member_0[1]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[4] == P2_marking_member_0[0]) && + ( P2_marking_member_0[4] == P2_marking_member_0[1]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[2]; - b = P2_marking_member_0[4]; + a = P2_marking_member_0[2]; + b = P2_marking_member_0[4]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[3]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[3]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 2, 4, 0, 3 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[4] == P2_marking_member_0[0]) && - ( P2_marking_member_0[4] == P2_marking_member_0[3]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[4] == P2_marking_member_0[0]) && + ( P2_marking_member_0[4] == P2_marking_member_0[3]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[2]; - b = P2_marking_member_0[4]; + a = P2_marking_member_0[2]; + b = P2_marking_member_0[4]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[1]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[1]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 2, 4, 1, 0 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[4] == P2_marking_member_0[1]) && - ( P2_marking_member_0[4] == P2_marking_member_0[0]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[4] == P2_marking_member_0[1]) && + ( P2_marking_member_0[4] == P2_marking_member_0[0]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[2]; - b = P2_marking_member_0[4]; + a = P2_marking_member_0[2]; + b = P2_marking_member_0[4]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[3]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[3]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 2, 4, 1, 3 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[4] == P2_marking_member_0[1]) && - ( P2_marking_member_0[4] == P2_marking_member_0[3]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[4] == P2_marking_member_0[1]) && + ( P2_marking_member_0[4] == P2_marking_member_0[3]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[2]; - b = P2_marking_member_0[4]; + a = P2_marking_member_0[2]; + b = P2_marking_member_0[4]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_is_marked -= 4; + /* demarking of input places */ + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 2, 4, 3, 0 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[4] == P2_marking_member_0[3]) && - ( P2_marking_member_0[4] == P2_marking_member_0[0]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[4] == P2_marking_member_0[3]) && + ( P2_marking_member_0[4] == P2_marking_member_0[0]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[2]; - b = P2_marking_member_0[4]; + a = P2_marking_member_0[2]; + b = P2_marking_member_0[4]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[1]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[1]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 2, 4, 3, 1 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[4] == P2_marking_member_0[3]) && - ( P2_marking_member_0[4] == P2_marking_member_0[1]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[4] == P2_marking_member_0[3]) && + ( P2_marking_member_0[4] == P2_marking_member_0[1]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[2]; - b = P2_marking_member_0[4]; + a = P2_marking_member_0[2]; + b = P2_marking_member_0[4]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_is_marked -= 4; + /* demarking of input places */ + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 3, 0, 1, 4 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[0] == P2_marking_member_0[1]) && - ( P2_marking_member_0[0] == P2_marking_member_0[4]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[0] == P2_marking_member_0[1]) && + ( P2_marking_member_0[0] == P2_marking_member_0[4]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[3]; - b = P2_marking_member_0[0]; + a = P2_marking_member_0[3]; + b = P2_marking_member_0[0]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[2]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[2]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 3, 0, 2, 4 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[0] == P2_marking_member_0[2]) && - ( P2_marking_member_0[0] == P2_marking_member_0[4]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[0] == P2_marking_member_0[2]) && + ( P2_marking_member_0[0] == P2_marking_member_0[4]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[3]; - b = P2_marking_member_0[0]; + a = P2_marking_member_0[3]; + b = P2_marking_member_0[0]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[1]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[1]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 3, 0, 4, 1 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[0] == P2_marking_member_0[4]) && - ( P2_marking_member_0[0] == P2_marking_member_0[1]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[0] == P2_marking_member_0[4]) && + ( P2_marking_member_0[0] == P2_marking_member_0[1]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[3]; - b = P2_marking_member_0[0]; + a = P2_marking_member_0[3]; + b = P2_marking_member_0[0]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[2]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[2]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 3, 0, 4, 2 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[0] == P2_marking_member_0[4]) && - ( P2_marking_member_0[0] == P2_marking_member_0[2]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[0] == P2_marking_member_0[4]) && + ( P2_marking_member_0[0] == P2_marking_member_0[2]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[3]; - b = P2_marking_member_0[0]; + a = P2_marking_member_0[3]; + b = P2_marking_member_0[0]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[1]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[1]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 3, 1, 0, 4 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[1] == P2_marking_member_0[0]) && - ( P2_marking_member_0[1] == P2_marking_member_0[4]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[1] == P2_marking_member_0[0]) && + ( P2_marking_member_0[1] == P2_marking_member_0[4]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[3]; - b = P2_marking_member_0[1]; + a = P2_marking_member_0[3]; + b = P2_marking_member_0[1]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[2]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[2]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 3, 1, 2, 4 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[1] == P2_marking_member_0[2]) && - ( P2_marking_member_0[1] == P2_marking_member_0[4]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[1] == P2_marking_member_0[2]) && + ( P2_marking_member_0[1] == P2_marking_member_0[4]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[3]; - b = P2_marking_member_0[1]; + a = P2_marking_member_0[3]; + b = P2_marking_member_0[1]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_is_marked -= 4; + /* demarking of input places */ + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 3, 1, 4, 0 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[1] == P2_marking_member_0[4]) && - ( P2_marking_member_0[1] == P2_marking_member_0[0]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[1] == P2_marking_member_0[4]) && + ( P2_marking_member_0[1] == P2_marking_member_0[0]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[3]; - b = P2_marking_member_0[1]; + a = P2_marking_member_0[3]; + b = P2_marking_member_0[1]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[2]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[2]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 3, 1, 4, 2 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[1] == P2_marking_member_0[4]) && - ( P2_marking_member_0[1] == P2_marking_member_0[2]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[1] == P2_marking_member_0[4]) && + ( P2_marking_member_0[1] == P2_marking_member_0[2]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[3]; - b = P2_marking_member_0[1]; + a = P2_marking_member_0[3]; + b = P2_marking_member_0[1]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_is_marked -= 4; + /* demarking of input places */ + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 3, 2, 0, 4 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[2] == P2_marking_member_0[0]) && - ( P2_marking_member_0[2] == P2_marking_member_0[4]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[2] == P2_marking_member_0[0]) && + ( P2_marking_member_0[2] == P2_marking_member_0[4]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[3]; - b = P2_marking_member_0[2]; + a = P2_marking_member_0[3]; + b = P2_marking_member_0[2]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[1]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[1]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 3, 2, 1, 4 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[2] == P2_marking_member_0[1]) && - ( P2_marking_member_0[2] == P2_marking_member_0[4]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[2] == P2_marking_member_0[1]) && + ( P2_marking_member_0[2] == P2_marking_member_0[4]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[3]; - b = P2_marking_member_0[2]; + a = P2_marking_member_0[3]; + b = P2_marking_member_0[2]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_is_marked -= 4; + /* demarking of input places */ + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 3, 2, 4, 0 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[2] == P2_marking_member_0[4]) && - ( P2_marking_member_0[2] == P2_marking_member_0[0]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[2] == P2_marking_member_0[4]) && + ( P2_marking_member_0[2] == P2_marking_member_0[0]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[3]; - b = P2_marking_member_0[2]; + a = P2_marking_member_0[3]; + b = P2_marking_member_0[2]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[1]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[1]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 3, 2, 4, 1 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[2] == P2_marking_member_0[4]) && - ( P2_marking_member_0[2] == P2_marking_member_0[1]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[2] == P2_marking_member_0[4]) && + ( P2_marking_member_0[2] == P2_marking_member_0[1]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[3]; - b = P2_marking_member_0[2]; + a = P2_marking_member_0[3]; + b = P2_marking_member_0[2]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_is_marked -= 4; + /* demarking of input places */ + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 3, 4, 0, 1 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[4] == P2_marking_member_0[0]) && - ( P2_marking_member_0[4] == P2_marking_member_0[1]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[4] == P2_marking_member_0[0]) && + ( P2_marking_member_0[4] == P2_marking_member_0[1]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[3]; - b = P2_marking_member_0[4]; + a = P2_marking_member_0[3]; + b = P2_marking_member_0[4]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[2]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[2]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 3, 4, 0, 2 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[4] == P2_marking_member_0[0]) && - ( P2_marking_member_0[4] == P2_marking_member_0[2]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[4] == P2_marking_member_0[0]) && + ( P2_marking_member_0[4] == P2_marking_member_0[2]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[3]; - b = P2_marking_member_0[4]; + a = P2_marking_member_0[3]; + b = P2_marking_member_0[4]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[1]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[1]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 3, 4, 1, 0 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[4] == P2_marking_member_0[1]) && - ( P2_marking_member_0[4] == P2_marking_member_0[0]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[4] == P2_marking_member_0[1]) && + ( P2_marking_member_0[4] == P2_marking_member_0[0]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[3]; - b = P2_marking_member_0[4]; + a = P2_marking_member_0[3]; + b = P2_marking_member_0[4]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[2]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[2]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 3, 4, 1, 2 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[4] == P2_marking_member_0[1]) && - ( P2_marking_member_0[4] == P2_marking_member_0[2]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[4] == P2_marking_member_0[1]) && + ( P2_marking_member_0[4] == P2_marking_member_0[2]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[3]; - b = P2_marking_member_0[4]; + a = P2_marking_member_0[3]; + b = P2_marking_member_0[4]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_is_marked -= 4; + /* demarking of input places */ + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 3, 4, 2, 0 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[4] == P2_marking_member_0[2]) && - ( P2_marking_member_0[4] == P2_marking_member_0[0]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[4] == P2_marking_member_0[2]) && + ( P2_marking_member_0[4] == P2_marking_member_0[0]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[3]; - b = P2_marking_member_0[4]; + a = P2_marking_member_0[3]; + b = P2_marking_member_0[4]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[1]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[1]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 3, 4, 2, 1 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[4] == P2_marking_member_0[2]) && - ( P2_marking_member_0[4] == P2_marking_member_0[1]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[4] == P2_marking_member_0[2]) && + ( P2_marking_member_0[4] == P2_marking_member_0[1]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[3]; - b = P2_marking_member_0[4]; + a = P2_marking_member_0[3]; + b = P2_marking_member_0[4]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_is_marked -= 4; + /* demarking of input places */ + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 4, 0, 1, 2 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[0] == P2_marking_member_0[1]) && - ( P2_marking_member_0[0] == P2_marking_member_0[2]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[0] == P2_marking_member_0[1]) && + ( P2_marking_member_0[0] == P2_marking_member_0[2]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[4]; - b = P2_marking_member_0[0]; + a = P2_marking_member_0[4]; + b = P2_marking_member_0[0]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[3]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[3]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 4, 0, 1, 3 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[0] == P2_marking_member_0[1]) && - ( P2_marking_member_0[0] == P2_marking_member_0[3]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[0] == P2_marking_member_0[1]) && + ( P2_marking_member_0[0] == P2_marking_member_0[3]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[4]; - b = P2_marking_member_0[0]; + a = P2_marking_member_0[4]; + b = P2_marking_member_0[0]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[2]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[2]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 4, 0, 2, 1 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[0] == P2_marking_member_0[2]) && - ( P2_marking_member_0[0] == P2_marking_member_0[1]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[0] == P2_marking_member_0[2]) && + ( P2_marking_member_0[0] == P2_marking_member_0[1]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[4]; - b = P2_marking_member_0[0]; + a = P2_marking_member_0[4]; + b = P2_marking_member_0[0]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[3]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[3]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 4, 0, 2, 3 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[0] == P2_marking_member_0[2]) && - ( P2_marking_member_0[0] == P2_marking_member_0[3]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[0] == P2_marking_member_0[2]) && + ( P2_marking_member_0[0] == P2_marking_member_0[3]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[4]; - b = P2_marking_member_0[0]; + a = P2_marking_member_0[4]; + b = P2_marking_member_0[0]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[1]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[1]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 4, 0, 3, 1 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[0] == P2_marking_member_0[3]) && - ( P2_marking_member_0[0] == P2_marking_member_0[1]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[0] == P2_marking_member_0[3]) && + ( P2_marking_member_0[0] == P2_marking_member_0[1]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[4]; - b = P2_marking_member_0[0]; + a = P2_marking_member_0[4]; + b = P2_marking_member_0[0]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[2]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[2]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 4, 0, 3, 2 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[0] == P2_marking_member_0[3]) && - ( P2_marking_member_0[0] == P2_marking_member_0[2]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[0] == P2_marking_member_0[3]) && + ( P2_marking_member_0[0] == P2_marking_member_0[2]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[4]; - b = P2_marking_member_0[0]; + a = P2_marking_member_0[4]; + b = P2_marking_member_0[0]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[1]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[1]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 4, 1, 0, 2 */ /* Transition T2 */ - if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[1] == P2_marking_member_0[0]) && - ( P2_marking_member_0[1] == P2_marking_member_0[2]) ) ) { + if ( (P2_is_marked >= 5) && + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[1] == P2_marking_member_0[0]) && + ( P2_marking_member_0[1] == P2_marking_member_0[2]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[4]; - b = P2_marking_member_0[1]; + a = P2_marking_member_0[4]; + b = P2_marking_member_0[1]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[3]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[3]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ - } + } /* end of if (Transition condition) */ + } /* Permutation for Place P2 : 4, 1, 0, 3 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[1] == P2_marking_member_0[0]) && - ( P2_marking_member_0[1] == P2_marking_member_0[3]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[1] == P2_marking_member_0[0]) && + ( P2_marking_member_0[1] == P2_marking_member_0[3]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[4]; - b = P2_marking_member_0[1]; + a = P2_marking_member_0[4]; + b = P2_marking_member_0[1]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[2]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[2]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 4, 1, 2, 0 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[1] == P2_marking_member_0[2]) && - ( P2_marking_member_0[1] == P2_marking_member_0[0]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[1] == P2_marking_member_0[2]) && + ( P2_marking_member_0[1] == P2_marking_member_0[0]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[4]; - b = P2_marking_member_0[1]; + a = P2_marking_member_0[4]; + b = P2_marking_member_0[1]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[3]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[3]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 4, 1, 2, 3 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[1] == P2_marking_member_0[2]) && - ( P2_marking_member_0[1] == P2_marking_member_0[3]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[1] == P2_marking_member_0[2]) && + ( P2_marking_member_0[1] == P2_marking_member_0[3]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[4]; - b = P2_marking_member_0[1]; + a = P2_marking_member_0[4]; + b = P2_marking_member_0[1]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_is_marked -= 4; + /* demarking of input places */ + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 4, 1, 3, 0 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[1] == P2_marking_member_0[3]) && - ( P2_marking_member_0[1] == P2_marking_member_0[0]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[1] == P2_marking_member_0[3]) && + ( P2_marking_member_0[1] == P2_marking_member_0[0]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[4]; - b = P2_marking_member_0[1]; + a = P2_marking_member_0[4]; + b = P2_marking_member_0[1]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[2]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[2]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 4, 1, 3, 2 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[1] == P2_marking_member_0[3]) && - ( P2_marking_member_0[1] == P2_marking_member_0[2]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[1] == P2_marking_member_0[3]) && + ( P2_marking_member_0[1] == P2_marking_member_0[2]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[4]; - b = P2_marking_member_0[1]; + a = P2_marking_member_0[4]; + b = P2_marking_member_0[1]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_is_marked -= 4; + /* demarking of input places */ + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 4, 2, 0, 1 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[2] == P2_marking_member_0[0]) && - ( P2_marking_member_0[2] == P2_marking_member_0[1]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[2] == P2_marking_member_0[0]) && + ( P2_marking_member_0[2] == P2_marking_member_0[1]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[4]; - b = P2_marking_member_0[2]; + a = P2_marking_member_0[4]; + b = P2_marking_member_0[2]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[3]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[3]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 4, 2, 0, 3 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[2] == P2_marking_member_0[0]) && - ( P2_marking_member_0[2] == P2_marking_member_0[3]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[2] == P2_marking_member_0[0]) && + ( P2_marking_member_0[2] == P2_marking_member_0[3]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[4]; - b = P2_marking_member_0[2]; + a = P2_marking_member_0[4]; + b = P2_marking_member_0[2]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[1]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[1]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 4, 2, 1, 0 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[2] == P2_marking_member_0[1]) && - ( P2_marking_member_0[2] == P2_marking_member_0[0]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[2] == P2_marking_member_0[1]) && + ( P2_marking_member_0[2] == P2_marking_member_0[0]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[4]; - b = P2_marking_member_0[2]; + a = P2_marking_member_0[4]; + b = P2_marking_member_0[2]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[3]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[3]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 4, 2, 1, 3 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[2] == P2_marking_member_0[1]) && - ( P2_marking_member_0[2] == P2_marking_member_0[3]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[2] == P2_marking_member_0[1]) && + ( P2_marking_member_0[2] == P2_marking_member_0[3]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[4]; - b = P2_marking_member_0[2]; + a = P2_marking_member_0[4]; + b = P2_marking_member_0[2]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_is_marked -= 4; + /* demarking of input places */ + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 4, 2, 3, 0 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[2] == P2_marking_member_0[3]) && - ( P2_marking_member_0[2] == P2_marking_member_0[0]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[2] == P2_marking_member_0[3]) && + ( P2_marking_member_0[2] == P2_marking_member_0[0]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[4]; - b = P2_marking_member_0[2]; + a = P2_marking_member_0[4]; + b = P2_marking_member_0[2]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[1]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[1]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 4, 2, 3, 1 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[2] == P2_marking_member_0[3]) && - ( P2_marking_member_0[2] == P2_marking_member_0[1]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[2] == P2_marking_member_0[3]) && + ( P2_marking_member_0[2] == P2_marking_member_0[1]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[4]; - b = P2_marking_member_0[2]; + a = P2_marking_member_0[4]; + b = P2_marking_member_0[2]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_is_marked -= 4; + /* demarking of input places */ + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 4, 3, 0, 1 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[3] == P2_marking_member_0[0]) && - ( P2_marking_member_0[3] == P2_marking_member_0[1]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[3] == P2_marking_member_0[0]) && + ( P2_marking_member_0[3] == P2_marking_member_0[1]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[4]; - b = P2_marking_member_0[3]; + a = P2_marking_member_0[4]; + b = P2_marking_member_0[3]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[2]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[2]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 4, 3, 0, 2 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[3] == P2_marking_member_0[0]) && - ( P2_marking_member_0[3] == P2_marking_member_0[2]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[3] == P2_marking_member_0[0]) && + ( P2_marking_member_0[3] == P2_marking_member_0[2]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[4]; - b = P2_marking_member_0[3]; + a = P2_marking_member_0[4]; + b = P2_marking_member_0[3]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[1]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[1]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 4, 3, 1, 0 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[3] == P2_marking_member_0[1]) && - ( P2_marking_member_0[3] == P2_marking_member_0[0]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[3] == P2_marking_member_0[1]) && + ( P2_marking_member_0[3] == P2_marking_member_0[0]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[4]; - b = P2_marking_member_0[3]; + a = P2_marking_member_0[4]; + b = P2_marking_member_0[3]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[2]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[2]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 4, 3, 1, 2 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[3] == P2_marking_member_0[1]) && - ( P2_marking_member_0[3] == P2_marking_member_0[2]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[3] == P2_marking_member_0[1]) && + ( P2_marking_member_0[3] == P2_marking_member_0[2]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[4]; - b = P2_marking_member_0[3]; + a = P2_marking_member_0[4]; + b = P2_marking_member_0[3]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_is_marked -= 4; + /* demarking of input places */ + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 4, 3, 2, 0 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[3] == P2_marking_member_0[2]) && - ( P2_marking_member_0[3] == P2_marking_member_0[0]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[3] == P2_marking_member_0[2]) && + ( P2_marking_member_0[3] == P2_marking_member_0[0]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[4]; - b = P2_marking_member_0[3]; + a = P2_marking_member_0[4]; + b = P2_marking_member_0[3]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_marking_member_0[0] = P2_marking_member_0[1]; - P2_is_marked -= 4; + /* demarking of input places */ + P2_marking_member_0[0] = P2_marking_member_0[1]; + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } /* Permutation for Place P2 : 4, 3, 2, 1 */ /* Transition T2 */ if ( (P2_is_marked >= 5) && - ( (P3_is_marked + 3) <= 6) && - (( P2_marking_member_0[3] == P2_marking_member_0[2]) && - ( P2_marking_member_0[3] == P2_marking_member_0[1]) ) ) { + ( (P3_is_marked + 3) <= 6) && + (( P2_marking_member_0[3] == P2_marking_member_0[2]) && + ( P2_marking_member_0[3] == P2_marking_member_0[1]) ) ) { - long a; - long b; - long c; + long a; + long b; + long c; - a = P2_marking_member_0[4]; - b = P2_marking_member_0[3]; + a = P2_marking_member_0[4]; + b = P2_marking_member_0[3]; - /* Transition condition */ - if ((b > a)) { + /* Transition condition */ + if ((b > a)) { - /* demarking of input places */ - P2_is_marked -= 4; + /* demarking of input places */ + P2_is_marked -= 4; - /* preaction */ - c = a + b; + /* preaction */ + c = a + b; - /* marking of output places */ - P3_marking_member_0[P3_is_marked+0] = a; - P3_marking_member_0[P3_is_marked+1] = b; - P3_marking_member_0[P3_is_marked+2] = c; - P3_is_marked += 3; + /* marking of output places */ + P3_marking_member_0[P3_is_marked+0] = a; + P3_marking_member_0[P3_is_marked+1] = b; + P3_marking_member_0[P3_is_marked+2] = c; + P3_is_marked += 3; - } /* end of if (Transition condition) */ + } /* end of if (Transition condition) */ } - } - - - dummy_i = 77; - - return dummy_i; - + } + return 0; } -/*************************************************************************** - * - * end of file - * - ***************************************************************************/ - int verify_benchmark(int unused) { int expP1_is_marked = 3; diff --git a/src/picojpeg/Makefile.am b/src/picojpeg/Makefile.am index ea63bb55..48e2e527 100644 --- a/src/picojpeg/Makefile.am +++ b/src/picojpeg/Makefile.am @@ -34,7 +34,8 @@ libpicojpeg_la_SOURCES = libpicojpeg.c picojpeg_test.c picojpeg.h picojpeg_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libpicojpeg.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) diff --git a/src/picojpeg/Makefile.in b/src/picojpeg/Makefile.in index e228ad6c..aa369ac3 100644 --- a/src/picojpeg/Makefile.in +++ b/src/picojpeg/Makefile.in @@ -174,6 +174,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_PICOJPEG_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_PICOJPEG_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_PICOJPEG_TRUE@ libpicojpeg.la \ +@ENABLED_BENCHMARK_PICOJPEG_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_PICOJPEG_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_PICOJPEG_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_PICOJPEG_TRUE@ $(am__DEPENDENCIES_1) @@ -396,7 +397,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_PICOJPEG_TRUE@picojpeg_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_PICOJPEG_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_PICOJPEG_TRUE@ libpicojpeg.la \ -@ENABLED_BENCHMARK_PICOJPEG_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_PICOJPEG_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_PICOJPEG_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/picojpeg/libpicojpeg.c b/src/picojpeg/libpicojpeg.c index c5738ae6..268de247 100644 --- a/src/picojpeg/libpicojpeg.c +++ b/src/picojpeg/libpicojpeg.c @@ -16,7 +16,7 @@ //------------------------------------------------------------------------------ // picojpeg.c v1.1 - Public domain, Rich Geldreich // Nov. 27, 2010 - Initial release -// Feb. 9, 2013 - Added H1V2/H2V1 support, cleaned up macros, signed shift fixes +// Feb. 9, 2013 - Added H1V2/H2V1 support, cleaned up macros, signed shift fixes // Also integrated and tested changes from Chris Phoenix . //------------------------------------------------------------------------------ #include "picojpeg.h" @@ -51,21 +51,21 @@ static int16 replicateSignBit16(int8 n) case 9: return 0xFF80; case 10: return 0xFFC0; case 11: return 0xFFE0; - case 12: return 0xFFF0; + case 12: return 0xFFF0; case 13: return 0xFFF8; case 14: return 0xFFFC; case 15: return 0xFFFE; default: return 0xFFFF; } } -static PJPG_INLINE int16 arithmeticRightShiftN16(int16 x, int8 n) +static PJPG_INLINE int16 arithmeticRightShiftN16(int16 x, int8 n) { int16 r = (uint16)x >> (uint8)n; if (x < 0) r |= replicateSignBit16(n); return r; } -static PJPG_INLINE long arithmeticRightShift8L(long x) +static PJPG_INLINE long arithmeticRightShift8L(long x) { long r = (unsigned long)x >> 8U; if (x < 0) @@ -137,11 +137,11 @@ typedef enum M_TEM = 0x01, M_ERROR = 0x100, - + RST0 = 0xD0 } JPEG_MARKER; //------------------------------------------------------------------------------ -static const int8 ZAG[] = +static const int8 ZAG[] = { 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, @@ -249,7 +249,7 @@ static void fillInBuf(void) // The highest level pjpeg entrypoints will catch the error and return the non-zero status. gCallbackStatus = status; } -} +} //------------------------------------------------------------------------------ static PJPG_INLINE uint8 getChar(void) { @@ -260,9 +260,9 @@ static PJPG_INLINE uint8 getChar(void) { gTemFlag = ~gTemFlag; return gTemFlag ? 0xFF : 0xD9; - } + } } - + gInBufLeft--; return gInBuf[gInBufOfs++]; } @@ -277,7 +277,7 @@ static PJPG_INLINE void stuffChar(uint8 i) static PJPG_INLINE uint8 getOctet(uint8 FFCheck) { uint8 c = getChar(); - + if ((FFCheck) && (c == 0xFF)) { uint8 n = getChar(); @@ -296,28 +296,28 @@ static uint16 getBits(uint8 numBits, uint8 FFCheck) { uint8 origBits = numBits; uint16 ret = gBitBuf; - + if (numBits > 8) { numBits -= 8; - + gBitBuf <<= gBitsLeft; - + gBitBuf |= getOctet(FFCheck); - + gBitBuf <<= (8 - gBitsLeft); - + ret = (ret & 0xFF00) | (gBitBuf >> 8); } - + if (gBitsLeft < numBits) { gBitBuf <<= gBitsLeft; - + gBitBuf |= getOctet(FFCheck); - + gBitBuf <<= (numBits - gBitsLeft); - + gBitsLeft = 8 - (numBits - gBitsLeft); } else @@ -325,7 +325,7 @@ static uint16 getBits(uint8 numBits, uint8 FFCheck) gBitsLeft = (uint8)(gBitsLeft - numBits); gBitBuf <<= numBits; } - + return ret >> (16 - origBits); } //------------------------------------------------------------------------------ @@ -342,19 +342,19 @@ static PJPG_INLINE uint16 getBits2(uint8 numBits) static PJPG_INLINE uint8 getBit(void) { uint8 ret = 0; - if (gBitBuf & 0x8000) + if (gBitBuf & 0x8000) ret = 1; - + if (!gBitsLeft) { gBitBuf |= getOctet(1); gBitsLeft += 8; } - + gBitsLeft--; gBitBuf <<= 1; - + return ret; } //------------------------------------------------------------------------------ @@ -367,7 +367,7 @@ static uint16 getExtendTest(uint8 i) case 2: return 0x0002; case 3: return 0x0004; case 4: return 0x0008; - case 5: return 0x0010; + case 5: return 0x0010; case 6: return 0x0020; case 7: return 0x0040; case 8: return 0x0080; @@ -376,31 +376,31 @@ static uint16 getExtendTest(uint8 i) case 11: return 0x0400; case 12: return 0x0800; case 13: return 0x1000; - case 14: return 0x2000; + case 14: return 0x2000; case 15: return 0x4000; default: return 0; - } + } } //------------------------------------------------------------------------------ static int16 getExtendOffset(uint8 i) -{ +{ switch (i) { case 0: return 0; - case 1: return ((-1)<<1) + 1; - case 2: return ((-1)<<2) + 1; - case 3: return ((-1)<<3) + 1; - case 4: return ((-1)<<4) + 1; - case 5: return ((-1)<<5) + 1; - case 6: return ((-1)<<6) + 1; - case 7: return ((-1)<<7) + 1; - case 8: return ((-1)<<8) + 1; + case 1: return ((-1)<<1) + 1; + case 2: return ((-1)<<2) + 1; + case 3: return ((-1)<<3) + 1; + case 4: return ((-1)<<4) + 1; + case 5: return ((-1)<<5) + 1; + case 6: return ((-1)<<6) + 1; + case 7: return ((-1)<<7) + 1; + case 8: return ((-1)<<8) + 1; case 9: return ((-1)<<9) + 1; - case 10: return ((-1)<<10) + 1; - case 11: return ((-1)<<11) + 1; - case 12: return ((-1)<<12) + 1; - case 13: return ((-1)<<13) + 1; - case 14: return ((-1)<<14) + 1; + case 10: return ((-1)<<10) + 1; + case 11: return ((-1)<<11) + 1; + case 12: return ((-1)<<12) + 1; + case 13: return ((-1)<<13) + 1; + case 14: return ((-1)<<14) + 1; case 15: return ((-1)<<15) + 1; default: return 0; } @@ -418,7 +418,7 @@ static PJPG_INLINE uint8 huffDecode(const HuffTable* pHuffTable, const uint8* pH uint16 code = getBit(); // This func only reads a bit at a time, which on modern CPU's is not terribly efficient. - // But on microcontrollers without strong integer shifting support this seems like a + // But on microcontrollers without strong integer shifting support this seems like a // more reasonable approach. for ( ; ; ) { @@ -448,11 +448,11 @@ static void huffCreate(const uint8* pBits, HuffTable* pHuffTable) uint8 j = 0; uint16 code = 0; - + for ( ; ; ) { uint8 num = pBits[i]; - + if (!num) { pHuffTable->mMinCode[i] = 0x0000; @@ -464,14 +464,14 @@ static void huffCreate(const uint8* pBits, HuffTable* pHuffTable) pHuffTable->mMinCode[i] = code; pHuffTable->mMaxCode[i] = code + num - 1; pHuffTable->mValPtr[i] = j; - + j = (uint8)(j + num); - + code = (uint16)(code + num); } - + code <<= 1; - + i++; if (i > 15) break; @@ -527,19 +527,19 @@ static uint8 readDHTMarker(void) uint8* pHuffVal; HuffTable* pHuffTable; uint16 count, totalRead; - + index = (uint8)getBits1(8); - + if ( ((index & 0xF) > 1) || ((index & 0xF0) > 0x10) ) return PJPG_BAD_DHT_INDEX; - + tableIndex = ((index >> 3) & 2) + (index & 1); - + pHuffTable = getHuffTable(tableIndex); pHuffVal = getHuffVal(tableIndex); - + gValidHuffTables |= (1 << tableIndex); - + count = 0; for (i = 0; i <= 15; i++) { @@ -547,7 +547,7 @@ static uint8 readDHTMarker(void) bits[i] = n; count = (uint16)(count + n); } - + if (count > getMaxHuffCodes(tableIndex)) return PJPG_BAD_DHT_COUNTS; @@ -563,7 +563,7 @@ static uint8 readDHTMarker(void) huffCreate(bits, pHuffTable); } - + return 0; } //------------------------------------------------------------------------------ @@ -590,7 +590,7 @@ static uint8 readDQTMarker(void) if (n > 1) return PJPG_BAD_DQT_TABLE; - gValidQuantTables |= (n ? 2 : 1); + gValidQuantTables |= (n ? 2 : 1); // read quantization entries, in zag order for (i = 0; i < 64; i++) @@ -601,11 +601,11 @@ static uint8 readDQTMarker(void) temp = (temp << 8) + getBits1(8); if (n) - gQuant1[i] = (int16)temp; + gQuant1[i] = (int16)temp; else - gQuant0[i] = (int16)temp; + gQuant0[i] = (int16)temp; } - + createWinogradQuant(n ? gQuant1 : gQuant0); totalRead = 64 + 1; @@ -618,7 +618,7 @@ static uint8 readDQTMarker(void) left = (uint16)(left - totalRead); } - + return 0; } //------------------------------------------------------------------------------ @@ -627,7 +627,7 @@ static uint8 readSOFMarker(void) uint8 i; uint16 left = getBits1(16); - if (getBits1(8) != 8) + if (getBits1(8) != 8) return PJPG_BAD_PRECISION; gImageYSize = getBits1(16); @@ -647,18 +647,18 @@ static uint8 readSOFMarker(void) if (left != (gCompsInFrame + gCompsInFrame + gCompsInFrame + 8)) return PJPG_BAD_SOF_LENGTH; - + for (i = 0; i < gCompsInFrame; i++) { gCompIdent[i] = (uint8)getBits1(8); gCompHSamp[i] = (uint8)getBits1(4); gCompVSamp[i] = (uint8)getBits1(4); gCompQuant[i] = (uint8)getBits1(8); - + if (gCompQuant[i] > 1) return PJPG_UNSUPPORTED_QUANT_TABLE; } - + return 0; } //------------------------------------------------------------------------------ @@ -677,7 +677,7 @@ static uint8 skipVariableMarker(void) getBits1(8); left--; } - + return 0; } //------------------------------------------------------------------------------ @@ -688,7 +688,7 @@ static uint8 readDRIMarker(void) return PJPG_BAD_DRI_LENGTH; gRestartInterval = getBits1(16); - + return 0; } //------------------------------------------------------------------------------ @@ -710,15 +710,15 @@ static uint8 readSOSMarker(void) if ( (left != (gCompsInScan + gCompsInScan + 3)) || (gCompsInScan < 1) || (gCompsInScan > PJPG_MAXCOMPSINSCAN) ) return PJPG_BAD_SOS_LENGTH; - + for (i = 0; i < gCompsInScan; i++) { uint8 cc = (uint8)getBits1(8); uint8 c = (uint8)getBits1(8); uint8 ci; - + left -= 2; - + for (ci = 0; ci < gCompsInFrame; ci++) if (cc == gCompIdent[ci]) break; @@ -738,12 +738,12 @@ static uint8 readSOSMarker(void) left -= 3; - while (left) + while (left) { getBits1(8); left--; } - + return 0; } //------------------------------------------------------------------------------ @@ -855,7 +855,7 @@ static uint8 processMarkers(uint8* pMarker) static uint8 locateSOIMarker(void) { uint16 bytesleft; - + uint8 lastchar = (uint8)getBits1(8); uint8 thischar = (uint8)getBits1(8); @@ -876,7 +876,7 @@ static uint8 locateSOIMarker(void) thischar = (uint8)getBits1(8); - if (lastchar == 0xFF) + if (lastchar == 0xFF) { if (thischar == M_SOI) break; @@ -892,7 +892,7 @@ static uint8 locateSOIMarker(void) if (thischar != 0xFF) return PJPG_NOT_JPEG; - + return 0; } //------------------------------------------------------------------------------ @@ -904,7 +904,7 @@ static uint8 locateSOFMarker(void) uint8 status = locateSOIMarker(); if (status) return status; - + status = processMarkers(&c); if (status) return status; @@ -922,10 +922,10 @@ static uint8 locateSOFMarker(void) status = readSOFMarker(); if (status) return status; - + break; } - case M_SOF9: + case M_SOF9: { return PJPG_NO_ARITHMITIC_SUPPORT; } @@ -935,7 +935,7 @@ static uint8 locateSOFMarker(void) return PJPG_UNSUPPORTED_MARKER; } } - + return 0; } //------------------------------------------------------------------------------ @@ -946,7 +946,7 @@ static uint8 locateSOSMarker(uint8* pFoundEOI) uint8 status; *pFoundEOI = 0; - + status = processMarkers(&c); if (status) return status; @@ -989,11 +989,11 @@ static void fixInBuffer(void) { /* In case any 0xFF's where pulled into the buffer during marker scanning */ - if (gBitsLeft > 0) + if (gBitsLeft > 0) stuffChar((uint8)gBitBuf); - + stuffChar((uint8)(gBitBuf >> 8)); - + gBitsLeft = 8; getBits2(8); getBits2(8); @@ -1013,7 +1013,7 @@ static uint8 processRestart(void) if (i == 0) return PJPG_BAD_RESTART_MARKER; - + for ( ; i > 0; i--) if ((c = getChar()) != 0xFF) break; @@ -1039,7 +1039,7 @@ static uint8 processRestart(void) gBitsLeft = 8; getBits2(8); getBits2(8); - + return 0; } //------------------------------------------------------------------------------ @@ -1051,12 +1051,12 @@ static uint8 checkHuffTables(void) { uint8 compDCTab = gCompDCTab[gCompList[i]]; uint8 compACTab = gCompACTab[gCompList[i]] + 2; - + if ( ((gValidHuffTables & (1 << compDCTab)) == 0) || ((gValidHuffTables & (1 << compACTab)) == 0) ) - return PJPG_UNDEFINED_HUFF_TABLE; + return PJPG_UNDEFINED_HUFF_TABLE; } - + return 0; } //------------------------------------------------------------------------------ @@ -1067,12 +1067,12 @@ static uint8 checkQuantTables(void) for (i = 0; i < gCompsInScan; i++) { uint8 compQuantMask = gCompQuant[gCompList[i]] ? 2 : 1; - + if ((gValidQuantTables & compQuantMask) == 0) return PJPG_UNDEFINED_QUANT_TABLE; - } + } - return 0; + return 0; } //------------------------------------------------------------------------------ static uint8 initScan(void) @@ -1083,7 +1083,7 @@ static uint8 initScan(void) return status; if (foundEOI) return PJPG_UNEXPECTED_MARKER; - + status = checkHuffTables(); if (status) return status; @@ -1136,7 +1136,7 @@ static uint8 initFrame(void) gMCUOrg[0] = 0; gMCUOrg[1] = 1; gMCUOrg[2] = 2; - + gMaxMCUXSize = 8; gMaxMCUYSize = 8; } @@ -1189,9 +1189,9 @@ static uint8 initFrame(void) gMaxMCUSPerRow = (gImageXSize + (gMaxMCUXSize - 1)) >> ((gMaxMCUXSize == 8) ? 3 : 4); gMaxMCUSPerCol = (gImageYSize + (gMaxMCUYSize - 1)) >> ((gMaxMCUYSize == 8) ? 3 : 4); - + gNumMCUSRemaining = gMaxMCUSPerRow * gMaxMCUSPerCol; - + return 0; } //---------------------------------------------------------------------------- @@ -1207,7 +1207,7 @@ static uint8 initFrame(void) #define PJPG_WINOGRAD_QUANT_SCALE_BITS 10 -const uint8 gWinogradQuant[] = +const uint8 gWinogradQuant[] = { 128, 178, 178, 167, 246, 167, 151, 232, 232, 151, 128, 209, 219, 209, 128, 101, @@ -1217,14 +1217,14 @@ const uint8 gWinogradQuant[] = 118, 91, 49, 46, 81, 101, 101, 81, 46, 42, 69, 79, 69, 42, 35, 54, 54, 35, 28, 37, 28, 19, 19, 10, -}; +}; // Multiply quantization matrix by the Winograd IDCT scale factors static void createWinogradQuant(int16* pQuant) { uint8 i; - - for (i = 0; i < 64; i++) + + for (i = 0; i < 64; i++) { long x = pQuant[i]; x *= gWinogradQuant[i]; @@ -1276,12 +1276,12 @@ static PJPG_INLINE uint8 clamp(int16 s) { if ((uint16)s > 255U) { - if (s < 0) - return 0; - else if (s > 255) + if (s < 0) + return 0; + else if (s > 255) return 255; } - + return (uint8)s; } @@ -1289,7 +1289,7 @@ static void idctRows(void) { uint8 i; int16* pSrc = gCoeffBuf; - + for (i = 0; i < 8; i++) { if ((pSrc[1] | pSrc[2] | pSrc[3] | pSrc[4] | pSrc[5] | pSrc[6] | pSrc[7]) == 0) @@ -1355,17 +1355,17 @@ static void idctRows(void) *(pSrc+6) = x41 - tmp2; *(pSrc+7) = x40 - x17; } - + pSrc += 8; - } + } } static void idctCols(void) { uint8 i; - + int16* pSrc = gCoeffBuf; - + for (i = 0; i < 8; i++) { if ((pSrc[1*8] | pSrc[2*8] | pSrc[3*8] | pSrc[4*8] | pSrc[5*8] | pSrc[6*8] | pSrc[7*8]) == 0) @@ -1433,15 +1433,15 @@ static void idctCols(void) *(pSrc+7*8) = clamp(PJPG_DESCALE(x40 - x17) + 128); } - pSrc++; - } + pSrc++; + } } /*----------------------------------------------------------------------------*/ static PJPG_INLINE uint8 addAndClamp(uint8 a, int16 b) { b = a + b; - + if ((uint16)b > 255U) { if (b < 0) @@ -1449,7 +1449,7 @@ static PJPG_INLINE uint8 addAndClamp(uint8 a, int16 b) else if (b > 255) return 255; } - + return (uint8)b; } /*----------------------------------------------------------------------------*/ @@ -1512,7 +1512,7 @@ static void upsampleCb(uint8 srcOfs, uint8 dstOfs) pDstG = pDstG - 8 + 16; pDstB = pDstB - 8 + 16; } -} +} /*----------------------------------------------------------------------------*/ // Cb upsample and accumulate, 4x8 to 8x8 static void upsampleCbH(uint8 srcOfs, uint8 dstOfs) @@ -1543,7 +1543,7 @@ static void upsampleCbH(uint8 srcOfs, uint8 dstOfs) pSrc = pSrc - 4 + 8; } -} +} /*----------------------------------------------------------------------------*/ // Cb upsample and accumulate, 8x4 to 8x8 static void upsampleCbV(uint8 srcOfs, uint8 dstOfs) @@ -1575,7 +1575,7 @@ static void upsampleCbV(uint8 srcOfs, uint8 dstOfs) pDstG = pDstG - 8 + 16; pDstB = pDstB - 8 + 16; } -} +} /*----------------------------------------------------------------------------*/ // 103/256 //R = Y + 1.402 (Cr-128) @@ -1606,13 +1606,13 @@ static void upsampleCr(uint8 srcOfs, uint8 dstOfs) pDstR[1] = addAndClamp(pDstR[1], crR); pDstR[8] = addAndClamp(pDstR[8], crR); pDstR[9] = addAndClamp(pDstR[9], crR); - + crG = ((cr * 183U) >> 8U) - 91; pDstG[0] = subAndClamp(pDstG[0], crG); pDstG[1] = subAndClamp(pDstG[1], crG); pDstG[8] = subAndClamp(pDstG[8], crG); pDstG[9] = subAndClamp(pDstG[9], crG); - + pDstR += 2; pDstG += 2; } @@ -1621,7 +1621,7 @@ static void upsampleCr(uint8 srcOfs, uint8 dstOfs) pDstR = pDstR - 8 + 16; pDstG = pDstG - 8 + 16; } -} +} /*----------------------------------------------------------------------------*/ // Cr upsample and accumulate, 4x8 to 8x8 static void upsampleCrH(uint8 srcOfs, uint8 dstOfs) @@ -1641,18 +1641,18 @@ static void upsampleCrH(uint8 srcOfs, uint8 dstOfs) crR = (cr + ((cr * 103U) >> 8U)) - 179; pDstR[0] = addAndClamp(pDstR[0], crR); pDstR[1] = addAndClamp(pDstR[1], crR); - + crG = ((cr * 183U) >> 8U) - 91; pDstG[0] = subAndClamp(pDstG[0], crG); pDstG[1] = subAndClamp(pDstG[1], crG); - + pDstR += 2; pDstG += 2; } pSrc = pSrc - 4 + 8; } -} +} /*----------------------------------------------------------------------------*/ // Cr upsample and accumulate, 8x4 to 8x8 static void upsampleCrV(uint8 srcOfs, uint8 dstOfs) @@ -1684,7 +1684,7 @@ static void upsampleCrV(uint8 srcOfs, uint8 dstOfs) pDstR = pDstR - 8 + 16; pDstG = pDstG - 8 + 16; } -} +} /*----------------------------------------------------------------------------*/ // Convert Y to RGB static void copyY(uint8 dstOfs) @@ -1694,11 +1694,11 @@ static void copyY(uint8 dstOfs) uint8* pGDst = gMCUBufG + dstOfs; uint8* pBDst = gMCUBufB + dstOfs; int16* pSrc = gCoeffBuf; - + for (i = 64; i > 0; i--) { uint8 c = (uint8)*pSrc++; - + *pRDst++ = c; *pGDst++ = c; *pBDst++ = c; @@ -1755,7 +1755,7 @@ static void transformBlock(uint8 mcuBlock) { idctRows(); idctCols(); - + switch (gScanType) { case PJPG_GRAYSCALE: @@ -1818,7 +1818,7 @@ static void transformBlock(uint8 mcuBlock) } break; - } + } case PJPG_YH2V1: { // MCU size: 16x8, 4 blocks per MCU @@ -1847,9 +1847,9 @@ static void transformBlock(uint8 mcuBlock) break; } } - + break; - } + } case PJPG_YH2V2: { // MCU size: 16x16, 6 blocks per MCU @@ -1894,8 +1894,8 @@ static void transformBlock(uint8 mcuBlock) } break; - } - } + } + } } //------------------------------------------------------------------------------ static void transformBlockReduce(uint8 mcuBlock) @@ -2111,9 +2111,9 @@ static void transformBlockReduce(uint8 mcuBlock) static uint8 decodeNextMCU(void) { uint8 status; - uint8 mcuBlock; + uint8 mcuBlock; - if (gRestartInterval) + if (gRestartInterval) { if (gRestartsLeft == 0) { @@ -2122,28 +2122,28 @@ static uint8 decodeNextMCU(void) return status; } gRestartsLeft--; - } - + } + for (mcuBlock = 0; mcuBlock < gMaxBlocksPerMCU; mcuBlock++) { uint8 componentID = gMCUOrg[mcuBlock]; - uint8 compQuant = gCompQuant[componentID]; + uint8 compQuant = gCompQuant[componentID]; uint8 compDCTab = gCompDCTab[componentID]; uint8 numExtraBits, compACTab, k; const int16* pQ = compQuant ? gQuant1 : gQuant0; uint16 r, dc; uint8 s = huffDecode(compDCTab ? &gHuffTab1 : &gHuffTab0, compDCTab ? gHuffVal1 : gHuffVal0); - + r = 0; numExtraBits = s & 0xF; if (numExtraBits) r = getBits2(numExtraBits); dc = huffExtend(r, s); - + dc = dc + gLastDC[componentID]; gLastDC[componentID] = dc; - + gCoeffBuf[0] = dc * pQ[0]; compACTab = gCompACTab[componentID]; @@ -2186,7 +2186,7 @@ static uint8 decodeNextMCU(void) } } - transformBlockReduce(mcuBlock); + transformBlockReduce(mcuBlock); } else { @@ -2222,8 +2222,8 @@ static uint8 decodeNextMCU(void) } ac = huffExtend(extraBits, s); - - gCoeffBuf[ZAG[k]] = ac * pQ[k]; + + gCoeffBuf[ZAG[k]] = ac * pQ[k]; } else { @@ -2231,50 +2231,50 @@ static uint8 decodeNextMCU(void) { if ((k + 16) > 64) return PJPG_DECODE_ERROR; - + for (r = 16; r > 0; r--) gCoeffBuf[ZAG[k++]] = 0; - + k--; // - 1 because the loop counter is k } else break; } } - + while (k < 64) gCoeffBuf[ZAG[k++]] = 0; - transformBlock(mcuBlock); + transformBlock(mcuBlock); } } - + return 0; } //------------------------------------------------------------------------------ unsigned char pjpeg_decode_mcu(void) { uint8 status; - + if (gCallbackStatus) return gCallbackStatus; - + if (!gNumMCUSRemaining) return PJPG_NO_MORE_BLOCKS; - + status = decodeNextMCU(); if ((status) || (gCallbackStatus)) return gCallbackStatus ? gCallbackStatus : status; - + gNumMCUSRemaining--; - + return 0; } //------------------------------------------------------------------------------ unsigned char pjpeg_decode_init(pjpeg_image_info_t *pInfo, pjpeg_need_bytes_callback_t pNeed_bytes_callback, void *pCallback_data, unsigned char reduce) { uint8 status; - + pInfo->m_width = 0; pInfo->m_height = 0; pInfo->m_comps = 0; pInfo->m_MCUSPerRow = 0; pInfo->m_MCUSPerCol = 0; pInfo->m_scanType = PJPG_GRAYSCALE; @@ -2285,11 +2285,11 @@ unsigned char pjpeg_decode_init(pjpeg_image_info_t *pInfo, pjpeg_need_bytes_call g_pCallback_data = pCallback_data; gCallbackStatus = 0; gReduce = reduce; - + status = init(); if ((status) || (gCallbackStatus)) return gCallbackStatus ? gCallbackStatus : status; - + status = locateSOFMarker(); if ((status) || (gCallbackStatus)) return gCallbackStatus ? gCallbackStatus : status; @@ -2307,6 +2307,6 @@ unsigned char pjpeg_decode_init(pjpeg_image_info_t *pInfo, pjpeg_need_bytes_call pInfo->m_MCUSPerRow = gMaxMCUSPerRow; pInfo->m_MCUSPerCol = gMaxMCUSPerCol; pInfo->m_MCUWidth = gMaxMCUXSize; pInfo->m_MCUHeight = gMaxMCUYSize; pInfo->m_pMCUBufR = gMCUBufR; pInfo->m_pMCUBufG = gMCUBufG; pInfo->m_pMCUBufB = gMCUBufB; - + return 0; } diff --git a/src/picojpeg/picojpeg.h b/src/picojpeg/picojpeg.h index be26aaed..21792c7e 100644 --- a/src/picojpeg/picojpeg.h +++ b/src/picojpeg/picojpeg.h @@ -63,7 +63,7 @@ enum PJPG_UNSUPPORTED_COMP_IDENT, PJPG_UNSUPPORTED_QUANT_TABLE, PJPG_UNSUPPORTED_MODE, // picojpeg doesn't support progressive JPEG's -}; +}; // Scan types typedef enum @@ -80,29 +80,29 @@ typedef struct // Image resolution int m_width; int m_height; - + // Number of components (1 or 3) int m_comps; - + // Total number of minimum coded units (MCU's) per row/col. int m_MCUSPerRow; int m_MCUSPerCol; - + // Scan type pjpeg_scan_type_t m_scanType; - + // MCU width/height in pixels (each is either 8 or 16 depending on the scan type) int m_MCUWidth; int m_MCUHeight; // m_pMCUBufR, m_pMCUBufG, and m_pMCUBufB are pointers to internal MCU Y or RGB pixel component buffers. // Each time pjpegDecodeMCU() is called successfully these buffers will be filled with 8x8 pixel blocks of Y or RGB pixels. - // Each MCU consists of (m_MCUWidth/8)*(m_MCUHeight/8) Y/RGB blocks: 1 for greyscale/no subsampling, 2 for H1V2/H2V1, or 4 blocks for H2V2 sampling factors. + // Each MCU consists of (m_MCUWidth/8)*(m_MCUHeight/8) Y/RGB blocks: 1 for greyscale/no subsampling, 2 for H1V2/H2V1, or 4 blocks for H2V2 sampling factors. // Each block is a contiguous array of 64 (8x8) bytes of a single component: either Y for grayscale images, or R, G or B components for color images. // // The 8x8 pixel blocks are organized in these byte arrays like this: // - // PJPG_GRAYSCALE: Each MCU is decoded to a single block of 8x8 grayscale pixels. + // PJPG_GRAYSCALE: Each MCU is decoded to a single block of 8x8 grayscale pixels. // Only the values in m_pMCUBufR are valid. Each 8 bytes is a row of pixels (raster order: left to right, top to bottom) from the 8x8 block. // // PJPG_H1V1: Each MCU contains is decoded to a single block of 8x8 RGB pixels. @@ -110,12 +110,12 @@ typedef struct // PJPG_YH2V1: Each MCU is decoded to 2 blocks, or 16x8 pixels. // The 2 RGB blocks are at byte offsets: 0, 64 // - // PJPG_YH1V2: Each MCU is decoded to 2 blocks, or 8x16 pixels. - // The 2 RGB blocks are at byte offsets: 0, + // PJPG_YH1V2: Each MCU is decoded to 2 blocks, or 8x16 pixels. + // The 2 RGB blocks are at byte offsets: 0, // 128 // // PJPG_YH2V2: Each MCU is decoded to 4 blocks, or 16x16 pixels. - // The 2x2 block array is organized at byte offsets: 0, 64, + // The 2x2 block array is organized at byte offsets: 0, 64, // 128, 192 // // It is up to the caller to copy or blit these pixels from these buffers into the destination bitmap. diff --git a/src/picojpeg/picojpeg_test.c b/src/picojpeg/picojpeg_test.c index 0f44f09c..e94c6022 100644 --- a/src/picojpeg/picojpeg_test.c +++ b/src/picojpeg/picojpeg_test.c @@ -1,5 +1,3 @@ - - /* BEEBS picobenchmark benchmark Copyright (C) 2014 Embecosm Limited and University of Bristol @@ -28,51 +26,91 @@ /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) +#define LOCAL_SCALE_FACTOR 5 const unsigned char jpeg_data[] = { - 0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01, 0x01, 0x01, 0x00, 0x48, - 0x00, 0x48, 0x00, 0x00, 0xff, 0xdb, 0x00, 0x43, 0x00, 0x50, 0x37, 0x3c, 0x46, 0x3c, 0x32, 0x50, - 0x46, 0x41, 0x46, 0x5a, 0x55, 0x50, 0x5f, 0x78, 0xc8, 0x82, 0x78, 0x6e, 0x6e, 0x78, 0xf5, 0xaf, - 0xb9, 0x91, 0xc8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0x55, 0x5a, - 0x5a, 0x78, 0x69, 0x78, 0xeb, 0x82, 0x82, 0xeb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0x00, 0x11, 0x08, 0x00, 0x40, 0x00, 0x33, 0x03, 0x01, 0x11, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, - 0x01, 0xff, 0xc4, 0x00, 0x18, 0x00, 0x00, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x00, 0x04, 0xff, 0xc4, 0x00, 0x26, 0x10, - 0x00, 0x02, 0x02, 0x01, 0x03, 0x03, 0x04, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x02, 0x00, 0x11, 0x03, 0x12, 0x21, 0x31, 0x41, 0x61, 0x71, 0x04, 0x22, 0x53, 0x91, 0x13, - 0x23, 0x51, 0x62, 0xff, 0xc4, 0x00, 0x15, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xc4, 0x00, 0x14, 0x11, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0xc7, 0x88, - 0x0b, 0x28, 0x4d, 0x66, 0xe1, 0x02, 0xcf, 0x58, 0x05, 0x45, 0x88, 0x00, 0xa9, 0x10, 0x34, 0x0e, - 0xaf, 0x6f, 0x68, 0x54, 0x33, 0x64, 0x03, 0x61, 0x02, 0x6a, 0x49, 0xdb, 0x49, 0x84, 0x59, 0x50, - 0x91, 0x50, 0xa0, 0x3d, 0xa4, 0x80, 0x7c, 0x88, 0x18, 0xd5, 0x48, 0x05, 0x09, 0x43, 0xeb, 0xff, - 0x00, 0x2b, 0xf5, 0x02, 0x78, 0xd4, 0x1c, 0xac, 0x48, 0x10, 0x8e, 0xb5, 0x55, 0xa8, 0x0c, 0xa5, - 0x2f, 0xdb, 0x52, 0x2a, 0x19, 0x53, 0xf6, 0x82, 0x04, 0xa1, 0x0e, 0x45, 0xf8, 0x84, 0x0d, 0xad, - 0x7e, 0x21, 0x20, 0xd0, 0x30, 0x04, 0x93, 0x5c, 0x99, 0x43, 0xe2, 0xc6, 0x57, 0x20, 0xd4, 0xd7, - 0x7d, 0x20, 0x3a, 0xe1, 0x40, 0xf6, 0x49, 0xf1, 0x20, 0xa3, 0x8b, 0x17, 0xc5, 0x09, 0x47, 0x26, - 0x35, 0x05, 0xb5, 0x1e, 0x20, 0x75, 0x02, 0x95, 0xc0, 0xfa, 0x81, 0xcf, 0x52, 0x0c, 0x6c, 0x0d, - 0xa0, 0x25, 0xbd, 0xdd, 0xd1, 0xf3, 0x2a, 0x28, 0x43, 0xb0, 0x04, 0x0e, 0x3a, 0xdc, 0x29, 0xb2, - 0x13, 0xf8, 0x6a, 0x11, 0x25, 0x53, 0x22, 0xa9, 0x7d, 0xe0, 0x2e, 0xa8, 0x06, 0xc1, 0xda, 0xa0, - 0x29, 0x21, 0x4d, 0x30, 0x35, 0x2a, 0x28, 0xb9, 0x17, 0x85, 0x06, 0x15, 0x50, 0x97, 0x8c, 0xd8, - 0xef, 0x20, 0xe5, 0x01, 0xf9, 0xd3, 0x52, 0xa1, 0xb5, 0x0e, 0xb0, 0x14, 0x90, 0x39, 0x32, 0x28, - 0xe2, 0x60, 0xd9, 0x17, 0xcc, 0xa2, 0xd9, 0xb1, 0x02, 0x35, 0x58, 0x1e, 0x60, 0x0c, 0x58, 0x95, - 0x06, 0xa6, 0x20, 0xf8, 0x90, 0x3b, 0x67, 0x41, 0xb0, 0xb3, 0x02, 0x4f, 0x9c, 0x55, 0x40, 0x8e, - 0xb5, 0xfe, 0x09, 0x51, 0x12, 0xd7, 0x01, 0xfd, 0x3b, 0x11, 0x99, 0x7b, 0x98, 0x55, 0x7d, 0x4b, - 0xbb, 0x64, 0x00, 0xec, 0xbd, 0x04, 0x05, 0x45, 0x62, 0x36, 0xb2, 0x3b, 0x42, 0x1b, 0x2a, 0x1c, - 0x40, 0x74, 0xb8, 0x11, 0x06, 0x00, 0xb8, 0x1f, 0xff, 0xd9 + 0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, + 0x49, 0x46, 0x00, 0x01, 0x01, 0x01, 0x00, 0x48, + 0x00, 0x48, 0x00, 0x00, 0xff, 0xdb, 0x00, 0x43, + 0x00, 0x50, 0x37, 0x3c, 0x46, 0x3c, 0x32, 0x50, + 0x46, 0x41, 0x46, 0x5a, 0x55, 0x50, 0x5f, 0x78, + 0xc8, 0x82, 0x78, 0x6e, 0x6e, 0x78, 0xf5, 0xaf, + 0xb9, 0x91, 0xc8, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0x55, 0x5a, + 0x5a, 0x78, 0x69, 0x78, 0xeb, 0x82, 0x82, 0xeb, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0x00, 0x11, 0x08, 0x00, 0x40, 0x00, 0x33, 0x03, + 0x01, 0x11, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, + 0x01, 0xff, 0xc4, 0x00, 0x18, 0x00, 0x00, 0x03, + 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, + 0x03, 0x00, 0x04, 0xff, 0xc4, 0x00, 0x26, 0x10, + 0x00, 0x02, 0x02, 0x01, 0x03, 0x03, 0x04, 0x03, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x02, 0x00, 0x11, 0x03, 0x12, 0x21, 0x31, + 0x41, 0x61, 0x71, 0x04, 0x22, 0x53, 0x91, 0x13, + 0x23, 0x51, 0x62, 0xff, 0xc4, 0x00, 0x15, 0x01, + 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0xff, 0xc4, 0x00, 0x14, 0x11, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, + 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0xc7, 0x88, + 0x0b, 0x28, 0x4d, 0x66, 0xe1, 0x02, 0xcf, 0x58, + 0x05, 0x45, 0x88, 0x00, 0xa9, 0x10, 0x34, 0x0e, + 0xaf, 0x6f, 0x68, 0x54, 0x33, 0x64, 0x03, 0x61, + 0x02, 0x6a, 0x49, 0xdb, 0x49, 0x84, 0x59, 0x50, + 0x91, 0x50, 0xa0, 0x3d, 0xa4, 0x80, 0x7c, 0x88, + 0x18, 0xd5, 0x48, 0x05, 0x09, 0x43, 0xeb, 0xff, + 0x00, 0x2b, 0xf5, 0x02, 0x78, 0xd4, 0x1c, 0xac, + 0x48, 0x10, 0x8e, 0xb5, 0x55, 0xa8, 0x0c, 0xa5, + 0x2f, 0xdb, 0x52, 0x2a, 0x19, 0x53, 0xf6, 0x82, + 0x04, 0xa1, 0x0e, 0x45, 0xf8, 0x84, 0x0d, 0xad, + 0x7e, 0x21, 0x20, 0xd0, 0x30, 0x04, 0x93, 0x5c, + 0x99, 0x43, 0xe2, 0xc6, 0x57, 0x20, 0xd4, 0xd7, + 0x7d, 0x20, 0x3a, 0xe1, 0x40, 0xf6, 0x49, 0xf1, + 0x20, 0xa3, 0x8b, 0x17, 0xc5, 0x09, 0x47, 0x26, + 0x35, 0x05, 0xb5, 0x1e, 0x20, 0x75, 0x02, 0x95, + 0xc0, 0xfa, 0x81, 0xcf, 0x52, 0x0c, 0x6c, 0x0d, + 0xa0, 0x25, 0xbd, 0xdd, 0xd1, 0xf3, 0x2a, 0x28, + 0x43, 0xb0, 0x04, 0x0e, 0x3a, 0xdc, 0x29, 0xb2, + 0x13, 0xf8, 0x6a, 0x11, 0x25, 0x53, 0x22, 0xa9, + 0x7d, 0xe0, 0x2e, 0xa8, 0x06, 0xc1, 0xda, 0xa0, + 0x29, 0x21, 0x4d, 0x30, 0x35, 0x2a, 0x28, 0xb9, + 0x17, 0x85, 0x06, 0x15, 0x50, 0x97, 0x8c, 0xd8, + 0xef, 0x20, 0xe5, 0x01, 0xf9, 0xd3, 0x52, 0xa1, + 0xb5, 0x0e, 0xb0, 0x14, 0x90, 0x39, 0x32, 0x28, + 0xe2, 0x60, 0xd9, 0x17, 0xcc, 0xa2, 0xd9, 0xb1, + 0x02, 0x35, 0x58, 0x1e, 0x60, 0x0c, 0x58, 0x95, + 0x06, 0xa6, 0x20, 0xf8, 0x90, 0x3b, 0x67, 0x41, + 0xb0, 0xb3, 0x02, 0x4f, 0x9c, 0x55, 0x40, 0x8e, + 0xb5, 0xfe, 0x09, 0x51, 0x12, 0xd7, 0x01, 0xfd, + 0x3b, 0x11, 0x99, 0x7b, 0x98, 0x55, 0x7d, 0x4b, + 0xbb, 0x64, 0x00, 0xec, 0xbd, 0x04, 0x05, 0x45, + 0x62, 0x36, 0xb2, 0x3b, 0x42, 0x1b, 0x2a, 0x1c, + 0x40, 0x74, 0xb8, 0x11, 0x06, 0x00, 0xb8, 0x1f, + 0xff, 0xd9 }; + unsigned jpeg_off = 0; #define MIN(a,b) ((a)<(b)?(a):(b)) -unsigned char pjpeg_need_bytes_callback(unsigned char* pBuf, unsigned char buf_size, unsigned char *pBytes_actually_read, void *pCallback_data) +unsigned char pjpeg_need_bytes_callback(unsigned char *pBuf, + unsigned char buf_size, + unsigned char *pBytes_actually_read, + void *pCallback_data) { unsigned n = MIN(sizeof(jpeg_data) - jpeg_off, buf_size); @@ -83,13 +121,45 @@ unsigned char pjpeg_need_bytes_callback(unsigned char* pBuf, unsigned char buf_s } - -/* This benchmark does not support verification */ +pjpeg_image_info_t pInfo; int verify_benchmark (int res __attribute ((unused)) ) { - return -1; + static const unsigned char r_ref[64] = { + 33, 33, 33, 33, 33, 33, 33, 33, + 32, 32, 32, 32, 32, 32, 32, 32, + 29, 29, 29, 29, 29, 29, 29, 29, + 25, 25, 25, 25, 25, 25, 25, 25, + 21, 21, 21, 21, 21, 21, 21, 21, + 17, 17, 17, 17, 17, 17, 17, 17, + 14, 14, 14, 14, 14, 14, 14, 14, + 13, 13, 13, 13, 13, 13, 13, 13 + }; + static const unsigned char g_ref[64] = { + 53, 53, 53, 53, 53, 53, 53, 53, + 52, 52, 52, 52, 52, 52, 52, 52, + 49, 49, 49, 49, 49, 49, 49, 49, + 45, 45, 45, 45, 45, 45, 45, 45, + 41, 41, 41, 41, 41, 41, 41, 41, + 37, 37, 37, 37, 37, 37, 37, 37, + 34, 34, 34, 34, 34, 34, 34, 34, + 33, 33, 33, 33, 33, 33, 33, 33 + }; + static const unsigned char b_ref[64] = { + 67, 67, 67, 67, 67, 67, 67, 67, + 66, 66, 66, 66, 66, 66, 66, 66, + 63, 63, 63, 63, 63, 63, 63, 63, + 59, 59, 59, 59, 59, 59, 59, 59, + 55, 55, 55, 55, 55, 55, 55, 55, + 51, 51, 51, 51, 51, 51, 51, 51, + 48, 48, 48, 48, 48, 48, 48, 48, + 47, 47, 47, 47, 47, 47, 47, 47 + }; + + return (0 == memcmp (pInfo.m_pMCUBufR, r_ref, 64)) + && (0 == memcmp (pInfo.m_pMCUBufG, g_ref, 64)) + && (0 == memcmp (pInfo.m_pMCUBufB, b_ref, 64)); } @@ -102,21 +172,24 @@ initialise_benchmark (void) int benchmark (void) { - pjpeg_image_info_t pInfo; - unsigned char status; + int i; - jpeg_off = 0; + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + { + unsigned char status; - status = pjpeg_decode_init(&pInfo, pjpeg_need_bytes_callback, 0, 0); + jpeg_off = 0; - for(;;) - { - status = pjpeg_decode_mcu(); + status = pjpeg_decode_init(&pInfo, pjpeg_need_bytes_callback, 0, 0); - if(status == PJPG_NO_MORE_BLOCKS) - break; - } - return 0; -} + for(;;) + { + status = pjpeg_decode_mcu(); + if(status == PJPG_NO_MORE_BLOCKS) + break; + } + } + return 0; +} diff --git a/src/prime/Makefile.am b/src/prime/Makefile.am index 6e3984ed..c0af3a2c 100644 --- a/src/prime/Makefile.am +++ b/src/prime/Makefile.am @@ -34,6 +34,7 @@ libprime_la_SOURCES = libprime.c prime_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libprime.la \ + $(top_builddir)/support/libbeebsc.la \ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) diff --git a/src/prime/Makefile.in b/src/prime/Makefile.in index f8bdbbe8..f2e022e4 100644 --- a/src/prime/Makefile.in +++ b/src/prime/Makefile.in @@ -171,6 +171,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_PRIME_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_PRIME_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_PRIME_TRUE@ libprime.la \ +@ENABLED_BENCHMARK_PRIME_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_PRIME_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_PRIME_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_PRIME_TRUE@ $(am__DEPENDENCIES_1) @@ -393,6 +394,7 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_PRIME_TRUE@prime_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_PRIME_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_PRIME_TRUE@ libprime.la \ +@ENABLED_BENCHMARK_PRIME_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_PRIME_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/prime/libprime.c b/src/prime/libprime.c index 916594e1..bf197306 100644 --- a/src/prime/libprime.c +++ b/src/prime/libprime.c @@ -25,7 +25,7 @@ /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) +#define LOCAL_SCALE_FACTOR 283 typedef unsigned char bool; typedef unsigned long ulong; @@ -68,19 +68,23 @@ ulong y; int benchmark (void) { - swap (&x, &y); - result = (!(prime(x) && prime(y))); - return 0; + int i; + + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + { + x = 21649L; + y = 513239L; + + swap (&x, &y); + result = (!(prime(x) && prime(y))); + } + + return result; } void initialise_benchmark() { - x = 21649L; - y = 513239L; } int verify_benchmark(int unused) { - int expected = 0; - if (result != expected) - return 0; - return 1; + return 0 == result; } diff --git a/src/qrduino/Makefile.am b/src/qrduino/Makefile.am index 7a0ba384..1530bae0 100644 --- a/src/qrduino/Makefile.am +++ b/src/qrduino/Makefile.am @@ -29,12 +29,18 @@ bin_PROGRAMS = qrduino noinst_LTLIBRARIES = libqrduino.la qrduino_SOURCES = -libqrduino_la_SOURCES = qrtest.c qrencode.c qrencode.h qrframe.c ecctable.h qrbits.h +libqrduino_la_SOURCES = qrtest.c \ + qrencode.c \ + qrencode.h \ + qrframe.c \ + ecctable.h \ + qrbits.h qrduino_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libqrduino.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) diff --git a/src/qrduino/Makefile.in b/src/qrduino/Makefile.in index 734a747c..7626b658 100644 --- a/src/qrduino/Makefile.in +++ b/src/qrduino/Makefile.in @@ -173,6 +173,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_QRDUINO_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_QRDUINO_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_QRDUINO_TRUE@ libqrduino.la \ +@ENABLED_BENCHMARK_QRDUINO_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_QRDUINO_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_QRDUINO_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_QRDUINO_TRUE@ $(am__DEPENDENCIES_1) @@ -391,11 +392,18 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_QRDUINO_TRUE@LIBM = $(if $(DUMMY_LIBM),$(DUMMY_LIBM),-lm) @ENABLED_BENCHMARK_QRDUINO_TRUE@noinst_LTLIBRARIES = libqrduino.la @ENABLED_BENCHMARK_QRDUINO_TRUE@qrduino_SOURCES = -@ENABLED_BENCHMARK_QRDUINO_TRUE@libqrduino_la_SOURCES = qrtest.c qrencode.c qrencode.h qrframe.c ecctable.h qrbits.h +@ENABLED_BENCHMARK_QRDUINO_TRUE@libqrduino_la_SOURCES = qrtest.c \ +@ENABLED_BENCHMARK_QRDUINO_TRUE@ qrencode.c \ +@ENABLED_BENCHMARK_QRDUINO_TRUE@ qrencode.h \ +@ENABLED_BENCHMARK_QRDUINO_TRUE@ qrframe.c \ +@ENABLED_BENCHMARK_QRDUINO_TRUE@ ecctable.h \ +@ENABLED_BENCHMARK_QRDUINO_TRUE@ qrbits.h + @ENABLED_BENCHMARK_QRDUINO_TRUE@qrduino_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_QRDUINO_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_QRDUINO_TRUE@ libqrduino.la \ -@ENABLED_BENCHMARK_QRDUINO_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_QRDUINO_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_QRDUINO_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/qrduino/qrframe.c b/src/qrduino/qrframe.c index 58d4a0b6..20cbff0e 100644 --- a/src/qrduino/qrframe.c +++ b/src/qrduino/qrframe.c @@ -24,71 +24,9 @@ #include #include -/* BEEBS heap is just an array */ +/* Header for BEEBS library calls */ -#include - -#define HEAP_SIZE 8192 -static char heap[HEAP_SIZE]; -static void *heap_ptr; -static void *heap_end; - -/* Initialize the BEEBS heap pointers */ - -void -init_heap (void) -{ - heap_ptr = (void *) heap; - heap_end = heap_ptr + HEAP_SIZE; -} - -/* BEEBS version of malloc. - - This is primarily to reduce library and OS dependencies. Malloc is - generally not used in embedded code, or if it is, only in well defined - contexts to pre-allocate a fixed amount of memory. So this simplistic - implementation is just fine. */ - -static void * -malloc_beebs (size_t size) -{ - void *new_ptr = heap_ptr; - - if (((heap_ptr + size) > heap_end) || (0 == size)) - return NULL; - else - { - heap_ptr += size; - return new_ptr; - } -} - -/* BEEBS version of calloc. - - Implement as wrapper for malloc */ - -static void * -calloc_beebs (size_t nmemb, size_t size) -{ - void *new_ptr = malloc_beebs (nmemb * size); - - /* Calloc is defined to zero the memory. OK to use a function here, because - it will be handled specially by the compiler anyway. */ - - if (NULL != new_ptr) - memset (new_ptr, 0, nmemb * size); - - return new_ptr; -} - -/* BEEBS version of free. - - For our simplified version of memory handling, free can just do nothing. */ - -static void -free_beebs (void *ptr) -{ -} +#include "beebsc.h" #ifndef __AVR__ #define PROGMEM diff --git a/src/qrduino/qrtest.c b/src/qrduino/qrtest.c index 60d577ba..3513058e 100644 --- a/src/qrduino/qrtest.c +++ b/src/qrduino/qrtest.c @@ -27,7 +27,12 @@ /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 8) +#define LOCAL_SCALE_FACTOR 6 + +/* BEEBS heap is just an array */ + +#define HEAP_SIZE 8192 +static char heap[HEAP_SIZE]; static const char *encode; static int size; @@ -35,39 +40,37 @@ static int size; int benchmark (void) { + static const char *in_encode = "http://www.mageec.com"; + int i; + + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + { + encode = in_encode; + size = 22; + init_heap_beebs ((void *) heap, HEAP_SIZE); + + initeccsize(1, size); - initeccsize(1, size); + memcpy(strinbuf, encode, size); - memcpy(strinbuf, encode, size); + initframe(); + qrencode(); + freeframe(); + freeecc(); + } - initframe(); - qrencode(); - freeframe(); - freeecc(); return 0; } -extern void init_heap (void); - void initialise_benchmark() { - static const char *in_encode = "http://www.mageec.com"; - encode = in_encode; - size = 22; - init_heap (); } int verify_benchmark(int unused) { - int i; - // #include - // for (i=0; i<22; i++) - // printf("%d,", strinbuf[i]); - // maybe should be a char - int expected[22] = - {254,101,63,128,130,110,160,128,186,65,46, - 128,186,38,46,128,186,9,174,128,130,20}; - for (i=0; i<22; i++) - if (strinbuf[i] != expected[i]) - return 0; - return 1; -} + unsigned char expected[22] = { + 254, 101, 63, 128, 130, 110, 160, 128, 186, 65, 46, + 128, 186, 38, 46, 128, 186, 9, 174, 128, 130, 20 + }; + return (0 == memcmp (strinbuf, expected, 22 * sizeof (strinbuf[0]))) + && check_heap_beebs ((void *) heap); +} diff --git a/src/qsort/Makefile.am b/src/qsort/Makefile.am index f11e434b..d1bc8fc7 100644 --- a/src/qsort/Makefile.am +++ b/src/qsort/Makefile.am @@ -34,6 +34,7 @@ libqsort_la_SOURCES = libqsort.c qsort_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libqsort.la \ + $(top_builddir)/support/libbeebsc.la \ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) diff --git a/src/qsort/Makefile.in b/src/qsort/Makefile.in index ecae81cf..5a77508a 100644 --- a/src/qsort/Makefile.in +++ b/src/qsort/Makefile.in @@ -171,6 +171,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_QSORT_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_QSORT_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_QSORT_TRUE@ libqsort.la \ +@ENABLED_BENCHMARK_QSORT_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_QSORT_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_QSORT_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_QSORT_TRUE@ $(am__DEPENDENCIES_1) @@ -393,6 +394,7 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_QSORT_TRUE@qsort_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_QSORT_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_QSORT_TRUE@ libqsort.la \ +@ENABLED_BENCHMARK_QSORT_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_QSORT_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/qsort/libqsort.c b/src/qsort/libqsort.c index c684af22..73873c96 100644 --- a/src/qsort/libqsort.c +++ b/src/qsort/libqsort.c @@ -1,5 +1,3 @@ - - /* BEEBS qsort-exam benchmark Copyright (C) 2014 Embecosm Limited and University of Bristol @@ -21,11 +19,12 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ +#include #include "support.h" /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) +#define LOCAL_SCALE_FACTOR 965 /*************************************************************************/ /* */ @@ -75,16 +74,21 @@ #define M 7 #define NSTACK 50 -float arr[20] = { - 5, 4, 10.3, 1.1, 5.7, 100, 231, 111, 49.5, 99, - 10, 150, 222.22, 101, 77, 44, 35, 20.54, 99.99, 88.88 +static const float arr_ref[20] = { + 5.0, 4.0, 10.3, 1.1, 5.7, 100.0, 231.0, 111.0, 49.5, 99.0, + 10.0, 150.0, 222.22, 101.0, 77.0, 44.0, 35.0, 20.54, 99.99, 88.88 }; +static float arr[20]; + int istack[100]; +/* Fix for C. The original program assumed the values were in arr[1] to + arr[n]. This version assumes arr[0] to arr[n-1]. */ + void sort(unsigned long n) { - unsigned long i,ir=n,j,k,l=1; + unsigned long i,ir=n-1,j,k,l=0; int jstack=0; float a,temp; @@ -140,13 +144,17 @@ void sort(unsigned long n) } - -/* This benchmark does not support verification */ - int verify_benchmark (int res __attribute ((unused)) ) { - return -1; + static const float arr_exp[20] = { + 1.10, 4.0, 5.0, 5.70, 10.0, + 10.30, 20.54, 35.0, 44.0, 49.50, + 77.0, 88.88, 99.0, 99.99, 100.0, + 101.0, 111.0, 150.0, 222.22, 231.00 + }; + + return 0 == memcmp (arr, arr_exp, 20 * sizeof (arr[0])); } @@ -159,7 +167,14 @@ initialise_benchmark (void) int benchmark() { - sort(20); + int i; + + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + { + memcpy (arr, arr_ref, 20 * sizeof (arr[0])); + sort(20); + } + return 0; } diff --git a/src/qurt/Makefile.am b/src/qurt/Makefile.am index d3614fed..e803b943 100644 --- a/src/qurt/Makefile.am +++ b/src/qurt/Makefile.am @@ -34,8 +34,8 @@ libqurt_la_SOURCES = libqurt.c qurt_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libqurt.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) - - + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) \ + $(LIBM) endif diff --git a/src/qurt/Makefile.in b/src/qurt/Makefile.in index 2613a571..2da36cf0 100644 --- a/src/qurt/Makefile.in +++ b/src/qurt/Makefile.in @@ -170,9 +170,11 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_QURT_TRUE@qurt_DEPENDENCIES = \ @ENABLED_BENCHMARK_QURT_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_QURT_TRUE@ $(top_builddir)/support/libsupport.la \ -@ENABLED_BENCHMARK_QURT_TRUE@ libqurt.la $(am__DEPENDENCIES_1) \ +@ENABLED_BENCHMARK_QURT_TRUE@ libqurt.la \ +@ENABLED_BENCHMARK_QURT_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_QURT_TRUE@ $(am__DEPENDENCIES_1) \ -@ENABLED_BENCHMARK_QURT_TRUE@ $(am__DEPENDENCIES_1) +@ENABLED_BENCHMARK_QURT_TRUE@ $(am__DEPENDENCIES_1) \ +@ENABLED_BENCHMARK_QURT_TRUE@ $(am__DEPENDENCIES_1) $(LIBM) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false @@ -392,7 +394,9 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_QURT_TRUE@qurt_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_QURT_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_QURT_TRUE@ libqurt.la \ -@ENABLED_BENCHMARK_QURT_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_QURT_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_QURT_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) \ +@ENABLED_BENCHMARK_QURT_TRUE@ $(LIBM) all: all-am diff --git a/src/qurt/libqurt.c b/src/qurt/libqurt.c index e81bf41f..b25dec21 100644 --- a/src/qurt/libqurt.c +++ b/src/qurt/libqurt.c @@ -1,5 +1,3 @@ - - /* BEEBS qurt benchmark ************************************************************************* @@ -70,11 +68,12 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ +#include #include "support.h" /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) +#define LOCAL_SCALE_FACTOR 215 float *a, x1[2], x2[2]; int flag; @@ -170,7 +169,10 @@ static float in3[] = {1.0, -4.0, 8.0}; int verify_benchmark (int res __attribute ((unused)) ) { - return -1; + return (fabs (x1[0] - 2.0) < 1.0e-6) + && (fabs (x1[1] - 2.0) < 1.0e-6) + && (fabs (x2[0] - 2.0) < 1.0e-6) + && (fabs (x2[1] + 2.0) < 1.0e-6); } @@ -183,13 +185,17 @@ initialise_benchmark (void) int benchmark (void) { - a = in1; - result = qurt(); - a = in2; - result = qurt(); - a = in3; - result = qurt(); + int i; + + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + { + a = in1; + result = qurt(); + a = in2; + result = qurt(); + a = in3; + result = qurt(); + } + return 0; } - - diff --git a/src/recursion/Makefile.am b/src/recursion/Makefile.am index 2bc36c0f..eb10c91f 100644 --- a/src/recursion/Makefile.am +++ b/src/recursion/Makefile.am @@ -34,7 +34,8 @@ librecursion_la_SOURCES = librecursion.c recursion_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ librecursion.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) diff --git a/src/recursion/Makefile.in b/src/recursion/Makefile.in index c99d4228..c7170252 100644 --- a/src/recursion/Makefile.in +++ b/src/recursion/Makefile.in @@ -172,6 +172,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_RECURSION_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_RECURSION_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_RECURSION_TRUE@ librecursion.la \ +@ENABLED_BENCHMARK_RECURSION_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_RECURSION_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_RECURSION_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_RECURSION_TRUE@ $(am__DEPENDENCIES_1) @@ -395,7 +396,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_RECURSION_TRUE@recursion_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_RECURSION_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_RECURSION_TRUE@ librecursion.la \ -@ENABLED_BENCHMARK_RECURSION_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_RECURSION_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_RECURSION_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/recursion/librecursion.c b/src/recursion/librecursion.c index 442b145c..3fb8d1f3 100644 --- a/src/recursion/librecursion.c +++ b/src/recursion/librecursion.c @@ -23,7 +23,7 @@ /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) +#define LOCAL_SCALE_FACTOR 2005 /* $Id: recursion.c,v 1.2 2005/04/04 11:34:58 csg Exp $ */ @@ -100,20 +100,21 @@ static int n; int benchmark(void) { - In = fib(n); + int i; + + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + { + n = 10; + In = fib(n); + } + return In; } void initialise_benchmark() { - n = 10; } int verify_benchmark(int r) { - int expected = 89; - if (r != expected) - return 0; - return 1; + return 89 == r; } - - diff --git a/src/rijndael/Makefile.am b/src/rijndael/Makefile.am index 4b2a72c4..3f93600b 100644 --- a/src/rijndael/Makefile.am +++ b/src/rijndael/Makefile.am @@ -35,7 +35,8 @@ librijndael_la_SOURCES = aes.c aes.h aestab.h aesxam.c rijndael_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ librijndael.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) rijndael_CFLAGS = -fno-strict-aliasing ${AM_CFLAGS} endif diff --git a/src/rijndael/Makefile.in b/src/rijndael/Makefile.in index 76d0f9f8..783a9da8 100644 --- a/src/rijndael/Makefile.in +++ b/src/rijndael/Makefile.in @@ -172,6 +172,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_RIJNDAEL_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_RIJNDAEL_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_RIJNDAEL_TRUE@ librijndael.la \ +@ENABLED_BENCHMARK_RIJNDAEL_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_RIJNDAEL_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_RIJNDAEL_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_RIJNDAEL_TRUE@ $(am__DEPENDENCIES_1) @@ -397,7 +398,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_RIJNDAEL_TRUE@rijndael_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_RIJNDAEL_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_RIJNDAEL_TRUE@ librijndael.la \ -@ENABLED_BENCHMARK_RIJNDAEL_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_RIJNDAEL_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_RIJNDAEL_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) @ENABLED_BENCHMARK_RIJNDAEL_TRUE@rijndael_CFLAGS = -fno-strict-aliasing ${AM_CFLAGS} all: all-am diff --git a/src/rijndael/aesxam.c b/src/rijndael/aesxam.c index 30cacc2c..d8b82ec7 100644 --- a/src/rijndael/aesxam.c +++ b/src/rijndael/aesxam.c @@ -61,6 +61,7 @@ #include #include +#include #include #include "aes.h" @@ -68,7 +69,7 @@ /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 9) +#define LOCAL_SCALE_FACTOR 4 #ifndef fpos_t #define fpos_t size_t @@ -78,47 +79,38 @@ #define RAND(a,b) (((a = 36969 * (a & 65535) + (a >> 16)) << 16) + (b = 18000 * (b & 65535) + (b >> 16)) ) -/* Yield a sequence of random numbers in the range [0, 2^15-1]. +static unsigned long fr_a[2], fr_mt, fr_count; +static char fr_r[4]; - The seed is always initialized to zero. long int is guaranteed to be at - least 32 bits. The seed only ever uses 31 bits (so is positive). - - For BEEBS this gets round different operating systems using different - multipliers and offsets and RAND_MAX variations. */ - -static int -rand_beebs () +void +initrand (void) { - static long int seed = 0; - - seed = (seed * 1103515245L + 12345) & ((1UL << 31) - 1); - return (int) (seed >> 16); - + memset (fr_a, 0, 2 * sizeof (fr_a[0])); + memset (fr_r, 0, 4 * sizeof (fr_r[0])); + fr_mt = 0L; + fr_count = 0L; } - void fillrand(byte *buf, int len) { - static unsigned long a[2], mt = 1, count = 4; - static char r[4]; int i; - if(mt) { - mt = 0; - /*cycles(a);*/ - a[0]=0xeaf3; - a[1]=0x35fe; + if(fr_mt) { + fr_mt = 0; + /*cycles(fr_a);*/ + fr_a[0]=0xeaf3; + fr_a[1]=0x35fe; } for(i = 0; i < len; ++i) { - if(count == 4) + if(fr_count == 4) { - *(unsigned long*)r = RAND(a[0], a[1]); - count = 0; + *(unsigned long*)fr_r = RAND(fr_a[0], fr_a[1]); + fr_count = 0; } - buf[i] = r[count++]; + buf[i] = fr_r[fr_count++]; } } @@ -187,13 +179,23 @@ int decfile(aes *ctx, byte *outbuf) char *presetkey="ABCDEF1234567890ABCDEF1234567890"; - -/* This benchmark does not support verification */ +byte encoutbuf[16], decoutbuf[16]; int -verify_benchmark (int res __attribute ((unused)) ) +verify_benchmark (int res) { - return -1; + static const byte enc_exp[16] = { + 0x8d, 0xc4, 0x5d, 0x44, 0x9b, 0x2d, 0x53, 0xec, + 0xf6, 0x65, 0x64, 0x1a, 0x3f, 0xc8, 0x52, 0x69 + }; + static const byte dec_exp[16] = { + 0x2a, 0xe1, 0x24, 0x42, 0x91, 0x4b, 0xd6, 0x4a, + 0xf5, 0x45, 0xaf, 0xc2, 0x84, 0xa9, 0x02, 0x55 + }; + + return (0 == res) + && (0 == memcmp (enc_exp, encoutbuf, 16 * sizeof (enc_exp[0]))) + && (0 == memcmp (dec_exp, decoutbuf, 16 * sizeof (dec_exp[0]))); } @@ -206,58 +208,57 @@ initialise_benchmark (void) int benchmark() { - char *cp=0, ch=0; - byte key[32]={0}; - int i=0, by=0, key_len=0, err=0; - byte encoutbuf[16], decoutbuf[16]; - - { - aes ctx = {0}; + static const aes ctx_ref = {0}; + int err; + int i; + + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + { + aes ctx; + char *cp=0, ch=0; + byte key[32]={0}; + int i=0, by=0, key_len=0; + + srand_beebs (0); + initrand (); + memset (encoutbuf, 0, 16 * sizeof (encoutbuf[0])); + memset (decoutbuf, 0, 16 * sizeof (decoutbuf[0])); + + err = 0; + ctx = ctx_ref; by=0; key_len=0; err = 0; cp = presetkey; /* this is a pointer to the hexadecimal key digits */ i = 0; /* this is a count for the input digits processed */ while(i < 64 && *cp) /* the maximum key length is 32 bytes and */ - { /* hence at most 64 hexadecimal digits */ - ch = *cp++; /* process a hexadecimal digit */ - if(ch >= '0' && ch <= '9') - by = (by << 4) + ch - '0'; - else if(ch >= 'A' && ch <= 'F') - by = (by << 4) + ch - 'A' + 10; - else /* error if not hexadecimal */ - { - err = -2; goto exit; - } - - /* store a key byte for each pair of hexadecimal digits */ - if(i++ & 1) - key[i / 2 - 1] = by & 0xff; - } + { /* hence at most 64 hexadecimal digits */ + ch = *cp++; /* process a hexadecimal digit */ + if(ch >= '0' && ch <= '9') + by = (by << 4) + ch - '0'; + else if(ch >= 'A' && ch <= 'F') + by = (by << 4) + ch - 'A' + 10; + else /* error if not hexadecimal */ + return -2; + + /* store a key byte for each pair of hexadecimal digits */ + if(i++ & 1) + key[i / 2 - 1] = by & 0xff; + } if(*cp) - { - err = -3; goto exit; - } + return -3; else if(i < 32 || (i & 15)) - { - err = -4; goto exit; - } + return -4; key_len = i / 2; set_key(key, key_len, enc, &ctx); - err = encfile(&ctx, encoutbuf); - set_key(key, key_len, dec, &ctx); - err = decfile(&ctx, decoutbuf); + } - } - -exit: - - return err; + return err; } diff --git a/src/select/Makefile.am b/src/select/Makefile.am index a55bb250..476c13ff 100644 --- a/src/select/Makefile.am +++ b/src/select/Makefile.am @@ -34,6 +34,8 @@ libselect_la_SOURCES = libselect.c select_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libselect.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) \ + $(LIBM) endif diff --git a/src/select/Makefile.in b/src/select/Makefile.in index bf3ca87c..507e9ee3 100644 --- a/src/select/Makefile.in +++ b/src/select/Makefile.in @@ -171,9 +171,10 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_SELECT_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_SELECT_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_SELECT_TRUE@ libselect.la \ +@ENABLED_BENCHMARK_SELECT_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_SELECT_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_SELECT_TRUE@ $(am__DEPENDENCIES_1) \ -@ENABLED_BENCHMARK_SELECT_TRUE@ $(am__DEPENDENCIES_1) +@ENABLED_BENCHMARK_SELECT_TRUE@ $(am__DEPENDENCIES_1) $(LIBM) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false @@ -393,7 +394,9 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_SELECT_TRUE@select_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_SELECT_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_SELECT_TRUE@ libselect.la \ -@ENABLED_BENCHMARK_SELECT_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_SELECT_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_SELECT_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) \ +@ENABLED_BENCHMARK_SELECT_TRUE@ $(LIBM) all: all-am diff --git a/src/select/libselect.c b/src/select/libselect.c index 0663c5db..f5a8ecfb 100644 --- a/src/select/libselect.c +++ b/src/select/libselect.c @@ -1,4 +1,3 @@ - /* BEEBS select benchmark SOURCE : Numerical Recipes in C - The Second Edition @@ -22,94 +21,127 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ +#include "math.h" +#include "string.h" #include "support.h" /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) - -#define SWAP(a,b) \ -do{ \ - temp=(a); \ - (a)=(b); \ - (b)=temp; \ -}while(0); \ - -float arr[20] = { - 5, 4, 10.3, 1.1, 5.7, 100, 231, 111, 49.5, 99, - 10, 150, 222.22, 101, 77, 44, 35, 20.54, 99.99, 888.88 +#define LOCAL_SCALE_FACTOR 1749 + +static const float arr_ref[20] = { + 5.00, 4.00, 10.30, 1.10, 5.70, + 100.00, 231.00, 111.00, 49.50, 99.00, + 10.00, 150.00, 222.22, 101.00, 77.00, + 44.00, 35.00, 20.54, 99.99, 888.88 }; +float arr[20]; + +static void +swap (unsigned long a, + unsigned long b) +{ + float t = arr[a]; + + arr[a] = arr[b]; + arr[b] = t; +} + +/* Fix for C. The original program assumed the values were in arr[1] to + arr[n]. This version assumes arr[0] to arr[n-1]. */ -float select(unsigned long k, unsigned long n) +float + select(unsigned long k, /* Element wanted */ + unsigned long n) /* Size of arr */ { - unsigned long i,ir,j,l,mid; - float a,temp; - int flag, flag2; - - l=1; - ir=n; - flag = flag2 = 0; - while (!flag) { - if (ir <= l+1) { - if (ir == l+1) - if (arr[ir] < arr[l]) { - SWAP(arr[l],arr[ir]) - } - flag = 1; - } else if (!flag) { - mid=(l+ir) >> 1; - SWAP(arr[mid],arr[l+1]) - if (arr[l+1] > arr[ir]) { - SWAP(arr[l+1],arr[ir]) - } - if (arr[l] > arr[ir]) { - SWAP(arr[l],arr[ir]) - } - if (arr[l+1]> arr[l]) { - SWAP(arr[l+1],arr[l]) - } - i=l+1; - j=ir; - a=arr[l]; - while (!flag2) { - i++; - while (arr[i] < a) i++; - j--; - while (arr[j] > a) j--; - if (j < i) flag2 = 1; - if (!flag2) SWAP(arr[i],arr[j]); - - } - arr[l]=arr[j]; - arr[j]=a; - if (j >= k) ir=j-1; - if (j <= k) l=i; - } + unsigned long i,ir,j,l,mid; + float a,temp; + int flag, flag2; + + l=0; + ir=n-1; + + while (1) + { + if (ir <= (l + 1)) + { + if (ir == (l + 1) && (arr[ir] < arr[l])) + swap (l, ir); + + return arr[k - 1]; + } + else + { + mid = (l + ir) >> 1; + swap (mid, l + 1); + + if (arr[l] > arr[ir]) + swap (l, ir); + if (arr[l + 1] > arr[ir]) + swap (l + 1, ir); + + if (arr[l] > arr[l + 1]) + swap (l, l + 1); + + i = l + 1; + j = ir; + a = arr[l + 1]; + + while (1) + { + do + i++; + while (arr[i] < a); + + do + j--; + while (arr[j] > a); + + if (j < i) + break; + + swap (i, j); + } + + arr[l + 1] = arr[j]; + arr[j] = a; + + if (j >= (k - 1)) + ir = j - 1; + + if (j <= (k - 1)) + l = i; } - return arr[k]; + } } static int x, y; +volatile float result; int benchmark (void) { - select(x, y); + int i; + + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + { + memcpy (arr, arr_ref, 20 * sizeof (arr[0])); + x = 10; + y = 20; + result = select(x, y); + } + return 0; } void initialise_benchmark() { - x = 10; - y = 20; } -/* This benchmark does not support verification */ - int -verify_benchmark (int res __attribute ((unused)) ) +verify_benchmark (int res) { - return -1; + return fabs (result - 49.50) < 1.0e-6; } diff --git a/src/sglib-arraybinsearch/Makefile.am b/src/sglib-arraybinsearch/Makefile.am index 6ba3b7f7..a319df82 100644 --- a/src/sglib-arraybinsearch/Makefile.am +++ b/src/sglib-arraybinsearch/Makefile.am @@ -34,6 +34,7 @@ libsglib_arraybinsearch_la_SOURCES = arraybinsearch.c sglib.h sglib_arraybinsearch_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libsglib-arraybinsearch.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) endif diff --git a/src/sglib-arraybinsearch/Makefile.in b/src/sglib-arraybinsearch/Makefile.in index efb0d9b5..61e4c286 100644 --- a/src/sglib-arraybinsearch/Makefile.in +++ b/src/sglib-arraybinsearch/Makefile.in @@ -171,6 +171,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_SGLIB_ARRAYBINSEARCH_TRUE@sglib_arraybinsearch_DEPENDENCIES = $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_SGLIB_ARRAYBINSEARCH_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_SGLIB_ARRAYBINSEARCH_TRUE@ libsglib-arraybinsearch.la \ +@ENABLED_BENCHMARK_SGLIB_ARRAYBINSEARCH_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_SGLIB_ARRAYBINSEARCH_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_SGLIB_ARRAYBINSEARCH_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_SGLIB_ARRAYBINSEARCH_TRUE@ $(am__DEPENDENCIES_1) @@ -395,7 +396,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_SGLIB_ARRAYBINSEARCH_TRUE@sglib_arraybinsearch_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_SGLIB_ARRAYBINSEARCH_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_SGLIB_ARRAYBINSEARCH_TRUE@ libsglib-arraybinsearch.la \ -@ENABLED_BENCHMARK_SGLIB_ARRAYBINSEARCH_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_SGLIB_ARRAYBINSEARCH_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_SGLIB_ARRAYBINSEARCH_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/sglib-arraybinsearch/arraybinsearch.c b/src/sglib-arraybinsearch/arraybinsearch.c index 214305b5..edc26b94 100644 --- a/src/sglib-arraybinsearch/arraybinsearch.c +++ b/src/sglib-arraybinsearch/arraybinsearch.c @@ -1,4 +1,3 @@ - /* BEEBS arraybinsearch benchmark Copyright (C) 2014 Embecosm Limited and University of Bristol @@ -25,7 +24,7 @@ /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) +#define LOCAL_SCALE_FACTOR 489 #include @@ -53,22 +52,26 @@ initialise_benchmark (void) int benchmark() { - volatile int cnt=0; - int tmp, index, i; - - index = 0; - for(i=0; i< 100; i++) { - tmp = array[i]; - SGLIB_ARRAY_BINARY_SEARCH(int, array, 0, i, tmp, SGLIB_NUMERIC_COMPARATOR, found, index); - cnt += index; - } - + volatile int cnt; + int i; + + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + { + int tmp, index, i; + cnt = 0; + + index = 0; + for(i=0; i< 100; i++) { + tmp = array[i]; + SGLIB_ARRAY_BINARY_SEARCH(int, array, 0, i, tmp, + SGLIB_NUMERIC_COMPARATOR, found, index); + cnt += index; + } + } + return cnt; } int verify_benchmark(int r) { - int expected = 2455; - if (r != expected) - return 0; - return 1; + return 2455 == r; } diff --git a/src/sglib-arrayheapsort/Makefile.am b/src/sglib-arrayheapsort/Makefile.am index ce1255d6..42dad24f 100644 --- a/src/sglib-arrayheapsort/Makefile.am +++ b/src/sglib-arrayheapsort/Makefile.am @@ -30,12 +30,13 @@ noinst_LTLIBRARIES = libsglib-arrayheapsort.la sglib_arrayheapsort_SOURCES = -libsglib_arrayheapsort_la_SOURCES = arraysort.c sglib.h +libsglib_arrayheapsort_la_SOURCES = arrayheapsort.c sglib.h libsglib_arrayheapsort_la_CPPFLAGS = -DHEAP_SORT ${AM_CPPFLAGS} sglib_arrayheapsort_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libsglib-arrayheapsort.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) endif diff --git a/src/sglib-arrayheapsort/Makefile.in b/src/sglib-arrayheapsort/Makefile.in index 87967da3..2970e1dc 100644 --- a/src/sglib-arrayheapsort/Makefile.in +++ b/src/sglib-arrayheapsort/Makefile.in @@ -154,8 +154,8 @@ CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libsglib_arrayheapsort_la_LIBADD = -am__libsglib_arrayheapsort_la_SOURCES_DIST = arraysort.c sglib.h -@ENABLED_BENCHMARK_SGLIB_ARRAYHEAPSORT_TRUE@am_libsglib_arrayheapsort_la_OBJECTS = libsglib_arrayheapsort_la-arraysort.lo +am__libsglib_arrayheapsort_la_SOURCES_DIST = arrayheapsort.c sglib.h +@ENABLED_BENCHMARK_SGLIB_ARRAYHEAPSORT_TRUE@am_libsglib_arrayheapsort_la_OBJECTS = libsglib_arrayheapsort_la-arrayheapsort.lo libsglib_arrayheapsort_la_OBJECTS = \ $(am_libsglib_arrayheapsort_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) @@ -171,6 +171,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_SGLIB_ARRAYHEAPSORT_TRUE@sglib_arrayheapsort_DEPENDENCIES = $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_SGLIB_ARRAYHEAPSORT_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_SGLIB_ARRAYHEAPSORT_TRUE@ libsglib-arrayheapsort.la \ +@ENABLED_BENCHMARK_SGLIB_ARRAYHEAPSORT_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_SGLIB_ARRAYHEAPSORT_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_SGLIB_ARRAYHEAPSORT_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_SGLIB_ARRAYHEAPSORT_TRUE@ $(am__DEPENDENCIES_1) @@ -391,12 +392,13 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_SGLIB_ARRAYHEAPSORT_TRUE@LIBM = $(if $(DUMMY_LIBM),$(DUMMY_LIBM),-lm) @ENABLED_BENCHMARK_SGLIB_ARRAYHEAPSORT_TRUE@noinst_LTLIBRARIES = libsglib-arrayheapsort.la @ENABLED_BENCHMARK_SGLIB_ARRAYHEAPSORT_TRUE@sglib_arrayheapsort_SOURCES = -@ENABLED_BENCHMARK_SGLIB_ARRAYHEAPSORT_TRUE@libsglib_arrayheapsort_la_SOURCES = arraysort.c sglib.h +@ENABLED_BENCHMARK_SGLIB_ARRAYHEAPSORT_TRUE@libsglib_arrayheapsort_la_SOURCES = arrayheapsort.c sglib.h @ENABLED_BENCHMARK_SGLIB_ARRAYHEAPSORT_TRUE@libsglib_arrayheapsort_la_CPPFLAGS = -DHEAP_SORT ${AM_CPPFLAGS} @ENABLED_BENCHMARK_SGLIB_ARRAYHEAPSORT_TRUE@sglib_arrayheapsort_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_SGLIB_ARRAYHEAPSORT_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_SGLIB_ARRAYHEAPSORT_TRUE@ libsglib-arrayheapsort.la \ -@ENABLED_BENCHMARK_SGLIB_ARRAYHEAPSORT_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_SGLIB_ARRAYHEAPSORT_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_SGLIB_ARRAYHEAPSORT_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am @@ -506,7 +508,7 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsglib_arrayheapsort_la-arraysort.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsglib_arrayheapsort_la-arrayheapsort.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -529,12 +531,12 @@ distclean-compile: @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< -libsglib_arrayheapsort_la-arraysort.lo: arraysort.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsglib_arrayheapsort_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsglib_arrayheapsort_la-arraysort.lo -MD -MP -MF $(DEPDIR)/libsglib_arrayheapsort_la-arraysort.Tpo -c -o libsglib_arrayheapsort_la-arraysort.lo `test -f 'arraysort.c' || echo '$(srcdir)/'`arraysort.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsglib_arrayheapsort_la-arraysort.Tpo $(DEPDIR)/libsglib_arrayheapsort_la-arraysort.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='arraysort.c' object='libsglib_arrayheapsort_la-arraysort.lo' libtool=yes @AMDEPBACKSLASH@ +libsglib_arrayheapsort_la-arrayheapsort.lo: arrayheapsort.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsglib_arrayheapsort_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsglib_arrayheapsort_la-arrayheapsort.lo -MD -MP -MF $(DEPDIR)/libsglib_arrayheapsort_la-arrayheapsort.Tpo -c -o libsglib_arrayheapsort_la-arrayheapsort.lo `test -f 'arrayheapsort.c' || echo '$(srcdir)/'`arrayheapsort.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsglib_arrayheapsort_la-arrayheapsort.Tpo $(DEPDIR)/libsglib_arrayheapsort_la-arrayheapsort.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='arrayheapsort.c' object='libsglib_arrayheapsort_la-arrayheapsort.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsglib_arrayheapsort_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsglib_arrayheapsort_la-arraysort.lo `test -f 'arraysort.c' || echo '$(srcdir)/'`arraysort.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsglib_arrayheapsort_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsglib_arrayheapsort_la-arrayheapsort.lo `test -f 'arrayheapsort.c' || echo '$(srcdir)/'`arrayheapsort.c mostlyclean-libtool: -rm -f *.lo diff --git a/src/sglib-arraysort/arraysort.c b/src/sglib-arrayheapsort/arrayheapsort.c similarity index 65% rename from src/sglib-arraysort/arraysort.c rename to src/sglib-arrayheapsort/arrayheapsort.c index 83ac4dc7..f59d9834 100644 --- a/src/sglib-arraysort/arraysort.c +++ b/src/sglib-arrayheapsort/arrayheapsort.c @@ -1,5 +1,3 @@ - - /* BEEBS arraysort benchmark Copyright (C) 2014 Embecosm Limited and University of Bristol @@ -21,12 +19,13 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ +#include #include "support.h" #include "sglib.h" /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) +#define LOCAL_SCALE_FACTOR 205 int array[100] = {14, 66, 12, 41, 86, 69, 19, 77, 68, 38, 26, 42, 37, 23, 17, 29, 55, 13, 90, 92, 76, 99, 10, 54, 57, 83, 40, 44, 75, 33, 24, 28, 80, 18, 78, 32, 93, 89, 52, 11, @@ -37,12 +36,23 @@ int array[100] = {14, 66, 12, 41, 86, 69, 19, 77, 68, 38, 26, 42, 37, 23, 17, 29 int array2[100]; -/* This benchmark does not support verification */ - int verify_benchmark (int res __attribute ((unused)) ) { - return -1; + static const int array_exp[100] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99 + }; + + return 0 == memcmp (array2, array_exp, 100 * sizeof (array[0])); } @@ -55,20 +65,13 @@ initialise_benchmark (void) int benchmark() { - volatile int cnt=0; - int i; + int i; - for(i = 0 ;i<100; ++i) - array2[i] = array[i]; + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + { + memcpy (array2, array, 100 * sizeof (array[0])); + SGLIB_ARRAY_SINGLE_HEAP_SORT(int, array2, 100, SGLIB_NUMERIC_COMPARATOR); + } -#ifdef QUICK_SORT - SGLIB_ARRAY_SINGLE_QUICK_SORT(int, array2, 100, SGLIB_NUMERIC_COMPARATOR); -#elif defined HEAP_SORT - SGLIB_ARRAY_SINGLE_HEAP_SORT(int, array2, 100, SGLIB_NUMERIC_COMPARATOR); -#else -#error "Expected QUICK_SORT or HEAP_SORT to be defined" -#endif - - return cnt; + return 0; } - diff --git a/src/sglib-arrayheapsort/arraysort.c b/src/sglib-arrayheapsort/arraysort.c deleted file mode 120000 index 099c21c9..00000000 --- a/src/sglib-arrayheapsort/arraysort.c +++ /dev/null @@ -1 +0,0 @@ -../sglib-arraysort/arraysort.c \ No newline at end of file diff --git a/src/sglib-arrayheapsort/sglib.h b/src/sglib-arrayheapsort/sglib.h deleted file mode 120000 index 3b5b2423..00000000 --- a/src/sglib-arrayheapsort/sglib.h +++ /dev/null @@ -1 +0,0 @@ -../sglib-arraysort/sglib.h \ No newline at end of file diff --git a/src/sglib-arrayheapsort/sglib.h b/src/sglib-arrayheapsort/sglib.h new file mode 100644 index 00000000..84dcaae4 --- /dev/null +++ b/src/sglib-arrayheapsort/sglib.h @@ -0,0 +1,1965 @@ +/* This file is part of the Bristol/Embecosm Embedded Benchmark Suite. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* + + This is SGLIB version 1.0.3 + + (C) by Marian Vittek, Bratislava, http://www.xref-tech.com/sglib, 2003-5 + + License Conditions: You can use a verbatim copy (including this + copyright notice) of sglib freely in any project, commercial or not. + You can also use derivative forms freely under terms of Open Source + Software license or under terms of GNU Public License. If you need + to use a derivative form in a commercial project, or you need sglib + under any other license conditions, contact the author. + + + +*/ + + +#ifndef _SGLIB__h_ +#define _SGLIB__h_ + +/* the assert is used exclusively to write unexpected error messages */ +#define assert(a) + + +/* ---------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- */ +/* - LEVEL - 0 INTERFACE - */ +/* ---------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- */ + + +/* ---------------------------------------------------------------------------- */ +/* ------------------------------ STATIC ARRAYS ------------------------------- */ +/* ---------------------------------------------------------------------------- */ + +/* + + Basic algorithms for sorting arrays. Multiple depending arrays can + be rearranged using user defined 'elem_exchangers' + +*/ + +/* HEAP - SORT (level 0) */ + +#define SGLIB_ARRAY_SINGLE_HEAP_SORT(type, a, max, comparator) {\ + SGLIB_ARRAY_HEAP_SORT(type, a, max, comparator, SGLIB_ARRAY_ELEMENTS_EXCHANGER);\ +} + +#define SGLIB_ARRAY_HEAP_SORT(type, a, max, comparator, elem_exchanger) {\ + int _k_;\ + for(_k_=(max)/2; _k_>=0; _k_--) {\ + SGLIB___ARRAY_HEAP_DOWN(type, a, _k_, max, comparator, elem_exchanger);\ + }\ + for(_k_=(max)-1; _k_>=0; _k_--) {\ + elem_exchanger(type, a, 0, _k_);\ + SGLIB___ARRAY_HEAP_DOWN(type, a, 0, _k_, comparator, elem_exchanger);\ + }\ +} + +#define SGLIB___ARRAY_HEAP_DOWN(type, a, ind, max, comparator, elem_exchanger) {\ + int _m_, _l_, _r_, _i_;\ + _i_ = (ind);\ + _m_ = _i_;\ + do {\ + _i_ = _m_; \ + _l_ = 2*_i_+1;\ + _r_ = _l_+1;\ + if (_l_ < (max)){\ + if (comparator(((a)[_m_]), ((a)[_l_])) < 0) _m_ = _l_;\ + if (_r_ < (max)) {\ + if (comparator(((a)[_m_]), ((a)[_r_])) < 0) _m_ = _r_;\ + }\ + }\ + if (_m_ != _i_) {\ + elem_exchanger(type, a, _i_, _m_);\ + }\ + } while (_m_ != _i_);\ +} + + +/* QUICK - SORT (level 0) */ + +#define SGLIB_ARRAY_SINGLE_QUICK_SORT(type, a, max, comparator) {\ + SGLIB_ARRAY_QUICK_SORT(type, a, max, comparator, SGLIB_ARRAY_ELEMENTS_EXCHANGER);\ +} + +#define SGLIB_ARRAY_QUICK_SORT(type, a, max, comparator, elem_exchanger) {\ + int _i_, _j_, _p_, _stacki_, _start_, _end_;\ + /* can sort up to 2^64 elements */\ + int _startStack_[64]; \ + int _endStack_[64];\ + _startStack_[0] = 0;\ + _endStack_[0] = (max);\ + _stacki_ = 1;\ + while (_stacki_ > 0) {\ + _stacki_ --;\ + _start_ = _startStack_[_stacki_];\ + _end_ = _endStack_[_stacki_];\ + while (_end_ - _start_ > 2) {\ + _p_ = _start_;\ + _i_ = _start_ + 1;\ + _j_ = _end_ - 1;\ + while (_i_<_j_) {\ + for(; _i_<=_j_ && comparator(((a)[_i_]),((a)[_p_]))<=0; _i_++) ;\ + if (_i_ > _j_) {\ + /* all remaining elements lesseq than pivot */\ + elem_exchanger(type, a, _j_, _p_);\ + _i_ = _j_;\ + } else {\ + for(; _i_<=_j_ && comparator(((a)[_j_]),((a)[_p_]))>=0; _j_--) ;\ + if (_i_ > _j_) {\ + /* all remaining elements greater than pivot */\ + elem_exchanger(type, a, _j_, _p_);\ + _i_ = _j_;\ + } else if (_i_ < _j_) {\ + elem_exchanger(type, a, _i_, _j_);\ + if (_i_+2 < _j_) {_i_++; _j_--;}\ + else if (_i_+1 < _j_) _i_++;\ + }\ + }\ + }\ + /* O.K. i==j and pivot is on a[i] == a[j] */\ + /* handle recursive calls without recursion */\ + if (_i_-_start_ > 1 && _end_-_j_ > 1) {\ + /* two recursive calls, use array-stack */\ + if (_i_-_start_ < _end_-_j_-1) {\ + _startStack_[_stacki_] = _j_+1;\ + _endStack_[_stacki_] = _end_;\ + _stacki_ ++;\ + _end_ = _i_;\ + } else {\ + _startStack_[_stacki_] = _start_;\ + _endStack_[_stacki_] = _i_;\ + _stacki_ ++;\ + _start_ = _j_+1;\ + }\ + } else {\ + if (_i_-_start_ > 1) {\ + _end_ = _i_;\ + } else {\ + _start_ = _j_+1;\ + }\ + }\ + }\ + if (_end_ - _start_ == 2) {\ + if (comparator(((a)[_start_]),((a)[_end_-1])) > 0) {\ + elem_exchanger(type, a, _start_, _end_-1);\ + }\ + }\ + }\ +} + +/* BINARY SEARCH (level 0) */ + +#define SGLIB_ARRAY_BINARY_SEARCH(type, a, start_index, end_index, key, comparator, found, result_index) {\ + int _kk_, _cc_, _ii_, _jj_, _ff_;\ + _ii_ = (start_index); \ + _jj_ = (end_index);\ + _ff_ = 0;\ + while (_ii_ <= _jj_ && _ff_==0) {\ + _kk_ = (_jj_+_ii_)/2;\ + _cc_ = comparator(((a)[_kk_]), (key));\ + if (_cc_ == 0) {\ + (result_index) = _kk_; \ + _ff_ = 1;\ + } else if (_cc_ < 0) {\ + _ii_ = _kk_+1;\ + } else {\ + _jj_ = _kk_-1;\ + }\ + }\ + if (_ff_ == 0) {\ + /* not found, but set its resulting place in the array */\ + (result_index) = _jj_+1;\ + }\ + (found) = _ff_;\ +} + +/* -------------------------------- queue (in an array) ------------------ */ +/* queue is a quadruple (a,i,j,dim) such that: */ +/* a is the array storing values */ +/* i is the index of the first used element in the array */ +/* j is the index of the first free element in the array */ +/* dim is the size of the array a */ +/* !!!!!!! This data structure is NOT documented, do not use it !!!!!!!!!! */ + +#define SGLIB_QUEUE_INIT(type, a, i, j) { i = j = 0; } +#define SGLIB_QUEUE_IS_EMPTY(type, a, i, j) ((i)==(j)) +#define SGLIB_QUEUE_IS_FULL(type, a, i, j, dim) ((i)==((j)+1)%(dim)) +#define SGLIB_QUEUE_FIRST_ELEMENT(type, a, i, j) (a[i]) +#define SGLIB_QUEUE_ADD_NEXT(type, a, i, j, dim) {\ + if (SGLIB_QUEUE_IS_FULL(type, a, i, j, dim)) assert(0 && "the queue is full");\ + (j) = ((j)+1) % (dim);\ +} +#define SGLIB_QUEUE_ADD(type, a, elem, i, j, dim) {\ + a[j] = (elem);\ + SGLIB_QUEUE_ADD_NEXT(type, a, i, j, dim);\ +} +#define SGLIB_QUEUE_DELETE_FIRST(type, a, i, j, dim) {\ + if (SGLIB_QUEUE_IS_EMPTY(type, a, i, j)) assert(0 && "the queue is empty");\ + (i) = ((i)+1) % (dim);\ +} +#define SGLIB_QUEUE_DELETE(type, a, i, j, dim) {\ + SGLIB_QUEUE_DELETE_FIRST(type, a, i, j, dim);\ +} + +/* ----------------- priority queue (heap) (in an array) -------------------- */ +/* heap is a triple (a,i,dim) such that: */ +/* a is the array storing values */ +/* i is the index of the first free element in the array */ +/* dim is the size of the array a */ +/* !!!!!!! This data structure is NOT documented, do not use it !!!!!!!!!! */ + +#define SGLIB_HEAP_INIT(type, a, i) { i = 0; } +#define SGLIB_HEAP_IS_EMPTY(type, a, i) ((i)==0) +#define SGLIB_HEAP_IS_FULL(type, a, i, dim) ((i)==(dim)) +#define SGLIB_HEAP_FIRST_ELEMENT(type, a, i) (a[0]) +#define SGLIB_HEAP_ADD_NEXT(type, a, i, dim, comparator, elem_exchanger) {\ + int _i_;\ + if (SGLIB_HEAP_IS_FULL(type, a, i, dim)) assert(0 && "the heap is full");\ + _i_ = (i)++;\ + while (_i_ > 0 && comparator(a[_i_/2], a[_i_]) < 0) {\ + elem_exchanger(type, a, (_i_/2), _i_);\ + _i_ = _i_/2;\ + }\ +} +#define SGLIB_HEAP_ADD(type, a, elem, i, dim, comparator) {\ + if (SGLIB_HEAP_IS_FULL(type, a, i, dim)) assert(0 && "the heap is full");\ + a[i] = (elem);\ + SGLIB_HEAP_ADD_NEXT(type, a, i, dim, comparator, SGLIB_ARRAY_ELEMENTS_EXCHANGER);\ +} +#define SGLIB_HEAP_DELETE_FIRST(type, a, i, dim, comparator, elem_exchanger) {\ + if (SGLIB_HEAP_IS_EMPTY(type, a, i)) assert(0 && "the heap is empty");\ + (i)--;\ + a[0] = a[i];\ + SGLIB___ARRAY_HEAP_DOWN(type, a, 0, i, comparator, elem_exchanger);\ +} +#define SGLIB_HEAP_DELETE(type, a, i, dim, comparator) {\ + SGLIB_HEAP_DELETE_FIRST(type, a, i, dim, comparator, SGLIB_ARRAY_ELEMENTS_EXCHANGER);\ +} + + +/* ----------------- hashed table of pointers (in an array) -------------------- */ + +/* + + This hashed table is storing pointers to objects (not containers). + In this table there is a one-to-one mapping between 'objects' stored + in the table and indexes where they are placed. Each index is + pointing to exactly one 'object' and each 'object' stored in the + table occurs on exactly one index. Once an object is stored in the + table, it can be represented via its index. + + In case of collision while adding an object the index shifted + by SGLIB_HASH_TAB_SHIFT_CONSTANT (constant can be redefined) + + You can NOT delete an element from such hash table. The only + justification (I can see) for this data structure is an exchange + file format, having an index table at the beginning and then + refering objects via indexes. + + !!!!!!! This data structure is NOT documented, do not use it !!!!!!!!!! + +*/ + +#define SGLIB_HASH_TAB_INIT(type, table, dim) {\ + int _i_;\ + for(_i_ = 0; _i_ < (dim); _i_++) (table)[_i_] = NULL;\ +} + +#define SGLIB_HASH_TAB_ADD_IF_NOT_MEMBER(type, table, dim, elem, hash_function, comparator, member){\ + unsigned _pos_;\ + type *_elem_;\ + SGLIB_HASH_TAB_FIND_MEMBER(type, table, dim, elem, _pos_, _elem_);\ + (member) = (table)[_pos_];\ + if (_elem_ == NULL) {\ + if ((table)[_pos_] != NULL) assert(0 && "the hash table is full");\ + (table)[_pos_] = (elem);\ + }\ +} + +#define SGLIB_HASH_TAB_FIND_MEMBER(type, table, dim, elem, hash_function, comparator, resultIndex, resultMember) {\ + unsigned _i_;\ + int _count_;\ + type *_e_;\ + _count = 0;\ + _i_ = hash_function(elem);\ + _i_ %= (dim);\ + while ((_e_=(table)[_i_])!=NULL && comparator(_e_, (elem))!=0 && _count_<(dim)) {\ + _count_ ++;\ + _i_ = (_i_ + SGLIB_HASH_TAB_SHIFT_CONSTANT) % (dim);\ + }\ + (resultIndex) = _i_;\ + if (_count_ < (dim)) (resultMember) = _e_;\ + else (resultMember) = NULL;\ +} + +#define SGLIB_HASH_TAB_IS_MEMBER(type, table, dim, elem, hash_function, resultIndex) {\ + unsigned _i_;\ + int _c_;\ + type *_e_;\ + _count = 0;\ + _i_ = hash_function(elem);\ + _i_ %= (dim);\ + while ((_e_=(table)[_i_])!=NULL && _e_!=(elem) && _c_<(dim)) {\ + _c_ ++;\ + _i_ = (_i_ + SGLIB_HASH_TAB_SHIFT_CONSTANT) % (dim);\ + }\ + if (_e_==(elem)) (resultIndex) = _i_;\ + else (resultIndex) = -1;\ +} + +#define SGLIB_HASH_TAB_MAP_ON_ELEMENTS(type, table, dim, iteratedIndex, iteratedVariable, command) {\ + unsigned iteratedIndex;\ + type *iteratedVariable;\ + for(iteratedIndex=0; iteratedIndex < (dim); iteratedIndex++) {\ + iteratedVariable = (table)[iteratedIndex];\ + if (iteratedVariable != NULL) {command;}\ + }\ +} + + +/* ---------------------------------------------------------------------------- */ +/* ------------------------- DYNAMIC DATA STRUCTURES -------------------------- */ +/* ---------------------------------------------------------------------------- */ + +/* ------------------------------------ lists (level 0) --------------------- */ + +#define SGLIB_LIST_ADD(type, list, elem, next) {\ + (elem)->next = (list);\ + (list) = (elem);\ +} + +#define SGLIB_LIST_CONCAT(type, first, second, next) {\ + if ((first)==NULL) {\ + (first) = (second);\ + } else {\ + type *_p_;\ + for(_p_ = (first); _p_->next!=NULL; _p_=_p_->next) ;\ + _p_->next = (second);\ + }\ +} + +#define SGLIB_LIST_DELETE(type, list, elem, next) {\ + type **_p_;\ + for(_p_ = &(list); *_p_!=NULL && *_p_!=(elem); _p_= &(*_p_)->next) ;\ + assert(*_p_!=NULL && "element is not member of the container, use DELETE_IF_MEMBER instead"!=NULL);\ + *_p_ = (*_p_)->next;\ +} + +#define SGLIB_LIST_ADD_IF_NOT_MEMBER(type, list, elem, comparator, next, member) {\ + type *_p_;\ + for(_p_ = (list); _p_!=NULL && comparator(_p_, (elem)) != 0; _p_= _p_->next) ;\ + (member) = _p_;\ + if (_p_ == NULL) {\ + SGLIB_LIST_ADD(type, list, elem, next);\ + }\ +} + +#define SGLIB_LIST_DELETE_IF_MEMBER(type, list, elem, comparator, next, member) {\ + type **_p_;\ + for(_p_ = &(list); *_p_!=NULL && comparator((*_p_), (elem)) != 0; _p_= &(*_p_)->next) ;\ + (member) = *_p_;\ + if (*_p_ != NULL) {\ + *_p_ = (*_p_)->next;\ + }\ +} + +#define SGLIB_LIST_IS_MEMBER(type, list, elem, next, result) {\ + type *_p_;\ + for(_p_ = (list); _p_!=NULL && _p_ != (elem); _p_= _p_->next) ;\ + (result) = (_p_!=NULL);\ +} + +#define SGLIB_LIST_FIND_MEMBER(type, list, elem, comparator, next, member) {\ + type *_p_;\ + for(_p_ = (list); _p_!=NULL && comparator(_p_, (elem)) != 0; _p_= _p_->next) ;\ + (member) = _p_;\ +} + +#define SGLIB_LIST_MAP_ON_ELEMENTS(type, list, iteratedVariable, next, command) {\ + type *_ne_;\ + type *iteratedVariable;\ + (iteratedVariable) = (list); \ + while ((iteratedVariable)!=NULL) {\ + _ne_ = (iteratedVariable)->next;\ + {command;};\ + (iteratedVariable) = _ne_;\ + }\ +} + +#define SGLIB_LIST_LEN(type, list, next, result) {\ + type *_ce_;\ + (result) = 0;\ + SGLIB_LIST_MAP_ON_ELEMENTS(type, list, _ce_, next, (result)++);\ +} + +#define SGLIB_LIST_REVERSE(type, list, next) {\ + type *_list_,*_tmp_,*_res_;\ + _list_ = (list);\ + _res_ = NULL;\ + while (_list_!=NULL) {\ + _tmp_ = _list_->next; _list_->next = _res_;\ + _res_ = _list_; _list_ = _tmp_;\ + }\ + (list) = _res_;\ +} + +#define SGLIB_LIST_SORT(type, list, comparator, next) {\ + /* a non-recursive merge sort on lists */\ + type *_r_;\ + type *_a_, *_b_, *_todo_, *_t_, **_restail_;\ + int _i_, _n_, _contFlag_;\ + _r_ = (list);\ + _contFlag_ = 1;\ + for(_n_ = 1; _contFlag_; _n_ = _n_+_n_) {\ + _todo_ = _r_; _r_ = NULL; _restail_ = &_r_; _contFlag_ =0;\ + while (_todo_!=NULL) {\ + _a_ = _todo_;\ + for(_i_ = 1, _t_ = _a_; _i_ < _n_ && _t_!=NULL; _i_++, _t_ = _t_->next) ;\ + if (_t_ ==NULL) {\ + *_restail_ = _a_;\ + break;\ + }\ + _b_ = _t_->next; _t_->next=NULL;\ + for(_i_ =1, _t_ = _b_; _i_<_n_ && _t_!=NULL; _i_++, _t_ = _t_->next) ;\ + if (_t_ ==NULL) {\ + _todo_ =NULL;\ + } else {\ + _todo_ = _t_->next; _t_->next=NULL;\ + }\ + /* merge */\ + while (_a_!=NULL && _b_!=NULL) {\ + if (comparator(_a_, _b_) < 0) {\ + *_restail_ = _a_; _restail_ = &(_a_->next); _a_ = _a_->next;\ + } else {\ + *_restail_ = _b_; _restail_ = &(_b_->next); _b_ = _b_->next;\ + }\ + }\ + if (_a_!=NULL) *_restail_ = _a_;\ + else *_restail_ = _b_;\ + while (*_restail_!=NULL) _restail_ = &((*_restail_)->next);\ + _contFlag_ =1;\ + }\ + }\ + (list) = _r_;\ +} + +/* --------------------------------- sorted list (level 0) --------------------- */ +/* + All operations suppose that the list is sorted and they preserve + this property. +*/ + + +#define SGLIB_SORTED_LIST_ADD(type, list, elem, comparator, next) {\ + type **_e_;\ + int _cmpres_;\ + SGLIB_SORTED_LIST_FIND_MEMBER_OR_PLACE(type, list, elem, comparator, next, _cmpres_, _e_);\ + (elem)->next = *_e_;\ + *_e_ = (elem);\ +} + +#define SGLIB_SORTED_LIST_ADD_IF_NOT_MEMBER(type, list, elem, comparator, next, member) {\ + type **_e_;\ + int _cmp_res_;\ + SGLIB_SORTED_LIST_FIND_MEMBER_OR_PLACE(type, list, elem, comparator, next, _cmp_res_, _e_);\ + if (_cmp_res_ != 0) {\ + (elem)->next = *_e_;\ + *_e_ = (elem);\ + (member) = NULL;\ + } else {\ + (member) = *_e_;\ + }\ +} + +#define SGLIB_SORTED_LIST_DELETE(type, list, elem, next) {\ + SGLIB_LIST_DELETE(type, list, elem, next);\ +} + +#define SGLIB_SORTED_LIST_DELETE_IF_MEMBER(type, list, elem, comparator, next, member) {\ + type **_e_;\ + int _cmp_res_;\ + SGLIB_SORTED_LIST_FIND_MEMBER_OR_PLACE(type, list, elem, comparator, next, _cmp_res_, _e_);\ + if (_cmp_res_ == 0) {\ + (member) = *_e_;\ + *_e_ = (*_e_)->next;\ + } else {\ + (member) = NULL;\ + }\ +} + +#define SGLIB_SORTED_LIST_FIND_MEMBER(type, list, elem, comparator, next, member) {\ + type *_p_;\ + int _cmpres_ = 1;\ + for(_p_ = (list); _p_!=NULL && (_cmpres_=comparator(_p_, (elem))) < 0; _p_=_p_->next) ;\ + if (_cmpres_ != 0) (member) = NULL;\ + else (member) = _p_;\ +} + +#define SGLIB_SORTED_LIST_IS_MEMBER(type, list, elem, comparator, next, result) {\ + type *_p_;\ + for(_p_ = (list); _p_!=NULL && comparator(_p_, (elem)) < 0; _p_=_p_->next) ;\ + while (_p_ != NULL && _p_ != (elem) && comparator(_p_, (elem)) == 0) _p_=_p_->next;\ + (result) = (_p_ == (elem));\ +} + +#define SGLIB_SORTED_LIST_FIND_MEMBER_OR_PLACE(type, list, elem, comparator, next, comparator_result, member_ptr) {\ + (comparator_result) = -1;\ + for((member_ptr) = &(list); \ + *(member_ptr)!=NULL && ((comparator_result)=comparator((*member_ptr), (elem))) < 0; \ + (member_ptr) = &(*(member_ptr))->next) ;\ +} + +#define SGLIB_SORTED_LIST_LEN(type, list, next, result) {\ + SGLIB_LIST_LEN(type, list, next, result);\ +} + +#define SGLIB_SORTED_LIST_MAP_ON_ELEMENTS(type, list, iteratedVariable, next, command) {\ + SGLIB_LIST_MAP_ON_ELEMENTS(type, list, iteratedVariable, next, command);\ +} + + +/* ------------------------------- double linked list (level 0) ------------------------- */ +/* + Lists with back pointer to previous element. Those lists implements deletion + of an element in a constant time. +*/ + +#define SGLIB___DL_LIST_CREATE_SINGLETON(type, list, elem, previous, next) {\ + (list) = (elem);\ + (list)->next = (list)->previous = NULL;\ +} + +#define SGLIB_DL_LIST_ADD_AFTER(type, place, elem, previous, next) {\ + if ((place) == NULL) {\ + SGLIB___DL_LIST_CREATE_SINGLETON(type, place, elem, previous, next);\ + } else {\ + (elem)->next = (place)->next;\ + (elem)->previous = (place);\ + (place)->next = (elem);\ + if ((elem)->next != NULL) (elem)->next->previous = (elem);\ + }\ +} + +#define SGLIB_DL_LIST_ADD_BEFORE(type, place, elem, previous, next) {\ + if ((place) == NULL) {\ + SGLIB___DL_LIST_CREATE_SINGLETON(type, place, elem, previous, next);\ + } else {\ + (elem)->next = (place);\ + (elem)->previous = (place)->previous;\ + (place)->previous = (elem);\ + if ((elem)->previous != NULL) (elem)->previous->next = (elem);\ + }\ +} + +#define SGLIB_DL_LIST_ADD(type, list, elem, previous, next) {\ + SGLIB_DL_LIST_ADD_BEFORE(type, list, elem, previous, next)\ +} + +#define SGLIB___DL_LIST_GENERIC_ADD_IF_NOT_MEMBER(type, list, elem, comparator, previous, next, member, the_add_operation) {\ + type *_dlp_;\ + for(_dlp_ = (list); _dlp_!=NULL && comparator(_dlp_, (elem)) != 0; _dlp_= _dlp_->previous) ;\ + if (_dlp_ == NULL && (list) != NULL) {\ + for(_dlp_ = (list)->next; _dlp_!=NULL && comparator(_dlp_, (elem)) != 0; _dlp_= _dlp_->next) ;\ + }\ + (member) = _dlp_;\ + if (_dlp_ == NULL) {\ + the_add_operation(type, list, elem, previous, next);\ + }\ +} + +#define SGLIB_DL_LIST_ADD_BEFORE_IF_NOT_MEMBER(type, list, elem, comparator, previous, next, member) {\ + SGLIB___DL_LIST_GENERIC_ADD_IF_NOT_MEMBER(type, list, elem, comparator, previous, next, member, SGLIB_DL_LIST_ADD_BEFORE);\ +} + +#define SGLIB_DL_LIST_ADD_AFTER_IF_NOT_MEMBER(type, list, elem, comparator, previous, next, member) {\ + SGLIB___DL_LIST_GENERIC_ADD_IF_NOT_MEMBER(type, list, elem, comparator, previous, next, member, SGLIB_DL_LIST_ADD_AFTER);\ +} + +#define SGLIB_DL_LIST_ADD_IF_NOT_MEMBER(type, list, elem, comparator, previous, next, member) {\ + SGLIB___DL_LIST_GENERIC_ADD_IF_NOT_MEMBER(type, list, elem, comparator, previous, next, member, SGLIB_DL_LIST_ADD);\ +} + +#define SGLIB_DL_LIST_CONCAT(type, first, second, previous, next) {\ + if ((first)==NULL) {\ + (first) = (second);\ + } else if ((second)!=NULL) {\ + type *_dlp_;\ + for(_dlp_ = (first); _dlp_->next!=NULL; _dlp_=_dlp_->next) ;\ + SGLIB_DL_LIST_ADD_AFTER(type, _dlp_, second, previous, next);\ + }\ +} + +#define SGLIB_DL_LIST_DELETE(type, list, elem, previous, next) {\ + type *_l_;\ + _l_ = (list);\ + if (_l_ == (elem)) {\ + if ((elem)->previous != NULL) _l_ = (elem)->previous;\ + else _l_ = (elem)->next;\ + }\ + if ((elem)->next != NULL) (elem)->next->previous = (elem)->previous;\ + if ((elem)->previous != NULL) (elem)->previous->next = (elem)->next;\ + (list) = _l_;\ +} + +#define SGLIB_DL_LIST_DELETE_IF_MEMBER(type, list, elem, comparator, previous, next, member) {\ + type *_dlp_;\ + for(_dlp_ = (list); _dlp_!=NULL && comparator(_dlp_, (elem)) != 0; _dlp_= _dlp_->previous) ;\ + if (_dlp_ == NULL && (list) != NULL) {\ + for(_dlp_ = (list)->next; _dlp_!=NULL && comparator(_dlp_, (elem)) != 0; _dlp_= _dlp_->next) ;\ + }\ + (member) = _dlp_;\ + if (_dlp_ != NULL) {\ + SGLIB_DL_LIST_DELETE(type, list, _dlp_, previous, next);\ + }\ +} + +#define SGLIB_DL_LIST_IS_MEMBER(type, list, elem, previous, next, result) {\ + type *_dlp_;\ + SGLIB_LIST_IS_MEMBER(type, list, elem, previous, result);\ + if (result == 0 && (list) != NULL) {\ + _dlp_ = (list)->next;\ + SGLIB_LIST_IS_MEMBER(type, _dlp_, elem, next, result);\ + }\ +} + +#define SGLIB_DL_LIST_FIND_MEMBER(type, list, elem, comparator, previous, next, member) {\ + type *_dlp_;\ + SGLIB_LIST_FIND_MEMBER(type, list, elem, comparator, previous, member);\ + if ((member) == NULL && (list) != NULL) {\ + _dlp_ = (list)->next;\ + SGLIB_LIST_FIND_MEMBER(type, _dlp_, elem, comparator, next, member);\ + }\ +} + +#define SGLIB_DL_LIST_MAP_ON_ELEMENTS(type, list, iteratedVariable, previous, next, command) {\ + type *_dl_;\ + type *iteratedVariable;\ + if ((list)!=NULL) {\ + _dl_ = (list)->next;\ + SGLIB_LIST_MAP_ON_ELEMENTS(type, list, iteratedVariable, previous, command);\ + SGLIB_LIST_MAP_ON_ELEMENTS(type, _dl_, iteratedVariable, next, command);\ + }\ +} + +#define SGLIB_DL_LIST_SORT(type, list, comparator, previous, next) {\ + type *_dll_, *_dlp_, *_dlt_;\ + _dll_ = (list);\ + if (_dll_ != NULL) {\ + for(; _dll_->previous!=NULL; _dll_=_dll_->previous) ;\ + SGLIB_LIST_SORT(type, _dll_, comparator, next);\ + SGLIB___DL_LIST_CREATE_FROM_LIST(type, _dll_, previous, next);\ + (list) = _dll_;\ + }\ +} + +#define SGLIB_DL_LIST_GET_FIRST(type, list, previous, next, result) {\ + type *_dll_;\ + _dll_ = (list);\ + if (_dll_ != NULL) {\ + for(; _dll_->previous!=NULL; _dll_=_dll_->previous) ;\ + }\ + (result) = _dll_;\ +} + +#define SGLIB_DL_LIST_GET_LAST(type, list, previous, next, result) {\ + type *_dll_;\ + _dll_ = (list);\ + if (_dll_ != NULL) {\ + for(; _dll_->next!=NULL; _dll_=_dll_->next) ;\ + }\ + (result) = _dll_;\ +} + +#define SGLIB_DL_LIST_LEN(type, list, previous, next, result) {\ + type *_dl_;\ + int _r1_, _r2_;\ + if ((list)==NULL) {\ + (result) = 0;\ + } else {\ + SGLIB_LIST_LEN(type, list, previous, _r1_);\ + _dl_ = (list)->next;\ + SGLIB_LIST_LEN(type, _dl_, next, _r2_);\ + (result) = _r1_ + _r2_;\ + }\ +} + +#define SGLIB_DL_LIST_REVERSE(type, list, previous, next) {\ + type *_list_,*_nlist_,*_dlp_,*_dln_;\ + _list_ = (list);\ + if (_list_!=NULL) {\ + _nlist_ = _list_->next;\ + while (_list_!=NULL) {\ + _dln_ = _list_->next; \ + _dlp_ = _list_->previous; \ + _list_->next = _dlp_;\ + _list_->previous = _dln_;\ + _list_ = _dlp_;\ + }\ + while (_nlist_!=NULL) {\ + _dln_ = _nlist_->next; \ + _dlp_ = _nlist_->previous; \ + _nlist_->next = _dlp_;\ + _nlist_->previous = _dln_;\ + _nlist_ = _dln_;\ + }\ + }\ +} + +#define SGLIB___DL_LIST_CREATE_FROM_LIST(type, list, previous, next) {\ + type *_dlp_, *_dlt_;\ + _dlp_ = NULL;\ + for(_dlt_ = (list); _dlt_!=NULL; _dlt_ = _dlt_->next) {\ + _dlt_->previous = _dlp_;\ + _dlp_ = _dlt_;\ + }\ +} + + +/* ------------------------------- binary tree traversal (level 0) -------------------- */ + + +#define SGLIB___BIN_TREE_MAP_ON_ELEMENTS(type, tree, iteratedVariable, order, left, right, command) {\ + /* this is non-recursive implementation of tree traversal */\ + /* it maintains the path to the current node in the array '_path_' */\ + /* the _path_[0] contains the root of the tree; */\ + /* the _path_[_pathi_] contains the _current_element_ */\ + /* the macro does not use the _current_element_ after execution of command */\ + /* command can destroy it, it can free the element for example */\ + type *_path_[SGLIB_MAX_TREE_DEEP];\ + type *_right_[SGLIB_MAX_TREE_DEEP];\ + char _pass_[SGLIB_MAX_TREE_DEEP];\ + type *_cn_;\ + int _pathi_;\ + type *iteratedVariable;\ + _cn_ = (tree);\ + _pathi_ = 0;\ + while (_cn_!=NULL) {\ + /* push down to leftmost innermost element */\ + while(_cn_!=NULL) {\ + _path_[_pathi_] = _cn_;\ + _right_[_pathi_] = _cn_->right;\ + _pass_[_pathi_] = 0;\ + _cn_ = _cn_->left;\ + if (order == 0) {\ + iteratedVariable = _path_[_pathi_];\ + {command;}\ + }\ + _pathi_ ++;\ + if (_pathi_ >= SGLIB_MAX_TREE_DEEP) assert(0 && "the binary_tree is too deep");\ + }\ + do {\ + _pathi_ --;\ + if ((order==1 && _pass_[_pathi_] == 0)\ + || (order == 2 && (_pass_[_pathi_] == 1 || _right_[_pathi_]==NULL))) {\ + iteratedVariable = _path_[_pathi_];\ + {command;}\ + }\ + _pass_[_pathi_] ++;\ + } while (_pathi_>0 && _right_[_pathi_]==NULL) ;\ + _cn_ = _right_[_pathi_];\ + _right_[_pathi_] = NULL;\ + _pathi_ ++;\ + }\ +} + +#define SGLIB_BIN_TREE_MAP_ON_ELEMENTS(type, tree, _current_element_, left, right, command) {\ + SGLIB___BIN_TREE_MAP_ON_ELEMENTS(type, tree, _current_element_, 1, left, right, command);\ +} + +#define SGLIB_BIN_TREE_MAP_ON_ELEMENTS_PREORDER(type, tree, _current_element_, left, right, command) {\ + SGLIB___BIN_TREE_MAP_ON_ELEMENTS(type, tree, _current_element_, 0, left, right, command);\ +} + +#define SGLIB_BIN_TREE_MAP_ON_ELEMENTS_POSTORDER(type, tree, _current_element_, left, right, command) {\ + SGLIB___BIN_TREE_MAP_ON_ELEMENTS(type, tree, _current_element_, 2, left, right, command);\ +} + +#define SGLIB___BIN_TREE_FIND_MEMBER(type, tree, elem, left, right, comparator, res) {\ + type *_s_;\ + int _c_;\ + _s_ = (tree);\ + while (_s_!=NULL) {\ + _c_ = comparator((elem), _s_);\ + if (_c_ < 0) _s_ = _s_->left;\ + else if (_c_ > 0) _s_ = _s_->right;\ + else break;\ + }\ + (res) = _s_;\ +} + +/* ---------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- */ +/* - LEVEL - 1 INTERFACE - */ +/* ---------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- */ + + + +/* ---------------------------------------------------------------------------- */ +/* ------------------------------ STATIC ARRAYS ------------------------------- */ +/* ---------------------------------------------------------------------------- */ + +/* ----------------------------- array sorting (level 1) ---------------------- */ + +#define SGLIB_DEFINE_ARRAY_SORTING_PROTOTYPES(type, comparator) \ + extern void sglib_##type##_array_quick_sort(type *a, int max);\ + extern void sglib_##type##_array_heap_sort(type *a, int max);\ + + +#define SGLIB_DEFINE_ARRAY_SORTING_FUNCTIONS(type, comparator) \ + void sglib_##type##_array_quick_sort(type *a, int max) {\ + SGLIB_ARRAY_SINGLE_QUICK_SORT(type, a, max, comparator);\ + }\ + void sglib_##type##_array_heap_sort(type *a, int max) {\ + SGLIB_ARRAY_SINGLE_HEAP_SORT(type, a, max, comparator);\ + }\ + + +/* ----------------------------- array queue (level 1) ------------------- */ +/* sglib's queue is stored in a fixed sized array */ +/* queue_type MUST be a structure containing fields: */ +/* afield is the array storing elem_type */ +/* ifield is the index of the first element in the queue */ +/* jfield is the index of the first free element after the queue */ +/* dim is the size of the array afield */ +/* !!!!!!! This data structure is NOT documented, do not use it !!!!!!!!!! */ + + +#define SGLIB_DEFINE_QUEUE_PROTOTYPES(queue_type, elem_type, afield, ifield, jfield, dim) \ + extern void sglib_##queue_type##_init(queue_type *q); \ + extern int sglib_##queue_type##_is_empty(queue_type *q); \ + extern int sglib_##queue_type##_is_full(queue_type *q); \ + extern elem_type sglib_##queue_type##_first_element(queue_type *q); \ + extern elem_type *sglib_##queue_type##_first_element_ptr(queue_type *q); \ + extern void sglib_##queue_type##_add_next(queue_type *q); \ + extern void sglib_##queue_type##_add(queue_type *q, elem_type elem); \ + extern void sglib_##queue_type##_delete_first(queue_type *q); \ + extern void sglib_##queue_type##_delete(queue_type *q); + + +#define SGLIB_DEFINE_QUEUE_FUNCTIONS(queue_type, elem_type, afield, ifield, jfield, dim) \ + void sglib_##queue_type##_init(queue_type *q) {\ + SGLIB_QUEUE_INIT(elem_type, q->afield, q->ifield, q->jfield);\ + }\ + int sglib_##queue_type##_is_empty(queue_type *q) {\ + return(SGLIB_QUEUE_IS_EMPTY(elem_type, q->afield, q->ifield, q->jfield));\ + }\ + int sglib_##queue_type##_is_full(queue_type *q) {\ + return(SGLIB_QUEUE_IS_FULL(elem_type, q->afield, q->ifield, q->jfield));\ + }\ + elem_type sglib_##queue_type##_first_element(queue_type *q) {\ + return(SGLIB_QUEUE_FIRST_ELEMENT(elem_type, q->afield, q->ifield, q->jfield));\ + }\ + elem_type *sglib_##queue_type##_first_element_ptr(queue_type *q) {\ + return(& SGLIB_QUEUE_FIRST_ELEMENT(elem_type, q->afield, q->ifield, q->jfield));\ + }\ + void sglib_##queue_type##_add_next(queue_type *q) {\ + SGLIB_QUEUE_ADD_NEXT(elem_type, q->afield, q->ifield, q->jfield, dim);\ + }\ + void sglib_##queue_type##_add(queue_type *q, elem_type elem) {\ + SGLIB_QUEUE_ADD(elem_type, q->afield, elem, q->ifield, q->jfield, dim);\ + }\ + void sglib_##queue_type##_delete_first(queue_type *q) {\ + SGLIB_QUEUE_DELETE_FIRST(elem_type, q->afield, q->ifield, q->jfield, dim);\ + }\ + void sglib_##queue_type##_delete(queue_type *q) {\ + SGLIB_QUEUE_DELETE_FIRST(elem_type, q->afield, q->ifield, q->jfield, dim);\ + } + + +/* ------------------------ array heap (level 1) ------------------------- */ +/* sglib's heap is a priority queue implemented in a fixed sized array */ +/* heap_type MUST be a structure containing fields: */ +/* afield is the array of size dim storing elem_type */ +/* ifield is the index of the first free element after the queue */ +/* !!!!!!! This data structure is NOT documented, do not use it !!!!!!!!!! */ + + +#define SGLIB_DEFINE_HEAP_PROTOTYPES(heap_type, elem_type, afield, ifield, dim, comparator, elem_exchanger) \ + extern void sglib_##heap_type##_init(heap_type *q); \ + extern int sglib_##heap_type##_is_empty(heap_type *q); \ + extern int sglib_##heap_type##_is_full(heap_type *q); \ + extern elem_type sglib_##heap_type##_first_element(heap_type *q); \ + extern elem_type *sglib_##heap_type##_first_element_ptr(heap_type *q); \ + extern void sglib_##heap_type##_add_next(heap_type *q); \ + extern void sglib_##heap_type##_add(heap_type *q, elem_type elem); \ + extern void sglib_##heap_type##_delete_first(heap_type *q); \ + extern void sglib_##heap_type##_delete(heap_type *q) + +#define SGLIB_DEFINE_HEAP_FUNCTIONS(heap_type, elem_type, afield, ifield, dim, comparator, elem_exchanger) \ + void sglib_##heap_type##_init(heap_type *q) {\ + SGLIB_HEAP_INIT(elem_type, q->afield, q->ifield);\ + }\ + int sglib_##heap_type##_is_empty(heap_type *q) {\ + return(SGLIB_HEAP_IS_EMPTY(elem_type, q->afield, q->ifield));\ + }\ + int sglib_##heap_type##_is_full(heap_type *q) {\ + return(SGLIB_HEAP_IS_FULL(elem_type, q->afield, q->ifield));\ + }\ + elem_type sglib_##heap_type##_first_element(heap_type *q) {\ + return(SGLIB_HEAP_FIRST_ELEMENT(elem_type, q->afield, q->ifield));\ + }\ + elem_type *sglib_##heap_type##_first_element_ptr(heap_type *q) {\ + return(& SGLIB_HEAP_FIRST_ELEMENT(elem_type, q->afield, q->ifield));\ + }\ + void sglib_##heap_type##_add_next(heap_type *q) {\ + SGLIB_HEAP_ADD_NEXT(elem_type, q->afield, q->ifield, dim, comparator, elem_exchanger);\ + }\ + void sglib_##heap_type##_add(heap_type *q, elem_type elem) {\ + SGLIB_HEAP_ADD(elem_type, q->afield, elem, q->ifield, dim, comparator, elem_exchanger);\ + }\ + void sglib_##heap_type##_delete_first(heap_type *q) {\ + SGLIB_HEAP_DELETE_FIRST(elem_type, q->afield, q->ifield, dim, comparator, elem_exchanger);\ + }\ + void sglib_##heap_type##_delete(heap_type *q) {\ + SGLIB_HEAP_DELETE_FIRST(elem_type, q->afield, q->ifield, dim, comparator, elem_exchanger);\ + } + + +/* ------------------------ hashed table (level 1) ------------------------- */ +/* + + sglib's hash table is an array storing directly pointers to objects (not containers). + In this table there is a one-to-one mapping between 'objects' stored + in the table and indexes where they are placed. Each index is + pointing to exactly one 'object' and each 'object' stored in the + table occurs on exactly one index. Once an object is stored in the + table, it can be represented via its index. + + type - is the type of elements + dim - is the size of the hash array + hash_function - is a hashing function mapping type* to unsigned + comparator - is a comparator on elements + + !!!!!!! This data structure is NOT documented, do not use it !!!!!!!!!! +*/ + +#define SGLIB_DEFINE_HASHED_TABLE_PROTOTYPES(type, dim, hash_function, comparator) \ + struct sglib_hashed_##type##_iterator {\ + int currentIndex;\ + int (*subcomparator)(type *, type *);\ + type *equalto;\ + };\ + extern void sglib_hashed_##type##_init(type *table[dim]);\ + extern int sglib_hashed_##type##_add_if_not_member(type *table[dim], type *elem, type **member);\ + extern int sglib_hashed_##type##_is_member(type *table[dim], type *elem);\ + extern type * sglib_hashed_##type##_find_member(type *table[dim], type *elem);\ + extern type *sglib_hashed_##type##_it_init(struct sglib_hashed_##type##_iterator *it, type *table[dim]); \ + extern type *sglib_hashed_##type##_it_init_on_equal(struct sglib_hashed_##type##_iterator *it, type *table[dim], int (*subcomparator)(type *, type *), type *equalto); \ + extern type *sglib_hashed_##type##_it_current(struct sglib_hashed_##type##_iterator *it); \ + extern type *sglib_hashed_##type##_it_next(struct sglib_hashed_##type##_iterator *it); + +#define SGLIB_DEFINE_HASHED_TABLE_FUNCTIONS(type, dim, hash_function, comparator) \ + struct sglib_hashed_##type##_iterator {\ + int currentIndex;\ + type **table;\ + int (*subcomparator)(type *, type *);\ + type *equalto;\ + };\ + void sglib_hashed_##type##_init(type *table[dim]) {\ + SGLIB_HASH_TAB_INIT(type, table, dim);\ + }\ + int sglib_hashed_##type##_add_if_not_member(type *table[dim], type *elem, type **member) {\ + SGLIB_HASH_TAB_ADD_IF_NOT_MEMBER(type, table, dim, elem, hash_function, comparator, *member);\ + }\ + int sglib_hashed_##type##_is_member(type *table[dim], type *elem) {\ + int ind;\ + SGLIB_HASH_TAB_IS_MEMBER(type, table, dim, elem, hash_function, ind);\ + return(ind != -1);\ + }\ + type * sglib_hashed_##type##_find_member(type *table[dim], type *elem) {\ + type *mmb;\ + int ind;\ + SGLIB_HASH_TAB_FIND_MEMBER(type, table, dim, elem, hash_function, comparator, ind, mmb);\ + return(mmb);\ + }\ + type *sglib_hashed_##type##_it_init_on_equal(struct sglib_hashed_##type##_iterator *it, type *table[dim], int (*subcomparator)(type *, type *), type *equalto) {\ + int i;\ + it->table = table;\ + it->subcomparator = subcomparator;\ + it->equalto = equalto;\ + for(i=0; i<(dim) && table[i]==NULL; i++) ;\ + it->currentIndex = i;\ + if (i<(dim)) return(table[i]);\ + return(NULL);\ + }\ + type *sglib_hashed_##type##_it_init(struct sglib_hashed_##type##_iterator *it, type *table[dim]) {\ + sglib_hashed_##type##_it_init_on_equal(it, table, NULL, NULL);\ + }\ + type *sglib_hashed_##type##_it_current(struct sglib_hashed_##type##_iterator *it) {\ + return(table[it->currentIndex]);\ + }\ + type *sglib_hashed_##type##_it_next(struct sglib_hashed_##type##_iterator *it) {\ + i=it->currentIndex;\ + if (i<(dim)) {\ + for(i++; i<(dim) && table[i]==NULL; i++) ;\ + }\ + it->currentIndex = i;\ + if (i<(dim)) return(table[i]);\ + return(NULL);\ + } + + +/* ------------------- hashed container (only for level 1) -------------------- */ +/* + hashed container is a table of given fixed size containing another + (dynamic) base container in each cell. Once an object should be + inserted into the hashed container, a hash function is used to + determine the cell where the object belongs and the object is + inserted into the base container stored in this cell. Usually the + base container is simply a list or a sorted list, but it can be a + red-black tree as well. + + parameters: + type - the type of the container stored in each cell. + dim - the size of the hashed array + hash_function - the hashing function hashing 'type *' to unsigned. + +*/ + +#define SGLIB_DEFINE_HASHED_CONTAINER_PROTOTYPES(type, dim, hash_function) \ + struct sglib_hashed_##type##_iterator {\ + struct sglib_##type##_iterator containerIt;\ + type **table;\ + int currentIndex;\ + int (*subcomparator)(type *, type *);\ + type *equalto;\ + };\ + extern void sglib_hashed_##type##_init(type *table[dim]);\ + extern void sglib_hashed_##type##_add(type *table[dim], type *elem);\ + extern int sglib_hashed_##type##_add_if_not_member(type *table[dim], type *elem, type **member);\ + extern void sglib_hashed_##type##_delete(type *table[dim], type *elem);\ + extern int sglib_hashed_##type##_delete_if_member(type *table[dim], type *elem, type **memb);\ + extern int sglib_hashed_##type##_is_member(type *table[dim], type *elem);\ + extern type * sglib_hashed_##type##_find_member(type *table[dim], type *elem);\ + extern type *sglib_hashed_##type##_it_init(struct sglib_hashed_##type##_iterator *it, type *table[dim]); \ + extern type *sglib_hashed_##type##_it_init_on_equal(struct sglib_hashed_##type##_iterator *it, type *table[dim], int (*subcomparator)(type *, type *), type *equalto); \ + extern type *sglib_hashed_##type##_it_current(struct sglib_hashed_##type##_iterator *it); \ + extern type *sglib_hashed_##type##_it_next(struct sglib_hashed_##type##_iterator *it); + +#define SGLIB_DEFINE_HASHED_CONTAINER_FUNCTIONS(type, dim, hash_function) \ + /*extern unsigned hash_function(type *elem);*/\ + void sglib_hashed_##type##_init(type *table[dim]) {\ + unsigned i;\ + for(i=0; i<(dim); i++) table[i] = NULL;\ + }\ + void sglib_hashed_##type##_add(type *table[dim], type *elem) {\ + unsigned i;\ + i = ((unsigned)hash_function(elem)) % (dim);\ + sglib_##type##_add(&(table)[i], elem);\ + }\ + int sglib_hashed_##type##_add_if_not_member(type *table[dim], type *elem, type **member) {\ + unsigned i;\ + i = ((unsigned)hash_function(elem)) % (dim);\ + return(sglib_##type##_add_if_not_member(&(table)[i], elem, member));\ + }\ + void sglib_hashed_##type##_delete(type *table[dim], type *elem) {\ + unsigned i;\ + i = ((unsigned)hash_function(elem)) % (dim);\ + sglib_##type##_delete(&(table)[i], elem);\ + }\ + int sglib_hashed_##type##_delete_if_member(type *table[dim], type *elem, type **memb) {\ + unsigned i;\ + i = ((unsigned)hash_function(elem)) % (dim);\ + return(sglib_##type##_delete_if_member(&(table)[i], elem, memb));\ + }\ + int sglib_hashed_##type##_is_member(type *table[dim], type *elem) {\ + unsigned i;\ + i = ((unsigned)hash_function(elem)) % (dim);\ + return(sglib_##type##_is_member((table)[i], elem));\ + }\ + type * sglib_hashed_##type##_find_member(type *table[dim], type *elem) {\ + unsigned i;\ + i = ((unsigned)hash_function(elem)) % (dim);\ + return(sglib_##type##_find_member((table)[i], elem));\ + }\ + type *sglib_hashed_##type##_it_init_on_equal(struct sglib_hashed_##type##_iterator *it, type *table[dim], int (*subcomparator)(type *, type *), type *equalto) {\ + type *e;\ + it->table = table;\ + it->currentIndex = 0;\ + it->subcomparator = subcomparator;\ + it->equalto = equalto;\ + e = sglib_##type##_it_init_on_equal(&it->containerIt, table[it->currentIndex], it->subcomparator, it->equalto);\ + if (e==NULL) e = sglib_hashed_##type##_it_next(it);\ + return(e);\ + }\ + type *sglib_hashed_##type##_it_init(struct sglib_hashed_##type##_iterator *it, type *table[dim]) {\ + return(sglib_hashed_##type##_it_init_on_equal(it, table, NULL, NULL));\ + }\ + type *sglib_hashed_##type##_it_current(struct sglib_hashed_##type##_iterator *it) {\ + return(sglib_##type##_it_current(&it->containerIt));\ + }\ + type *sglib_hashed_##type##_it_next(struct sglib_hashed_##type##_iterator *it) {\ + type *e;\ + e = sglib_##type##_it_next(&it->containerIt);\ + while (e==NULL && (++(it->currentIndex))<(dim)) {\ + e = sglib_##type##_it_init_on_equal(&it->containerIt, it->table[it->currentIndex], it->subcomparator, it->equalto);\ + }\ + return(e);\ + } + + + +/* ---------------------------------------------------------------------------- */ +/* ------------------------- DYNAMIC DATA STRUCTURES -------------------------- */ +/* ---------------------------------------------------------------------------- */ + + + +/* ------------------------------------ list (level 1) -------------------------------- */ + +#define SGLIB_DEFINE_LIST_PROTOTYPES(type, comparator, next) \ + struct sglib_##type##_iterator {\ + type *currentelem;\ + type *nextelem;\ + int (*subcomparator)(type *, type *);\ + type *equalto;\ + };\ + extern void sglib_##type##_add(type **list, type *elem);\ + extern int sglib_##type##_add_if_not_member(type **list, type *elem, type **member);\ + extern void sglib_##type##_concat(type **first, type *second);\ + extern void sglib_##type##_delete(type **list, type *elem);\ + extern int sglib_##type##_delete_if_member(type **list, type *elem, type **member);\ + extern int sglib_##type##_is_member(type *list, type *elem);\ + extern type *sglib_##type##_find_member(type *list, type *elem);\ + extern void sglib_##type##_sort(type **list);\ + extern int sglib_##type##_len(type *list);\ + extern void sglib_##type##_reverse(type **list);\ + extern type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *list); \ + extern type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *list, int (*subcomparator)(type *, type *), type *equalto); \ + extern type *sglib_##type##_it_current(struct sglib_##type##_iterator *it); \ + extern type *sglib_##type##_it_next(struct sglib_##type##_iterator *it); + + +#define SGLIB_DEFINE_LIST_FUNCTIONS(type, comparator, next) \ + int sglib_##type##_is_member(type *list, type *elem) {\ + int result;\ + SGLIB_LIST_IS_MEMBER(type, list, elem, next, result);\ + return(result);\ + }\ + type *sglib_##type##_find_member(type *list, type *elem) {\ + type *result;\ + SGLIB_LIST_FIND_MEMBER(type, list, elem, comparator, next, result);\ + return(result);\ + }\ + int sglib_##type##_add_if_not_member(type **list, type *elem, type **member) {\ + SGLIB_LIST_ADD_IF_NOT_MEMBER(type, *list, elem, comparator, next, *member);\ + return(*member==NULL);\ + }\ + void sglib_##type##_add(type **list, type *elem) {\ + SGLIB_LIST_ADD(type, *list, elem, next);\ + }\ + void sglib_##type##_concat(type **first, type *second) {\ + SGLIB_LIST_CONCAT(type, *first, second, next);\ + }\ + void sglib_##type##_delete(type **list, type *elem) {\ + SGLIB_LIST_DELETE(type, *list, elem, next);\ + }\ + int sglib_##type##_delete_if_member(type **list, type *elem, type **member) {\ + SGLIB_LIST_DELETE_IF_MEMBER(type, *list, elem, comparator, next, *member);\ + return(*member!=NULL);\ + }\ + void sglib_##type##_sort(type **list) { \ + SGLIB_LIST_SORT(type, *list, comparator, next);\ + }\ + int sglib_##type##_len(type *list) {\ + int res;\ + SGLIB_LIST_LEN(type, list, next, res);\ + return(res);\ + }\ + void sglib_##type##_reverse(type **list) {\ + SGLIB_LIST_REVERSE(type, *list, next);\ + }\ + \ + type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *list, int (*subcomparator)(type *, type *), type *equalto) {\ + it->subcomparator = subcomparator;\ + it->equalto = equalto;\ + it->nextelem = list;\ + return(sglib_##type##_it_next(it));\ + }\ + type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *list) {\ + return(sglib_##type##_it_init_on_equal(it, list, NULL, NULL));\ + }\ + type *sglib_##type##_it_current(struct sglib_##type##_iterator *it) {\ + return(it->currentelem);\ + }\ + type *sglib_##type##_it_next(struct sglib_##type##_iterator *it) {\ + type *ce, *eq;\ + int (*scp)(type *, type *);\ + ce = it->nextelem;\ + it->nextelem = NULL;\ + if (it->subcomparator != NULL) {\ + eq = it->equalto; \ + scp = it->subcomparator;\ + while (ce!=NULL && scp(ce, eq)!=0) ce = ce->next;\ + }\ + it->currentelem = ce;\ + if (ce != NULL) it->nextelem = ce->next;\ + return(ce);\ + } + +/* ----------------------------- sorted list (level 1) ----------------------------------- */ + + +#define SGLIB_DEFINE_SORTED_LIST_PROTOTYPES(type, comparator, next) \ + struct sglib_##type##_iterator {\ + type *currentelem;\ + type *nextelem;\ + int (*subcomparator)(type *, type *);\ + type *equalto;\ + };\ + extern void sglib_##type##_add(type **list, type *elem);\ + extern int sglib_##type##_add_if_not_member(type **list, type *elem, type **member);\ + extern void sglib_##type##_delete(type **list, type *elem);\ + extern int sglib_##type##_delete_if_member(type **list, type *elem, type **member);\ + extern int sglib_##type##_is_member(type *list, type *elem);\ + extern type *sglib_##type##_find_member(type *list, type *elem);\ + extern int sglib_##type##_len(type *list);\ + extern void sglib_##type##_sort(type **list);\ + extern type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *list); \ + extern type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *list, int (*subcomparator)(type *, type *), type *equalto); \ + extern type *sglib_##type##_it_current(struct sglib_##type##_iterator *it); \ + extern type *sglib_##type##_it_next(struct sglib_##type##_iterator *it); + + +#define SGLIB_DEFINE_SORTED_LIST_FUNCTIONS(type, comparator, next) \ + int sglib_##type##_is_member(type *list, type *elem) {\ + int result;\ + SGLIB_SORTED_LIST_IS_MEMBER(type, list, elem, comparator, next, result);\ + return(result);\ + }\ + type *sglib_##type##_find_member(type *list, type *elem) {\ + type *result;\ + SGLIB_SORTED_LIST_FIND_MEMBER(type, list, elem, comparator, next, result);\ + return(result);\ + }\ + int sglib_##type##_add_if_not_member(type **list, type *elem, type **member) {\ + SGLIB_SORTED_LIST_ADD_IF_NOT_MEMBER(type, *list, elem, comparator, next, *member);\ + return(*member==NULL);\ + }\ + void sglib_##type##_add(type **list, type *elem) {\ + SGLIB_SORTED_LIST_ADD(type, *list, elem, comparator, next);\ + }\ + void sglib_##type##_delete(type **list, type *elem) {\ + SGLIB_SORTED_LIST_DELETE(type, *list, elem, next);\ + }\ + int sglib_##type##_delete_if_member(type **list, type *elem, type **member) {\ + SGLIB_SORTED_LIST_DELETE_IF_MEMBER(type, *list, elem, comparator, next, *member);\ + return(*member!=NULL);\ + }\ + int sglib_##type##_len(type *list) {\ + int res;\ + SGLIB_SORTED_LIST_LEN(type, list, next, res);\ + return(res);\ + }\ + void sglib_##type##_sort(type **list) { \ + SGLIB_LIST_SORT(type, *list, comparator, next);\ + }\ + \ + type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *list, int (*subcomparator)(type *, type *), type *equalto) {\ + it->subcomparator = subcomparator;\ + it->equalto = equalto;\ + it->nextelem = list;\ + return(sglib_##type##_it_next(it));\ + }\ + type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *list) {\ + return(sglib_##type##_it_init_on_equal(it, list, NULL, NULL));\ + }\ + type *sglib_##type##_it_current(struct sglib_##type##_iterator *it) {\ + return(it->currentelem);\ + }\ + type *sglib_##type##_it_next(struct sglib_##type##_iterator *it) {\ + type *ce, *eq;\ + int (*scp)(type *, type *);\ + int c;\ + ce = it->nextelem;\ + it->nextelem = NULL;\ + if (it->subcomparator != NULL) {\ + eq = it->equalto; \ + scp = it->subcomparator;\ + while (ce!=NULL && (c=scp(ce, eq)) < 0) ce = ce->next;\ + if (ce != NULL && c > 0) ce = NULL;\ + }\ + it->currentelem = ce;\ + if (ce != NULL) it->nextelem = ce->next;\ + return(ce);\ + } + + +/* ----------------------------- double linked list (level 1) ------------------------------ */ + + +#define SGLIB_DEFINE_DL_LIST_PROTOTYPES(type, comparator, previous, next) \ + struct sglib_##type##_iterator {\ + type *currentelem;\ + type *prevelem;\ + type *nextelem;\ + int (*subcomparator)(type *, type *);\ + type *equalto;\ + };\ + extern void sglib_##type##_add(type **list, type *elem);\ + extern void sglib_##type##_add_before(type **list, type *elem);\ + extern void sglib_##type##_add_after(type **list, type *elem);\ + extern int sglib_##type##_add_if_not_member(type **list, type *elem, type **member);\ + extern int sglib_##type##_add_before_if_not_member(type **list, type *elem, type **member);\ + extern int sglib_##type##_add_after_if_not_member(type **list, type *elem, type **member);\ + extern void sglib_##type##_concat(type **first, type *second);\ + extern void sglib_##type##_delete(type **list, type *elem);\ + extern int sglib_##type##_delete_if_member(type **list, type *elem, type **member);\ + extern int sglib_##type##_is_member(type *list, type *elem);\ + extern type *sglib_##type##_find_member(type *list, type *elem);\ + extern type *sglib_##type##_get_first(type *list);\ + extern type *sglib_##type##_get_last(type *list);\ + extern void sglib_##type##_sort(type **list);\ + extern int sglib_##type##_len(type *list);\ + extern void sglib_##type##_reverse(type **list);\ + extern type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *list); \ + extern type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *list, int (*subcomparator)(type *, type *), type *equalto); \ + extern type *sglib_##type##_it_current(struct sglib_##type##_iterator *it); \ + extern type *sglib_##type##_it_next(struct sglib_##type##_iterator *it); + + +#define SGLIB_DEFINE_DL_LIST_FUNCTIONS(type, comparator, previous, next) \ + void sglib_##type##_add(type **list, type *elem) {\ + SGLIB_DL_LIST_ADD(type, *list, elem, previous, next);\ + }\ + void sglib_##type##_add_after(type **list, type *elem) {\ + SGLIB_DL_LIST_ADD_AFTER(type, *list, elem, previous, next);\ + }\ + void sglib_##type##_add_before(type **list, type *elem) {\ + SGLIB_DL_LIST_ADD_BEFORE(type, *list, elem, previous, next);\ + }\ + int sglib_##type##_add_if_not_member(type **list, type *elem, type **member) {\ + SGLIB_DL_LIST_ADD_IF_NOT_MEMBER(type, *list, elem, comparator, previous, next, *member);\ + return(*member==NULL);\ + }\ + int sglib_##type##_add_after_if_not_member(type **list, type *elem, type **member) {\ + SGLIB_DL_LIST_ADD_AFTER_IF_NOT_MEMBER(type, *list, elem, comparator, previous, next, *member);\ + return(*member==NULL);\ + }\ + int sglib_##type##_add_before_if_not_member(type **list, type *elem, type **member) {\ + SGLIB_DL_LIST_ADD_BEFORE_IF_NOT_MEMBER(type, *list, elem, comparator, previous, next, *member);\ + return(*member==NULL);\ + }\ + void sglib_##type##_concat(type **first, type *second) {\ + SGLIB_DL_LIST_CONCAT(type, *first, second, previous, next);\ + }\ + void sglib_##type##_delete(type **list, type *elem) {\ + SGLIB_DL_LIST_DELETE(type, *list, elem, previous, next);\ + }\ + int sglib_##type##_delete_if_member(type **list, type *elem, type **member) {\ + SGLIB_DL_LIST_DELETE_IF_MEMBER(type, *list, elem, comparator, previous, next, *member);\ + return(*member!=NULL);\ + }\ + int sglib_##type##_is_member(type *list, type *elem) {\ + int result;\ + SGLIB_DL_LIST_IS_MEMBER(type, list, elem, previous, next, result);\ + return(result);\ + }\ + type *sglib_##type##_find_member(type *list, type *elem) {\ + type *result;\ + SGLIB_DL_LIST_FIND_MEMBER(type, list, elem, comparator, previous, next, result);\ + return(result);\ + }\ + type *sglib_##type##_get_first(type *list) {\ + type *result;\ + SGLIB_DL_LIST_GET_FIRST(type, list, previous, next, result);\ + return(result);\ + }\ + type *sglib_##type##_get_last(type *list) {\ + type *result;\ + SGLIB_DL_LIST_GET_LAST(type, list, previous, next, result);\ + return(result);\ + }\ + void sglib_##type##_sort(type **list) {\ + SGLIB_DL_LIST_SORT(type, *list, comparator, previous, next);\ + }\ + int sglib_##type##_len(type *list) {\ + int res;\ + SGLIB_DL_LIST_LEN(type, list, previous, next, res);\ + return(res);\ + }\ + void sglib_##type##_reverse(type **list) {\ + SGLIB_DL_LIST_REVERSE(type, *list, previous, next);\ + }\ + \ + type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *list, int (*subcomparator)(type *, type *), type *equalto) {\ + it->subcomparator = subcomparator;\ + it->equalto = equalto;\ + it->prevelem = list;\ + it->nextelem = list;\ + if (list != NULL) it->nextelem = list->next;\ + return(sglib_##type##_it_next(it));\ + }\ + type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *list) {\ + return(sglib_##type##_it_init_on_equal(it, list, NULL, NULL));\ + }\ + type *sglib_##type##_it_current(struct sglib_##type##_iterator *it) {\ + return(it->currentelem);\ + }\ + type *sglib_##type##_it_next(struct sglib_##type##_iterator *it) {\ + type *ce, *eq;\ + int (*scp)(type *, type *);\ + ce = it->prevelem;\ + it->prevelem = NULL;\ + if (it->subcomparator != NULL) {\ + eq = it->equalto; \ + scp = it->subcomparator;\ + while (ce!=NULL && scp(eq, ce)!=0) ce = ce->previous;\ + }\ + if (ce != NULL) {\ + it->prevelem = ce->previous;\ + } else {\ + ce = it->nextelem;\ + it->nextelem = NULL;\ + if (it->subcomparator != NULL) {\ + eq = it->equalto; \ + scp = it->subcomparator;\ + while (ce!=NULL && scp(ce, eq)!=0) ce = ce->next;\ + }\ + if (ce != NULL) it->nextelem = ce->next;\ + }\ + it->currentelem = ce;\ + return(ce);\ + } + + +/* --------------------------------- red-black trees (level 1) -------------------------------- */ + +/* + +This implementation requires pointers to left and right sons (no +parent pointer is needed) and one bit of additional information +storing the color of the node. The implementation follows discrepancy +fixing rules from: +http://www.cis.ohio-state.edu/~gurari/course/cis680/cis680Ch11.html + +*/ + +#define SGLIB___RBTREE_FIX_INSERTION_DISCREPANCY(type, tree, leftt, rightt, bits, RED, BLACK) {\ + type *t, *tl, *a, *b, *c, *ar, *bl, *br, *cl, *cr;\ + t = *tree;\ + tl = t->leftt;\ + if (t->rightt!=NULL && SGLIB___GET_VALUE(t->rightt->bits)==RED) {\ + if (SGLIB___GET_VALUE(tl->bits)==RED) {\ + if ((tl->leftt!=NULL && SGLIB___GET_VALUE(tl->leftt->bits)==RED) \ + || (tl->rightt!=NULL && SGLIB___GET_VALUE(tl->rightt->bits)==RED)) {\ + SGLIB___SET_VALUE(t->leftt->bits,BLACK);\ + SGLIB___SET_VALUE(t->rightt->bits,BLACK);\ + SGLIB___SET_VALUE(t->bits,RED);\ + }\ + }\ + } else {\ + if (SGLIB___GET_VALUE(tl->bits)==RED) {\ + if (tl->leftt!=NULL && SGLIB___GET_VALUE(tl->leftt->bits)==RED) {\ + a = t; b = tl; c = tl->leftt;\ + br = b->rightt;\ + a->leftt = br;\ + b->leftt = c; b->rightt = a;\ + SGLIB___SET_VALUE(a->bits,RED);\ + SGLIB___SET_VALUE(b->bits,BLACK);\ + *tree = b;\ + } else if (tl->rightt!=NULL && SGLIB___GET_VALUE(tl->rightt->bits)==RED) {\ + a = t; b = tl; ar=a->rightt;\ + bl=b->leftt; c=b->rightt;\ + cl=c->leftt; cr=c->rightt;\ + b->rightt = cl;\ + a->leftt = cr;\ + c->leftt = b;\ + c->rightt = a;\ + SGLIB___SET_VALUE(c->bits,BLACK);\ + SGLIB___SET_VALUE(a->bits,RED);\ + *tree = c;\ + }\ + }\ + }\ +} + +#define SGLIB___RBTREE_FIX_DELETION_DISCREPANCY(type, tree, leftt, rightt, bits, RED, BLACK, res) {\ + type *t, *a, *b, *c, *d, *ar, *bl, *br, *cl, *cr, *dl, *dr;\ + t = a = *tree;\ + assert(t!=NULL);\ + ar = a->rightt;\ + b = t->leftt;\ + if (b==NULL) {\ + assert(SGLIB___GET_VALUE(t->bits)==RED);\ + SGLIB___SET_VALUE(t->bits,BLACK);\ + res = 0;\ + } else {\ + bl = b->leftt;\ + br = b->rightt;\ + if (SGLIB___GET_VALUE(b->bits)==RED) {\ + if (br==NULL) {\ + *tree = b;\ + SGLIB___SET_VALUE(b->bits,BLACK);\ + b->rightt = a;\ + a->leftt = br;\ + res = 0;\ + } else {\ + c = br;\ + assert(c!=NULL && SGLIB___GET_VALUE(c->bits)==BLACK);\ + cl = c->leftt;\ + cr = c->rightt;\ + if ((cl==NULL||SGLIB___GET_VALUE(cl->bits)==BLACK) && (cr==NULL||SGLIB___GET_VALUE(cr->bits)==BLACK)) {\ + *tree = b;\ + b->rightt = a;\ + SGLIB___SET_VALUE(b->bits,BLACK);\ + a->leftt = c;\ + SGLIB___SET_VALUE(c->bits,RED);\ + res = 0;\ + } else if (cl!=NULL && SGLIB___GET_VALUE(cl->bits)==RED) {\ + if (cr!=NULL && SGLIB___GET_VALUE(cr->bits)==RED) {\ + d = cr;\ + dl = d->leftt;\ + dr = d->rightt;\ + *tree = d;\ + SGLIB___SET_VALUE(d->bits,BLACK);\ + d->leftt = b;\ + c->rightt = dl;\ + d->rightt = a;\ + a->leftt = dr;\ + res = 0;\ + } else {\ + *tree = c;\ + c->leftt = b;\ + c->rightt = a;\ + b->leftt = bl;\ + b->rightt = cl;\ + a->leftt = cr;\ + SGLIB___SET_VALUE(cl->bits,BLACK);\ + res = 0;\ + }\ + } else if (cr!=NULL && SGLIB___GET_VALUE(cr->bits)==RED) {\ + assert(cl==NULL || SGLIB___GET_VALUE(cl->bits)==BLACK);\ + d = cr;\ + dl = d->leftt;\ + dr = d->rightt;\ + *tree = d;\ + SGLIB___SET_VALUE(d->bits,BLACK);\ + d->leftt = b;\ + c->rightt = dl;\ + d->rightt = a;\ + a->leftt = dr;\ + res = 0;\ + } else {\ + assert(0);\ + res = 0;\ + }\ + }\ + } else {\ + if ((bl==NULL || SGLIB___GET_VALUE(bl->bits)==BLACK) && (br==NULL || SGLIB___GET_VALUE(br->bits)==BLACK)) {\ + res = (SGLIB___GET_VALUE(a->bits)==BLACK);\ + SGLIB___SET_VALUE(a->bits,BLACK);\ + SGLIB___SET_VALUE(b->bits,RED);\ + } else if (bl!=NULL && SGLIB___GET_VALUE(bl->bits)==RED) {\ + if (br==NULL || SGLIB___GET_VALUE(br->bits)==BLACK) {\ + *tree = b;\ + SGLIB___SET_VALUE(b->bits,SGLIB___GET_VALUE(a->bits));\ + SGLIB___SET_VALUE(a->bits,BLACK);\ + b->rightt = a;\ + a->leftt = br;\ + SGLIB___SET_VALUE(bl->bits,BLACK);\ + res = 0;\ + } else {\ + assert(bl!=NULL);\ + assert(br!=NULL);\ + assert(SGLIB___GET_VALUE(bl->bits)==RED);\ + assert(SGLIB___GET_VALUE(br->bits)==RED);\ + c = br;\ + cl = c->leftt;\ + cr = c->rightt;\ + *tree = c;\ + SGLIB___SET_VALUE(c->bits,SGLIB___GET_VALUE(a->bits));\ + SGLIB___SET_VALUE(a->bits,BLACK);\ + c->leftt = b;\ + c->rightt = a;\ + b->rightt = cl;\ + a->leftt = cr;\ + res = 0;\ + }\ + } else {\ + assert(br!=NULL && SGLIB___GET_VALUE(br->bits)==RED);\ + c = br;\ + cl = c->leftt;\ + cr = c->rightt;\ + *tree = c;\ + SGLIB___SET_VALUE(c->bits,SGLIB___GET_VALUE(a->bits));\ + SGLIB___SET_VALUE(a->bits,BLACK);\ + c->leftt = b;\ + c->rightt = a;\ + b->rightt = cl;\ + a->leftt = cr;\ + res = 0;\ + }\ + }\ + }\ +} + + +#define SGLIB_DEFINE_RBTREE_FUNCTIONS_GENERAL(type, left, right, bits, comparator, RED, BLACK) \ +static void sglib___##type##_fix_left_insertion_discrepancy(type **tree) {\ + SGLIB___RBTREE_FIX_INSERTION_DISCREPANCY(type, tree, left, right, bits, RED, BLACK);\ +}\ +\ +static void sglib___##type##_fix_right_insertion_discrepancy(type **tree) {\ + SGLIB___RBTREE_FIX_INSERTION_DISCREPANCY(type, tree, right, left, bits, RED, BLACK);\ +}\ +\ +static int sglib___##type##_fix_left_deletion_discrepancy(type **tree) {\ + int res;\ + SGLIB___RBTREE_FIX_DELETION_DISCREPANCY(type, tree, right, left, bits, RED, BLACK, res);\ + return(res);\ +}\ +\ +static int sglib___##type##_fix_right_deletion_discrepancy(type **tree) {\ + int res;\ + SGLIB___RBTREE_FIX_DELETION_DISCREPANCY(type, tree, left, right, bits, RED, BLACK, res);\ + return(res);\ +}\ +\ +static void sglib___##type##_add_recursive(type **tree, type *elem) {\ + int cmp;\ + type *t;\ + t = *tree;\ + if (t == NULL) {\ + SGLIB___SET_VALUE(elem->bits,RED);\ + *tree =elem;\ + } else {\ + cmp = comparator(elem, t);\ + if (cmp < 0 || (cmp==0 && elemleft, elem);\ + if (SGLIB___GET_VALUE(t->bits)==BLACK) sglib___##type##_fix_left_insertion_discrepancy(tree);\ + } else {\ + sglib___##type##_add_recursive(&t->right, elem);\ + if (SGLIB___GET_VALUE(t->bits)==BLACK) sglib___##type##_fix_right_insertion_discrepancy(tree);\ + }\ + }\ +}\ +\ +static int sglib___##type##_delete_rightmost_leaf(type **tree, type **theLeaf) {\ + type *t;\ + int res, deepDecreased;\ + t = *tree;\ + res = 0;\ + assert(t!=NULL);\ + if (t->right == NULL) {\ + *theLeaf = t;\ + if (t->left!=NULL) {\ + if (SGLIB___GET_VALUE(t->bits)==BLACK && SGLIB___GET_VALUE(t->left->bits)==BLACK) res = 1;\ + SGLIB___SET_VALUE(t->left->bits,BLACK);\ + *tree = t->left;\ + } else {\ + *tree = NULL;\ + res = (SGLIB___GET_VALUE(t->bits)==BLACK);\ + }\ + } else {\ + deepDecreased = sglib___##type##_delete_rightmost_leaf(&t->right, theLeaf);\ + if (deepDecreased) res = sglib___##type##_fix_right_deletion_discrepancy(tree);\ + }\ + return(res);\ +}\ +\ +int sglib___##type##_delete_recursive(type **tree, type *elem) {\ + type *t, *theLeaf;\ + int cmp, res, deepDecreased;\ + t = *tree;\ + res = 0;\ + if (t==NULL) {\ + assert(0 && "The element to delete not found in the tree, use 'delete_if_member'"!=NULL);\ + } else {\ + cmp = comparator(elem, t);\ + if (cmp < 0 || (cmp==0 && elemleft, elem);\ + if (deepDecreased) {\ + res = sglib___##type##_fix_left_deletion_discrepancy(tree);\ + }\ + } else if (cmp > 0 || (cmp==0 && elem>t)) {\ + deepDecreased = sglib___##type##_delete_recursive(&t->right, elem);\ + if (deepDecreased) {\ + res = sglib___##type##_fix_right_deletion_discrepancy(tree);\ + }\ + } else {\ + assert(elem==t && "Deleting an element which is non member of the tree, use 'delete_if_member'"!=NULL);\ + if (t->left == NULL) {\ + if (t->right == NULL) {\ + /* a leaf, delete, it; */\ + *tree = NULL;\ + res = (SGLIB___GET_VALUE(t->bits)==BLACK);\ + } else {\ + if (SGLIB___GET_VALUE(t->bits)==0 && SGLIB___GET_VALUE(t->right->bits)==0) res = 1;\ + SGLIB___SET_VALUE(t->right->bits,BLACK);\ + *tree = t->right;\ + }\ + } else {\ + /* propagate deletion until righmost leaf of left subtree */\ + deepDecreased = sglib___##type##_delete_rightmost_leaf(&t->left, &theLeaf);\ + theLeaf->left = t->left;\ + theLeaf->right = t->right;\ + SGLIB___SET_VALUE(theLeaf->bits,SGLIB___GET_VALUE(t->bits));\ + *tree = theLeaf;\ + if (deepDecreased) res = sglib___##type##_fix_left_deletion_discrepancy(tree);\ + }\ + }\ + }\ + return(res);\ +}\ +\ +void sglib_##type##_add(type **tree, type *elem) {\ + elem->left = elem->right = NULL;\ + sglib___##type##_add_recursive(tree, elem);\ + SGLIB___SET_VALUE((*tree)->bits,BLACK);\ +}\ +\ +void sglib_##type##_delete(type **tree, type *elem) {\ + sglib___##type##_delete_recursive(tree, elem);\ + if (*tree!=NULL) SGLIB___SET_VALUE((*tree)->bits,BLACK);\ +}\ +\ +type *sglib_##type##_find_member(type *t, type *elem) {\ + type *res;\ + SGLIB___BIN_TREE_FIND_MEMBER(type, t, elem, left, right, comparator, res);\ + return(res);\ +}\ +\ +int sglib_##type##_is_member(type *t, type *elem) {\ + int cmp;\ + while (t!=NULL) {\ + cmp = comparator(elem, t);\ + if (cmp < 0 || (cmp==0 && elemleft;\ + } else if (cmp > 0 || (cmp==0 && elem>t)) {\ + t = t->right;\ + } else {\ + assert(t == elem);\ + return(1);\ + }\ + }\ + return(0);\ +}\ +\ +int sglib_##type##_delete_if_member(type **tree, type *elem, type **memb) {\ + if ((*memb=sglib_##type##_find_member(*tree, elem))!=NULL) {\ + sglib_##type##_delete(tree, *memb);\ + return(1);\ + } else {\ + return(0);\ + }\ +}\ +int sglib_##type##_add_if_not_member(type **tree, type *elem, type **memb) {\ + if ((*memb=sglib_##type##_find_member(*tree, elem))==NULL) {\ + sglib_##type##_add(tree, elem);\ + return(1);\ + } else {\ + return(0);\ + }\ +}\ +int sglib_##type##_len(type *t) {\ + int n;\ + type *e;\ + n = 0;\ + SGLIB_BIN_TREE_MAP_ON_ELEMENTS(type, t, e, left, right, n++);\ + return(n);\ +}\ +\ +void sglib__##type##_it_compute_current_elem(struct sglib_##type##_iterator *it) {\ + int i,j,cmp;\ + type *s, *eqt;\ + int (*subcomparator)(type *, type *);\ + eqt = it->equalto;\ + subcomparator = it->subcomparator;\ + it->currentelem = NULL;\ + while(it->pathi > 0 && it->currentelem==NULL) {\ + i = it->pathi-1;\ + if (i >= 0) {\ + if (it->pass[i] >= 2) {\ + /* goto up */\ + it->pathi --;\ + } else {\ + if (it->pass[i] == 0) {\ + /* goto left */\ + s = it->path[i]->left;\ + } else {\ + /* goto right */\ + s = it->path[i]->right;\ + }\ + if (eqt != NULL) {\ + if (subcomparator == NULL) {\ + SGLIB___BIN_TREE_FIND_MEMBER(type, s, eqt, left, right, comparator, s);\ + } else {\ + SGLIB___BIN_TREE_FIND_MEMBER(type, s, eqt, left, right, subcomparator, s);\ + }\ + }\ + if (s != NULL) {\ + j = i+1;\ + it->path[j] = s;\ + it->pass[j] = 0;\ + it->pathi ++;\ + }\ + it->pass[i] ++;\ + }\ + }\ + if (it->pathi>0 && it->order == it->pass[it->pathi-1]) {\ + it->currentelem = it->path[it->pathi-1];\ + }\ + }\ +}\ +type *sglib__##type##_it_init(struct sglib_##type##_iterator *it, type *tree, int order, int (*subcomparator)(type *, type *), type *equalto) {\ + type *t;\ + assert(it!=NULL);\ + it->order = order;\ + it->equalto = equalto;\ + it->subcomparator = subcomparator;\ + if (equalto == NULL) { \ + t = tree;\ + } else {\ + if (subcomparator == NULL) {\ + SGLIB___BIN_TREE_FIND_MEMBER(type, tree, equalto, left, right, comparator, t);\ + } else {\ + SGLIB___BIN_TREE_FIND_MEMBER(type, tree, equalto, left, right, subcomparator, t);\ + }\ + }\ + if (t == NULL) {\ + it->pathi = 0;\ + it->currentelem = NULL;\ + } else {\ + it->pathi = 1;\ + it->pass[0] = 0;\ + it->path[0] = t;\ + if (order == 0) {\ + it->currentelem = t;\ + } else {\ + sglib__##type##_it_compute_current_elem(it);\ + }\ + }\ + return(it->currentelem);\ +}\ +type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *tree) {\ + return(sglib__##type##_it_init(it, tree, 2, NULL, NULL));\ +}\ +type *sglib_##type##_it_init_preorder(struct sglib_##type##_iterator *it, type *tree) {\ + return(sglib__##type##_it_init(it, tree, 0, NULL, NULL));\ +}\ +type *sglib_##type##_it_init_inorder(struct sglib_##type##_iterator *it, type *tree) {\ + return(sglib__##type##_it_init(it, tree, 1, NULL, NULL));\ +}\ +type *sglib_##type##_it_init_postorder(struct sglib_##type##_iterator *it, type *tree) {\ + return(sglib__##type##_it_init(it, tree, 2, NULL, NULL));\ +}\ +type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *tree, int (*subcomparator)(type *, type *), type *equalto) {\ + return(sglib__##type##_it_init(it, tree, 1, subcomparator, equalto));\ +}\ +type *sglib_##type##_it_current(struct sglib_##type##_iterator *it) {\ + return(it->currentelem);\ +}\ +type *sglib_##type##_it_next(struct sglib_##type##_iterator *it) {\ + sglib__##type##_it_compute_current_elem(it);\ + return(it->currentelem);\ +}\ +\ +static void sglib___##type##_consistency_check_recursive(type *t, int *pathdeep, int cdeep) {\ + if (t==NULL) {\ + if (*pathdeep < 0) *pathdeep = cdeep;\ + else assert(*pathdeep == cdeep);\ + } else {\ + if (t->left!=NULL) assert(comparator(t->left, t) <= 0);\ + if (t->right!=NULL) assert(comparator(t, t->right) <= 0);\ + if (SGLIB___GET_VALUE(t->bits) == RED) {\ + assert(t->left == NULL || SGLIB___GET_VALUE(t->left->bits)==BLACK);\ + assert(t->right == NULL || SGLIB___GET_VALUE(t->right->bits)==BLACK);\ + sglib___##type##_consistency_check_recursive(t->left, pathdeep, cdeep);\ + sglib___##type##_consistency_check_recursive(t->right, pathdeep, cdeep);\ + } else {\ + sglib___##type##_consistency_check_recursive(t->left, pathdeep, cdeep+1);\ + sglib___##type##_consistency_check_recursive(t->right, pathdeep, cdeep+1);\ + }\ + }\ +}\ +\ +void sglib___##type##_consistency_check(type *t) {\ + int pathDeep;\ + assert(t==NULL || SGLIB___GET_VALUE(t->bits) == BLACK);\ + pathDeep = -1;\ + sglib___##type##_consistency_check_recursive(t, &pathDeep, 0);\ +} + + +#define SGLIB_DEFINE_RBTREE_PROTOTYPES(type, left, right, colorbit, comparator) \ + struct sglib_##type##_iterator {\ + type *currentelem;\ + char pass[SGLIB_MAX_TREE_DEEP];\ + type *path[SGLIB_MAX_TREE_DEEP];\ + short int pathi;\ + short int order;\ + type *equalto;\ + int (*subcomparator)(type *, type *);\ + };\ + extern void sglib___##type##_consistency_check(type *t); \ + extern void sglib_##type##_add(type **tree, type *elem); \ + extern int sglib_##type##_add_if_not_member(type **tree, type *elem, type **memb); \ + extern void sglib_##type##_delete(type **tree, type *elem); \ + extern int sglib_##type##_delete_if_member(type **tree, type *elem, type **memb); \ + extern int sglib_##type##_is_member(type *t, type *elem); \ + extern type *sglib_##type##_find_member(type *t, type *elem); \ + extern int sglib_##type##_len(type *t); \ + extern type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *tree); \ + extern type *sglib_##type##_it_init_preorder(struct sglib_##type##_iterator *it, type *tree); \ + extern type *sglib_##type##_it_init_inorder(struct sglib_##type##_iterator *it, type *tree); \ + extern type *sglib_##type##_it_init_postorder(struct sglib_##type##_iterator *it, type *tree); \ + extern type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *tree, int (*subcomparator)(type *, type *), type *equalto); \ + extern type *sglib_##type##_it_current(struct sglib_##type##_iterator *it); \ + extern type *sglib_##type##_it_next(struct sglib_##type##_iterator *it); \ + + +#define SGLIB_DEFINE_RBTREE_FUNCTIONS(type, left, right, colorbit, comparator) \ + SGLIB_DEFINE_RBTREE_FUNCTIONS_GENERAL(type, left, right, colorbit, comparator, 1, 0) + + + +/* ---------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- */ +/* - SUPPLEMENTARY DEFINITIONS - */ +/* ---------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- */ + + +#define SGLIB___GET_VALUE(x) (x) +#define SGLIB___SET_VALUE(x, value) {(x) = (value);} +#define SGLIB_ARRAY_ELEMENTS_EXCHANGER(type, a, i, j) {type _sgl_aee_tmp_; _sgl_aee_tmp_=(a)[(i)]; (a)[(i)]=(a)[(j)]; (a)[(j)]= _sgl_aee_tmp_;} + + +#define SGLIB_SAFE_NUMERIC_COMPARATOR(x, y) (((x)>(y)?1:((x)<(y)?-1:0))) +#define SGLIB_SAFE_REVERSE_NUMERIC_COMPARATOR(x, y) (((x)>(y)?-1:((x)<(y)?1:0))) +#define SGLIB_FAST_NUMERIC_COMPARATOR(x, y) ((int)((x) - (y))) +#define SGLIB_FAST_REVERSE_NUMERIC_COMPARATOR(x, y) ((int)((y) - (x))) +#define SGLIB_NUMERIC_COMPARATOR(x, y) SGLIB_SAFE_NUMERIC_COMPARATOR(x, y) +#define SGLIB_REVERSE_NUMERIC_COMPARATOR(x, y) SGLIB_SAFE_REVERSE_NUMERIC_COMPARATOR(x, y) + +#ifndef SGLIB_MAX_TREE_DEEP +#define SGLIB_MAX_TREE_DEEP 128 +#endif + +#ifndef SGLIB_HASH_TAB_SHIFT_CONSTANT +#define SGLIB_HASH_TAB_SHIFT_CONSTANT 16381 /* should be a prime */ +/* #define SGLIB_HASH_TAB_SHIFT_CONSTANT 536870912*/ /* for large tables :) */ +#endif + +#endif /* _SGLIB__h_ */ diff --git a/src/sglib-arrayquicksort/Makefile.am b/src/sglib-arrayquicksort/Makefile.am index 3fe75f56..f403e53e 100644 --- a/src/sglib-arrayquicksort/Makefile.am +++ b/src/sglib-arrayquicksort/Makefile.am @@ -30,12 +30,13 @@ noinst_LTLIBRARIES = libsglib-arrayquicksort.la sglib_arrayquicksort_SOURCES = -libsglib_arrayquicksort_la_SOURCES = arraysort.c sglib.h +libsglib_arrayquicksort_la_SOURCES = arrayquicksort.c sglib.h libsglib_arrayquicksort_la_CPPFLAGS = -DQUICK_SORT ${AM_CPPFLAGS} sglib_arrayquicksort_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libsglib-arrayquicksort.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) endif diff --git a/src/sglib-arrayquicksort/Makefile.in b/src/sglib-arrayquicksort/Makefile.in index 66545150..ecae2802 100644 --- a/src/sglib-arrayquicksort/Makefile.in +++ b/src/sglib-arrayquicksort/Makefile.in @@ -154,8 +154,8 @@ CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libsglib_arrayquicksort_la_LIBADD = -am__libsglib_arrayquicksort_la_SOURCES_DIST = arraysort.c sglib.h -@ENABLED_BENCHMARK_SGLIB_ARRAYQUICKSORT_TRUE@am_libsglib_arrayquicksort_la_OBJECTS = libsglib_arrayquicksort_la-arraysort.lo +am__libsglib_arrayquicksort_la_SOURCES_DIST = arrayquicksort.c sglib.h +@ENABLED_BENCHMARK_SGLIB_ARRAYQUICKSORT_TRUE@am_libsglib_arrayquicksort_la_OBJECTS = libsglib_arrayquicksort_la-arrayquicksort.lo libsglib_arrayquicksort_la_OBJECTS = \ $(am_libsglib_arrayquicksort_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) @@ -171,6 +171,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_SGLIB_ARRAYQUICKSORT_TRUE@sglib_arrayquicksort_DEPENDENCIES = $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_SGLIB_ARRAYQUICKSORT_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_SGLIB_ARRAYQUICKSORT_TRUE@ libsglib-arrayquicksort.la \ +@ENABLED_BENCHMARK_SGLIB_ARRAYQUICKSORT_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_SGLIB_ARRAYQUICKSORT_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_SGLIB_ARRAYQUICKSORT_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_SGLIB_ARRAYQUICKSORT_TRUE@ $(am__DEPENDENCIES_1) @@ -391,12 +392,13 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_SGLIB_ARRAYQUICKSORT_TRUE@LIBM = $(if $(DUMMY_LIBM),$(DUMMY_LIBM),-lm) @ENABLED_BENCHMARK_SGLIB_ARRAYQUICKSORT_TRUE@noinst_LTLIBRARIES = libsglib-arrayquicksort.la @ENABLED_BENCHMARK_SGLIB_ARRAYQUICKSORT_TRUE@sglib_arrayquicksort_SOURCES = -@ENABLED_BENCHMARK_SGLIB_ARRAYQUICKSORT_TRUE@libsglib_arrayquicksort_la_SOURCES = arraysort.c sglib.h +@ENABLED_BENCHMARK_SGLIB_ARRAYQUICKSORT_TRUE@libsglib_arrayquicksort_la_SOURCES = arrayquicksort.c sglib.h @ENABLED_BENCHMARK_SGLIB_ARRAYQUICKSORT_TRUE@libsglib_arrayquicksort_la_CPPFLAGS = -DQUICK_SORT ${AM_CPPFLAGS} @ENABLED_BENCHMARK_SGLIB_ARRAYQUICKSORT_TRUE@sglib_arrayquicksort_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_SGLIB_ARRAYQUICKSORT_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_SGLIB_ARRAYQUICKSORT_TRUE@ libsglib-arrayquicksort.la \ -@ENABLED_BENCHMARK_SGLIB_ARRAYQUICKSORT_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_SGLIB_ARRAYQUICKSORT_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_SGLIB_ARRAYQUICKSORT_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am @@ -506,7 +508,7 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsglib_arrayquicksort_la-arraysort.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsglib_arrayquicksort_la-arrayquicksort.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -529,12 +531,12 @@ distclean-compile: @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< -libsglib_arrayquicksort_la-arraysort.lo: arraysort.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsglib_arrayquicksort_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsglib_arrayquicksort_la-arraysort.lo -MD -MP -MF $(DEPDIR)/libsglib_arrayquicksort_la-arraysort.Tpo -c -o libsglib_arrayquicksort_la-arraysort.lo `test -f 'arraysort.c' || echo '$(srcdir)/'`arraysort.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsglib_arrayquicksort_la-arraysort.Tpo $(DEPDIR)/libsglib_arrayquicksort_la-arraysort.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='arraysort.c' object='libsglib_arrayquicksort_la-arraysort.lo' libtool=yes @AMDEPBACKSLASH@ +libsglib_arrayquicksort_la-arrayquicksort.lo: arrayquicksort.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsglib_arrayquicksort_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsglib_arrayquicksort_la-arrayquicksort.lo -MD -MP -MF $(DEPDIR)/libsglib_arrayquicksort_la-arrayquicksort.Tpo -c -o libsglib_arrayquicksort_la-arrayquicksort.lo `test -f 'arrayquicksort.c' || echo '$(srcdir)/'`arrayquicksort.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsglib_arrayquicksort_la-arrayquicksort.Tpo $(DEPDIR)/libsglib_arrayquicksort_la-arrayquicksort.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='arrayquicksort.c' object='libsglib_arrayquicksort_la-arrayquicksort.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsglib_arrayquicksort_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsglib_arrayquicksort_la-arraysort.lo `test -f 'arraysort.c' || echo '$(srcdir)/'`arraysort.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsglib_arrayquicksort_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsglib_arrayquicksort_la-arrayquicksort.lo `test -f 'arrayquicksort.c' || echo '$(srcdir)/'`arrayquicksort.c mostlyclean-libtool: -rm -f *.lo diff --git a/src/sglib-arrayquicksort/arrayquicksort.c b/src/sglib-arrayquicksort/arrayquicksort.c new file mode 100644 index 00000000..4d7d877f --- /dev/null +++ b/src/sglib-arrayquicksort/arrayquicksort.c @@ -0,0 +1,84 @@ +/* BEEBS arraysort benchmark + + Copyright (C) 2014 Embecosm Limited and University of Bristol + + Contributor James Pallister + + This file is part of the Bristol/Embecosm Embedded Benchmark Suite. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include +#include "support.h" +#include "sglib.h" + +/* This scale factor will be changed to equalise the runtime of the + benchmarks. */ +#define LOCAL_SCALE_FACTOR 409 + +static const int array[100] = { + 14, 66, 12, 41, 86, 69, 19, 77, 68, 38, + 26, 42, 37, 23, 17, 29, 55, 13, 90, 92, + 76, 99, 10, 54, 57, 83, 40, 44, 75, 33, + 24, 28, 80, 18, 78, 32, 93, 89, 52, 11, + 21, 96, 50, 15, 48, 63, 87, 20, 8, 85, + 43, 16, 94, 88, 53, 84, 74, 91, 67, 36, + 95, 61, 64, 5, 30, 82, 72, 46, 59, 9, + 7, 3, 39, 31, 4, 73, 70, 60, 58, 81, + 56, 51, 45, 1, 6, 49, 27, 47, 34, 35, + 62, 97, 2, 79, 98, 25, 22, 65, 71, 0 +}; + +int array2[100]; + + +int +verify_benchmark (int res __attribute ((unused)) ) +{ + static const int array_exp[100] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99 + }; + + return 0 == memcmp (array2, array_exp, 100 * sizeof (array[0])); +} + + +void +initialise_benchmark (void) +{ +} + + + +int benchmark() +{ + int i; + + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + { + memcpy (array2, array, 100 * sizeof (array[0])); + SGLIB_ARRAY_SINGLE_QUICK_SORT(int, array2, 100, SGLIB_NUMERIC_COMPARATOR); + } + + return 0; +} diff --git a/src/sglib-arrayquicksort/arraysort.c b/src/sglib-arrayquicksort/arraysort.c deleted file mode 120000 index 099c21c9..00000000 --- a/src/sglib-arrayquicksort/arraysort.c +++ /dev/null @@ -1 +0,0 @@ -../sglib-arraysort/arraysort.c \ No newline at end of file diff --git a/src/sglib-arrayquicksort/sglib.h b/src/sglib-arrayquicksort/sglib.h deleted file mode 120000 index 3b5b2423..00000000 --- a/src/sglib-arrayquicksort/sglib.h +++ /dev/null @@ -1 +0,0 @@ -../sglib-arraysort/sglib.h \ No newline at end of file diff --git a/src/sglib-arrayquicksort/sglib.h b/src/sglib-arrayquicksort/sglib.h new file mode 100644 index 00000000..84dcaae4 --- /dev/null +++ b/src/sglib-arrayquicksort/sglib.h @@ -0,0 +1,1965 @@ +/* This file is part of the Bristol/Embecosm Embedded Benchmark Suite. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* + + This is SGLIB version 1.0.3 + + (C) by Marian Vittek, Bratislava, http://www.xref-tech.com/sglib, 2003-5 + + License Conditions: You can use a verbatim copy (including this + copyright notice) of sglib freely in any project, commercial or not. + You can also use derivative forms freely under terms of Open Source + Software license or under terms of GNU Public License. If you need + to use a derivative form in a commercial project, or you need sglib + under any other license conditions, contact the author. + + + +*/ + + +#ifndef _SGLIB__h_ +#define _SGLIB__h_ + +/* the assert is used exclusively to write unexpected error messages */ +#define assert(a) + + +/* ---------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- */ +/* - LEVEL - 0 INTERFACE - */ +/* ---------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- */ + + +/* ---------------------------------------------------------------------------- */ +/* ------------------------------ STATIC ARRAYS ------------------------------- */ +/* ---------------------------------------------------------------------------- */ + +/* + + Basic algorithms for sorting arrays. Multiple depending arrays can + be rearranged using user defined 'elem_exchangers' + +*/ + +/* HEAP - SORT (level 0) */ + +#define SGLIB_ARRAY_SINGLE_HEAP_SORT(type, a, max, comparator) {\ + SGLIB_ARRAY_HEAP_SORT(type, a, max, comparator, SGLIB_ARRAY_ELEMENTS_EXCHANGER);\ +} + +#define SGLIB_ARRAY_HEAP_SORT(type, a, max, comparator, elem_exchanger) {\ + int _k_;\ + for(_k_=(max)/2; _k_>=0; _k_--) {\ + SGLIB___ARRAY_HEAP_DOWN(type, a, _k_, max, comparator, elem_exchanger);\ + }\ + for(_k_=(max)-1; _k_>=0; _k_--) {\ + elem_exchanger(type, a, 0, _k_);\ + SGLIB___ARRAY_HEAP_DOWN(type, a, 0, _k_, comparator, elem_exchanger);\ + }\ +} + +#define SGLIB___ARRAY_HEAP_DOWN(type, a, ind, max, comparator, elem_exchanger) {\ + int _m_, _l_, _r_, _i_;\ + _i_ = (ind);\ + _m_ = _i_;\ + do {\ + _i_ = _m_; \ + _l_ = 2*_i_+1;\ + _r_ = _l_+1;\ + if (_l_ < (max)){\ + if (comparator(((a)[_m_]), ((a)[_l_])) < 0) _m_ = _l_;\ + if (_r_ < (max)) {\ + if (comparator(((a)[_m_]), ((a)[_r_])) < 0) _m_ = _r_;\ + }\ + }\ + if (_m_ != _i_) {\ + elem_exchanger(type, a, _i_, _m_);\ + }\ + } while (_m_ != _i_);\ +} + + +/* QUICK - SORT (level 0) */ + +#define SGLIB_ARRAY_SINGLE_QUICK_SORT(type, a, max, comparator) {\ + SGLIB_ARRAY_QUICK_SORT(type, a, max, comparator, SGLIB_ARRAY_ELEMENTS_EXCHANGER);\ +} + +#define SGLIB_ARRAY_QUICK_SORT(type, a, max, comparator, elem_exchanger) {\ + int _i_, _j_, _p_, _stacki_, _start_, _end_;\ + /* can sort up to 2^64 elements */\ + int _startStack_[64]; \ + int _endStack_[64];\ + _startStack_[0] = 0;\ + _endStack_[0] = (max);\ + _stacki_ = 1;\ + while (_stacki_ > 0) {\ + _stacki_ --;\ + _start_ = _startStack_[_stacki_];\ + _end_ = _endStack_[_stacki_];\ + while (_end_ - _start_ > 2) {\ + _p_ = _start_;\ + _i_ = _start_ + 1;\ + _j_ = _end_ - 1;\ + while (_i_<_j_) {\ + for(; _i_<=_j_ && comparator(((a)[_i_]),((a)[_p_]))<=0; _i_++) ;\ + if (_i_ > _j_) {\ + /* all remaining elements lesseq than pivot */\ + elem_exchanger(type, a, _j_, _p_);\ + _i_ = _j_;\ + } else {\ + for(; _i_<=_j_ && comparator(((a)[_j_]),((a)[_p_]))>=0; _j_--) ;\ + if (_i_ > _j_) {\ + /* all remaining elements greater than pivot */\ + elem_exchanger(type, a, _j_, _p_);\ + _i_ = _j_;\ + } else if (_i_ < _j_) {\ + elem_exchanger(type, a, _i_, _j_);\ + if (_i_+2 < _j_) {_i_++; _j_--;}\ + else if (_i_+1 < _j_) _i_++;\ + }\ + }\ + }\ + /* O.K. i==j and pivot is on a[i] == a[j] */\ + /* handle recursive calls without recursion */\ + if (_i_-_start_ > 1 && _end_-_j_ > 1) {\ + /* two recursive calls, use array-stack */\ + if (_i_-_start_ < _end_-_j_-1) {\ + _startStack_[_stacki_] = _j_+1;\ + _endStack_[_stacki_] = _end_;\ + _stacki_ ++;\ + _end_ = _i_;\ + } else {\ + _startStack_[_stacki_] = _start_;\ + _endStack_[_stacki_] = _i_;\ + _stacki_ ++;\ + _start_ = _j_+1;\ + }\ + } else {\ + if (_i_-_start_ > 1) {\ + _end_ = _i_;\ + } else {\ + _start_ = _j_+1;\ + }\ + }\ + }\ + if (_end_ - _start_ == 2) {\ + if (comparator(((a)[_start_]),((a)[_end_-1])) > 0) {\ + elem_exchanger(type, a, _start_, _end_-1);\ + }\ + }\ + }\ +} + +/* BINARY SEARCH (level 0) */ + +#define SGLIB_ARRAY_BINARY_SEARCH(type, a, start_index, end_index, key, comparator, found, result_index) {\ + int _kk_, _cc_, _ii_, _jj_, _ff_;\ + _ii_ = (start_index); \ + _jj_ = (end_index);\ + _ff_ = 0;\ + while (_ii_ <= _jj_ && _ff_==0) {\ + _kk_ = (_jj_+_ii_)/2;\ + _cc_ = comparator(((a)[_kk_]), (key));\ + if (_cc_ == 0) {\ + (result_index) = _kk_; \ + _ff_ = 1;\ + } else if (_cc_ < 0) {\ + _ii_ = _kk_+1;\ + } else {\ + _jj_ = _kk_-1;\ + }\ + }\ + if (_ff_ == 0) {\ + /* not found, but set its resulting place in the array */\ + (result_index) = _jj_+1;\ + }\ + (found) = _ff_;\ +} + +/* -------------------------------- queue (in an array) ------------------ */ +/* queue is a quadruple (a,i,j,dim) such that: */ +/* a is the array storing values */ +/* i is the index of the first used element in the array */ +/* j is the index of the first free element in the array */ +/* dim is the size of the array a */ +/* !!!!!!! This data structure is NOT documented, do not use it !!!!!!!!!! */ + +#define SGLIB_QUEUE_INIT(type, a, i, j) { i = j = 0; } +#define SGLIB_QUEUE_IS_EMPTY(type, a, i, j) ((i)==(j)) +#define SGLIB_QUEUE_IS_FULL(type, a, i, j, dim) ((i)==((j)+1)%(dim)) +#define SGLIB_QUEUE_FIRST_ELEMENT(type, a, i, j) (a[i]) +#define SGLIB_QUEUE_ADD_NEXT(type, a, i, j, dim) {\ + if (SGLIB_QUEUE_IS_FULL(type, a, i, j, dim)) assert(0 && "the queue is full");\ + (j) = ((j)+1) % (dim);\ +} +#define SGLIB_QUEUE_ADD(type, a, elem, i, j, dim) {\ + a[j] = (elem);\ + SGLIB_QUEUE_ADD_NEXT(type, a, i, j, dim);\ +} +#define SGLIB_QUEUE_DELETE_FIRST(type, a, i, j, dim) {\ + if (SGLIB_QUEUE_IS_EMPTY(type, a, i, j)) assert(0 && "the queue is empty");\ + (i) = ((i)+1) % (dim);\ +} +#define SGLIB_QUEUE_DELETE(type, a, i, j, dim) {\ + SGLIB_QUEUE_DELETE_FIRST(type, a, i, j, dim);\ +} + +/* ----------------- priority queue (heap) (in an array) -------------------- */ +/* heap is a triple (a,i,dim) such that: */ +/* a is the array storing values */ +/* i is the index of the first free element in the array */ +/* dim is the size of the array a */ +/* !!!!!!! This data structure is NOT documented, do not use it !!!!!!!!!! */ + +#define SGLIB_HEAP_INIT(type, a, i) { i = 0; } +#define SGLIB_HEAP_IS_EMPTY(type, a, i) ((i)==0) +#define SGLIB_HEAP_IS_FULL(type, a, i, dim) ((i)==(dim)) +#define SGLIB_HEAP_FIRST_ELEMENT(type, a, i) (a[0]) +#define SGLIB_HEAP_ADD_NEXT(type, a, i, dim, comparator, elem_exchanger) {\ + int _i_;\ + if (SGLIB_HEAP_IS_FULL(type, a, i, dim)) assert(0 && "the heap is full");\ + _i_ = (i)++;\ + while (_i_ > 0 && comparator(a[_i_/2], a[_i_]) < 0) {\ + elem_exchanger(type, a, (_i_/2), _i_);\ + _i_ = _i_/2;\ + }\ +} +#define SGLIB_HEAP_ADD(type, a, elem, i, dim, comparator) {\ + if (SGLIB_HEAP_IS_FULL(type, a, i, dim)) assert(0 && "the heap is full");\ + a[i] = (elem);\ + SGLIB_HEAP_ADD_NEXT(type, a, i, dim, comparator, SGLIB_ARRAY_ELEMENTS_EXCHANGER);\ +} +#define SGLIB_HEAP_DELETE_FIRST(type, a, i, dim, comparator, elem_exchanger) {\ + if (SGLIB_HEAP_IS_EMPTY(type, a, i)) assert(0 && "the heap is empty");\ + (i)--;\ + a[0] = a[i];\ + SGLIB___ARRAY_HEAP_DOWN(type, a, 0, i, comparator, elem_exchanger);\ +} +#define SGLIB_HEAP_DELETE(type, a, i, dim, comparator) {\ + SGLIB_HEAP_DELETE_FIRST(type, a, i, dim, comparator, SGLIB_ARRAY_ELEMENTS_EXCHANGER);\ +} + + +/* ----------------- hashed table of pointers (in an array) -------------------- */ + +/* + + This hashed table is storing pointers to objects (not containers). + In this table there is a one-to-one mapping between 'objects' stored + in the table and indexes where they are placed. Each index is + pointing to exactly one 'object' and each 'object' stored in the + table occurs on exactly one index. Once an object is stored in the + table, it can be represented via its index. + + In case of collision while adding an object the index shifted + by SGLIB_HASH_TAB_SHIFT_CONSTANT (constant can be redefined) + + You can NOT delete an element from such hash table. The only + justification (I can see) for this data structure is an exchange + file format, having an index table at the beginning and then + refering objects via indexes. + + !!!!!!! This data structure is NOT documented, do not use it !!!!!!!!!! + +*/ + +#define SGLIB_HASH_TAB_INIT(type, table, dim) {\ + int _i_;\ + for(_i_ = 0; _i_ < (dim); _i_++) (table)[_i_] = NULL;\ +} + +#define SGLIB_HASH_TAB_ADD_IF_NOT_MEMBER(type, table, dim, elem, hash_function, comparator, member){\ + unsigned _pos_;\ + type *_elem_;\ + SGLIB_HASH_TAB_FIND_MEMBER(type, table, dim, elem, _pos_, _elem_);\ + (member) = (table)[_pos_];\ + if (_elem_ == NULL) {\ + if ((table)[_pos_] != NULL) assert(0 && "the hash table is full");\ + (table)[_pos_] = (elem);\ + }\ +} + +#define SGLIB_HASH_TAB_FIND_MEMBER(type, table, dim, elem, hash_function, comparator, resultIndex, resultMember) {\ + unsigned _i_;\ + int _count_;\ + type *_e_;\ + _count = 0;\ + _i_ = hash_function(elem);\ + _i_ %= (dim);\ + while ((_e_=(table)[_i_])!=NULL && comparator(_e_, (elem))!=0 && _count_<(dim)) {\ + _count_ ++;\ + _i_ = (_i_ + SGLIB_HASH_TAB_SHIFT_CONSTANT) % (dim);\ + }\ + (resultIndex) = _i_;\ + if (_count_ < (dim)) (resultMember) = _e_;\ + else (resultMember) = NULL;\ +} + +#define SGLIB_HASH_TAB_IS_MEMBER(type, table, dim, elem, hash_function, resultIndex) {\ + unsigned _i_;\ + int _c_;\ + type *_e_;\ + _count = 0;\ + _i_ = hash_function(elem);\ + _i_ %= (dim);\ + while ((_e_=(table)[_i_])!=NULL && _e_!=(elem) && _c_<(dim)) {\ + _c_ ++;\ + _i_ = (_i_ + SGLIB_HASH_TAB_SHIFT_CONSTANT) % (dim);\ + }\ + if (_e_==(elem)) (resultIndex) = _i_;\ + else (resultIndex) = -1;\ +} + +#define SGLIB_HASH_TAB_MAP_ON_ELEMENTS(type, table, dim, iteratedIndex, iteratedVariable, command) {\ + unsigned iteratedIndex;\ + type *iteratedVariable;\ + for(iteratedIndex=0; iteratedIndex < (dim); iteratedIndex++) {\ + iteratedVariable = (table)[iteratedIndex];\ + if (iteratedVariable != NULL) {command;}\ + }\ +} + + +/* ---------------------------------------------------------------------------- */ +/* ------------------------- DYNAMIC DATA STRUCTURES -------------------------- */ +/* ---------------------------------------------------------------------------- */ + +/* ------------------------------------ lists (level 0) --------------------- */ + +#define SGLIB_LIST_ADD(type, list, elem, next) {\ + (elem)->next = (list);\ + (list) = (elem);\ +} + +#define SGLIB_LIST_CONCAT(type, first, second, next) {\ + if ((first)==NULL) {\ + (first) = (second);\ + } else {\ + type *_p_;\ + for(_p_ = (first); _p_->next!=NULL; _p_=_p_->next) ;\ + _p_->next = (second);\ + }\ +} + +#define SGLIB_LIST_DELETE(type, list, elem, next) {\ + type **_p_;\ + for(_p_ = &(list); *_p_!=NULL && *_p_!=(elem); _p_= &(*_p_)->next) ;\ + assert(*_p_!=NULL && "element is not member of the container, use DELETE_IF_MEMBER instead"!=NULL);\ + *_p_ = (*_p_)->next;\ +} + +#define SGLIB_LIST_ADD_IF_NOT_MEMBER(type, list, elem, comparator, next, member) {\ + type *_p_;\ + for(_p_ = (list); _p_!=NULL && comparator(_p_, (elem)) != 0; _p_= _p_->next) ;\ + (member) = _p_;\ + if (_p_ == NULL) {\ + SGLIB_LIST_ADD(type, list, elem, next);\ + }\ +} + +#define SGLIB_LIST_DELETE_IF_MEMBER(type, list, elem, comparator, next, member) {\ + type **_p_;\ + for(_p_ = &(list); *_p_!=NULL && comparator((*_p_), (elem)) != 0; _p_= &(*_p_)->next) ;\ + (member) = *_p_;\ + if (*_p_ != NULL) {\ + *_p_ = (*_p_)->next;\ + }\ +} + +#define SGLIB_LIST_IS_MEMBER(type, list, elem, next, result) {\ + type *_p_;\ + for(_p_ = (list); _p_!=NULL && _p_ != (elem); _p_= _p_->next) ;\ + (result) = (_p_!=NULL);\ +} + +#define SGLIB_LIST_FIND_MEMBER(type, list, elem, comparator, next, member) {\ + type *_p_;\ + for(_p_ = (list); _p_!=NULL && comparator(_p_, (elem)) != 0; _p_= _p_->next) ;\ + (member) = _p_;\ +} + +#define SGLIB_LIST_MAP_ON_ELEMENTS(type, list, iteratedVariable, next, command) {\ + type *_ne_;\ + type *iteratedVariable;\ + (iteratedVariable) = (list); \ + while ((iteratedVariable)!=NULL) {\ + _ne_ = (iteratedVariable)->next;\ + {command;};\ + (iteratedVariable) = _ne_;\ + }\ +} + +#define SGLIB_LIST_LEN(type, list, next, result) {\ + type *_ce_;\ + (result) = 0;\ + SGLIB_LIST_MAP_ON_ELEMENTS(type, list, _ce_, next, (result)++);\ +} + +#define SGLIB_LIST_REVERSE(type, list, next) {\ + type *_list_,*_tmp_,*_res_;\ + _list_ = (list);\ + _res_ = NULL;\ + while (_list_!=NULL) {\ + _tmp_ = _list_->next; _list_->next = _res_;\ + _res_ = _list_; _list_ = _tmp_;\ + }\ + (list) = _res_;\ +} + +#define SGLIB_LIST_SORT(type, list, comparator, next) {\ + /* a non-recursive merge sort on lists */\ + type *_r_;\ + type *_a_, *_b_, *_todo_, *_t_, **_restail_;\ + int _i_, _n_, _contFlag_;\ + _r_ = (list);\ + _contFlag_ = 1;\ + for(_n_ = 1; _contFlag_; _n_ = _n_+_n_) {\ + _todo_ = _r_; _r_ = NULL; _restail_ = &_r_; _contFlag_ =0;\ + while (_todo_!=NULL) {\ + _a_ = _todo_;\ + for(_i_ = 1, _t_ = _a_; _i_ < _n_ && _t_!=NULL; _i_++, _t_ = _t_->next) ;\ + if (_t_ ==NULL) {\ + *_restail_ = _a_;\ + break;\ + }\ + _b_ = _t_->next; _t_->next=NULL;\ + for(_i_ =1, _t_ = _b_; _i_<_n_ && _t_!=NULL; _i_++, _t_ = _t_->next) ;\ + if (_t_ ==NULL) {\ + _todo_ =NULL;\ + } else {\ + _todo_ = _t_->next; _t_->next=NULL;\ + }\ + /* merge */\ + while (_a_!=NULL && _b_!=NULL) {\ + if (comparator(_a_, _b_) < 0) {\ + *_restail_ = _a_; _restail_ = &(_a_->next); _a_ = _a_->next;\ + } else {\ + *_restail_ = _b_; _restail_ = &(_b_->next); _b_ = _b_->next;\ + }\ + }\ + if (_a_!=NULL) *_restail_ = _a_;\ + else *_restail_ = _b_;\ + while (*_restail_!=NULL) _restail_ = &((*_restail_)->next);\ + _contFlag_ =1;\ + }\ + }\ + (list) = _r_;\ +} + +/* --------------------------------- sorted list (level 0) --------------------- */ +/* + All operations suppose that the list is sorted and they preserve + this property. +*/ + + +#define SGLIB_SORTED_LIST_ADD(type, list, elem, comparator, next) {\ + type **_e_;\ + int _cmpres_;\ + SGLIB_SORTED_LIST_FIND_MEMBER_OR_PLACE(type, list, elem, comparator, next, _cmpres_, _e_);\ + (elem)->next = *_e_;\ + *_e_ = (elem);\ +} + +#define SGLIB_SORTED_LIST_ADD_IF_NOT_MEMBER(type, list, elem, comparator, next, member) {\ + type **_e_;\ + int _cmp_res_;\ + SGLIB_SORTED_LIST_FIND_MEMBER_OR_PLACE(type, list, elem, comparator, next, _cmp_res_, _e_);\ + if (_cmp_res_ != 0) {\ + (elem)->next = *_e_;\ + *_e_ = (elem);\ + (member) = NULL;\ + } else {\ + (member) = *_e_;\ + }\ +} + +#define SGLIB_SORTED_LIST_DELETE(type, list, elem, next) {\ + SGLIB_LIST_DELETE(type, list, elem, next);\ +} + +#define SGLIB_SORTED_LIST_DELETE_IF_MEMBER(type, list, elem, comparator, next, member) {\ + type **_e_;\ + int _cmp_res_;\ + SGLIB_SORTED_LIST_FIND_MEMBER_OR_PLACE(type, list, elem, comparator, next, _cmp_res_, _e_);\ + if (_cmp_res_ == 0) {\ + (member) = *_e_;\ + *_e_ = (*_e_)->next;\ + } else {\ + (member) = NULL;\ + }\ +} + +#define SGLIB_SORTED_LIST_FIND_MEMBER(type, list, elem, comparator, next, member) {\ + type *_p_;\ + int _cmpres_ = 1;\ + for(_p_ = (list); _p_!=NULL && (_cmpres_=comparator(_p_, (elem))) < 0; _p_=_p_->next) ;\ + if (_cmpres_ != 0) (member) = NULL;\ + else (member) = _p_;\ +} + +#define SGLIB_SORTED_LIST_IS_MEMBER(type, list, elem, comparator, next, result) {\ + type *_p_;\ + for(_p_ = (list); _p_!=NULL && comparator(_p_, (elem)) < 0; _p_=_p_->next) ;\ + while (_p_ != NULL && _p_ != (elem) && comparator(_p_, (elem)) == 0) _p_=_p_->next;\ + (result) = (_p_ == (elem));\ +} + +#define SGLIB_SORTED_LIST_FIND_MEMBER_OR_PLACE(type, list, elem, comparator, next, comparator_result, member_ptr) {\ + (comparator_result) = -1;\ + for((member_ptr) = &(list); \ + *(member_ptr)!=NULL && ((comparator_result)=comparator((*member_ptr), (elem))) < 0; \ + (member_ptr) = &(*(member_ptr))->next) ;\ +} + +#define SGLIB_SORTED_LIST_LEN(type, list, next, result) {\ + SGLIB_LIST_LEN(type, list, next, result);\ +} + +#define SGLIB_SORTED_LIST_MAP_ON_ELEMENTS(type, list, iteratedVariable, next, command) {\ + SGLIB_LIST_MAP_ON_ELEMENTS(type, list, iteratedVariable, next, command);\ +} + + +/* ------------------------------- double linked list (level 0) ------------------------- */ +/* + Lists with back pointer to previous element. Those lists implements deletion + of an element in a constant time. +*/ + +#define SGLIB___DL_LIST_CREATE_SINGLETON(type, list, elem, previous, next) {\ + (list) = (elem);\ + (list)->next = (list)->previous = NULL;\ +} + +#define SGLIB_DL_LIST_ADD_AFTER(type, place, elem, previous, next) {\ + if ((place) == NULL) {\ + SGLIB___DL_LIST_CREATE_SINGLETON(type, place, elem, previous, next);\ + } else {\ + (elem)->next = (place)->next;\ + (elem)->previous = (place);\ + (place)->next = (elem);\ + if ((elem)->next != NULL) (elem)->next->previous = (elem);\ + }\ +} + +#define SGLIB_DL_LIST_ADD_BEFORE(type, place, elem, previous, next) {\ + if ((place) == NULL) {\ + SGLIB___DL_LIST_CREATE_SINGLETON(type, place, elem, previous, next);\ + } else {\ + (elem)->next = (place);\ + (elem)->previous = (place)->previous;\ + (place)->previous = (elem);\ + if ((elem)->previous != NULL) (elem)->previous->next = (elem);\ + }\ +} + +#define SGLIB_DL_LIST_ADD(type, list, elem, previous, next) {\ + SGLIB_DL_LIST_ADD_BEFORE(type, list, elem, previous, next)\ +} + +#define SGLIB___DL_LIST_GENERIC_ADD_IF_NOT_MEMBER(type, list, elem, comparator, previous, next, member, the_add_operation) {\ + type *_dlp_;\ + for(_dlp_ = (list); _dlp_!=NULL && comparator(_dlp_, (elem)) != 0; _dlp_= _dlp_->previous) ;\ + if (_dlp_ == NULL && (list) != NULL) {\ + for(_dlp_ = (list)->next; _dlp_!=NULL && comparator(_dlp_, (elem)) != 0; _dlp_= _dlp_->next) ;\ + }\ + (member) = _dlp_;\ + if (_dlp_ == NULL) {\ + the_add_operation(type, list, elem, previous, next);\ + }\ +} + +#define SGLIB_DL_LIST_ADD_BEFORE_IF_NOT_MEMBER(type, list, elem, comparator, previous, next, member) {\ + SGLIB___DL_LIST_GENERIC_ADD_IF_NOT_MEMBER(type, list, elem, comparator, previous, next, member, SGLIB_DL_LIST_ADD_BEFORE);\ +} + +#define SGLIB_DL_LIST_ADD_AFTER_IF_NOT_MEMBER(type, list, elem, comparator, previous, next, member) {\ + SGLIB___DL_LIST_GENERIC_ADD_IF_NOT_MEMBER(type, list, elem, comparator, previous, next, member, SGLIB_DL_LIST_ADD_AFTER);\ +} + +#define SGLIB_DL_LIST_ADD_IF_NOT_MEMBER(type, list, elem, comparator, previous, next, member) {\ + SGLIB___DL_LIST_GENERIC_ADD_IF_NOT_MEMBER(type, list, elem, comparator, previous, next, member, SGLIB_DL_LIST_ADD);\ +} + +#define SGLIB_DL_LIST_CONCAT(type, first, second, previous, next) {\ + if ((first)==NULL) {\ + (first) = (second);\ + } else if ((second)!=NULL) {\ + type *_dlp_;\ + for(_dlp_ = (first); _dlp_->next!=NULL; _dlp_=_dlp_->next) ;\ + SGLIB_DL_LIST_ADD_AFTER(type, _dlp_, second, previous, next);\ + }\ +} + +#define SGLIB_DL_LIST_DELETE(type, list, elem, previous, next) {\ + type *_l_;\ + _l_ = (list);\ + if (_l_ == (elem)) {\ + if ((elem)->previous != NULL) _l_ = (elem)->previous;\ + else _l_ = (elem)->next;\ + }\ + if ((elem)->next != NULL) (elem)->next->previous = (elem)->previous;\ + if ((elem)->previous != NULL) (elem)->previous->next = (elem)->next;\ + (list) = _l_;\ +} + +#define SGLIB_DL_LIST_DELETE_IF_MEMBER(type, list, elem, comparator, previous, next, member) {\ + type *_dlp_;\ + for(_dlp_ = (list); _dlp_!=NULL && comparator(_dlp_, (elem)) != 0; _dlp_= _dlp_->previous) ;\ + if (_dlp_ == NULL && (list) != NULL) {\ + for(_dlp_ = (list)->next; _dlp_!=NULL && comparator(_dlp_, (elem)) != 0; _dlp_= _dlp_->next) ;\ + }\ + (member) = _dlp_;\ + if (_dlp_ != NULL) {\ + SGLIB_DL_LIST_DELETE(type, list, _dlp_, previous, next);\ + }\ +} + +#define SGLIB_DL_LIST_IS_MEMBER(type, list, elem, previous, next, result) {\ + type *_dlp_;\ + SGLIB_LIST_IS_MEMBER(type, list, elem, previous, result);\ + if (result == 0 && (list) != NULL) {\ + _dlp_ = (list)->next;\ + SGLIB_LIST_IS_MEMBER(type, _dlp_, elem, next, result);\ + }\ +} + +#define SGLIB_DL_LIST_FIND_MEMBER(type, list, elem, comparator, previous, next, member) {\ + type *_dlp_;\ + SGLIB_LIST_FIND_MEMBER(type, list, elem, comparator, previous, member);\ + if ((member) == NULL && (list) != NULL) {\ + _dlp_ = (list)->next;\ + SGLIB_LIST_FIND_MEMBER(type, _dlp_, elem, comparator, next, member);\ + }\ +} + +#define SGLIB_DL_LIST_MAP_ON_ELEMENTS(type, list, iteratedVariable, previous, next, command) {\ + type *_dl_;\ + type *iteratedVariable;\ + if ((list)!=NULL) {\ + _dl_ = (list)->next;\ + SGLIB_LIST_MAP_ON_ELEMENTS(type, list, iteratedVariable, previous, command);\ + SGLIB_LIST_MAP_ON_ELEMENTS(type, _dl_, iteratedVariable, next, command);\ + }\ +} + +#define SGLIB_DL_LIST_SORT(type, list, comparator, previous, next) {\ + type *_dll_, *_dlp_, *_dlt_;\ + _dll_ = (list);\ + if (_dll_ != NULL) {\ + for(; _dll_->previous!=NULL; _dll_=_dll_->previous) ;\ + SGLIB_LIST_SORT(type, _dll_, comparator, next);\ + SGLIB___DL_LIST_CREATE_FROM_LIST(type, _dll_, previous, next);\ + (list) = _dll_;\ + }\ +} + +#define SGLIB_DL_LIST_GET_FIRST(type, list, previous, next, result) {\ + type *_dll_;\ + _dll_ = (list);\ + if (_dll_ != NULL) {\ + for(; _dll_->previous!=NULL; _dll_=_dll_->previous) ;\ + }\ + (result) = _dll_;\ +} + +#define SGLIB_DL_LIST_GET_LAST(type, list, previous, next, result) {\ + type *_dll_;\ + _dll_ = (list);\ + if (_dll_ != NULL) {\ + for(; _dll_->next!=NULL; _dll_=_dll_->next) ;\ + }\ + (result) = _dll_;\ +} + +#define SGLIB_DL_LIST_LEN(type, list, previous, next, result) {\ + type *_dl_;\ + int _r1_, _r2_;\ + if ((list)==NULL) {\ + (result) = 0;\ + } else {\ + SGLIB_LIST_LEN(type, list, previous, _r1_);\ + _dl_ = (list)->next;\ + SGLIB_LIST_LEN(type, _dl_, next, _r2_);\ + (result) = _r1_ + _r2_;\ + }\ +} + +#define SGLIB_DL_LIST_REVERSE(type, list, previous, next) {\ + type *_list_,*_nlist_,*_dlp_,*_dln_;\ + _list_ = (list);\ + if (_list_!=NULL) {\ + _nlist_ = _list_->next;\ + while (_list_!=NULL) {\ + _dln_ = _list_->next; \ + _dlp_ = _list_->previous; \ + _list_->next = _dlp_;\ + _list_->previous = _dln_;\ + _list_ = _dlp_;\ + }\ + while (_nlist_!=NULL) {\ + _dln_ = _nlist_->next; \ + _dlp_ = _nlist_->previous; \ + _nlist_->next = _dlp_;\ + _nlist_->previous = _dln_;\ + _nlist_ = _dln_;\ + }\ + }\ +} + +#define SGLIB___DL_LIST_CREATE_FROM_LIST(type, list, previous, next) {\ + type *_dlp_, *_dlt_;\ + _dlp_ = NULL;\ + for(_dlt_ = (list); _dlt_!=NULL; _dlt_ = _dlt_->next) {\ + _dlt_->previous = _dlp_;\ + _dlp_ = _dlt_;\ + }\ +} + + +/* ------------------------------- binary tree traversal (level 0) -------------------- */ + + +#define SGLIB___BIN_TREE_MAP_ON_ELEMENTS(type, tree, iteratedVariable, order, left, right, command) {\ + /* this is non-recursive implementation of tree traversal */\ + /* it maintains the path to the current node in the array '_path_' */\ + /* the _path_[0] contains the root of the tree; */\ + /* the _path_[_pathi_] contains the _current_element_ */\ + /* the macro does not use the _current_element_ after execution of command */\ + /* command can destroy it, it can free the element for example */\ + type *_path_[SGLIB_MAX_TREE_DEEP];\ + type *_right_[SGLIB_MAX_TREE_DEEP];\ + char _pass_[SGLIB_MAX_TREE_DEEP];\ + type *_cn_;\ + int _pathi_;\ + type *iteratedVariable;\ + _cn_ = (tree);\ + _pathi_ = 0;\ + while (_cn_!=NULL) {\ + /* push down to leftmost innermost element */\ + while(_cn_!=NULL) {\ + _path_[_pathi_] = _cn_;\ + _right_[_pathi_] = _cn_->right;\ + _pass_[_pathi_] = 0;\ + _cn_ = _cn_->left;\ + if (order == 0) {\ + iteratedVariable = _path_[_pathi_];\ + {command;}\ + }\ + _pathi_ ++;\ + if (_pathi_ >= SGLIB_MAX_TREE_DEEP) assert(0 && "the binary_tree is too deep");\ + }\ + do {\ + _pathi_ --;\ + if ((order==1 && _pass_[_pathi_] == 0)\ + || (order == 2 && (_pass_[_pathi_] == 1 || _right_[_pathi_]==NULL))) {\ + iteratedVariable = _path_[_pathi_];\ + {command;}\ + }\ + _pass_[_pathi_] ++;\ + } while (_pathi_>0 && _right_[_pathi_]==NULL) ;\ + _cn_ = _right_[_pathi_];\ + _right_[_pathi_] = NULL;\ + _pathi_ ++;\ + }\ +} + +#define SGLIB_BIN_TREE_MAP_ON_ELEMENTS(type, tree, _current_element_, left, right, command) {\ + SGLIB___BIN_TREE_MAP_ON_ELEMENTS(type, tree, _current_element_, 1, left, right, command);\ +} + +#define SGLIB_BIN_TREE_MAP_ON_ELEMENTS_PREORDER(type, tree, _current_element_, left, right, command) {\ + SGLIB___BIN_TREE_MAP_ON_ELEMENTS(type, tree, _current_element_, 0, left, right, command);\ +} + +#define SGLIB_BIN_TREE_MAP_ON_ELEMENTS_POSTORDER(type, tree, _current_element_, left, right, command) {\ + SGLIB___BIN_TREE_MAP_ON_ELEMENTS(type, tree, _current_element_, 2, left, right, command);\ +} + +#define SGLIB___BIN_TREE_FIND_MEMBER(type, tree, elem, left, right, comparator, res) {\ + type *_s_;\ + int _c_;\ + _s_ = (tree);\ + while (_s_!=NULL) {\ + _c_ = comparator((elem), _s_);\ + if (_c_ < 0) _s_ = _s_->left;\ + else if (_c_ > 0) _s_ = _s_->right;\ + else break;\ + }\ + (res) = _s_;\ +} + +/* ---------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- */ +/* - LEVEL - 1 INTERFACE - */ +/* ---------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- */ + + + +/* ---------------------------------------------------------------------------- */ +/* ------------------------------ STATIC ARRAYS ------------------------------- */ +/* ---------------------------------------------------------------------------- */ + +/* ----------------------------- array sorting (level 1) ---------------------- */ + +#define SGLIB_DEFINE_ARRAY_SORTING_PROTOTYPES(type, comparator) \ + extern void sglib_##type##_array_quick_sort(type *a, int max);\ + extern void sglib_##type##_array_heap_sort(type *a, int max);\ + + +#define SGLIB_DEFINE_ARRAY_SORTING_FUNCTIONS(type, comparator) \ + void sglib_##type##_array_quick_sort(type *a, int max) {\ + SGLIB_ARRAY_SINGLE_QUICK_SORT(type, a, max, comparator);\ + }\ + void sglib_##type##_array_heap_sort(type *a, int max) {\ + SGLIB_ARRAY_SINGLE_HEAP_SORT(type, a, max, comparator);\ + }\ + + +/* ----------------------------- array queue (level 1) ------------------- */ +/* sglib's queue is stored in a fixed sized array */ +/* queue_type MUST be a structure containing fields: */ +/* afield is the array storing elem_type */ +/* ifield is the index of the first element in the queue */ +/* jfield is the index of the first free element after the queue */ +/* dim is the size of the array afield */ +/* !!!!!!! This data structure is NOT documented, do not use it !!!!!!!!!! */ + + +#define SGLIB_DEFINE_QUEUE_PROTOTYPES(queue_type, elem_type, afield, ifield, jfield, dim) \ + extern void sglib_##queue_type##_init(queue_type *q); \ + extern int sglib_##queue_type##_is_empty(queue_type *q); \ + extern int sglib_##queue_type##_is_full(queue_type *q); \ + extern elem_type sglib_##queue_type##_first_element(queue_type *q); \ + extern elem_type *sglib_##queue_type##_first_element_ptr(queue_type *q); \ + extern void sglib_##queue_type##_add_next(queue_type *q); \ + extern void sglib_##queue_type##_add(queue_type *q, elem_type elem); \ + extern void sglib_##queue_type##_delete_first(queue_type *q); \ + extern void sglib_##queue_type##_delete(queue_type *q); + + +#define SGLIB_DEFINE_QUEUE_FUNCTIONS(queue_type, elem_type, afield, ifield, jfield, dim) \ + void sglib_##queue_type##_init(queue_type *q) {\ + SGLIB_QUEUE_INIT(elem_type, q->afield, q->ifield, q->jfield);\ + }\ + int sglib_##queue_type##_is_empty(queue_type *q) {\ + return(SGLIB_QUEUE_IS_EMPTY(elem_type, q->afield, q->ifield, q->jfield));\ + }\ + int sglib_##queue_type##_is_full(queue_type *q) {\ + return(SGLIB_QUEUE_IS_FULL(elem_type, q->afield, q->ifield, q->jfield));\ + }\ + elem_type sglib_##queue_type##_first_element(queue_type *q) {\ + return(SGLIB_QUEUE_FIRST_ELEMENT(elem_type, q->afield, q->ifield, q->jfield));\ + }\ + elem_type *sglib_##queue_type##_first_element_ptr(queue_type *q) {\ + return(& SGLIB_QUEUE_FIRST_ELEMENT(elem_type, q->afield, q->ifield, q->jfield));\ + }\ + void sglib_##queue_type##_add_next(queue_type *q) {\ + SGLIB_QUEUE_ADD_NEXT(elem_type, q->afield, q->ifield, q->jfield, dim);\ + }\ + void sglib_##queue_type##_add(queue_type *q, elem_type elem) {\ + SGLIB_QUEUE_ADD(elem_type, q->afield, elem, q->ifield, q->jfield, dim);\ + }\ + void sglib_##queue_type##_delete_first(queue_type *q) {\ + SGLIB_QUEUE_DELETE_FIRST(elem_type, q->afield, q->ifield, q->jfield, dim);\ + }\ + void sglib_##queue_type##_delete(queue_type *q) {\ + SGLIB_QUEUE_DELETE_FIRST(elem_type, q->afield, q->ifield, q->jfield, dim);\ + } + + +/* ------------------------ array heap (level 1) ------------------------- */ +/* sglib's heap is a priority queue implemented in a fixed sized array */ +/* heap_type MUST be a structure containing fields: */ +/* afield is the array of size dim storing elem_type */ +/* ifield is the index of the first free element after the queue */ +/* !!!!!!! This data structure is NOT documented, do not use it !!!!!!!!!! */ + + +#define SGLIB_DEFINE_HEAP_PROTOTYPES(heap_type, elem_type, afield, ifield, dim, comparator, elem_exchanger) \ + extern void sglib_##heap_type##_init(heap_type *q); \ + extern int sglib_##heap_type##_is_empty(heap_type *q); \ + extern int sglib_##heap_type##_is_full(heap_type *q); \ + extern elem_type sglib_##heap_type##_first_element(heap_type *q); \ + extern elem_type *sglib_##heap_type##_first_element_ptr(heap_type *q); \ + extern void sglib_##heap_type##_add_next(heap_type *q); \ + extern void sglib_##heap_type##_add(heap_type *q, elem_type elem); \ + extern void sglib_##heap_type##_delete_first(heap_type *q); \ + extern void sglib_##heap_type##_delete(heap_type *q) + +#define SGLIB_DEFINE_HEAP_FUNCTIONS(heap_type, elem_type, afield, ifield, dim, comparator, elem_exchanger) \ + void sglib_##heap_type##_init(heap_type *q) {\ + SGLIB_HEAP_INIT(elem_type, q->afield, q->ifield);\ + }\ + int sglib_##heap_type##_is_empty(heap_type *q) {\ + return(SGLIB_HEAP_IS_EMPTY(elem_type, q->afield, q->ifield));\ + }\ + int sglib_##heap_type##_is_full(heap_type *q) {\ + return(SGLIB_HEAP_IS_FULL(elem_type, q->afield, q->ifield));\ + }\ + elem_type sglib_##heap_type##_first_element(heap_type *q) {\ + return(SGLIB_HEAP_FIRST_ELEMENT(elem_type, q->afield, q->ifield));\ + }\ + elem_type *sglib_##heap_type##_first_element_ptr(heap_type *q) {\ + return(& SGLIB_HEAP_FIRST_ELEMENT(elem_type, q->afield, q->ifield));\ + }\ + void sglib_##heap_type##_add_next(heap_type *q) {\ + SGLIB_HEAP_ADD_NEXT(elem_type, q->afield, q->ifield, dim, comparator, elem_exchanger);\ + }\ + void sglib_##heap_type##_add(heap_type *q, elem_type elem) {\ + SGLIB_HEAP_ADD(elem_type, q->afield, elem, q->ifield, dim, comparator, elem_exchanger);\ + }\ + void sglib_##heap_type##_delete_first(heap_type *q) {\ + SGLIB_HEAP_DELETE_FIRST(elem_type, q->afield, q->ifield, dim, comparator, elem_exchanger);\ + }\ + void sglib_##heap_type##_delete(heap_type *q) {\ + SGLIB_HEAP_DELETE_FIRST(elem_type, q->afield, q->ifield, dim, comparator, elem_exchanger);\ + } + + +/* ------------------------ hashed table (level 1) ------------------------- */ +/* + + sglib's hash table is an array storing directly pointers to objects (not containers). + In this table there is a one-to-one mapping between 'objects' stored + in the table and indexes where they are placed. Each index is + pointing to exactly one 'object' and each 'object' stored in the + table occurs on exactly one index. Once an object is stored in the + table, it can be represented via its index. + + type - is the type of elements + dim - is the size of the hash array + hash_function - is a hashing function mapping type* to unsigned + comparator - is a comparator on elements + + !!!!!!! This data structure is NOT documented, do not use it !!!!!!!!!! +*/ + +#define SGLIB_DEFINE_HASHED_TABLE_PROTOTYPES(type, dim, hash_function, comparator) \ + struct sglib_hashed_##type##_iterator {\ + int currentIndex;\ + int (*subcomparator)(type *, type *);\ + type *equalto;\ + };\ + extern void sglib_hashed_##type##_init(type *table[dim]);\ + extern int sglib_hashed_##type##_add_if_not_member(type *table[dim], type *elem, type **member);\ + extern int sglib_hashed_##type##_is_member(type *table[dim], type *elem);\ + extern type * sglib_hashed_##type##_find_member(type *table[dim], type *elem);\ + extern type *sglib_hashed_##type##_it_init(struct sglib_hashed_##type##_iterator *it, type *table[dim]); \ + extern type *sglib_hashed_##type##_it_init_on_equal(struct sglib_hashed_##type##_iterator *it, type *table[dim], int (*subcomparator)(type *, type *), type *equalto); \ + extern type *sglib_hashed_##type##_it_current(struct sglib_hashed_##type##_iterator *it); \ + extern type *sglib_hashed_##type##_it_next(struct sglib_hashed_##type##_iterator *it); + +#define SGLIB_DEFINE_HASHED_TABLE_FUNCTIONS(type, dim, hash_function, comparator) \ + struct sglib_hashed_##type##_iterator {\ + int currentIndex;\ + type **table;\ + int (*subcomparator)(type *, type *);\ + type *equalto;\ + };\ + void sglib_hashed_##type##_init(type *table[dim]) {\ + SGLIB_HASH_TAB_INIT(type, table, dim);\ + }\ + int sglib_hashed_##type##_add_if_not_member(type *table[dim], type *elem, type **member) {\ + SGLIB_HASH_TAB_ADD_IF_NOT_MEMBER(type, table, dim, elem, hash_function, comparator, *member);\ + }\ + int sglib_hashed_##type##_is_member(type *table[dim], type *elem) {\ + int ind;\ + SGLIB_HASH_TAB_IS_MEMBER(type, table, dim, elem, hash_function, ind);\ + return(ind != -1);\ + }\ + type * sglib_hashed_##type##_find_member(type *table[dim], type *elem) {\ + type *mmb;\ + int ind;\ + SGLIB_HASH_TAB_FIND_MEMBER(type, table, dim, elem, hash_function, comparator, ind, mmb);\ + return(mmb);\ + }\ + type *sglib_hashed_##type##_it_init_on_equal(struct sglib_hashed_##type##_iterator *it, type *table[dim], int (*subcomparator)(type *, type *), type *equalto) {\ + int i;\ + it->table = table;\ + it->subcomparator = subcomparator;\ + it->equalto = equalto;\ + for(i=0; i<(dim) && table[i]==NULL; i++) ;\ + it->currentIndex = i;\ + if (i<(dim)) return(table[i]);\ + return(NULL);\ + }\ + type *sglib_hashed_##type##_it_init(struct sglib_hashed_##type##_iterator *it, type *table[dim]) {\ + sglib_hashed_##type##_it_init_on_equal(it, table, NULL, NULL);\ + }\ + type *sglib_hashed_##type##_it_current(struct sglib_hashed_##type##_iterator *it) {\ + return(table[it->currentIndex]);\ + }\ + type *sglib_hashed_##type##_it_next(struct sglib_hashed_##type##_iterator *it) {\ + i=it->currentIndex;\ + if (i<(dim)) {\ + for(i++; i<(dim) && table[i]==NULL; i++) ;\ + }\ + it->currentIndex = i;\ + if (i<(dim)) return(table[i]);\ + return(NULL);\ + } + + +/* ------------------- hashed container (only for level 1) -------------------- */ +/* + hashed container is a table of given fixed size containing another + (dynamic) base container in each cell. Once an object should be + inserted into the hashed container, a hash function is used to + determine the cell where the object belongs and the object is + inserted into the base container stored in this cell. Usually the + base container is simply a list or a sorted list, but it can be a + red-black tree as well. + + parameters: + type - the type of the container stored in each cell. + dim - the size of the hashed array + hash_function - the hashing function hashing 'type *' to unsigned. + +*/ + +#define SGLIB_DEFINE_HASHED_CONTAINER_PROTOTYPES(type, dim, hash_function) \ + struct sglib_hashed_##type##_iterator {\ + struct sglib_##type##_iterator containerIt;\ + type **table;\ + int currentIndex;\ + int (*subcomparator)(type *, type *);\ + type *equalto;\ + };\ + extern void sglib_hashed_##type##_init(type *table[dim]);\ + extern void sglib_hashed_##type##_add(type *table[dim], type *elem);\ + extern int sglib_hashed_##type##_add_if_not_member(type *table[dim], type *elem, type **member);\ + extern void sglib_hashed_##type##_delete(type *table[dim], type *elem);\ + extern int sglib_hashed_##type##_delete_if_member(type *table[dim], type *elem, type **memb);\ + extern int sglib_hashed_##type##_is_member(type *table[dim], type *elem);\ + extern type * sglib_hashed_##type##_find_member(type *table[dim], type *elem);\ + extern type *sglib_hashed_##type##_it_init(struct sglib_hashed_##type##_iterator *it, type *table[dim]); \ + extern type *sglib_hashed_##type##_it_init_on_equal(struct sglib_hashed_##type##_iterator *it, type *table[dim], int (*subcomparator)(type *, type *), type *equalto); \ + extern type *sglib_hashed_##type##_it_current(struct sglib_hashed_##type##_iterator *it); \ + extern type *sglib_hashed_##type##_it_next(struct sglib_hashed_##type##_iterator *it); + +#define SGLIB_DEFINE_HASHED_CONTAINER_FUNCTIONS(type, dim, hash_function) \ + /*extern unsigned hash_function(type *elem);*/\ + void sglib_hashed_##type##_init(type *table[dim]) {\ + unsigned i;\ + for(i=0; i<(dim); i++) table[i] = NULL;\ + }\ + void sglib_hashed_##type##_add(type *table[dim], type *elem) {\ + unsigned i;\ + i = ((unsigned)hash_function(elem)) % (dim);\ + sglib_##type##_add(&(table)[i], elem);\ + }\ + int sglib_hashed_##type##_add_if_not_member(type *table[dim], type *elem, type **member) {\ + unsigned i;\ + i = ((unsigned)hash_function(elem)) % (dim);\ + return(sglib_##type##_add_if_not_member(&(table)[i], elem, member));\ + }\ + void sglib_hashed_##type##_delete(type *table[dim], type *elem) {\ + unsigned i;\ + i = ((unsigned)hash_function(elem)) % (dim);\ + sglib_##type##_delete(&(table)[i], elem);\ + }\ + int sglib_hashed_##type##_delete_if_member(type *table[dim], type *elem, type **memb) {\ + unsigned i;\ + i = ((unsigned)hash_function(elem)) % (dim);\ + return(sglib_##type##_delete_if_member(&(table)[i], elem, memb));\ + }\ + int sglib_hashed_##type##_is_member(type *table[dim], type *elem) {\ + unsigned i;\ + i = ((unsigned)hash_function(elem)) % (dim);\ + return(sglib_##type##_is_member((table)[i], elem));\ + }\ + type * sglib_hashed_##type##_find_member(type *table[dim], type *elem) {\ + unsigned i;\ + i = ((unsigned)hash_function(elem)) % (dim);\ + return(sglib_##type##_find_member((table)[i], elem));\ + }\ + type *sglib_hashed_##type##_it_init_on_equal(struct sglib_hashed_##type##_iterator *it, type *table[dim], int (*subcomparator)(type *, type *), type *equalto) {\ + type *e;\ + it->table = table;\ + it->currentIndex = 0;\ + it->subcomparator = subcomparator;\ + it->equalto = equalto;\ + e = sglib_##type##_it_init_on_equal(&it->containerIt, table[it->currentIndex], it->subcomparator, it->equalto);\ + if (e==NULL) e = sglib_hashed_##type##_it_next(it);\ + return(e);\ + }\ + type *sglib_hashed_##type##_it_init(struct sglib_hashed_##type##_iterator *it, type *table[dim]) {\ + return(sglib_hashed_##type##_it_init_on_equal(it, table, NULL, NULL));\ + }\ + type *sglib_hashed_##type##_it_current(struct sglib_hashed_##type##_iterator *it) {\ + return(sglib_##type##_it_current(&it->containerIt));\ + }\ + type *sglib_hashed_##type##_it_next(struct sglib_hashed_##type##_iterator *it) {\ + type *e;\ + e = sglib_##type##_it_next(&it->containerIt);\ + while (e==NULL && (++(it->currentIndex))<(dim)) {\ + e = sglib_##type##_it_init_on_equal(&it->containerIt, it->table[it->currentIndex], it->subcomparator, it->equalto);\ + }\ + return(e);\ + } + + + +/* ---------------------------------------------------------------------------- */ +/* ------------------------- DYNAMIC DATA STRUCTURES -------------------------- */ +/* ---------------------------------------------------------------------------- */ + + + +/* ------------------------------------ list (level 1) -------------------------------- */ + +#define SGLIB_DEFINE_LIST_PROTOTYPES(type, comparator, next) \ + struct sglib_##type##_iterator {\ + type *currentelem;\ + type *nextelem;\ + int (*subcomparator)(type *, type *);\ + type *equalto;\ + };\ + extern void sglib_##type##_add(type **list, type *elem);\ + extern int sglib_##type##_add_if_not_member(type **list, type *elem, type **member);\ + extern void sglib_##type##_concat(type **first, type *second);\ + extern void sglib_##type##_delete(type **list, type *elem);\ + extern int sglib_##type##_delete_if_member(type **list, type *elem, type **member);\ + extern int sglib_##type##_is_member(type *list, type *elem);\ + extern type *sglib_##type##_find_member(type *list, type *elem);\ + extern void sglib_##type##_sort(type **list);\ + extern int sglib_##type##_len(type *list);\ + extern void sglib_##type##_reverse(type **list);\ + extern type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *list); \ + extern type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *list, int (*subcomparator)(type *, type *), type *equalto); \ + extern type *sglib_##type##_it_current(struct sglib_##type##_iterator *it); \ + extern type *sglib_##type##_it_next(struct sglib_##type##_iterator *it); + + +#define SGLIB_DEFINE_LIST_FUNCTIONS(type, comparator, next) \ + int sglib_##type##_is_member(type *list, type *elem) {\ + int result;\ + SGLIB_LIST_IS_MEMBER(type, list, elem, next, result);\ + return(result);\ + }\ + type *sglib_##type##_find_member(type *list, type *elem) {\ + type *result;\ + SGLIB_LIST_FIND_MEMBER(type, list, elem, comparator, next, result);\ + return(result);\ + }\ + int sglib_##type##_add_if_not_member(type **list, type *elem, type **member) {\ + SGLIB_LIST_ADD_IF_NOT_MEMBER(type, *list, elem, comparator, next, *member);\ + return(*member==NULL);\ + }\ + void sglib_##type##_add(type **list, type *elem) {\ + SGLIB_LIST_ADD(type, *list, elem, next);\ + }\ + void sglib_##type##_concat(type **first, type *second) {\ + SGLIB_LIST_CONCAT(type, *first, second, next);\ + }\ + void sglib_##type##_delete(type **list, type *elem) {\ + SGLIB_LIST_DELETE(type, *list, elem, next);\ + }\ + int sglib_##type##_delete_if_member(type **list, type *elem, type **member) {\ + SGLIB_LIST_DELETE_IF_MEMBER(type, *list, elem, comparator, next, *member);\ + return(*member!=NULL);\ + }\ + void sglib_##type##_sort(type **list) { \ + SGLIB_LIST_SORT(type, *list, comparator, next);\ + }\ + int sglib_##type##_len(type *list) {\ + int res;\ + SGLIB_LIST_LEN(type, list, next, res);\ + return(res);\ + }\ + void sglib_##type##_reverse(type **list) {\ + SGLIB_LIST_REVERSE(type, *list, next);\ + }\ + \ + type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *list, int (*subcomparator)(type *, type *), type *equalto) {\ + it->subcomparator = subcomparator;\ + it->equalto = equalto;\ + it->nextelem = list;\ + return(sglib_##type##_it_next(it));\ + }\ + type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *list) {\ + return(sglib_##type##_it_init_on_equal(it, list, NULL, NULL));\ + }\ + type *sglib_##type##_it_current(struct sglib_##type##_iterator *it) {\ + return(it->currentelem);\ + }\ + type *sglib_##type##_it_next(struct sglib_##type##_iterator *it) {\ + type *ce, *eq;\ + int (*scp)(type *, type *);\ + ce = it->nextelem;\ + it->nextelem = NULL;\ + if (it->subcomparator != NULL) {\ + eq = it->equalto; \ + scp = it->subcomparator;\ + while (ce!=NULL && scp(ce, eq)!=0) ce = ce->next;\ + }\ + it->currentelem = ce;\ + if (ce != NULL) it->nextelem = ce->next;\ + return(ce);\ + } + +/* ----------------------------- sorted list (level 1) ----------------------------------- */ + + +#define SGLIB_DEFINE_SORTED_LIST_PROTOTYPES(type, comparator, next) \ + struct sglib_##type##_iterator {\ + type *currentelem;\ + type *nextelem;\ + int (*subcomparator)(type *, type *);\ + type *equalto;\ + };\ + extern void sglib_##type##_add(type **list, type *elem);\ + extern int sglib_##type##_add_if_not_member(type **list, type *elem, type **member);\ + extern void sglib_##type##_delete(type **list, type *elem);\ + extern int sglib_##type##_delete_if_member(type **list, type *elem, type **member);\ + extern int sglib_##type##_is_member(type *list, type *elem);\ + extern type *sglib_##type##_find_member(type *list, type *elem);\ + extern int sglib_##type##_len(type *list);\ + extern void sglib_##type##_sort(type **list);\ + extern type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *list); \ + extern type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *list, int (*subcomparator)(type *, type *), type *equalto); \ + extern type *sglib_##type##_it_current(struct sglib_##type##_iterator *it); \ + extern type *sglib_##type##_it_next(struct sglib_##type##_iterator *it); + + +#define SGLIB_DEFINE_SORTED_LIST_FUNCTIONS(type, comparator, next) \ + int sglib_##type##_is_member(type *list, type *elem) {\ + int result;\ + SGLIB_SORTED_LIST_IS_MEMBER(type, list, elem, comparator, next, result);\ + return(result);\ + }\ + type *sglib_##type##_find_member(type *list, type *elem) {\ + type *result;\ + SGLIB_SORTED_LIST_FIND_MEMBER(type, list, elem, comparator, next, result);\ + return(result);\ + }\ + int sglib_##type##_add_if_not_member(type **list, type *elem, type **member) {\ + SGLIB_SORTED_LIST_ADD_IF_NOT_MEMBER(type, *list, elem, comparator, next, *member);\ + return(*member==NULL);\ + }\ + void sglib_##type##_add(type **list, type *elem) {\ + SGLIB_SORTED_LIST_ADD(type, *list, elem, comparator, next);\ + }\ + void sglib_##type##_delete(type **list, type *elem) {\ + SGLIB_SORTED_LIST_DELETE(type, *list, elem, next);\ + }\ + int sglib_##type##_delete_if_member(type **list, type *elem, type **member) {\ + SGLIB_SORTED_LIST_DELETE_IF_MEMBER(type, *list, elem, comparator, next, *member);\ + return(*member!=NULL);\ + }\ + int sglib_##type##_len(type *list) {\ + int res;\ + SGLIB_SORTED_LIST_LEN(type, list, next, res);\ + return(res);\ + }\ + void sglib_##type##_sort(type **list) { \ + SGLIB_LIST_SORT(type, *list, comparator, next);\ + }\ + \ + type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *list, int (*subcomparator)(type *, type *), type *equalto) {\ + it->subcomparator = subcomparator;\ + it->equalto = equalto;\ + it->nextelem = list;\ + return(sglib_##type##_it_next(it));\ + }\ + type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *list) {\ + return(sglib_##type##_it_init_on_equal(it, list, NULL, NULL));\ + }\ + type *sglib_##type##_it_current(struct sglib_##type##_iterator *it) {\ + return(it->currentelem);\ + }\ + type *sglib_##type##_it_next(struct sglib_##type##_iterator *it) {\ + type *ce, *eq;\ + int (*scp)(type *, type *);\ + int c;\ + ce = it->nextelem;\ + it->nextelem = NULL;\ + if (it->subcomparator != NULL) {\ + eq = it->equalto; \ + scp = it->subcomparator;\ + while (ce!=NULL && (c=scp(ce, eq)) < 0) ce = ce->next;\ + if (ce != NULL && c > 0) ce = NULL;\ + }\ + it->currentelem = ce;\ + if (ce != NULL) it->nextelem = ce->next;\ + return(ce);\ + } + + +/* ----------------------------- double linked list (level 1) ------------------------------ */ + + +#define SGLIB_DEFINE_DL_LIST_PROTOTYPES(type, comparator, previous, next) \ + struct sglib_##type##_iterator {\ + type *currentelem;\ + type *prevelem;\ + type *nextelem;\ + int (*subcomparator)(type *, type *);\ + type *equalto;\ + };\ + extern void sglib_##type##_add(type **list, type *elem);\ + extern void sglib_##type##_add_before(type **list, type *elem);\ + extern void sglib_##type##_add_after(type **list, type *elem);\ + extern int sglib_##type##_add_if_not_member(type **list, type *elem, type **member);\ + extern int sglib_##type##_add_before_if_not_member(type **list, type *elem, type **member);\ + extern int sglib_##type##_add_after_if_not_member(type **list, type *elem, type **member);\ + extern void sglib_##type##_concat(type **first, type *second);\ + extern void sglib_##type##_delete(type **list, type *elem);\ + extern int sglib_##type##_delete_if_member(type **list, type *elem, type **member);\ + extern int sglib_##type##_is_member(type *list, type *elem);\ + extern type *sglib_##type##_find_member(type *list, type *elem);\ + extern type *sglib_##type##_get_first(type *list);\ + extern type *sglib_##type##_get_last(type *list);\ + extern void sglib_##type##_sort(type **list);\ + extern int sglib_##type##_len(type *list);\ + extern void sglib_##type##_reverse(type **list);\ + extern type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *list); \ + extern type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *list, int (*subcomparator)(type *, type *), type *equalto); \ + extern type *sglib_##type##_it_current(struct sglib_##type##_iterator *it); \ + extern type *sglib_##type##_it_next(struct sglib_##type##_iterator *it); + + +#define SGLIB_DEFINE_DL_LIST_FUNCTIONS(type, comparator, previous, next) \ + void sglib_##type##_add(type **list, type *elem) {\ + SGLIB_DL_LIST_ADD(type, *list, elem, previous, next);\ + }\ + void sglib_##type##_add_after(type **list, type *elem) {\ + SGLIB_DL_LIST_ADD_AFTER(type, *list, elem, previous, next);\ + }\ + void sglib_##type##_add_before(type **list, type *elem) {\ + SGLIB_DL_LIST_ADD_BEFORE(type, *list, elem, previous, next);\ + }\ + int sglib_##type##_add_if_not_member(type **list, type *elem, type **member) {\ + SGLIB_DL_LIST_ADD_IF_NOT_MEMBER(type, *list, elem, comparator, previous, next, *member);\ + return(*member==NULL);\ + }\ + int sglib_##type##_add_after_if_not_member(type **list, type *elem, type **member) {\ + SGLIB_DL_LIST_ADD_AFTER_IF_NOT_MEMBER(type, *list, elem, comparator, previous, next, *member);\ + return(*member==NULL);\ + }\ + int sglib_##type##_add_before_if_not_member(type **list, type *elem, type **member) {\ + SGLIB_DL_LIST_ADD_BEFORE_IF_NOT_MEMBER(type, *list, elem, comparator, previous, next, *member);\ + return(*member==NULL);\ + }\ + void sglib_##type##_concat(type **first, type *second) {\ + SGLIB_DL_LIST_CONCAT(type, *first, second, previous, next);\ + }\ + void sglib_##type##_delete(type **list, type *elem) {\ + SGLIB_DL_LIST_DELETE(type, *list, elem, previous, next);\ + }\ + int sglib_##type##_delete_if_member(type **list, type *elem, type **member) {\ + SGLIB_DL_LIST_DELETE_IF_MEMBER(type, *list, elem, comparator, previous, next, *member);\ + return(*member!=NULL);\ + }\ + int sglib_##type##_is_member(type *list, type *elem) {\ + int result;\ + SGLIB_DL_LIST_IS_MEMBER(type, list, elem, previous, next, result);\ + return(result);\ + }\ + type *sglib_##type##_find_member(type *list, type *elem) {\ + type *result;\ + SGLIB_DL_LIST_FIND_MEMBER(type, list, elem, comparator, previous, next, result);\ + return(result);\ + }\ + type *sglib_##type##_get_first(type *list) {\ + type *result;\ + SGLIB_DL_LIST_GET_FIRST(type, list, previous, next, result);\ + return(result);\ + }\ + type *sglib_##type##_get_last(type *list) {\ + type *result;\ + SGLIB_DL_LIST_GET_LAST(type, list, previous, next, result);\ + return(result);\ + }\ + void sglib_##type##_sort(type **list) {\ + SGLIB_DL_LIST_SORT(type, *list, comparator, previous, next);\ + }\ + int sglib_##type##_len(type *list) {\ + int res;\ + SGLIB_DL_LIST_LEN(type, list, previous, next, res);\ + return(res);\ + }\ + void sglib_##type##_reverse(type **list) {\ + SGLIB_DL_LIST_REVERSE(type, *list, previous, next);\ + }\ + \ + type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *list, int (*subcomparator)(type *, type *), type *equalto) {\ + it->subcomparator = subcomparator;\ + it->equalto = equalto;\ + it->prevelem = list;\ + it->nextelem = list;\ + if (list != NULL) it->nextelem = list->next;\ + return(sglib_##type##_it_next(it));\ + }\ + type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *list) {\ + return(sglib_##type##_it_init_on_equal(it, list, NULL, NULL));\ + }\ + type *sglib_##type##_it_current(struct sglib_##type##_iterator *it) {\ + return(it->currentelem);\ + }\ + type *sglib_##type##_it_next(struct sglib_##type##_iterator *it) {\ + type *ce, *eq;\ + int (*scp)(type *, type *);\ + ce = it->prevelem;\ + it->prevelem = NULL;\ + if (it->subcomparator != NULL) {\ + eq = it->equalto; \ + scp = it->subcomparator;\ + while (ce!=NULL && scp(eq, ce)!=0) ce = ce->previous;\ + }\ + if (ce != NULL) {\ + it->prevelem = ce->previous;\ + } else {\ + ce = it->nextelem;\ + it->nextelem = NULL;\ + if (it->subcomparator != NULL) {\ + eq = it->equalto; \ + scp = it->subcomparator;\ + while (ce!=NULL && scp(ce, eq)!=0) ce = ce->next;\ + }\ + if (ce != NULL) it->nextelem = ce->next;\ + }\ + it->currentelem = ce;\ + return(ce);\ + } + + +/* --------------------------------- red-black trees (level 1) -------------------------------- */ + +/* + +This implementation requires pointers to left and right sons (no +parent pointer is needed) and one bit of additional information +storing the color of the node. The implementation follows discrepancy +fixing rules from: +http://www.cis.ohio-state.edu/~gurari/course/cis680/cis680Ch11.html + +*/ + +#define SGLIB___RBTREE_FIX_INSERTION_DISCREPANCY(type, tree, leftt, rightt, bits, RED, BLACK) {\ + type *t, *tl, *a, *b, *c, *ar, *bl, *br, *cl, *cr;\ + t = *tree;\ + tl = t->leftt;\ + if (t->rightt!=NULL && SGLIB___GET_VALUE(t->rightt->bits)==RED) {\ + if (SGLIB___GET_VALUE(tl->bits)==RED) {\ + if ((tl->leftt!=NULL && SGLIB___GET_VALUE(tl->leftt->bits)==RED) \ + || (tl->rightt!=NULL && SGLIB___GET_VALUE(tl->rightt->bits)==RED)) {\ + SGLIB___SET_VALUE(t->leftt->bits,BLACK);\ + SGLIB___SET_VALUE(t->rightt->bits,BLACK);\ + SGLIB___SET_VALUE(t->bits,RED);\ + }\ + }\ + } else {\ + if (SGLIB___GET_VALUE(tl->bits)==RED) {\ + if (tl->leftt!=NULL && SGLIB___GET_VALUE(tl->leftt->bits)==RED) {\ + a = t; b = tl; c = tl->leftt;\ + br = b->rightt;\ + a->leftt = br;\ + b->leftt = c; b->rightt = a;\ + SGLIB___SET_VALUE(a->bits,RED);\ + SGLIB___SET_VALUE(b->bits,BLACK);\ + *tree = b;\ + } else if (tl->rightt!=NULL && SGLIB___GET_VALUE(tl->rightt->bits)==RED) {\ + a = t; b = tl; ar=a->rightt;\ + bl=b->leftt; c=b->rightt;\ + cl=c->leftt; cr=c->rightt;\ + b->rightt = cl;\ + a->leftt = cr;\ + c->leftt = b;\ + c->rightt = a;\ + SGLIB___SET_VALUE(c->bits,BLACK);\ + SGLIB___SET_VALUE(a->bits,RED);\ + *tree = c;\ + }\ + }\ + }\ +} + +#define SGLIB___RBTREE_FIX_DELETION_DISCREPANCY(type, tree, leftt, rightt, bits, RED, BLACK, res) {\ + type *t, *a, *b, *c, *d, *ar, *bl, *br, *cl, *cr, *dl, *dr;\ + t = a = *tree;\ + assert(t!=NULL);\ + ar = a->rightt;\ + b = t->leftt;\ + if (b==NULL) {\ + assert(SGLIB___GET_VALUE(t->bits)==RED);\ + SGLIB___SET_VALUE(t->bits,BLACK);\ + res = 0;\ + } else {\ + bl = b->leftt;\ + br = b->rightt;\ + if (SGLIB___GET_VALUE(b->bits)==RED) {\ + if (br==NULL) {\ + *tree = b;\ + SGLIB___SET_VALUE(b->bits,BLACK);\ + b->rightt = a;\ + a->leftt = br;\ + res = 0;\ + } else {\ + c = br;\ + assert(c!=NULL && SGLIB___GET_VALUE(c->bits)==BLACK);\ + cl = c->leftt;\ + cr = c->rightt;\ + if ((cl==NULL||SGLIB___GET_VALUE(cl->bits)==BLACK) && (cr==NULL||SGLIB___GET_VALUE(cr->bits)==BLACK)) {\ + *tree = b;\ + b->rightt = a;\ + SGLIB___SET_VALUE(b->bits,BLACK);\ + a->leftt = c;\ + SGLIB___SET_VALUE(c->bits,RED);\ + res = 0;\ + } else if (cl!=NULL && SGLIB___GET_VALUE(cl->bits)==RED) {\ + if (cr!=NULL && SGLIB___GET_VALUE(cr->bits)==RED) {\ + d = cr;\ + dl = d->leftt;\ + dr = d->rightt;\ + *tree = d;\ + SGLIB___SET_VALUE(d->bits,BLACK);\ + d->leftt = b;\ + c->rightt = dl;\ + d->rightt = a;\ + a->leftt = dr;\ + res = 0;\ + } else {\ + *tree = c;\ + c->leftt = b;\ + c->rightt = a;\ + b->leftt = bl;\ + b->rightt = cl;\ + a->leftt = cr;\ + SGLIB___SET_VALUE(cl->bits,BLACK);\ + res = 0;\ + }\ + } else if (cr!=NULL && SGLIB___GET_VALUE(cr->bits)==RED) {\ + assert(cl==NULL || SGLIB___GET_VALUE(cl->bits)==BLACK);\ + d = cr;\ + dl = d->leftt;\ + dr = d->rightt;\ + *tree = d;\ + SGLIB___SET_VALUE(d->bits,BLACK);\ + d->leftt = b;\ + c->rightt = dl;\ + d->rightt = a;\ + a->leftt = dr;\ + res = 0;\ + } else {\ + assert(0);\ + res = 0;\ + }\ + }\ + } else {\ + if ((bl==NULL || SGLIB___GET_VALUE(bl->bits)==BLACK) && (br==NULL || SGLIB___GET_VALUE(br->bits)==BLACK)) {\ + res = (SGLIB___GET_VALUE(a->bits)==BLACK);\ + SGLIB___SET_VALUE(a->bits,BLACK);\ + SGLIB___SET_VALUE(b->bits,RED);\ + } else if (bl!=NULL && SGLIB___GET_VALUE(bl->bits)==RED) {\ + if (br==NULL || SGLIB___GET_VALUE(br->bits)==BLACK) {\ + *tree = b;\ + SGLIB___SET_VALUE(b->bits,SGLIB___GET_VALUE(a->bits));\ + SGLIB___SET_VALUE(a->bits,BLACK);\ + b->rightt = a;\ + a->leftt = br;\ + SGLIB___SET_VALUE(bl->bits,BLACK);\ + res = 0;\ + } else {\ + assert(bl!=NULL);\ + assert(br!=NULL);\ + assert(SGLIB___GET_VALUE(bl->bits)==RED);\ + assert(SGLIB___GET_VALUE(br->bits)==RED);\ + c = br;\ + cl = c->leftt;\ + cr = c->rightt;\ + *tree = c;\ + SGLIB___SET_VALUE(c->bits,SGLIB___GET_VALUE(a->bits));\ + SGLIB___SET_VALUE(a->bits,BLACK);\ + c->leftt = b;\ + c->rightt = a;\ + b->rightt = cl;\ + a->leftt = cr;\ + res = 0;\ + }\ + } else {\ + assert(br!=NULL && SGLIB___GET_VALUE(br->bits)==RED);\ + c = br;\ + cl = c->leftt;\ + cr = c->rightt;\ + *tree = c;\ + SGLIB___SET_VALUE(c->bits,SGLIB___GET_VALUE(a->bits));\ + SGLIB___SET_VALUE(a->bits,BLACK);\ + c->leftt = b;\ + c->rightt = a;\ + b->rightt = cl;\ + a->leftt = cr;\ + res = 0;\ + }\ + }\ + }\ +} + + +#define SGLIB_DEFINE_RBTREE_FUNCTIONS_GENERAL(type, left, right, bits, comparator, RED, BLACK) \ +static void sglib___##type##_fix_left_insertion_discrepancy(type **tree) {\ + SGLIB___RBTREE_FIX_INSERTION_DISCREPANCY(type, tree, left, right, bits, RED, BLACK);\ +}\ +\ +static void sglib___##type##_fix_right_insertion_discrepancy(type **tree) {\ + SGLIB___RBTREE_FIX_INSERTION_DISCREPANCY(type, tree, right, left, bits, RED, BLACK);\ +}\ +\ +static int sglib___##type##_fix_left_deletion_discrepancy(type **tree) {\ + int res;\ + SGLIB___RBTREE_FIX_DELETION_DISCREPANCY(type, tree, right, left, bits, RED, BLACK, res);\ + return(res);\ +}\ +\ +static int sglib___##type##_fix_right_deletion_discrepancy(type **tree) {\ + int res;\ + SGLIB___RBTREE_FIX_DELETION_DISCREPANCY(type, tree, left, right, bits, RED, BLACK, res);\ + return(res);\ +}\ +\ +static void sglib___##type##_add_recursive(type **tree, type *elem) {\ + int cmp;\ + type *t;\ + t = *tree;\ + if (t == NULL) {\ + SGLIB___SET_VALUE(elem->bits,RED);\ + *tree =elem;\ + } else {\ + cmp = comparator(elem, t);\ + if (cmp < 0 || (cmp==0 && elemleft, elem);\ + if (SGLIB___GET_VALUE(t->bits)==BLACK) sglib___##type##_fix_left_insertion_discrepancy(tree);\ + } else {\ + sglib___##type##_add_recursive(&t->right, elem);\ + if (SGLIB___GET_VALUE(t->bits)==BLACK) sglib___##type##_fix_right_insertion_discrepancy(tree);\ + }\ + }\ +}\ +\ +static int sglib___##type##_delete_rightmost_leaf(type **tree, type **theLeaf) {\ + type *t;\ + int res, deepDecreased;\ + t = *tree;\ + res = 0;\ + assert(t!=NULL);\ + if (t->right == NULL) {\ + *theLeaf = t;\ + if (t->left!=NULL) {\ + if (SGLIB___GET_VALUE(t->bits)==BLACK && SGLIB___GET_VALUE(t->left->bits)==BLACK) res = 1;\ + SGLIB___SET_VALUE(t->left->bits,BLACK);\ + *tree = t->left;\ + } else {\ + *tree = NULL;\ + res = (SGLIB___GET_VALUE(t->bits)==BLACK);\ + }\ + } else {\ + deepDecreased = sglib___##type##_delete_rightmost_leaf(&t->right, theLeaf);\ + if (deepDecreased) res = sglib___##type##_fix_right_deletion_discrepancy(tree);\ + }\ + return(res);\ +}\ +\ +int sglib___##type##_delete_recursive(type **tree, type *elem) {\ + type *t, *theLeaf;\ + int cmp, res, deepDecreased;\ + t = *tree;\ + res = 0;\ + if (t==NULL) {\ + assert(0 && "The element to delete not found in the tree, use 'delete_if_member'"!=NULL);\ + } else {\ + cmp = comparator(elem, t);\ + if (cmp < 0 || (cmp==0 && elemleft, elem);\ + if (deepDecreased) {\ + res = sglib___##type##_fix_left_deletion_discrepancy(tree);\ + }\ + } else if (cmp > 0 || (cmp==0 && elem>t)) {\ + deepDecreased = sglib___##type##_delete_recursive(&t->right, elem);\ + if (deepDecreased) {\ + res = sglib___##type##_fix_right_deletion_discrepancy(tree);\ + }\ + } else {\ + assert(elem==t && "Deleting an element which is non member of the tree, use 'delete_if_member'"!=NULL);\ + if (t->left == NULL) {\ + if (t->right == NULL) {\ + /* a leaf, delete, it; */\ + *tree = NULL;\ + res = (SGLIB___GET_VALUE(t->bits)==BLACK);\ + } else {\ + if (SGLIB___GET_VALUE(t->bits)==0 && SGLIB___GET_VALUE(t->right->bits)==0) res = 1;\ + SGLIB___SET_VALUE(t->right->bits,BLACK);\ + *tree = t->right;\ + }\ + } else {\ + /* propagate deletion until righmost leaf of left subtree */\ + deepDecreased = sglib___##type##_delete_rightmost_leaf(&t->left, &theLeaf);\ + theLeaf->left = t->left;\ + theLeaf->right = t->right;\ + SGLIB___SET_VALUE(theLeaf->bits,SGLIB___GET_VALUE(t->bits));\ + *tree = theLeaf;\ + if (deepDecreased) res = sglib___##type##_fix_left_deletion_discrepancy(tree);\ + }\ + }\ + }\ + return(res);\ +}\ +\ +void sglib_##type##_add(type **tree, type *elem) {\ + elem->left = elem->right = NULL;\ + sglib___##type##_add_recursive(tree, elem);\ + SGLIB___SET_VALUE((*tree)->bits,BLACK);\ +}\ +\ +void sglib_##type##_delete(type **tree, type *elem) {\ + sglib___##type##_delete_recursive(tree, elem);\ + if (*tree!=NULL) SGLIB___SET_VALUE((*tree)->bits,BLACK);\ +}\ +\ +type *sglib_##type##_find_member(type *t, type *elem) {\ + type *res;\ + SGLIB___BIN_TREE_FIND_MEMBER(type, t, elem, left, right, comparator, res);\ + return(res);\ +}\ +\ +int sglib_##type##_is_member(type *t, type *elem) {\ + int cmp;\ + while (t!=NULL) {\ + cmp = comparator(elem, t);\ + if (cmp < 0 || (cmp==0 && elemleft;\ + } else if (cmp > 0 || (cmp==0 && elem>t)) {\ + t = t->right;\ + } else {\ + assert(t == elem);\ + return(1);\ + }\ + }\ + return(0);\ +}\ +\ +int sglib_##type##_delete_if_member(type **tree, type *elem, type **memb) {\ + if ((*memb=sglib_##type##_find_member(*tree, elem))!=NULL) {\ + sglib_##type##_delete(tree, *memb);\ + return(1);\ + } else {\ + return(0);\ + }\ +}\ +int sglib_##type##_add_if_not_member(type **tree, type *elem, type **memb) {\ + if ((*memb=sglib_##type##_find_member(*tree, elem))==NULL) {\ + sglib_##type##_add(tree, elem);\ + return(1);\ + } else {\ + return(0);\ + }\ +}\ +int sglib_##type##_len(type *t) {\ + int n;\ + type *e;\ + n = 0;\ + SGLIB_BIN_TREE_MAP_ON_ELEMENTS(type, t, e, left, right, n++);\ + return(n);\ +}\ +\ +void sglib__##type##_it_compute_current_elem(struct sglib_##type##_iterator *it) {\ + int i,j,cmp;\ + type *s, *eqt;\ + int (*subcomparator)(type *, type *);\ + eqt = it->equalto;\ + subcomparator = it->subcomparator;\ + it->currentelem = NULL;\ + while(it->pathi > 0 && it->currentelem==NULL) {\ + i = it->pathi-1;\ + if (i >= 0) {\ + if (it->pass[i] >= 2) {\ + /* goto up */\ + it->pathi --;\ + } else {\ + if (it->pass[i] == 0) {\ + /* goto left */\ + s = it->path[i]->left;\ + } else {\ + /* goto right */\ + s = it->path[i]->right;\ + }\ + if (eqt != NULL) {\ + if (subcomparator == NULL) {\ + SGLIB___BIN_TREE_FIND_MEMBER(type, s, eqt, left, right, comparator, s);\ + } else {\ + SGLIB___BIN_TREE_FIND_MEMBER(type, s, eqt, left, right, subcomparator, s);\ + }\ + }\ + if (s != NULL) {\ + j = i+1;\ + it->path[j] = s;\ + it->pass[j] = 0;\ + it->pathi ++;\ + }\ + it->pass[i] ++;\ + }\ + }\ + if (it->pathi>0 && it->order == it->pass[it->pathi-1]) {\ + it->currentelem = it->path[it->pathi-1];\ + }\ + }\ +}\ +type *sglib__##type##_it_init(struct sglib_##type##_iterator *it, type *tree, int order, int (*subcomparator)(type *, type *), type *equalto) {\ + type *t;\ + assert(it!=NULL);\ + it->order = order;\ + it->equalto = equalto;\ + it->subcomparator = subcomparator;\ + if (equalto == NULL) { \ + t = tree;\ + } else {\ + if (subcomparator == NULL) {\ + SGLIB___BIN_TREE_FIND_MEMBER(type, tree, equalto, left, right, comparator, t);\ + } else {\ + SGLIB___BIN_TREE_FIND_MEMBER(type, tree, equalto, left, right, subcomparator, t);\ + }\ + }\ + if (t == NULL) {\ + it->pathi = 0;\ + it->currentelem = NULL;\ + } else {\ + it->pathi = 1;\ + it->pass[0] = 0;\ + it->path[0] = t;\ + if (order == 0) {\ + it->currentelem = t;\ + } else {\ + sglib__##type##_it_compute_current_elem(it);\ + }\ + }\ + return(it->currentelem);\ +}\ +type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *tree) {\ + return(sglib__##type##_it_init(it, tree, 2, NULL, NULL));\ +}\ +type *sglib_##type##_it_init_preorder(struct sglib_##type##_iterator *it, type *tree) {\ + return(sglib__##type##_it_init(it, tree, 0, NULL, NULL));\ +}\ +type *sglib_##type##_it_init_inorder(struct sglib_##type##_iterator *it, type *tree) {\ + return(sglib__##type##_it_init(it, tree, 1, NULL, NULL));\ +}\ +type *sglib_##type##_it_init_postorder(struct sglib_##type##_iterator *it, type *tree) {\ + return(sglib__##type##_it_init(it, tree, 2, NULL, NULL));\ +}\ +type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *tree, int (*subcomparator)(type *, type *), type *equalto) {\ + return(sglib__##type##_it_init(it, tree, 1, subcomparator, equalto));\ +}\ +type *sglib_##type##_it_current(struct sglib_##type##_iterator *it) {\ + return(it->currentelem);\ +}\ +type *sglib_##type##_it_next(struct sglib_##type##_iterator *it) {\ + sglib__##type##_it_compute_current_elem(it);\ + return(it->currentelem);\ +}\ +\ +static void sglib___##type##_consistency_check_recursive(type *t, int *pathdeep, int cdeep) {\ + if (t==NULL) {\ + if (*pathdeep < 0) *pathdeep = cdeep;\ + else assert(*pathdeep == cdeep);\ + } else {\ + if (t->left!=NULL) assert(comparator(t->left, t) <= 0);\ + if (t->right!=NULL) assert(comparator(t, t->right) <= 0);\ + if (SGLIB___GET_VALUE(t->bits) == RED) {\ + assert(t->left == NULL || SGLIB___GET_VALUE(t->left->bits)==BLACK);\ + assert(t->right == NULL || SGLIB___GET_VALUE(t->right->bits)==BLACK);\ + sglib___##type##_consistency_check_recursive(t->left, pathdeep, cdeep);\ + sglib___##type##_consistency_check_recursive(t->right, pathdeep, cdeep);\ + } else {\ + sglib___##type##_consistency_check_recursive(t->left, pathdeep, cdeep+1);\ + sglib___##type##_consistency_check_recursive(t->right, pathdeep, cdeep+1);\ + }\ + }\ +}\ +\ +void sglib___##type##_consistency_check(type *t) {\ + int pathDeep;\ + assert(t==NULL || SGLIB___GET_VALUE(t->bits) == BLACK);\ + pathDeep = -1;\ + sglib___##type##_consistency_check_recursive(t, &pathDeep, 0);\ +} + + +#define SGLIB_DEFINE_RBTREE_PROTOTYPES(type, left, right, colorbit, comparator) \ + struct sglib_##type##_iterator {\ + type *currentelem;\ + char pass[SGLIB_MAX_TREE_DEEP];\ + type *path[SGLIB_MAX_TREE_DEEP];\ + short int pathi;\ + short int order;\ + type *equalto;\ + int (*subcomparator)(type *, type *);\ + };\ + extern void sglib___##type##_consistency_check(type *t); \ + extern void sglib_##type##_add(type **tree, type *elem); \ + extern int sglib_##type##_add_if_not_member(type **tree, type *elem, type **memb); \ + extern void sglib_##type##_delete(type **tree, type *elem); \ + extern int sglib_##type##_delete_if_member(type **tree, type *elem, type **memb); \ + extern int sglib_##type##_is_member(type *t, type *elem); \ + extern type *sglib_##type##_find_member(type *t, type *elem); \ + extern int sglib_##type##_len(type *t); \ + extern type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *tree); \ + extern type *sglib_##type##_it_init_preorder(struct sglib_##type##_iterator *it, type *tree); \ + extern type *sglib_##type##_it_init_inorder(struct sglib_##type##_iterator *it, type *tree); \ + extern type *sglib_##type##_it_init_postorder(struct sglib_##type##_iterator *it, type *tree); \ + extern type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *tree, int (*subcomparator)(type *, type *), type *equalto); \ + extern type *sglib_##type##_it_current(struct sglib_##type##_iterator *it); \ + extern type *sglib_##type##_it_next(struct sglib_##type##_iterator *it); \ + + +#define SGLIB_DEFINE_RBTREE_FUNCTIONS(type, left, right, colorbit, comparator) \ + SGLIB_DEFINE_RBTREE_FUNCTIONS_GENERAL(type, left, right, colorbit, comparator, 1, 0) + + + +/* ---------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- */ +/* - SUPPLEMENTARY DEFINITIONS - */ +/* ---------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- */ + + +#define SGLIB___GET_VALUE(x) (x) +#define SGLIB___SET_VALUE(x, value) {(x) = (value);} +#define SGLIB_ARRAY_ELEMENTS_EXCHANGER(type, a, i, j) {type _sgl_aee_tmp_; _sgl_aee_tmp_=(a)[(i)]; (a)[(i)]=(a)[(j)]; (a)[(j)]= _sgl_aee_tmp_;} + + +#define SGLIB_SAFE_NUMERIC_COMPARATOR(x, y) (((x)>(y)?1:((x)<(y)?-1:0))) +#define SGLIB_SAFE_REVERSE_NUMERIC_COMPARATOR(x, y) (((x)>(y)?-1:((x)<(y)?1:0))) +#define SGLIB_FAST_NUMERIC_COMPARATOR(x, y) ((int)((x) - (y))) +#define SGLIB_FAST_REVERSE_NUMERIC_COMPARATOR(x, y) ((int)((y) - (x))) +#define SGLIB_NUMERIC_COMPARATOR(x, y) SGLIB_SAFE_NUMERIC_COMPARATOR(x, y) +#define SGLIB_REVERSE_NUMERIC_COMPARATOR(x, y) SGLIB_SAFE_REVERSE_NUMERIC_COMPARATOR(x, y) + +#ifndef SGLIB_MAX_TREE_DEEP +#define SGLIB_MAX_TREE_DEEP 128 +#endif + +#ifndef SGLIB_HASH_TAB_SHIFT_CONSTANT +#define SGLIB_HASH_TAB_SHIFT_CONSTANT 16381 /* should be a prime */ +/* #define SGLIB_HASH_TAB_SHIFT_CONSTANT 536870912*/ /* for large tables :) */ +#endif + +#endif /* _SGLIB__h_ */ diff --git a/src/sglib-arraysort/.gitignore b/src/sglib-arraysort/.gitignore deleted file mode 100644 index e573d49f..00000000 --- a/src/sglib-arraysort/.gitignore +++ /dev/null @@ -1 +0,0 @@ -sglib-arraysort diff --git a/src/sglib-arraysort/Makefile.am b/src/sglib-arraysort/Makefile.am deleted file mode 100644 index 0d9609c7..00000000 --- a/src/sglib-arraysort/Makefile.am +++ /dev/null @@ -1,26 +0,0 @@ -# Makefile.am for distributing sglib-arraysort. -# -# Copyright (C) 2013 Embecosm Limited and University of Bristol -# -# This file is part of the Bristol/Embecosm Embedded Benchmark Suite. -# -# Contributor: James Pallister -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# SPDX-License-Identifier: GPL-3.0-or-later - -# Not a benchmark per se, but the base software for other benchmarks. - -EXTRA_DIST = arraysort.c sglib.h diff --git a/src/sglib-arraysort/Makefile.in b/src/sglib-arraysort/Makefile.in deleted file mode 100644 index 7230d080..00000000 --- a/src/sglib-arraysort/Makefile.in +++ /dev/null @@ -1,480 +0,0 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2014 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -# Makefile.am for distributing sglib-arraysort. -# -# Copyright (C) 2013 Embecosm Limited and University of Bristol -# -# This file is part of the Bristol/Embecosm Embedded Benchmark Suite. -# -# Contributor: James Pallister -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# SPDX-License-Identifier: GPL-3.0-or-later - -# Not a benchmark per se, but the base software for other benchmarks. -VPATH = @srcdir@ -am__is_gnu_make = { \ - if test -z '$(MAKELEVEL)'; then \ - false; \ - elif test -n '$(MAKE_HOST)'; then \ - true; \ - elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ - true; \ - else \ - false; \ - fi; \ -} -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -target_triplet = @target@ -subdir = src/sglib-arraysort -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ - $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ - $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ - $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -SOURCES = -DIST_SOURCES = -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -am__DIST_COMMON = $(srcdir)/Makefile.in -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AR = @AR@ -ARCH = @ARCH@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -BENCHMARKS = @BENCHMARKS@ -BOARD = @BOARD@ -CC = @CC@ -CCAS = @CCAS@ -CCASDEPMODE = @CCASDEPMODE@ -CCASFLAGS = @CCASFLAGS@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CHIP = @CHIP@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEJAGNU = @DEJAGNU@ -DEPDIR = @DEPDIR@ -DLLTOOL = @DLLTOOL@ -DSYMUTIL = @DSYMUTIL@ -DUMMY_COMPILERRT = @DUMMY_COMPILERRT@ -DUMMY_CRT0 = @DUMMY_CRT0@ -DUMMY_LIBC = @DUMMY_LIBC@ -DUMMY_LIBGCC = @DUMMY_LIBGCC@ -DUMMY_LIBM = @DUMMY_LIBM@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LIBTOOL_DEPS = @LIBTOOL_DEPS@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MKDIR_P = @MKDIR_P@ -NM = @NM@ -NMEDIT = @NMEDIT@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -RANLIB = @RANLIB@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -VERSION = @VERSION@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target = @target@ -target_alias = @target_alias@ -target_cpu = @target_cpu@ -target_os = @target_os@ -target_vendor = @target_vendor@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -EXTRA_DIST = arraysort.c sglib.h -all: all-am - -.SUFFIXES: -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/sglib-arraysort/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu src/sglib-arraysort/Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs -tags TAGS: - -ctags CTAGS: - -cscope cscopelist: - - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile -installdirs: -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic clean-libtool mostlyclean-am - -distclean: distclean-am - -rm -f Makefile -distclean-am: clean-am distclean-generic - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-generic mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: - -.MAKE: install-am install-strip - -.PHONY: all all-am check check-am clean clean-generic clean-libtool \ - cscopelist-am ctags-am distclean distclean-generic \ - distclean-libtool distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags-am uninstall uninstall-am - -.PRECIOUS: Makefile - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/src/sglib-arraysort/sglib.h b/src/sglib-arraysort/sglib.h deleted file mode 100644 index 84dcaae4..00000000 --- a/src/sglib-arraysort/sglib.h +++ /dev/null @@ -1,1965 +0,0 @@ -/* This file is part of the Bristol/Embecosm Embedded Benchmark Suite. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* - - This is SGLIB version 1.0.3 - - (C) by Marian Vittek, Bratislava, http://www.xref-tech.com/sglib, 2003-5 - - License Conditions: You can use a verbatim copy (including this - copyright notice) of sglib freely in any project, commercial or not. - You can also use derivative forms freely under terms of Open Source - Software license or under terms of GNU Public License. If you need - to use a derivative form in a commercial project, or you need sglib - under any other license conditions, contact the author. - - - -*/ - - -#ifndef _SGLIB__h_ -#define _SGLIB__h_ - -/* the assert is used exclusively to write unexpected error messages */ -#define assert(a) - - -/* ---------------------------------------------------------------------------- */ -/* ---------------------------------------------------------------------------- */ -/* - LEVEL - 0 INTERFACE - */ -/* ---------------------------------------------------------------------------- */ -/* ---------------------------------------------------------------------------- */ - - -/* ---------------------------------------------------------------------------- */ -/* ------------------------------ STATIC ARRAYS ------------------------------- */ -/* ---------------------------------------------------------------------------- */ - -/* - - Basic algorithms for sorting arrays. Multiple depending arrays can - be rearranged using user defined 'elem_exchangers' - -*/ - -/* HEAP - SORT (level 0) */ - -#define SGLIB_ARRAY_SINGLE_HEAP_SORT(type, a, max, comparator) {\ - SGLIB_ARRAY_HEAP_SORT(type, a, max, comparator, SGLIB_ARRAY_ELEMENTS_EXCHANGER);\ -} - -#define SGLIB_ARRAY_HEAP_SORT(type, a, max, comparator, elem_exchanger) {\ - int _k_;\ - for(_k_=(max)/2; _k_>=0; _k_--) {\ - SGLIB___ARRAY_HEAP_DOWN(type, a, _k_, max, comparator, elem_exchanger);\ - }\ - for(_k_=(max)-1; _k_>=0; _k_--) {\ - elem_exchanger(type, a, 0, _k_);\ - SGLIB___ARRAY_HEAP_DOWN(type, a, 0, _k_, comparator, elem_exchanger);\ - }\ -} - -#define SGLIB___ARRAY_HEAP_DOWN(type, a, ind, max, comparator, elem_exchanger) {\ - int _m_, _l_, _r_, _i_;\ - _i_ = (ind);\ - _m_ = _i_;\ - do {\ - _i_ = _m_; \ - _l_ = 2*_i_+1;\ - _r_ = _l_+1;\ - if (_l_ < (max)){\ - if (comparator(((a)[_m_]), ((a)[_l_])) < 0) _m_ = _l_;\ - if (_r_ < (max)) {\ - if (comparator(((a)[_m_]), ((a)[_r_])) < 0) _m_ = _r_;\ - }\ - }\ - if (_m_ != _i_) {\ - elem_exchanger(type, a, _i_, _m_);\ - }\ - } while (_m_ != _i_);\ -} - - -/* QUICK - SORT (level 0) */ - -#define SGLIB_ARRAY_SINGLE_QUICK_SORT(type, a, max, comparator) {\ - SGLIB_ARRAY_QUICK_SORT(type, a, max, comparator, SGLIB_ARRAY_ELEMENTS_EXCHANGER);\ -} - -#define SGLIB_ARRAY_QUICK_SORT(type, a, max, comparator, elem_exchanger) {\ - int _i_, _j_, _p_, _stacki_, _start_, _end_;\ - /* can sort up to 2^64 elements */\ - int _startStack_[64]; \ - int _endStack_[64];\ - _startStack_[0] = 0;\ - _endStack_[0] = (max);\ - _stacki_ = 1;\ - while (_stacki_ > 0) {\ - _stacki_ --;\ - _start_ = _startStack_[_stacki_];\ - _end_ = _endStack_[_stacki_];\ - while (_end_ - _start_ > 2) {\ - _p_ = _start_;\ - _i_ = _start_ + 1;\ - _j_ = _end_ - 1;\ - while (_i_<_j_) {\ - for(; _i_<=_j_ && comparator(((a)[_i_]),((a)[_p_]))<=0; _i_++) ;\ - if (_i_ > _j_) {\ - /* all remaining elements lesseq than pivot */\ - elem_exchanger(type, a, _j_, _p_);\ - _i_ = _j_;\ - } else {\ - for(; _i_<=_j_ && comparator(((a)[_j_]),((a)[_p_]))>=0; _j_--) ;\ - if (_i_ > _j_) {\ - /* all remaining elements greater than pivot */\ - elem_exchanger(type, a, _j_, _p_);\ - _i_ = _j_;\ - } else if (_i_ < _j_) {\ - elem_exchanger(type, a, _i_, _j_);\ - if (_i_+2 < _j_) {_i_++; _j_--;}\ - else if (_i_+1 < _j_) _i_++;\ - }\ - }\ - }\ - /* O.K. i==j and pivot is on a[i] == a[j] */\ - /* handle recursive calls without recursion */\ - if (_i_-_start_ > 1 && _end_-_j_ > 1) {\ - /* two recursive calls, use array-stack */\ - if (_i_-_start_ < _end_-_j_-1) {\ - _startStack_[_stacki_] = _j_+1;\ - _endStack_[_stacki_] = _end_;\ - _stacki_ ++;\ - _end_ = _i_;\ - } else {\ - _startStack_[_stacki_] = _start_;\ - _endStack_[_stacki_] = _i_;\ - _stacki_ ++;\ - _start_ = _j_+1;\ - }\ - } else {\ - if (_i_-_start_ > 1) {\ - _end_ = _i_;\ - } else {\ - _start_ = _j_+1;\ - }\ - }\ - }\ - if (_end_ - _start_ == 2) {\ - if (comparator(((a)[_start_]),((a)[_end_-1])) > 0) {\ - elem_exchanger(type, a, _start_, _end_-1);\ - }\ - }\ - }\ -} - -/* BINARY SEARCH (level 0) */ - -#define SGLIB_ARRAY_BINARY_SEARCH(type, a, start_index, end_index, key, comparator, found, result_index) {\ - int _kk_, _cc_, _ii_, _jj_, _ff_;\ - _ii_ = (start_index); \ - _jj_ = (end_index);\ - _ff_ = 0;\ - while (_ii_ <= _jj_ && _ff_==0) {\ - _kk_ = (_jj_+_ii_)/2;\ - _cc_ = comparator(((a)[_kk_]), (key));\ - if (_cc_ == 0) {\ - (result_index) = _kk_; \ - _ff_ = 1;\ - } else if (_cc_ < 0) {\ - _ii_ = _kk_+1;\ - } else {\ - _jj_ = _kk_-1;\ - }\ - }\ - if (_ff_ == 0) {\ - /* not found, but set its resulting place in the array */\ - (result_index) = _jj_+1;\ - }\ - (found) = _ff_;\ -} - -/* -------------------------------- queue (in an array) ------------------ */ -/* queue is a quadruple (a,i,j,dim) such that: */ -/* a is the array storing values */ -/* i is the index of the first used element in the array */ -/* j is the index of the first free element in the array */ -/* dim is the size of the array a */ -/* !!!!!!! This data structure is NOT documented, do not use it !!!!!!!!!! */ - -#define SGLIB_QUEUE_INIT(type, a, i, j) { i = j = 0; } -#define SGLIB_QUEUE_IS_EMPTY(type, a, i, j) ((i)==(j)) -#define SGLIB_QUEUE_IS_FULL(type, a, i, j, dim) ((i)==((j)+1)%(dim)) -#define SGLIB_QUEUE_FIRST_ELEMENT(type, a, i, j) (a[i]) -#define SGLIB_QUEUE_ADD_NEXT(type, a, i, j, dim) {\ - if (SGLIB_QUEUE_IS_FULL(type, a, i, j, dim)) assert(0 && "the queue is full");\ - (j) = ((j)+1) % (dim);\ -} -#define SGLIB_QUEUE_ADD(type, a, elem, i, j, dim) {\ - a[j] = (elem);\ - SGLIB_QUEUE_ADD_NEXT(type, a, i, j, dim);\ -} -#define SGLIB_QUEUE_DELETE_FIRST(type, a, i, j, dim) {\ - if (SGLIB_QUEUE_IS_EMPTY(type, a, i, j)) assert(0 && "the queue is empty");\ - (i) = ((i)+1) % (dim);\ -} -#define SGLIB_QUEUE_DELETE(type, a, i, j, dim) {\ - SGLIB_QUEUE_DELETE_FIRST(type, a, i, j, dim);\ -} - -/* ----------------- priority queue (heap) (in an array) -------------------- */ -/* heap is a triple (a,i,dim) such that: */ -/* a is the array storing values */ -/* i is the index of the first free element in the array */ -/* dim is the size of the array a */ -/* !!!!!!! This data structure is NOT documented, do not use it !!!!!!!!!! */ - -#define SGLIB_HEAP_INIT(type, a, i) { i = 0; } -#define SGLIB_HEAP_IS_EMPTY(type, a, i) ((i)==0) -#define SGLIB_HEAP_IS_FULL(type, a, i, dim) ((i)==(dim)) -#define SGLIB_HEAP_FIRST_ELEMENT(type, a, i) (a[0]) -#define SGLIB_HEAP_ADD_NEXT(type, a, i, dim, comparator, elem_exchanger) {\ - int _i_;\ - if (SGLIB_HEAP_IS_FULL(type, a, i, dim)) assert(0 && "the heap is full");\ - _i_ = (i)++;\ - while (_i_ > 0 && comparator(a[_i_/2], a[_i_]) < 0) {\ - elem_exchanger(type, a, (_i_/2), _i_);\ - _i_ = _i_/2;\ - }\ -} -#define SGLIB_HEAP_ADD(type, a, elem, i, dim, comparator) {\ - if (SGLIB_HEAP_IS_FULL(type, a, i, dim)) assert(0 && "the heap is full");\ - a[i] = (elem);\ - SGLIB_HEAP_ADD_NEXT(type, a, i, dim, comparator, SGLIB_ARRAY_ELEMENTS_EXCHANGER);\ -} -#define SGLIB_HEAP_DELETE_FIRST(type, a, i, dim, comparator, elem_exchanger) {\ - if (SGLIB_HEAP_IS_EMPTY(type, a, i)) assert(0 && "the heap is empty");\ - (i)--;\ - a[0] = a[i];\ - SGLIB___ARRAY_HEAP_DOWN(type, a, 0, i, comparator, elem_exchanger);\ -} -#define SGLIB_HEAP_DELETE(type, a, i, dim, comparator) {\ - SGLIB_HEAP_DELETE_FIRST(type, a, i, dim, comparator, SGLIB_ARRAY_ELEMENTS_EXCHANGER);\ -} - - -/* ----------------- hashed table of pointers (in an array) -------------------- */ - -/* - - This hashed table is storing pointers to objects (not containers). - In this table there is a one-to-one mapping between 'objects' stored - in the table and indexes where they are placed. Each index is - pointing to exactly one 'object' and each 'object' stored in the - table occurs on exactly one index. Once an object is stored in the - table, it can be represented via its index. - - In case of collision while adding an object the index shifted - by SGLIB_HASH_TAB_SHIFT_CONSTANT (constant can be redefined) - - You can NOT delete an element from such hash table. The only - justification (I can see) for this data structure is an exchange - file format, having an index table at the beginning and then - refering objects via indexes. - - !!!!!!! This data structure is NOT documented, do not use it !!!!!!!!!! - -*/ - -#define SGLIB_HASH_TAB_INIT(type, table, dim) {\ - int _i_;\ - for(_i_ = 0; _i_ < (dim); _i_++) (table)[_i_] = NULL;\ -} - -#define SGLIB_HASH_TAB_ADD_IF_NOT_MEMBER(type, table, dim, elem, hash_function, comparator, member){\ - unsigned _pos_;\ - type *_elem_;\ - SGLIB_HASH_TAB_FIND_MEMBER(type, table, dim, elem, _pos_, _elem_);\ - (member) = (table)[_pos_];\ - if (_elem_ == NULL) {\ - if ((table)[_pos_] != NULL) assert(0 && "the hash table is full");\ - (table)[_pos_] = (elem);\ - }\ -} - -#define SGLIB_HASH_TAB_FIND_MEMBER(type, table, dim, elem, hash_function, comparator, resultIndex, resultMember) {\ - unsigned _i_;\ - int _count_;\ - type *_e_;\ - _count = 0;\ - _i_ = hash_function(elem);\ - _i_ %= (dim);\ - while ((_e_=(table)[_i_])!=NULL && comparator(_e_, (elem))!=0 && _count_<(dim)) {\ - _count_ ++;\ - _i_ = (_i_ + SGLIB_HASH_TAB_SHIFT_CONSTANT) % (dim);\ - }\ - (resultIndex) = _i_;\ - if (_count_ < (dim)) (resultMember) = _e_;\ - else (resultMember) = NULL;\ -} - -#define SGLIB_HASH_TAB_IS_MEMBER(type, table, dim, elem, hash_function, resultIndex) {\ - unsigned _i_;\ - int _c_;\ - type *_e_;\ - _count = 0;\ - _i_ = hash_function(elem);\ - _i_ %= (dim);\ - while ((_e_=(table)[_i_])!=NULL && _e_!=(elem) && _c_<(dim)) {\ - _c_ ++;\ - _i_ = (_i_ + SGLIB_HASH_TAB_SHIFT_CONSTANT) % (dim);\ - }\ - if (_e_==(elem)) (resultIndex) = _i_;\ - else (resultIndex) = -1;\ -} - -#define SGLIB_HASH_TAB_MAP_ON_ELEMENTS(type, table, dim, iteratedIndex, iteratedVariable, command) {\ - unsigned iteratedIndex;\ - type *iteratedVariable;\ - for(iteratedIndex=0; iteratedIndex < (dim); iteratedIndex++) {\ - iteratedVariable = (table)[iteratedIndex];\ - if (iteratedVariable != NULL) {command;}\ - }\ -} - - -/* ---------------------------------------------------------------------------- */ -/* ------------------------- DYNAMIC DATA STRUCTURES -------------------------- */ -/* ---------------------------------------------------------------------------- */ - -/* ------------------------------------ lists (level 0) --------------------- */ - -#define SGLIB_LIST_ADD(type, list, elem, next) {\ - (elem)->next = (list);\ - (list) = (elem);\ -} - -#define SGLIB_LIST_CONCAT(type, first, second, next) {\ - if ((first)==NULL) {\ - (first) = (second);\ - } else {\ - type *_p_;\ - for(_p_ = (first); _p_->next!=NULL; _p_=_p_->next) ;\ - _p_->next = (second);\ - }\ -} - -#define SGLIB_LIST_DELETE(type, list, elem, next) {\ - type **_p_;\ - for(_p_ = &(list); *_p_!=NULL && *_p_!=(elem); _p_= &(*_p_)->next) ;\ - assert(*_p_!=NULL && "element is not member of the container, use DELETE_IF_MEMBER instead"!=NULL);\ - *_p_ = (*_p_)->next;\ -} - -#define SGLIB_LIST_ADD_IF_NOT_MEMBER(type, list, elem, comparator, next, member) {\ - type *_p_;\ - for(_p_ = (list); _p_!=NULL && comparator(_p_, (elem)) != 0; _p_= _p_->next) ;\ - (member) = _p_;\ - if (_p_ == NULL) {\ - SGLIB_LIST_ADD(type, list, elem, next);\ - }\ -} - -#define SGLIB_LIST_DELETE_IF_MEMBER(type, list, elem, comparator, next, member) {\ - type **_p_;\ - for(_p_ = &(list); *_p_!=NULL && comparator((*_p_), (elem)) != 0; _p_= &(*_p_)->next) ;\ - (member) = *_p_;\ - if (*_p_ != NULL) {\ - *_p_ = (*_p_)->next;\ - }\ -} - -#define SGLIB_LIST_IS_MEMBER(type, list, elem, next, result) {\ - type *_p_;\ - for(_p_ = (list); _p_!=NULL && _p_ != (elem); _p_= _p_->next) ;\ - (result) = (_p_!=NULL);\ -} - -#define SGLIB_LIST_FIND_MEMBER(type, list, elem, comparator, next, member) {\ - type *_p_;\ - for(_p_ = (list); _p_!=NULL && comparator(_p_, (elem)) != 0; _p_= _p_->next) ;\ - (member) = _p_;\ -} - -#define SGLIB_LIST_MAP_ON_ELEMENTS(type, list, iteratedVariable, next, command) {\ - type *_ne_;\ - type *iteratedVariable;\ - (iteratedVariable) = (list); \ - while ((iteratedVariable)!=NULL) {\ - _ne_ = (iteratedVariable)->next;\ - {command;};\ - (iteratedVariable) = _ne_;\ - }\ -} - -#define SGLIB_LIST_LEN(type, list, next, result) {\ - type *_ce_;\ - (result) = 0;\ - SGLIB_LIST_MAP_ON_ELEMENTS(type, list, _ce_, next, (result)++);\ -} - -#define SGLIB_LIST_REVERSE(type, list, next) {\ - type *_list_,*_tmp_,*_res_;\ - _list_ = (list);\ - _res_ = NULL;\ - while (_list_!=NULL) {\ - _tmp_ = _list_->next; _list_->next = _res_;\ - _res_ = _list_; _list_ = _tmp_;\ - }\ - (list) = _res_;\ -} - -#define SGLIB_LIST_SORT(type, list, comparator, next) {\ - /* a non-recursive merge sort on lists */\ - type *_r_;\ - type *_a_, *_b_, *_todo_, *_t_, **_restail_;\ - int _i_, _n_, _contFlag_;\ - _r_ = (list);\ - _contFlag_ = 1;\ - for(_n_ = 1; _contFlag_; _n_ = _n_+_n_) {\ - _todo_ = _r_; _r_ = NULL; _restail_ = &_r_; _contFlag_ =0;\ - while (_todo_!=NULL) {\ - _a_ = _todo_;\ - for(_i_ = 1, _t_ = _a_; _i_ < _n_ && _t_!=NULL; _i_++, _t_ = _t_->next) ;\ - if (_t_ ==NULL) {\ - *_restail_ = _a_;\ - break;\ - }\ - _b_ = _t_->next; _t_->next=NULL;\ - for(_i_ =1, _t_ = _b_; _i_<_n_ && _t_!=NULL; _i_++, _t_ = _t_->next) ;\ - if (_t_ ==NULL) {\ - _todo_ =NULL;\ - } else {\ - _todo_ = _t_->next; _t_->next=NULL;\ - }\ - /* merge */\ - while (_a_!=NULL && _b_!=NULL) {\ - if (comparator(_a_, _b_) < 0) {\ - *_restail_ = _a_; _restail_ = &(_a_->next); _a_ = _a_->next;\ - } else {\ - *_restail_ = _b_; _restail_ = &(_b_->next); _b_ = _b_->next;\ - }\ - }\ - if (_a_!=NULL) *_restail_ = _a_;\ - else *_restail_ = _b_;\ - while (*_restail_!=NULL) _restail_ = &((*_restail_)->next);\ - _contFlag_ =1;\ - }\ - }\ - (list) = _r_;\ -} - -/* --------------------------------- sorted list (level 0) --------------------- */ -/* - All operations suppose that the list is sorted and they preserve - this property. -*/ - - -#define SGLIB_SORTED_LIST_ADD(type, list, elem, comparator, next) {\ - type **_e_;\ - int _cmpres_;\ - SGLIB_SORTED_LIST_FIND_MEMBER_OR_PLACE(type, list, elem, comparator, next, _cmpres_, _e_);\ - (elem)->next = *_e_;\ - *_e_ = (elem);\ -} - -#define SGLIB_SORTED_LIST_ADD_IF_NOT_MEMBER(type, list, elem, comparator, next, member) {\ - type **_e_;\ - int _cmp_res_;\ - SGLIB_SORTED_LIST_FIND_MEMBER_OR_PLACE(type, list, elem, comparator, next, _cmp_res_, _e_);\ - if (_cmp_res_ != 0) {\ - (elem)->next = *_e_;\ - *_e_ = (elem);\ - (member) = NULL;\ - } else {\ - (member) = *_e_;\ - }\ -} - -#define SGLIB_SORTED_LIST_DELETE(type, list, elem, next) {\ - SGLIB_LIST_DELETE(type, list, elem, next);\ -} - -#define SGLIB_SORTED_LIST_DELETE_IF_MEMBER(type, list, elem, comparator, next, member) {\ - type **_e_;\ - int _cmp_res_;\ - SGLIB_SORTED_LIST_FIND_MEMBER_OR_PLACE(type, list, elem, comparator, next, _cmp_res_, _e_);\ - if (_cmp_res_ == 0) {\ - (member) = *_e_;\ - *_e_ = (*_e_)->next;\ - } else {\ - (member) = NULL;\ - }\ -} - -#define SGLIB_SORTED_LIST_FIND_MEMBER(type, list, elem, comparator, next, member) {\ - type *_p_;\ - int _cmpres_ = 1;\ - for(_p_ = (list); _p_!=NULL && (_cmpres_=comparator(_p_, (elem))) < 0; _p_=_p_->next) ;\ - if (_cmpres_ != 0) (member) = NULL;\ - else (member) = _p_;\ -} - -#define SGLIB_SORTED_LIST_IS_MEMBER(type, list, elem, comparator, next, result) {\ - type *_p_;\ - for(_p_ = (list); _p_!=NULL && comparator(_p_, (elem)) < 0; _p_=_p_->next) ;\ - while (_p_ != NULL && _p_ != (elem) && comparator(_p_, (elem)) == 0) _p_=_p_->next;\ - (result) = (_p_ == (elem));\ -} - -#define SGLIB_SORTED_LIST_FIND_MEMBER_OR_PLACE(type, list, elem, comparator, next, comparator_result, member_ptr) {\ - (comparator_result) = -1;\ - for((member_ptr) = &(list); \ - *(member_ptr)!=NULL && ((comparator_result)=comparator((*member_ptr), (elem))) < 0; \ - (member_ptr) = &(*(member_ptr))->next) ;\ -} - -#define SGLIB_SORTED_LIST_LEN(type, list, next, result) {\ - SGLIB_LIST_LEN(type, list, next, result);\ -} - -#define SGLIB_SORTED_LIST_MAP_ON_ELEMENTS(type, list, iteratedVariable, next, command) {\ - SGLIB_LIST_MAP_ON_ELEMENTS(type, list, iteratedVariable, next, command);\ -} - - -/* ------------------------------- double linked list (level 0) ------------------------- */ -/* - Lists with back pointer to previous element. Those lists implements deletion - of an element in a constant time. -*/ - -#define SGLIB___DL_LIST_CREATE_SINGLETON(type, list, elem, previous, next) {\ - (list) = (elem);\ - (list)->next = (list)->previous = NULL;\ -} - -#define SGLIB_DL_LIST_ADD_AFTER(type, place, elem, previous, next) {\ - if ((place) == NULL) {\ - SGLIB___DL_LIST_CREATE_SINGLETON(type, place, elem, previous, next);\ - } else {\ - (elem)->next = (place)->next;\ - (elem)->previous = (place);\ - (place)->next = (elem);\ - if ((elem)->next != NULL) (elem)->next->previous = (elem);\ - }\ -} - -#define SGLIB_DL_LIST_ADD_BEFORE(type, place, elem, previous, next) {\ - if ((place) == NULL) {\ - SGLIB___DL_LIST_CREATE_SINGLETON(type, place, elem, previous, next);\ - } else {\ - (elem)->next = (place);\ - (elem)->previous = (place)->previous;\ - (place)->previous = (elem);\ - if ((elem)->previous != NULL) (elem)->previous->next = (elem);\ - }\ -} - -#define SGLIB_DL_LIST_ADD(type, list, elem, previous, next) {\ - SGLIB_DL_LIST_ADD_BEFORE(type, list, elem, previous, next)\ -} - -#define SGLIB___DL_LIST_GENERIC_ADD_IF_NOT_MEMBER(type, list, elem, comparator, previous, next, member, the_add_operation) {\ - type *_dlp_;\ - for(_dlp_ = (list); _dlp_!=NULL && comparator(_dlp_, (elem)) != 0; _dlp_= _dlp_->previous) ;\ - if (_dlp_ == NULL && (list) != NULL) {\ - for(_dlp_ = (list)->next; _dlp_!=NULL && comparator(_dlp_, (elem)) != 0; _dlp_= _dlp_->next) ;\ - }\ - (member) = _dlp_;\ - if (_dlp_ == NULL) {\ - the_add_operation(type, list, elem, previous, next);\ - }\ -} - -#define SGLIB_DL_LIST_ADD_BEFORE_IF_NOT_MEMBER(type, list, elem, comparator, previous, next, member) {\ - SGLIB___DL_LIST_GENERIC_ADD_IF_NOT_MEMBER(type, list, elem, comparator, previous, next, member, SGLIB_DL_LIST_ADD_BEFORE);\ -} - -#define SGLIB_DL_LIST_ADD_AFTER_IF_NOT_MEMBER(type, list, elem, comparator, previous, next, member) {\ - SGLIB___DL_LIST_GENERIC_ADD_IF_NOT_MEMBER(type, list, elem, comparator, previous, next, member, SGLIB_DL_LIST_ADD_AFTER);\ -} - -#define SGLIB_DL_LIST_ADD_IF_NOT_MEMBER(type, list, elem, comparator, previous, next, member) {\ - SGLIB___DL_LIST_GENERIC_ADD_IF_NOT_MEMBER(type, list, elem, comparator, previous, next, member, SGLIB_DL_LIST_ADD);\ -} - -#define SGLIB_DL_LIST_CONCAT(type, first, second, previous, next) {\ - if ((first)==NULL) {\ - (first) = (second);\ - } else if ((second)!=NULL) {\ - type *_dlp_;\ - for(_dlp_ = (first); _dlp_->next!=NULL; _dlp_=_dlp_->next) ;\ - SGLIB_DL_LIST_ADD_AFTER(type, _dlp_, second, previous, next);\ - }\ -} - -#define SGLIB_DL_LIST_DELETE(type, list, elem, previous, next) {\ - type *_l_;\ - _l_ = (list);\ - if (_l_ == (elem)) {\ - if ((elem)->previous != NULL) _l_ = (elem)->previous;\ - else _l_ = (elem)->next;\ - }\ - if ((elem)->next != NULL) (elem)->next->previous = (elem)->previous;\ - if ((elem)->previous != NULL) (elem)->previous->next = (elem)->next;\ - (list) = _l_;\ -} - -#define SGLIB_DL_LIST_DELETE_IF_MEMBER(type, list, elem, comparator, previous, next, member) {\ - type *_dlp_;\ - for(_dlp_ = (list); _dlp_!=NULL && comparator(_dlp_, (elem)) != 0; _dlp_= _dlp_->previous) ;\ - if (_dlp_ == NULL && (list) != NULL) {\ - for(_dlp_ = (list)->next; _dlp_!=NULL && comparator(_dlp_, (elem)) != 0; _dlp_= _dlp_->next) ;\ - }\ - (member) = _dlp_;\ - if (_dlp_ != NULL) {\ - SGLIB_DL_LIST_DELETE(type, list, _dlp_, previous, next);\ - }\ -} - -#define SGLIB_DL_LIST_IS_MEMBER(type, list, elem, previous, next, result) {\ - type *_dlp_;\ - SGLIB_LIST_IS_MEMBER(type, list, elem, previous, result);\ - if (result == 0 && (list) != NULL) {\ - _dlp_ = (list)->next;\ - SGLIB_LIST_IS_MEMBER(type, _dlp_, elem, next, result);\ - }\ -} - -#define SGLIB_DL_LIST_FIND_MEMBER(type, list, elem, comparator, previous, next, member) {\ - type *_dlp_;\ - SGLIB_LIST_FIND_MEMBER(type, list, elem, comparator, previous, member);\ - if ((member) == NULL && (list) != NULL) {\ - _dlp_ = (list)->next;\ - SGLIB_LIST_FIND_MEMBER(type, _dlp_, elem, comparator, next, member);\ - }\ -} - -#define SGLIB_DL_LIST_MAP_ON_ELEMENTS(type, list, iteratedVariable, previous, next, command) {\ - type *_dl_;\ - type *iteratedVariable;\ - if ((list)!=NULL) {\ - _dl_ = (list)->next;\ - SGLIB_LIST_MAP_ON_ELEMENTS(type, list, iteratedVariable, previous, command);\ - SGLIB_LIST_MAP_ON_ELEMENTS(type, _dl_, iteratedVariable, next, command);\ - }\ -} - -#define SGLIB_DL_LIST_SORT(type, list, comparator, previous, next) {\ - type *_dll_, *_dlp_, *_dlt_;\ - _dll_ = (list);\ - if (_dll_ != NULL) {\ - for(; _dll_->previous!=NULL; _dll_=_dll_->previous) ;\ - SGLIB_LIST_SORT(type, _dll_, comparator, next);\ - SGLIB___DL_LIST_CREATE_FROM_LIST(type, _dll_, previous, next);\ - (list) = _dll_;\ - }\ -} - -#define SGLIB_DL_LIST_GET_FIRST(type, list, previous, next, result) {\ - type *_dll_;\ - _dll_ = (list);\ - if (_dll_ != NULL) {\ - for(; _dll_->previous!=NULL; _dll_=_dll_->previous) ;\ - }\ - (result) = _dll_;\ -} - -#define SGLIB_DL_LIST_GET_LAST(type, list, previous, next, result) {\ - type *_dll_;\ - _dll_ = (list);\ - if (_dll_ != NULL) {\ - for(; _dll_->next!=NULL; _dll_=_dll_->next) ;\ - }\ - (result) = _dll_;\ -} - -#define SGLIB_DL_LIST_LEN(type, list, previous, next, result) {\ - type *_dl_;\ - int _r1_, _r2_;\ - if ((list)==NULL) {\ - (result) = 0;\ - } else {\ - SGLIB_LIST_LEN(type, list, previous, _r1_);\ - _dl_ = (list)->next;\ - SGLIB_LIST_LEN(type, _dl_, next, _r2_);\ - (result) = _r1_ + _r2_;\ - }\ -} - -#define SGLIB_DL_LIST_REVERSE(type, list, previous, next) {\ - type *_list_,*_nlist_,*_dlp_,*_dln_;\ - _list_ = (list);\ - if (_list_!=NULL) {\ - _nlist_ = _list_->next;\ - while (_list_!=NULL) {\ - _dln_ = _list_->next; \ - _dlp_ = _list_->previous; \ - _list_->next = _dlp_;\ - _list_->previous = _dln_;\ - _list_ = _dlp_;\ - }\ - while (_nlist_!=NULL) {\ - _dln_ = _nlist_->next; \ - _dlp_ = _nlist_->previous; \ - _nlist_->next = _dlp_;\ - _nlist_->previous = _dln_;\ - _nlist_ = _dln_;\ - }\ - }\ -} - -#define SGLIB___DL_LIST_CREATE_FROM_LIST(type, list, previous, next) {\ - type *_dlp_, *_dlt_;\ - _dlp_ = NULL;\ - for(_dlt_ = (list); _dlt_!=NULL; _dlt_ = _dlt_->next) {\ - _dlt_->previous = _dlp_;\ - _dlp_ = _dlt_;\ - }\ -} - - -/* ------------------------------- binary tree traversal (level 0) -------------------- */ - - -#define SGLIB___BIN_TREE_MAP_ON_ELEMENTS(type, tree, iteratedVariable, order, left, right, command) {\ - /* this is non-recursive implementation of tree traversal */\ - /* it maintains the path to the current node in the array '_path_' */\ - /* the _path_[0] contains the root of the tree; */\ - /* the _path_[_pathi_] contains the _current_element_ */\ - /* the macro does not use the _current_element_ after execution of command */\ - /* command can destroy it, it can free the element for example */\ - type *_path_[SGLIB_MAX_TREE_DEEP];\ - type *_right_[SGLIB_MAX_TREE_DEEP];\ - char _pass_[SGLIB_MAX_TREE_DEEP];\ - type *_cn_;\ - int _pathi_;\ - type *iteratedVariable;\ - _cn_ = (tree);\ - _pathi_ = 0;\ - while (_cn_!=NULL) {\ - /* push down to leftmost innermost element */\ - while(_cn_!=NULL) {\ - _path_[_pathi_] = _cn_;\ - _right_[_pathi_] = _cn_->right;\ - _pass_[_pathi_] = 0;\ - _cn_ = _cn_->left;\ - if (order == 0) {\ - iteratedVariable = _path_[_pathi_];\ - {command;}\ - }\ - _pathi_ ++;\ - if (_pathi_ >= SGLIB_MAX_TREE_DEEP) assert(0 && "the binary_tree is too deep");\ - }\ - do {\ - _pathi_ --;\ - if ((order==1 && _pass_[_pathi_] == 0)\ - || (order == 2 && (_pass_[_pathi_] == 1 || _right_[_pathi_]==NULL))) {\ - iteratedVariable = _path_[_pathi_];\ - {command;}\ - }\ - _pass_[_pathi_] ++;\ - } while (_pathi_>0 && _right_[_pathi_]==NULL) ;\ - _cn_ = _right_[_pathi_];\ - _right_[_pathi_] = NULL;\ - _pathi_ ++;\ - }\ -} - -#define SGLIB_BIN_TREE_MAP_ON_ELEMENTS(type, tree, _current_element_, left, right, command) {\ - SGLIB___BIN_TREE_MAP_ON_ELEMENTS(type, tree, _current_element_, 1, left, right, command);\ -} - -#define SGLIB_BIN_TREE_MAP_ON_ELEMENTS_PREORDER(type, tree, _current_element_, left, right, command) {\ - SGLIB___BIN_TREE_MAP_ON_ELEMENTS(type, tree, _current_element_, 0, left, right, command);\ -} - -#define SGLIB_BIN_TREE_MAP_ON_ELEMENTS_POSTORDER(type, tree, _current_element_, left, right, command) {\ - SGLIB___BIN_TREE_MAP_ON_ELEMENTS(type, tree, _current_element_, 2, left, right, command);\ -} - -#define SGLIB___BIN_TREE_FIND_MEMBER(type, tree, elem, left, right, comparator, res) {\ - type *_s_;\ - int _c_;\ - _s_ = (tree);\ - while (_s_!=NULL) {\ - _c_ = comparator((elem), _s_);\ - if (_c_ < 0) _s_ = _s_->left;\ - else if (_c_ > 0) _s_ = _s_->right;\ - else break;\ - }\ - (res) = _s_;\ -} - -/* ---------------------------------------------------------------------------- */ -/* ---------------------------------------------------------------------------- */ -/* - LEVEL - 1 INTERFACE - */ -/* ---------------------------------------------------------------------------- */ -/* ---------------------------------------------------------------------------- */ - - - -/* ---------------------------------------------------------------------------- */ -/* ------------------------------ STATIC ARRAYS ------------------------------- */ -/* ---------------------------------------------------------------------------- */ - -/* ----------------------------- array sorting (level 1) ---------------------- */ - -#define SGLIB_DEFINE_ARRAY_SORTING_PROTOTYPES(type, comparator) \ - extern void sglib_##type##_array_quick_sort(type *a, int max);\ - extern void sglib_##type##_array_heap_sort(type *a, int max);\ - - -#define SGLIB_DEFINE_ARRAY_SORTING_FUNCTIONS(type, comparator) \ - void sglib_##type##_array_quick_sort(type *a, int max) {\ - SGLIB_ARRAY_SINGLE_QUICK_SORT(type, a, max, comparator);\ - }\ - void sglib_##type##_array_heap_sort(type *a, int max) {\ - SGLIB_ARRAY_SINGLE_HEAP_SORT(type, a, max, comparator);\ - }\ - - -/* ----------------------------- array queue (level 1) ------------------- */ -/* sglib's queue is stored in a fixed sized array */ -/* queue_type MUST be a structure containing fields: */ -/* afield is the array storing elem_type */ -/* ifield is the index of the first element in the queue */ -/* jfield is the index of the first free element after the queue */ -/* dim is the size of the array afield */ -/* !!!!!!! This data structure is NOT documented, do not use it !!!!!!!!!! */ - - -#define SGLIB_DEFINE_QUEUE_PROTOTYPES(queue_type, elem_type, afield, ifield, jfield, dim) \ - extern void sglib_##queue_type##_init(queue_type *q); \ - extern int sglib_##queue_type##_is_empty(queue_type *q); \ - extern int sglib_##queue_type##_is_full(queue_type *q); \ - extern elem_type sglib_##queue_type##_first_element(queue_type *q); \ - extern elem_type *sglib_##queue_type##_first_element_ptr(queue_type *q); \ - extern void sglib_##queue_type##_add_next(queue_type *q); \ - extern void sglib_##queue_type##_add(queue_type *q, elem_type elem); \ - extern void sglib_##queue_type##_delete_first(queue_type *q); \ - extern void sglib_##queue_type##_delete(queue_type *q); - - -#define SGLIB_DEFINE_QUEUE_FUNCTIONS(queue_type, elem_type, afield, ifield, jfield, dim) \ - void sglib_##queue_type##_init(queue_type *q) {\ - SGLIB_QUEUE_INIT(elem_type, q->afield, q->ifield, q->jfield);\ - }\ - int sglib_##queue_type##_is_empty(queue_type *q) {\ - return(SGLIB_QUEUE_IS_EMPTY(elem_type, q->afield, q->ifield, q->jfield));\ - }\ - int sglib_##queue_type##_is_full(queue_type *q) {\ - return(SGLIB_QUEUE_IS_FULL(elem_type, q->afield, q->ifield, q->jfield));\ - }\ - elem_type sglib_##queue_type##_first_element(queue_type *q) {\ - return(SGLIB_QUEUE_FIRST_ELEMENT(elem_type, q->afield, q->ifield, q->jfield));\ - }\ - elem_type *sglib_##queue_type##_first_element_ptr(queue_type *q) {\ - return(& SGLIB_QUEUE_FIRST_ELEMENT(elem_type, q->afield, q->ifield, q->jfield));\ - }\ - void sglib_##queue_type##_add_next(queue_type *q) {\ - SGLIB_QUEUE_ADD_NEXT(elem_type, q->afield, q->ifield, q->jfield, dim);\ - }\ - void sglib_##queue_type##_add(queue_type *q, elem_type elem) {\ - SGLIB_QUEUE_ADD(elem_type, q->afield, elem, q->ifield, q->jfield, dim);\ - }\ - void sglib_##queue_type##_delete_first(queue_type *q) {\ - SGLIB_QUEUE_DELETE_FIRST(elem_type, q->afield, q->ifield, q->jfield, dim);\ - }\ - void sglib_##queue_type##_delete(queue_type *q) {\ - SGLIB_QUEUE_DELETE_FIRST(elem_type, q->afield, q->ifield, q->jfield, dim);\ - } - - -/* ------------------------ array heap (level 1) ------------------------- */ -/* sglib's heap is a priority queue implemented in a fixed sized array */ -/* heap_type MUST be a structure containing fields: */ -/* afield is the array of size dim storing elem_type */ -/* ifield is the index of the first free element after the queue */ -/* !!!!!!! This data structure is NOT documented, do not use it !!!!!!!!!! */ - - -#define SGLIB_DEFINE_HEAP_PROTOTYPES(heap_type, elem_type, afield, ifield, dim, comparator, elem_exchanger) \ - extern void sglib_##heap_type##_init(heap_type *q); \ - extern int sglib_##heap_type##_is_empty(heap_type *q); \ - extern int sglib_##heap_type##_is_full(heap_type *q); \ - extern elem_type sglib_##heap_type##_first_element(heap_type *q); \ - extern elem_type *sglib_##heap_type##_first_element_ptr(heap_type *q); \ - extern void sglib_##heap_type##_add_next(heap_type *q); \ - extern void sglib_##heap_type##_add(heap_type *q, elem_type elem); \ - extern void sglib_##heap_type##_delete_first(heap_type *q); \ - extern void sglib_##heap_type##_delete(heap_type *q) - -#define SGLIB_DEFINE_HEAP_FUNCTIONS(heap_type, elem_type, afield, ifield, dim, comparator, elem_exchanger) \ - void sglib_##heap_type##_init(heap_type *q) {\ - SGLIB_HEAP_INIT(elem_type, q->afield, q->ifield);\ - }\ - int sglib_##heap_type##_is_empty(heap_type *q) {\ - return(SGLIB_HEAP_IS_EMPTY(elem_type, q->afield, q->ifield));\ - }\ - int sglib_##heap_type##_is_full(heap_type *q) {\ - return(SGLIB_HEAP_IS_FULL(elem_type, q->afield, q->ifield));\ - }\ - elem_type sglib_##heap_type##_first_element(heap_type *q) {\ - return(SGLIB_HEAP_FIRST_ELEMENT(elem_type, q->afield, q->ifield));\ - }\ - elem_type *sglib_##heap_type##_first_element_ptr(heap_type *q) {\ - return(& SGLIB_HEAP_FIRST_ELEMENT(elem_type, q->afield, q->ifield));\ - }\ - void sglib_##heap_type##_add_next(heap_type *q) {\ - SGLIB_HEAP_ADD_NEXT(elem_type, q->afield, q->ifield, dim, comparator, elem_exchanger);\ - }\ - void sglib_##heap_type##_add(heap_type *q, elem_type elem) {\ - SGLIB_HEAP_ADD(elem_type, q->afield, elem, q->ifield, dim, comparator, elem_exchanger);\ - }\ - void sglib_##heap_type##_delete_first(heap_type *q) {\ - SGLIB_HEAP_DELETE_FIRST(elem_type, q->afield, q->ifield, dim, comparator, elem_exchanger);\ - }\ - void sglib_##heap_type##_delete(heap_type *q) {\ - SGLIB_HEAP_DELETE_FIRST(elem_type, q->afield, q->ifield, dim, comparator, elem_exchanger);\ - } - - -/* ------------------------ hashed table (level 1) ------------------------- */ -/* - - sglib's hash table is an array storing directly pointers to objects (not containers). - In this table there is a one-to-one mapping between 'objects' stored - in the table and indexes where they are placed. Each index is - pointing to exactly one 'object' and each 'object' stored in the - table occurs on exactly one index. Once an object is stored in the - table, it can be represented via its index. - - type - is the type of elements - dim - is the size of the hash array - hash_function - is a hashing function mapping type* to unsigned - comparator - is a comparator on elements - - !!!!!!! This data structure is NOT documented, do not use it !!!!!!!!!! -*/ - -#define SGLIB_DEFINE_HASHED_TABLE_PROTOTYPES(type, dim, hash_function, comparator) \ - struct sglib_hashed_##type##_iterator {\ - int currentIndex;\ - int (*subcomparator)(type *, type *);\ - type *equalto;\ - };\ - extern void sglib_hashed_##type##_init(type *table[dim]);\ - extern int sglib_hashed_##type##_add_if_not_member(type *table[dim], type *elem, type **member);\ - extern int sglib_hashed_##type##_is_member(type *table[dim], type *elem);\ - extern type * sglib_hashed_##type##_find_member(type *table[dim], type *elem);\ - extern type *sglib_hashed_##type##_it_init(struct sglib_hashed_##type##_iterator *it, type *table[dim]); \ - extern type *sglib_hashed_##type##_it_init_on_equal(struct sglib_hashed_##type##_iterator *it, type *table[dim], int (*subcomparator)(type *, type *), type *equalto); \ - extern type *sglib_hashed_##type##_it_current(struct sglib_hashed_##type##_iterator *it); \ - extern type *sglib_hashed_##type##_it_next(struct sglib_hashed_##type##_iterator *it); - -#define SGLIB_DEFINE_HASHED_TABLE_FUNCTIONS(type, dim, hash_function, comparator) \ - struct sglib_hashed_##type##_iterator {\ - int currentIndex;\ - type **table;\ - int (*subcomparator)(type *, type *);\ - type *equalto;\ - };\ - void sglib_hashed_##type##_init(type *table[dim]) {\ - SGLIB_HASH_TAB_INIT(type, table, dim);\ - }\ - int sglib_hashed_##type##_add_if_not_member(type *table[dim], type *elem, type **member) {\ - SGLIB_HASH_TAB_ADD_IF_NOT_MEMBER(type, table, dim, elem, hash_function, comparator, *member);\ - }\ - int sglib_hashed_##type##_is_member(type *table[dim], type *elem) {\ - int ind;\ - SGLIB_HASH_TAB_IS_MEMBER(type, table, dim, elem, hash_function, ind);\ - return(ind != -1);\ - }\ - type * sglib_hashed_##type##_find_member(type *table[dim], type *elem) {\ - type *mmb;\ - int ind;\ - SGLIB_HASH_TAB_FIND_MEMBER(type, table, dim, elem, hash_function, comparator, ind, mmb);\ - return(mmb);\ - }\ - type *sglib_hashed_##type##_it_init_on_equal(struct sglib_hashed_##type##_iterator *it, type *table[dim], int (*subcomparator)(type *, type *), type *equalto) {\ - int i;\ - it->table = table;\ - it->subcomparator = subcomparator;\ - it->equalto = equalto;\ - for(i=0; i<(dim) && table[i]==NULL; i++) ;\ - it->currentIndex = i;\ - if (i<(dim)) return(table[i]);\ - return(NULL);\ - }\ - type *sglib_hashed_##type##_it_init(struct sglib_hashed_##type##_iterator *it, type *table[dim]) {\ - sglib_hashed_##type##_it_init_on_equal(it, table, NULL, NULL);\ - }\ - type *sglib_hashed_##type##_it_current(struct sglib_hashed_##type##_iterator *it) {\ - return(table[it->currentIndex]);\ - }\ - type *sglib_hashed_##type##_it_next(struct sglib_hashed_##type##_iterator *it) {\ - i=it->currentIndex;\ - if (i<(dim)) {\ - for(i++; i<(dim) && table[i]==NULL; i++) ;\ - }\ - it->currentIndex = i;\ - if (i<(dim)) return(table[i]);\ - return(NULL);\ - } - - -/* ------------------- hashed container (only for level 1) -------------------- */ -/* - hashed container is a table of given fixed size containing another - (dynamic) base container in each cell. Once an object should be - inserted into the hashed container, a hash function is used to - determine the cell where the object belongs and the object is - inserted into the base container stored in this cell. Usually the - base container is simply a list or a sorted list, but it can be a - red-black tree as well. - - parameters: - type - the type of the container stored in each cell. - dim - the size of the hashed array - hash_function - the hashing function hashing 'type *' to unsigned. - -*/ - -#define SGLIB_DEFINE_HASHED_CONTAINER_PROTOTYPES(type, dim, hash_function) \ - struct sglib_hashed_##type##_iterator {\ - struct sglib_##type##_iterator containerIt;\ - type **table;\ - int currentIndex;\ - int (*subcomparator)(type *, type *);\ - type *equalto;\ - };\ - extern void sglib_hashed_##type##_init(type *table[dim]);\ - extern void sglib_hashed_##type##_add(type *table[dim], type *elem);\ - extern int sglib_hashed_##type##_add_if_not_member(type *table[dim], type *elem, type **member);\ - extern void sglib_hashed_##type##_delete(type *table[dim], type *elem);\ - extern int sglib_hashed_##type##_delete_if_member(type *table[dim], type *elem, type **memb);\ - extern int sglib_hashed_##type##_is_member(type *table[dim], type *elem);\ - extern type * sglib_hashed_##type##_find_member(type *table[dim], type *elem);\ - extern type *sglib_hashed_##type##_it_init(struct sglib_hashed_##type##_iterator *it, type *table[dim]); \ - extern type *sglib_hashed_##type##_it_init_on_equal(struct sglib_hashed_##type##_iterator *it, type *table[dim], int (*subcomparator)(type *, type *), type *equalto); \ - extern type *sglib_hashed_##type##_it_current(struct sglib_hashed_##type##_iterator *it); \ - extern type *sglib_hashed_##type##_it_next(struct sglib_hashed_##type##_iterator *it); - -#define SGLIB_DEFINE_HASHED_CONTAINER_FUNCTIONS(type, dim, hash_function) \ - /*extern unsigned hash_function(type *elem);*/\ - void sglib_hashed_##type##_init(type *table[dim]) {\ - unsigned i;\ - for(i=0; i<(dim); i++) table[i] = NULL;\ - }\ - void sglib_hashed_##type##_add(type *table[dim], type *elem) {\ - unsigned i;\ - i = ((unsigned)hash_function(elem)) % (dim);\ - sglib_##type##_add(&(table)[i], elem);\ - }\ - int sglib_hashed_##type##_add_if_not_member(type *table[dim], type *elem, type **member) {\ - unsigned i;\ - i = ((unsigned)hash_function(elem)) % (dim);\ - return(sglib_##type##_add_if_not_member(&(table)[i], elem, member));\ - }\ - void sglib_hashed_##type##_delete(type *table[dim], type *elem) {\ - unsigned i;\ - i = ((unsigned)hash_function(elem)) % (dim);\ - sglib_##type##_delete(&(table)[i], elem);\ - }\ - int sglib_hashed_##type##_delete_if_member(type *table[dim], type *elem, type **memb) {\ - unsigned i;\ - i = ((unsigned)hash_function(elem)) % (dim);\ - return(sglib_##type##_delete_if_member(&(table)[i], elem, memb));\ - }\ - int sglib_hashed_##type##_is_member(type *table[dim], type *elem) {\ - unsigned i;\ - i = ((unsigned)hash_function(elem)) % (dim);\ - return(sglib_##type##_is_member((table)[i], elem));\ - }\ - type * sglib_hashed_##type##_find_member(type *table[dim], type *elem) {\ - unsigned i;\ - i = ((unsigned)hash_function(elem)) % (dim);\ - return(sglib_##type##_find_member((table)[i], elem));\ - }\ - type *sglib_hashed_##type##_it_init_on_equal(struct sglib_hashed_##type##_iterator *it, type *table[dim], int (*subcomparator)(type *, type *), type *equalto) {\ - type *e;\ - it->table = table;\ - it->currentIndex = 0;\ - it->subcomparator = subcomparator;\ - it->equalto = equalto;\ - e = sglib_##type##_it_init_on_equal(&it->containerIt, table[it->currentIndex], it->subcomparator, it->equalto);\ - if (e==NULL) e = sglib_hashed_##type##_it_next(it);\ - return(e);\ - }\ - type *sglib_hashed_##type##_it_init(struct sglib_hashed_##type##_iterator *it, type *table[dim]) {\ - return(sglib_hashed_##type##_it_init_on_equal(it, table, NULL, NULL));\ - }\ - type *sglib_hashed_##type##_it_current(struct sglib_hashed_##type##_iterator *it) {\ - return(sglib_##type##_it_current(&it->containerIt));\ - }\ - type *sglib_hashed_##type##_it_next(struct sglib_hashed_##type##_iterator *it) {\ - type *e;\ - e = sglib_##type##_it_next(&it->containerIt);\ - while (e==NULL && (++(it->currentIndex))<(dim)) {\ - e = sglib_##type##_it_init_on_equal(&it->containerIt, it->table[it->currentIndex], it->subcomparator, it->equalto);\ - }\ - return(e);\ - } - - - -/* ---------------------------------------------------------------------------- */ -/* ------------------------- DYNAMIC DATA STRUCTURES -------------------------- */ -/* ---------------------------------------------------------------------------- */ - - - -/* ------------------------------------ list (level 1) -------------------------------- */ - -#define SGLIB_DEFINE_LIST_PROTOTYPES(type, comparator, next) \ - struct sglib_##type##_iterator {\ - type *currentelem;\ - type *nextelem;\ - int (*subcomparator)(type *, type *);\ - type *equalto;\ - };\ - extern void sglib_##type##_add(type **list, type *elem);\ - extern int sglib_##type##_add_if_not_member(type **list, type *elem, type **member);\ - extern void sglib_##type##_concat(type **first, type *second);\ - extern void sglib_##type##_delete(type **list, type *elem);\ - extern int sglib_##type##_delete_if_member(type **list, type *elem, type **member);\ - extern int sglib_##type##_is_member(type *list, type *elem);\ - extern type *sglib_##type##_find_member(type *list, type *elem);\ - extern void sglib_##type##_sort(type **list);\ - extern int sglib_##type##_len(type *list);\ - extern void sglib_##type##_reverse(type **list);\ - extern type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *list); \ - extern type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *list, int (*subcomparator)(type *, type *), type *equalto); \ - extern type *sglib_##type##_it_current(struct sglib_##type##_iterator *it); \ - extern type *sglib_##type##_it_next(struct sglib_##type##_iterator *it); - - -#define SGLIB_DEFINE_LIST_FUNCTIONS(type, comparator, next) \ - int sglib_##type##_is_member(type *list, type *elem) {\ - int result;\ - SGLIB_LIST_IS_MEMBER(type, list, elem, next, result);\ - return(result);\ - }\ - type *sglib_##type##_find_member(type *list, type *elem) {\ - type *result;\ - SGLIB_LIST_FIND_MEMBER(type, list, elem, comparator, next, result);\ - return(result);\ - }\ - int sglib_##type##_add_if_not_member(type **list, type *elem, type **member) {\ - SGLIB_LIST_ADD_IF_NOT_MEMBER(type, *list, elem, comparator, next, *member);\ - return(*member==NULL);\ - }\ - void sglib_##type##_add(type **list, type *elem) {\ - SGLIB_LIST_ADD(type, *list, elem, next);\ - }\ - void sglib_##type##_concat(type **first, type *second) {\ - SGLIB_LIST_CONCAT(type, *first, second, next);\ - }\ - void sglib_##type##_delete(type **list, type *elem) {\ - SGLIB_LIST_DELETE(type, *list, elem, next);\ - }\ - int sglib_##type##_delete_if_member(type **list, type *elem, type **member) {\ - SGLIB_LIST_DELETE_IF_MEMBER(type, *list, elem, comparator, next, *member);\ - return(*member!=NULL);\ - }\ - void sglib_##type##_sort(type **list) { \ - SGLIB_LIST_SORT(type, *list, comparator, next);\ - }\ - int sglib_##type##_len(type *list) {\ - int res;\ - SGLIB_LIST_LEN(type, list, next, res);\ - return(res);\ - }\ - void sglib_##type##_reverse(type **list) {\ - SGLIB_LIST_REVERSE(type, *list, next);\ - }\ - \ - type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *list, int (*subcomparator)(type *, type *), type *equalto) {\ - it->subcomparator = subcomparator;\ - it->equalto = equalto;\ - it->nextelem = list;\ - return(sglib_##type##_it_next(it));\ - }\ - type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *list) {\ - return(sglib_##type##_it_init_on_equal(it, list, NULL, NULL));\ - }\ - type *sglib_##type##_it_current(struct sglib_##type##_iterator *it) {\ - return(it->currentelem);\ - }\ - type *sglib_##type##_it_next(struct sglib_##type##_iterator *it) {\ - type *ce, *eq;\ - int (*scp)(type *, type *);\ - ce = it->nextelem;\ - it->nextelem = NULL;\ - if (it->subcomparator != NULL) {\ - eq = it->equalto; \ - scp = it->subcomparator;\ - while (ce!=NULL && scp(ce, eq)!=0) ce = ce->next;\ - }\ - it->currentelem = ce;\ - if (ce != NULL) it->nextelem = ce->next;\ - return(ce);\ - } - -/* ----------------------------- sorted list (level 1) ----------------------------------- */ - - -#define SGLIB_DEFINE_SORTED_LIST_PROTOTYPES(type, comparator, next) \ - struct sglib_##type##_iterator {\ - type *currentelem;\ - type *nextelem;\ - int (*subcomparator)(type *, type *);\ - type *equalto;\ - };\ - extern void sglib_##type##_add(type **list, type *elem);\ - extern int sglib_##type##_add_if_not_member(type **list, type *elem, type **member);\ - extern void sglib_##type##_delete(type **list, type *elem);\ - extern int sglib_##type##_delete_if_member(type **list, type *elem, type **member);\ - extern int sglib_##type##_is_member(type *list, type *elem);\ - extern type *sglib_##type##_find_member(type *list, type *elem);\ - extern int sglib_##type##_len(type *list);\ - extern void sglib_##type##_sort(type **list);\ - extern type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *list); \ - extern type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *list, int (*subcomparator)(type *, type *), type *equalto); \ - extern type *sglib_##type##_it_current(struct sglib_##type##_iterator *it); \ - extern type *sglib_##type##_it_next(struct sglib_##type##_iterator *it); - - -#define SGLIB_DEFINE_SORTED_LIST_FUNCTIONS(type, comparator, next) \ - int sglib_##type##_is_member(type *list, type *elem) {\ - int result;\ - SGLIB_SORTED_LIST_IS_MEMBER(type, list, elem, comparator, next, result);\ - return(result);\ - }\ - type *sglib_##type##_find_member(type *list, type *elem) {\ - type *result;\ - SGLIB_SORTED_LIST_FIND_MEMBER(type, list, elem, comparator, next, result);\ - return(result);\ - }\ - int sglib_##type##_add_if_not_member(type **list, type *elem, type **member) {\ - SGLIB_SORTED_LIST_ADD_IF_NOT_MEMBER(type, *list, elem, comparator, next, *member);\ - return(*member==NULL);\ - }\ - void sglib_##type##_add(type **list, type *elem) {\ - SGLIB_SORTED_LIST_ADD(type, *list, elem, comparator, next);\ - }\ - void sglib_##type##_delete(type **list, type *elem) {\ - SGLIB_SORTED_LIST_DELETE(type, *list, elem, next);\ - }\ - int sglib_##type##_delete_if_member(type **list, type *elem, type **member) {\ - SGLIB_SORTED_LIST_DELETE_IF_MEMBER(type, *list, elem, comparator, next, *member);\ - return(*member!=NULL);\ - }\ - int sglib_##type##_len(type *list) {\ - int res;\ - SGLIB_SORTED_LIST_LEN(type, list, next, res);\ - return(res);\ - }\ - void sglib_##type##_sort(type **list) { \ - SGLIB_LIST_SORT(type, *list, comparator, next);\ - }\ - \ - type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *list, int (*subcomparator)(type *, type *), type *equalto) {\ - it->subcomparator = subcomparator;\ - it->equalto = equalto;\ - it->nextelem = list;\ - return(sglib_##type##_it_next(it));\ - }\ - type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *list) {\ - return(sglib_##type##_it_init_on_equal(it, list, NULL, NULL));\ - }\ - type *sglib_##type##_it_current(struct sglib_##type##_iterator *it) {\ - return(it->currentelem);\ - }\ - type *sglib_##type##_it_next(struct sglib_##type##_iterator *it) {\ - type *ce, *eq;\ - int (*scp)(type *, type *);\ - int c;\ - ce = it->nextelem;\ - it->nextelem = NULL;\ - if (it->subcomparator != NULL) {\ - eq = it->equalto; \ - scp = it->subcomparator;\ - while (ce!=NULL && (c=scp(ce, eq)) < 0) ce = ce->next;\ - if (ce != NULL && c > 0) ce = NULL;\ - }\ - it->currentelem = ce;\ - if (ce != NULL) it->nextelem = ce->next;\ - return(ce);\ - } - - -/* ----------------------------- double linked list (level 1) ------------------------------ */ - - -#define SGLIB_DEFINE_DL_LIST_PROTOTYPES(type, comparator, previous, next) \ - struct sglib_##type##_iterator {\ - type *currentelem;\ - type *prevelem;\ - type *nextelem;\ - int (*subcomparator)(type *, type *);\ - type *equalto;\ - };\ - extern void sglib_##type##_add(type **list, type *elem);\ - extern void sglib_##type##_add_before(type **list, type *elem);\ - extern void sglib_##type##_add_after(type **list, type *elem);\ - extern int sglib_##type##_add_if_not_member(type **list, type *elem, type **member);\ - extern int sglib_##type##_add_before_if_not_member(type **list, type *elem, type **member);\ - extern int sglib_##type##_add_after_if_not_member(type **list, type *elem, type **member);\ - extern void sglib_##type##_concat(type **first, type *second);\ - extern void sglib_##type##_delete(type **list, type *elem);\ - extern int sglib_##type##_delete_if_member(type **list, type *elem, type **member);\ - extern int sglib_##type##_is_member(type *list, type *elem);\ - extern type *sglib_##type##_find_member(type *list, type *elem);\ - extern type *sglib_##type##_get_first(type *list);\ - extern type *sglib_##type##_get_last(type *list);\ - extern void sglib_##type##_sort(type **list);\ - extern int sglib_##type##_len(type *list);\ - extern void sglib_##type##_reverse(type **list);\ - extern type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *list); \ - extern type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *list, int (*subcomparator)(type *, type *), type *equalto); \ - extern type *sglib_##type##_it_current(struct sglib_##type##_iterator *it); \ - extern type *sglib_##type##_it_next(struct sglib_##type##_iterator *it); - - -#define SGLIB_DEFINE_DL_LIST_FUNCTIONS(type, comparator, previous, next) \ - void sglib_##type##_add(type **list, type *elem) {\ - SGLIB_DL_LIST_ADD(type, *list, elem, previous, next);\ - }\ - void sglib_##type##_add_after(type **list, type *elem) {\ - SGLIB_DL_LIST_ADD_AFTER(type, *list, elem, previous, next);\ - }\ - void sglib_##type##_add_before(type **list, type *elem) {\ - SGLIB_DL_LIST_ADD_BEFORE(type, *list, elem, previous, next);\ - }\ - int sglib_##type##_add_if_not_member(type **list, type *elem, type **member) {\ - SGLIB_DL_LIST_ADD_IF_NOT_MEMBER(type, *list, elem, comparator, previous, next, *member);\ - return(*member==NULL);\ - }\ - int sglib_##type##_add_after_if_not_member(type **list, type *elem, type **member) {\ - SGLIB_DL_LIST_ADD_AFTER_IF_NOT_MEMBER(type, *list, elem, comparator, previous, next, *member);\ - return(*member==NULL);\ - }\ - int sglib_##type##_add_before_if_not_member(type **list, type *elem, type **member) {\ - SGLIB_DL_LIST_ADD_BEFORE_IF_NOT_MEMBER(type, *list, elem, comparator, previous, next, *member);\ - return(*member==NULL);\ - }\ - void sglib_##type##_concat(type **first, type *second) {\ - SGLIB_DL_LIST_CONCAT(type, *first, second, previous, next);\ - }\ - void sglib_##type##_delete(type **list, type *elem) {\ - SGLIB_DL_LIST_DELETE(type, *list, elem, previous, next);\ - }\ - int sglib_##type##_delete_if_member(type **list, type *elem, type **member) {\ - SGLIB_DL_LIST_DELETE_IF_MEMBER(type, *list, elem, comparator, previous, next, *member);\ - return(*member!=NULL);\ - }\ - int sglib_##type##_is_member(type *list, type *elem) {\ - int result;\ - SGLIB_DL_LIST_IS_MEMBER(type, list, elem, previous, next, result);\ - return(result);\ - }\ - type *sglib_##type##_find_member(type *list, type *elem) {\ - type *result;\ - SGLIB_DL_LIST_FIND_MEMBER(type, list, elem, comparator, previous, next, result);\ - return(result);\ - }\ - type *sglib_##type##_get_first(type *list) {\ - type *result;\ - SGLIB_DL_LIST_GET_FIRST(type, list, previous, next, result);\ - return(result);\ - }\ - type *sglib_##type##_get_last(type *list) {\ - type *result;\ - SGLIB_DL_LIST_GET_LAST(type, list, previous, next, result);\ - return(result);\ - }\ - void sglib_##type##_sort(type **list) {\ - SGLIB_DL_LIST_SORT(type, *list, comparator, previous, next);\ - }\ - int sglib_##type##_len(type *list) {\ - int res;\ - SGLIB_DL_LIST_LEN(type, list, previous, next, res);\ - return(res);\ - }\ - void sglib_##type##_reverse(type **list) {\ - SGLIB_DL_LIST_REVERSE(type, *list, previous, next);\ - }\ - \ - type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *list, int (*subcomparator)(type *, type *), type *equalto) {\ - it->subcomparator = subcomparator;\ - it->equalto = equalto;\ - it->prevelem = list;\ - it->nextelem = list;\ - if (list != NULL) it->nextelem = list->next;\ - return(sglib_##type##_it_next(it));\ - }\ - type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *list) {\ - return(sglib_##type##_it_init_on_equal(it, list, NULL, NULL));\ - }\ - type *sglib_##type##_it_current(struct sglib_##type##_iterator *it) {\ - return(it->currentelem);\ - }\ - type *sglib_##type##_it_next(struct sglib_##type##_iterator *it) {\ - type *ce, *eq;\ - int (*scp)(type *, type *);\ - ce = it->prevelem;\ - it->prevelem = NULL;\ - if (it->subcomparator != NULL) {\ - eq = it->equalto; \ - scp = it->subcomparator;\ - while (ce!=NULL && scp(eq, ce)!=0) ce = ce->previous;\ - }\ - if (ce != NULL) {\ - it->prevelem = ce->previous;\ - } else {\ - ce = it->nextelem;\ - it->nextelem = NULL;\ - if (it->subcomparator != NULL) {\ - eq = it->equalto; \ - scp = it->subcomparator;\ - while (ce!=NULL && scp(ce, eq)!=0) ce = ce->next;\ - }\ - if (ce != NULL) it->nextelem = ce->next;\ - }\ - it->currentelem = ce;\ - return(ce);\ - } - - -/* --------------------------------- red-black trees (level 1) -------------------------------- */ - -/* - -This implementation requires pointers to left and right sons (no -parent pointer is needed) and one bit of additional information -storing the color of the node. The implementation follows discrepancy -fixing rules from: -http://www.cis.ohio-state.edu/~gurari/course/cis680/cis680Ch11.html - -*/ - -#define SGLIB___RBTREE_FIX_INSERTION_DISCREPANCY(type, tree, leftt, rightt, bits, RED, BLACK) {\ - type *t, *tl, *a, *b, *c, *ar, *bl, *br, *cl, *cr;\ - t = *tree;\ - tl = t->leftt;\ - if (t->rightt!=NULL && SGLIB___GET_VALUE(t->rightt->bits)==RED) {\ - if (SGLIB___GET_VALUE(tl->bits)==RED) {\ - if ((tl->leftt!=NULL && SGLIB___GET_VALUE(tl->leftt->bits)==RED) \ - || (tl->rightt!=NULL && SGLIB___GET_VALUE(tl->rightt->bits)==RED)) {\ - SGLIB___SET_VALUE(t->leftt->bits,BLACK);\ - SGLIB___SET_VALUE(t->rightt->bits,BLACK);\ - SGLIB___SET_VALUE(t->bits,RED);\ - }\ - }\ - } else {\ - if (SGLIB___GET_VALUE(tl->bits)==RED) {\ - if (tl->leftt!=NULL && SGLIB___GET_VALUE(tl->leftt->bits)==RED) {\ - a = t; b = tl; c = tl->leftt;\ - br = b->rightt;\ - a->leftt = br;\ - b->leftt = c; b->rightt = a;\ - SGLIB___SET_VALUE(a->bits,RED);\ - SGLIB___SET_VALUE(b->bits,BLACK);\ - *tree = b;\ - } else if (tl->rightt!=NULL && SGLIB___GET_VALUE(tl->rightt->bits)==RED) {\ - a = t; b = tl; ar=a->rightt;\ - bl=b->leftt; c=b->rightt;\ - cl=c->leftt; cr=c->rightt;\ - b->rightt = cl;\ - a->leftt = cr;\ - c->leftt = b;\ - c->rightt = a;\ - SGLIB___SET_VALUE(c->bits,BLACK);\ - SGLIB___SET_VALUE(a->bits,RED);\ - *tree = c;\ - }\ - }\ - }\ -} - -#define SGLIB___RBTREE_FIX_DELETION_DISCREPANCY(type, tree, leftt, rightt, bits, RED, BLACK, res) {\ - type *t, *a, *b, *c, *d, *ar, *bl, *br, *cl, *cr, *dl, *dr;\ - t = a = *tree;\ - assert(t!=NULL);\ - ar = a->rightt;\ - b = t->leftt;\ - if (b==NULL) {\ - assert(SGLIB___GET_VALUE(t->bits)==RED);\ - SGLIB___SET_VALUE(t->bits,BLACK);\ - res = 0;\ - } else {\ - bl = b->leftt;\ - br = b->rightt;\ - if (SGLIB___GET_VALUE(b->bits)==RED) {\ - if (br==NULL) {\ - *tree = b;\ - SGLIB___SET_VALUE(b->bits,BLACK);\ - b->rightt = a;\ - a->leftt = br;\ - res = 0;\ - } else {\ - c = br;\ - assert(c!=NULL && SGLIB___GET_VALUE(c->bits)==BLACK);\ - cl = c->leftt;\ - cr = c->rightt;\ - if ((cl==NULL||SGLIB___GET_VALUE(cl->bits)==BLACK) && (cr==NULL||SGLIB___GET_VALUE(cr->bits)==BLACK)) {\ - *tree = b;\ - b->rightt = a;\ - SGLIB___SET_VALUE(b->bits,BLACK);\ - a->leftt = c;\ - SGLIB___SET_VALUE(c->bits,RED);\ - res = 0;\ - } else if (cl!=NULL && SGLIB___GET_VALUE(cl->bits)==RED) {\ - if (cr!=NULL && SGLIB___GET_VALUE(cr->bits)==RED) {\ - d = cr;\ - dl = d->leftt;\ - dr = d->rightt;\ - *tree = d;\ - SGLIB___SET_VALUE(d->bits,BLACK);\ - d->leftt = b;\ - c->rightt = dl;\ - d->rightt = a;\ - a->leftt = dr;\ - res = 0;\ - } else {\ - *tree = c;\ - c->leftt = b;\ - c->rightt = a;\ - b->leftt = bl;\ - b->rightt = cl;\ - a->leftt = cr;\ - SGLIB___SET_VALUE(cl->bits,BLACK);\ - res = 0;\ - }\ - } else if (cr!=NULL && SGLIB___GET_VALUE(cr->bits)==RED) {\ - assert(cl==NULL || SGLIB___GET_VALUE(cl->bits)==BLACK);\ - d = cr;\ - dl = d->leftt;\ - dr = d->rightt;\ - *tree = d;\ - SGLIB___SET_VALUE(d->bits,BLACK);\ - d->leftt = b;\ - c->rightt = dl;\ - d->rightt = a;\ - a->leftt = dr;\ - res = 0;\ - } else {\ - assert(0);\ - res = 0;\ - }\ - }\ - } else {\ - if ((bl==NULL || SGLIB___GET_VALUE(bl->bits)==BLACK) && (br==NULL || SGLIB___GET_VALUE(br->bits)==BLACK)) {\ - res = (SGLIB___GET_VALUE(a->bits)==BLACK);\ - SGLIB___SET_VALUE(a->bits,BLACK);\ - SGLIB___SET_VALUE(b->bits,RED);\ - } else if (bl!=NULL && SGLIB___GET_VALUE(bl->bits)==RED) {\ - if (br==NULL || SGLIB___GET_VALUE(br->bits)==BLACK) {\ - *tree = b;\ - SGLIB___SET_VALUE(b->bits,SGLIB___GET_VALUE(a->bits));\ - SGLIB___SET_VALUE(a->bits,BLACK);\ - b->rightt = a;\ - a->leftt = br;\ - SGLIB___SET_VALUE(bl->bits,BLACK);\ - res = 0;\ - } else {\ - assert(bl!=NULL);\ - assert(br!=NULL);\ - assert(SGLIB___GET_VALUE(bl->bits)==RED);\ - assert(SGLIB___GET_VALUE(br->bits)==RED);\ - c = br;\ - cl = c->leftt;\ - cr = c->rightt;\ - *tree = c;\ - SGLIB___SET_VALUE(c->bits,SGLIB___GET_VALUE(a->bits));\ - SGLIB___SET_VALUE(a->bits,BLACK);\ - c->leftt = b;\ - c->rightt = a;\ - b->rightt = cl;\ - a->leftt = cr;\ - res = 0;\ - }\ - } else {\ - assert(br!=NULL && SGLIB___GET_VALUE(br->bits)==RED);\ - c = br;\ - cl = c->leftt;\ - cr = c->rightt;\ - *tree = c;\ - SGLIB___SET_VALUE(c->bits,SGLIB___GET_VALUE(a->bits));\ - SGLIB___SET_VALUE(a->bits,BLACK);\ - c->leftt = b;\ - c->rightt = a;\ - b->rightt = cl;\ - a->leftt = cr;\ - res = 0;\ - }\ - }\ - }\ -} - - -#define SGLIB_DEFINE_RBTREE_FUNCTIONS_GENERAL(type, left, right, bits, comparator, RED, BLACK) \ -static void sglib___##type##_fix_left_insertion_discrepancy(type **tree) {\ - SGLIB___RBTREE_FIX_INSERTION_DISCREPANCY(type, tree, left, right, bits, RED, BLACK);\ -}\ -\ -static void sglib___##type##_fix_right_insertion_discrepancy(type **tree) {\ - SGLIB___RBTREE_FIX_INSERTION_DISCREPANCY(type, tree, right, left, bits, RED, BLACK);\ -}\ -\ -static int sglib___##type##_fix_left_deletion_discrepancy(type **tree) {\ - int res;\ - SGLIB___RBTREE_FIX_DELETION_DISCREPANCY(type, tree, right, left, bits, RED, BLACK, res);\ - return(res);\ -}\ -\ -static int sglib___##type##_fix_right_deletion_discrepancy(type **tree) {\ - int res;\ - SGLIB___RBTREE_FIX_DELETION_DISCREPANCY(type, tree, left, right, bits, RED, BLACK, res);\ - return(res);\ -}\ -\ -static void sglib___##type##_add_recursive(type **tree, type *elem) {\ - int cmp;\ - type *t;\ - t = *tree;\ - if (t == NULL) {\ - SGLIB___SET_VALUE(elem->bits,RED);\ - *tree =elem;\ - } else {\ - cmp = comparator(elem, t);\ - if (cmp < 0 || (cmp==0 && elemleft, elem);\ - if (SGLIB___GET_VALUE(t->bits)==BLACK) sglib___##type##_fix_left_insertion_discrepancy(tree);\ - } else {\ - sglib___##type##_add_recursive(&t->right, elem);\ - if (SGLIB___GET_VALUE(t->bits)==BLACK) sglib___##type##_fix_right_insertion_discrepancy(tree);\ - }\ - }\ -}\ -\ -static int sglib___##type##_delete_rightmost_leaf(type **tree, type **theLeaf) {\ - type *t;\ - int res, deepDecreased;\ - t = *tree;\ - res = 0;\ - assert(t!=NULL);\ - if (t->right == NULL) {\ - *theLeaf = t;\ - if (t->left!=NULL) {\ - if (SGLIB___GET_VALUE(t->bits)==BLACK && SGLIB___GET_VALUE(t->left->bits)==BLACK) res = 1;\ - SGLIB___SET_VALUE(t->left->bits,BLACK);\ - *tree = t->left;\ - } else {\ - *tree = NULL;\ - res = (SGLIB___GET_VALUE(t->bits)==BLACK);\ - }\ - } else {\ - deepDecreased = sglib___##type##_delete_rightmost_leaf(&t->right, theLeaf);\ - if (deepDecreased) res = sglib___##type##_fix_right_deletion_discrepancy(tree);\ - }\ - return(res);\ -}\ -\ -int sglib___##type##_delete_recursive(type **tree, type *elem) {\ - type *t, *theLeaf;\ - int cmp, res, deepDecreased;\ - t = *tree;\ - res = 0;\ - if (t==NULL) {\ - assert(0 && "The element to delete not found in the tree, use 'delete_if_member'"!=NULL);\ - } else {\ - cmp = comparator(elem, t);\ - if (cmp < 0 || (cmp==0 && elemleft, elem);\ - if (deepDecreased) {\ - res = sglib___##type##_fix_left_deletion_discrepancy(tree);\ - }\ - } else if (cmp > 0 || (cmp==0 && elem>t)) {\ - deepDecreased = sglib___##type##_delete_recursive(&t->right, elem);\ - if (deepDecreased) {\ - res = sglib___##type##_fix_right_deletion_discrepancy(tree);\ - }\ - } else {\ - assert(elem==t && "Deleting an element which is non member of the tree, use 'delete_if_member'"!=NULL);\ - if (t->left == NULL) {\ - if (t->right == NULL) {\ - /* a leaf, delete, it; */\ - *tree = NULL;\ - res = (SGLIB___GET_VALUE(t->bits)==BLACK);\ - } else {\ - if (SGLIB___GET_VALUE(t->bits)==0 && SGLIB___GET_VALUE(t->right->bits)==0) res = 1;\ - SGLIB___SET_VALUE(t->right->bits,BLACK);\ - *tree = t->right;\ - }\ - } else {\ - /* propagate deletion until righmost leaf of left subtree */\ - deepDecreased = sglib___##type##_delete_rightmost_leaf(&t->left, &theLeaf);\ - theLeaf->left = t->left;\ - theLeaf->right = t->right;\ - SGLIB___SET_VALUE(theLeaf->bits,SGLIB___GET_VALUE(t->bits));\ - *tree = theLeaf;\ - if (deepDecreased) res = sglib___##type##_fix_left_deletion_discrepancy(tree);\ - }\ - }\ - }\ - return(res);\ -}\ -\ -void sglib_##type##_add(type **tree, type *elem) {\ - elem->left = elem->right = NULL;\ - sglib___##type##_add_recursive(tree, elem);\ - SGLIB___SET_VALUE((*tree)->bits,BLACK);\ -}\ -\ -void sglib_##type##_delete(type **tree, type *elem) {\ - sglib___##type##_delete_recursive(tree, elem);\ - if (*tree!=NULL) SGLIB___SET_VALUE((*tree)->bits,BLACK);\ -}\ -\ -type *sglib_##type##_find_member(type *t, type *elem) {\ - type *res;\ - SGLIB___BIN_TREE_FIND_MEMBER(type, t, elem, left, right, comparator, res);\ - return(res);\ -}\ -\ -int sglib_##type##_is_member(type *t, type *elem) {\ - int cmp;\ - while (t!=NULL) {\ - cmp = comparator(elem, t);\ - if (cmp < 0 || (cmp==0 && elemleft;\ - } else if (cmp > 0 || (cmp==0 && elem>t)) {\ - t = t->right;\ - } else {\ - assert(t == elem);\ - return(1);\ - }\ - }\ - return(0);\ -}\ -\ -int sglib_##type##_delete_if_member(type **tree, type *elem, type **memb) {\ - if ((*memb=sglib_##type##_find_member(*tree, elem))!=NULL) {\ - sglib_##type##_delete(tree, *memb);\ - return(1);\ - } else {\ - return(0);\ - }\ -}\ -int sglib_##type##_add_if_not_member(type **tree, type *elem, type **memb) {\ - if ((*memb=sglib_##type##_find_member(*tree, elem))==NULL) {\ - sglib_##type##_add(tree, elem);\ - return(1);\ - } else {\ - return(0);\ - }\ -}\ -int sglib_##type##_len(type *t) {\ - int n;\ - type *e;\ - n = 0;\ - SGLIB_BIN_TREE_MAP_ON_ELEMENTS(type, t, e, left, right, n++);\ - return(n);\ -}\ -\ -void sglib__##type##_it_compute_current_elem(struct sglib_##type##_iterator *it) {\ - int i,j,cmp;\ - type *s, *eqt;\ - int (*subcomparator)(type *, type *);\ - eqt = it->equalto;\ - subcomparator = it->subcomparator;\ - it->currentelem = NULL;\ - while(it->pathi > 0 && it->currentelem==NULL) {\ - i = it->pathi-1;\ - if (i >= 0) {\ - if (it->pass[i] >= 2) {\ - /* goto up */\ - it->pathi --;\ - } else {\ - if (it->pass[i] == 0) {\ - /* goto left */\ - s = it->path[i]->left;\ - } else {\ - /* goto right */\ - s = it->path[i]->right;\ - }\ - if (eqt != NULL) {\ - if (subcomparator == NULL) {\ - SGLIB___BIN_TREE_FIND_MEMBER(type, s, eqt, left, right, comparator, s);\ - } else {\ - SGLIB___BIN_TREE_FIND_MEMBER(type, s, eqt, left, right, subcomparator, s);\ - }\ - }\ - if (s != NULL) {\ - j = i+1;\ - it->path[j] = s;\ - it->pass[j] = 0;\ - it->pathi ++;\ - }\ - it->pass[i] ++;\ - }\ - }\ - if (it->pathi>0 && it->order == it->pass[it->pathi-1]) {\ - it->currentelem = it->path[it->pathi-1];\ - }\ - }\ -}\ -type *sglib__##type##_it_init(struct sglib_##type##_iterator *it, type *tree, int order, int (*subcomparator)(type *, type *), type *equalto) {\ - type *t;\ - assert(it!=NULL);\ - it->order = order;\ - it->equalto = equalto;\ - it->subcomparator = subcomparator;\ - if (equalto == NULL) { \ - t = tree;\ - } else {\ - if (subcomparator == NULL) {\ - SGLIB___BIN_TREE_FIND_MEMBER(type, tree, equalto, left, right, comparator, t);\ - } else {\ - SGLIB___BIN_TREE_FIND_MEMBER(type, tree, equalto, left, right, subcomparator, t);\ - }\ - }\ - if (t == NULL) {\ - it->pathi = 0;\ - it->currentelem = NULL;\ - } else {\ - it->pathi = 1;\ - it->pass[0] = 0;\ - it->path[0] = t;\ - if (order == 0) {\ - it->currentelem = t;\ - } else {\ - sglib__##type##_it_compute_current_elem(it);\ - }\ - }\ - return(it->currentelem);\ -}\ -type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *tree) {\ - return(sglib__##type##_it_init(it, tree, 2, NULL, NULL));\ -}\ -type *sglib_##type##_it_init_preorder(struct sglib_##type##_iterator *it, type *tree) {\ - return(sglib__##type##_it_init(it, tree, 0, NULL, NULL));\ -}\ -type *sglib_##type##_it_init_inorder(struct sglib_##type##_iterator *it, type *tree) {\ - return(sglib__##type##_it_init(it, tree, 1, NULL, NULL));\ -}\ -type *sglib_##type##_it_init_postorder(struct sglib_##type##_iterator *it, type *tree) {\ - return(sglib__##type##_it_init(it, tree, 2, NULL, NULL));\ -}\ -type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *tree, int (*subcomparator)(type *, type *), type *equalto) {\ - return(sglib__##type##_it_init(it, tree, 1, subcomparator, equalto));\ -}\ -type *sglib_##type##_it_current(struct sglib_##type##_iterator *it) {\ - return(it->currentelem);\ -}\ -type *sglib_##type##_it_next(struct sglib_##type##_iterator *it) {\ - sglib__##type##_it_compute_current_elem(it);\ - return(it->currentelem);\ -}\ -\ -static void sglib___##type##_consistency_check_recursive(type *t, int *pathdeep, int cdeep) {\ - if (t==NULL) {\ - if (*pathdeep < 0) *pathdeep = cdeep;\ - else assert(*pathdeep == cdeep);\ - } else {\ - if (t->left!=NULL) assert(comparator(t->left, t) <= 0);\ - if (t->right!=NULL) assert(comparator(t, t->right) <= 0);\ - if (SGLIB___GET_VALUE(t->bits) == RED) {\ - assert(t->left == NULL || SGLIB___GET_VALUE(t->left->bits)==BLACK);\ - assert(t->right == NULL || SGLIB___GET_VALUE(t->right->bits)==BLACK);\ - sglib___##type##_consistency_check_recursive(t->left, pathdeep, cdeep);\ - sglib___##type##_consistency_check_recursive(t->right, pathdeep, cdeep);\ - } else {\ - sglib___##type##_consistency_check_recursive(t->left, pathdeep, cdeep+1);\ - sglib___##type##_consistency_check_recursive(t->right, pathdeep, cdeep+1);\ - }\ - }\ -}\ -\ -void sglib___##type##_consistency_check(type *t) {\ - int pathDeep;\ - assert(t==NULL || SGLIB___GET_VALUE(t->bits) == BLACK);\ - pathDeep = -1;\ - sglib___##type##_consistency_check_recursive(t, &pathDeep, 0);\ -} - - -#define SGLIB_DEFINE_RBTREE_PROTOTYPES(type, left, right, colorbit, comparator) \ - struct sglib_##type##_iterator {\ - type *currentelem;\ - char pass[SGLIB_MAX_TREE_DEEP];\ - type *path[SGLIB_MAX_TREE_DEEP];\ - short int pathi;\ - short int order;\ - type *equalto;\ - int (*subcomparator)(type *, type *);\ - };\ - extern void sglib___##type##_consistency_check(type *t); \ - extern void sglib_##type##_add(type **tree, type *elem); \ - extern int sglib_##type##_add_if_not_member(type **tree, type *elem, type **memb); \ - extern void sglib_##type##_delete(type **tree, type *elem); \ - extern int sglib_##type##_delete_if_member(type **tree, type *elem, type **memb); \ - extern int sglib_##type##_is_member(type *t, type *elem); \ - extern type *sglib_##type##_find_member(type *t, type *elem); \ - extern int sglib_##type##_len(type *t); \ - extern type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *tree); \ - extern type *sglib_##type##_it_init_preorder(struct sglib_##type##_iterator *it, type *tree); \ - extern type *sglib_##type##_it_init_inorder(struct sglib_##type##_iterator *it, type *tree); \ - extern type *sglib_##type##_it_init_postorder(struct sglib_##type##_iterator *it, type *tree); \ - extern type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *tree, int (*subcomparator)(type *, type *), type *equalto); \ - extern type *sglib_##type##_it_current(struct sglib_##type##_iterator *it); \ - extern type *sglib_##type##_it_next(struct sglib_##type##_iterator *it); \ - - -#define SGLIB_DEFINE_RBTREE_FUNCTIONS(type, left, right, colorbit, comparator) \ - SGLIB_DEFINE_RBTREE_FUNCTIONS_GENERAL(type, left, right, colorbit, comparator, 1, 0) - - - -/* ---------------------------------------------------------------------------- */ -/* ---------------------------------------------------------------------------- */ -/* - SUPPLEMENTARY DEFINITIONS - */ -/* ---------------------------------------------------------------------------- */ -/* ---------------------------------------------------------------------------- */ - - -#define SGLIB___GET_VALUE(x) (x) -#define SGLIB___SET_VALUE(x, value) {(x) = (value);} -#define SGLIB_ARRAY_ELEMENTS_EXCHANGER(type, a, i, j) {type _sgl_aee_tmp_; _sgl_aee_tmp_=(a)[(i)]; (a)[(i)]=(a)[(j)]; (a)[(j)]= _sgl_aee_tmp_;} - - -#define SGLIB_SAFE_NUMERIC_COMPARATOR(x, y) (((x)>(y)?1:((x)<(y)?-1:0))) -#define SGLIB_SAFE_REVERSE_NUMERIC_COMPARATOR(x, y) (((x)>(y)?-1:((x)<(y)?1:0))) -#define SGLIB_FAST_NUMERIC_COMPARATOR(x, y) ((int)((x) - (y))) -#define SGLIB_FAST_REVERSE_NUMERIC_COMPARATOR(x, y) ((int)((y) - (x))) -#define SGLIB_NUMERIC_COMPARATOR(x, y) SGLIB_SAFE_NUMERIC_COMPARATOR(x, y) -#define SGLIB_REVERSE_NUMERIC_COMPARATOR(x, y) SGLIB_SAFE_REVERSE_NUMERIC_COMPARATOR(x, y) - -#ifndef SGLIB_MAX_TREE_DEEP -#define SGLIB_MAX_TREE_DEEP 128 -#endif - -#ifndef SGLIB_HASH_TAB_SHIFT_CONSTANT -#define SGLIB_HASH_TAB_SHIFT_CONSTANT 16381 /* should be a prime */ -/* #define SGLIB_HASH_TAB_SHIFT_CONSTANT 536870912*/ /* for large tables :) */ -#endif - -#endif /* _SGLIB__h_ */ diff --git a/src/sglib-dllist/Makefile.am b/src/sglib-dllist/Makefile.am index 6b608b64..dfee8419 100644 --- a/src/sglib-dllist/Makefile.am +++ b/src/sglib-dllist/Makefile.am @@ -34,7 +34,8 @@ libsglib_dllist_la_SOURCES = dllist.c sglib.h sglib_dllist_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libsglib-dllist.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) diff --git a/src/sglib-dllist/Makefile.in b/src/sglib-dllist/Makefile.in index 32904399..281de4c7 100644 --- a/src/sglib-dllist/Makefile.in +++ b/src/sglib-dllist/Makefile.in @@ -173,6 +173,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_SGLIB_DLLIST_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_SGLIB_DLLIST_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_SGLIB_DLLIST_TRUE@ libsglib-dllist.la \ +@ENABLED_BENCHMARK_SGLIB_DLLIST_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_SGLIB_DLLIST_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_SGLIB_DLLIST_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_SGLIB_DLLIST_TRUE@ $(am__DEPENDENCIES_1) @@ -396,7 +397,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_SGLIB_DLLIST_TRUE@sglib_dllist_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_SGLIB_DLLIST_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_SGLIB_DLLIST_TRUE@ libsglib-dllist.la \ -@ENABLED_BENCHMARK_SGLIB_DLLIST_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_SGLIB_DLLIST_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_SGLIB_DLLIST_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/sglib-dllist/dllist.c b/src/sglib-dllist/dllist.c index e00ec219..3c85168f 100644 --- a/src/sglib-dllist/dllist.c +++ b/src/sglib-dllist/dllist.c @@ -1,5 +1,3 @@ - - /* BEEBS dllist benchmark Copyright (C) 2014 Embecosm Limited and University of Bristol @@ -31,7 +29,7 @@ /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) +#define LOCAL_SCALE_FACTOR 225 typedef struct dllist { int i; @@ -53,105 +51,62 @@ int array[100] = {14, 66, 12, 41, 86, 69, 19, 77, 68, 38, 26, 42, 37, 23, 17, 29 /* BEEBS heap is just an array */ -#include - #define HEAP_SIZE 8192 static char heap[HEAP_SIZE]; -static void *heap_ptr; -static void *heap_end; - -/* Initialize the BEEBS heap pointers */ - -static void -init_heap (void) -{ - heap_ptr = (void *) heap; - heap_end = heap_ptr + HEAP_SIZE; -} - -/* BEEBS version of malloc. - - This is primarily to reduce library and OS dependencies. Malloc is - generally not used in embedded code, or if it is, only in well defined - contexts to pre-allocate a fixed amount of memory. So this simplistic - implementation is just fine. */ -static void * -malloc_beebs (size_t size) -{ - void *new_ptr = heap_ptr; - - if (((heap_ptr + size) > heap_end) || (0 == size)) - return NULL; - else - { - heap_ptr += size; - return new_ptr; - } -} +dllist *the_list; -/* BEEBS version of free. - - For our simplified version of memory handling, free can just do nothing. */ - -static void -free_beebs (void *ptr) +int +verify_benchmark (int res) { -} + dllist *l; + int i = 0; -/* This benchmark does not support verification */ + for(l=sglib_dllist_get_first(the_list); l!=NULL; l=l->ptr_to_next) + { + if (l->i != i) + return 0; + i++; + } -int -verify_benchmark (int res __attribute ((unused)) ) -{ - return -1; + return (100 == res) && check_heap_beebs ((void *) heap); } void initialise_benchmark (void) { - init_heap (); } int benchmark() { - volatile int cnt=0; - dllist *l, *last, *the_list; - struct sglib_dllist_iterator it; - int i; + volatile int cnt; + int i; - the_list = NULL; - for(i = 0 ;i<100; ++i) - { - l = malloc_beebs(sizeof(dllist)); - l->i = array[i]; - sglib_dllist_add(&the_list, l); - } + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + { + dllist *l; + int i; - sglib_dllist_sort(&the_list); + init_heap_beebs ((void *) heap, HEAP_SIZE); + the_list = NULL; - last = sglib_dllist_get_first(the_list); - for(l=sglib_dllist_get_first(the_list); l!=NULL; l=l->ptr_to_next) - { - l->i = last->i; - last = l; - } + for(i = 0 ;i<100; ++i) + { + l = malloc_beebs(sizeof(dllist)); + l->i = array[i]; + sglib_dllist_add(&the_list, l); + } - for(l=sglib_dllist_get_last(the_list); l!=NULL; l=l->ptr_to_previous) - { - l->i = last->i; - last = l; - } + sglib_dllist_sort(&the_list); - for(l=sglib_dllist_it_init(&it,the_list); l!=NULL; l=sglib_dllist_it_next(&it)) - { - cnt += l->i; - free_beebs(l); - } + cnt = 0; + + for(l=sglib_dllist_get_first(the_list); l!=NULL; l=l->ptr_to_next) + cnt++; + } return cnt; } - diff --git a/src/sglib-hashtable/Makefile.am b/src/sglib-hashtable/Makefile.am index 08b962bc..82ecc28b 100644 --- a/src/sglib-hashtable/Makefile.am +++ b/src/sglib-hashtable/Makefile.am @@ -34,7 +34,8 @@ libsglib_hashtable_la_SOURCES = hashtable.c sglib.h sglib_hashtable_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libsglib-hashtable.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) diff --git a/src/sglib-hashtable/Makefile.in b/src/sglib-hashtable/Makefile.in index e216c876..1499d2fd 100644 --- a/src/sglib-hashtable/Makefile.in +++ b/src/sglib-hashtable/Makefile.in @@ -172,6 +172,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_SGLIB_HASHTABLE_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_SGLIB_HASHTABLE_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_SGLIB_HASHTABLE_TRUE@ libsglib-hashtable.la \ +@ENABLED_BENCHMARK_SGLIB_HASHTABLE_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_SGLIB_HASHTABLE_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_SGLIB_HASHTABLE_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_SGLIB_HASHTABLE_TRUE@ $(am__DEPENDENCIES_1) @@ -395,7 +396,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_SGLIB_HASHTABLE_TRUE@sglib_hashtable_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_SGLIB_HASHTABLE_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_SGLIB_HASHTABLE_TRUE@ libsglib-hashtable.la \ -@ENABLED_BENCHMARK_SGLIB_HASHTABLE_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_SGLIB_HASHTABLE_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_SGLIB_HASHTABLE_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/sglib-hashtable/hashtable.c b/src/sglib-hashtable/hashtable.c index 33ca17b4..4ce2abf9 100644 --- a/src/sglib-hashtable/hashtable.c +++ b/src/sglib-hashtable/hashtable.c @@ -27,7 +27,7 @@ /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) +#define LOCAL_SCALE_FACTOR 289 #define HASH_TAB_SIZE 20 @@ -59,97 +59,66 @@ int array[100] = {14, 66, 12, 41, 86, 69, 19, 77, 68, 38, 26, 42, 37, 23, 17, 29 /* BEEBS heap is just an array */ -#include - #define HEAP_SIZE 8192 static char heap[HEAP_SIZE]; -static void *heap_ptr; -static void *heap_end; -/* Initialize the BEEBS heap pointers */ -static void -init_heap (void) +int +verify_benchmark (int res) { - heap_ptr = (void *) heap; - heap_end = heap_ptr + HEAP_SIZE; -} - -/* BEEBS version of malloc. + int i; + struct ilist ii, *nn; - This is primarily to reduce library and OS dependencies. Malloc is - generally not used in embedded code, or if it is, only in well defined - contexts to pre-allocate a fixed amount of memory. So this simplistic - implementation is just fine. */ - -static void * -malloc_beebs (size_t size) -{ - void *new_ptr = heap_ptr; - - if (((heap_ptr + size) > heap_end) || (0 == size)) - return NULL; - else - { - heap_ptr += size; - return new_ptr; - } -} - -/* BEEBS version of free. - - For our simplified version of memory handling, free can just do nothing. */ - -static void -free_beebs (void *ptr) -{ -} + for (i=0; i<100; i++) { + ii.i = array[i]; + nn = sglib_hashed_ilist_find_member(htab, &ii); -/* This benchmark does not support verification */ + if ((nn == NULL) || (nn->i != array[i])) + return 0; + } -int -verify_benchmark (int res __attribute ((unused)) ) -{ - return -1; + return (100 == res) && check_heap_beebs ((void *) heap); } void initialise_benchmark (void) { - init_heap (); } int benchmark() { - int i; - struct ilist ii, *nn, *ll, *last; - struct sglib_hashed_ilist_iterator it; - volatile int cnt = 0; + volatile int cnt; + int j; + + for (j = 0; j < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); j++) + { + int i; + struct ilist ii, *nn, *ll; + struct sglib_hashed_ilist_iterator it; + + init_heap_beebs ((void *) heap, HEAP_SIZE); + sglib_hashed_ilist_init(htab); + + for (i=0; i<100; i++) { + ii.i = array[i]; + if (sglib_hashed_ilist_find_member(htab, &ii) == NULL) { + nn = malloc_beebs(sizeof(struct ilist)); + nn->i = array[i]; + sglib_hashed_ilist_add(htab, nn); + } + } - sglib_hashed_ilist_init(htab); + cnt = 0; - for (i=0; i<100; i++) { - ii.i = array[i]; - if (sglib_hashed_ilist_find_member(htab, &ii) == NULL) { - nn = malloc_beebs(sizeof(struct ilist)); - nn->i = array[i]; - sglib_hashed_ilist_add(htab, nn); + for(ll=sglib_hashed_ilist_it_init(&it,htab); + ll!=NULL; + ll=sglib_hashed_ilist_it_next(&it)) { + cnt++; + } } - } - - last=sglib_hashed_ilist_it_init(&it,htab); - for(ll=sglib_hashed_ilist_it_init(&it,htab); ll!=NULL; ll=sglib_hashed_ilist_it_next(&it)) { - ll->i = last->i; - last = ll; - } - - for(ll=sglib_hashed_ilist_it_init(&it,htab); ll!=NULL; ll=sglib_hashed_ilist_it_next(&it)) { - cnt += ll->i; - free_beebs(ll); - } return cnt; } diff --git a/src/sglib-listinsertsort/Makefile.am b/src/sglib-listinsertsort/Makefile.am index 54313d9f..12ff2e47 100644 --- a/src/sglib-listinsertsort/Makefile.am +++ b/src/sglib-listinsertsort/Makefile.am @@ -39,7 +39,8 @@ libsglib_listinsertsort_la_SOURCES = listinsertsort.c sglib.h sglib_listinsertsort_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libsglib-listinsertsort.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) diff --git a/src/sglib-listinsertsort/Makefile.in b/src/sglib-listinsertsort/Makefile.in index bb278a1d..fb98a9db 100644 --- a/src/sglib-listinsertsort/Makefile.in +++ b/src/sglib-listinsertsort/Makefile.in @@ -175,6 +175,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_SGLIB_LISTINSERTSORT_TRUE@sglib_listinsertsort_DEPENDENCIES = $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_SGLIB_LISTINSERTSORT_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_SGLIB_LISTINSERTSORT_TRUE@ libsglib-listinsertsort.la \ +@ENABLED_BENCHMARK_SGLIB_LISTINSERTSORT_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_SGLIB_LISTINSERTSORT_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_SGLIB_LISTINSERTSORT_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_SGLIB_LISTINSERTSORT_TRUE@ $(am__DEPENDENCIES_1) @@ -399,7 +400,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_SGLIB_LISTINSERTSORT_TRUE@sglib_listinsertsort_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_SGLIB_LISTINSERTSORT_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_SGLIB_LISTINSERTSORT_TRUE@ libsglib-listinsertsort.la \ -@ENABLED_BENCHMARK_SGLIB_LISTINSERTSORT_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_SGLIB_LISTINSERTSORT_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_SGLIB_LISTINSERTSORT_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/sglib-listinsertsort/listinsertsort.c b/src/sglib-listinsertsort/listinsertsort.c index ef14d719..122bd5b4 100644 --- a/src/sglib-listinsertsort/listinsertsort.c +++ b/src/sglib-listinsertsort/listinsertsort.c @@ -28,7 +28,7 @@ /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) +#define LOCAL_SCALE_FACTOR 135 int array[100] = {14, 66, 12, 41, 86, 69, 19, 77, 68, 38, 26, 42, 37, 23, 17, 29, 55, 13, @@ -49,90 +49,67 @@ SGLIB_DEFINE_SORTED_LIST_FUNCTIONS(iListType, ILIST_COMPARATOR, next_ptr) /* BEEBS heap is just an array */ -#include - #define HEAP_SIZE 8192 static char heap[HEAP_SIZE]; -static void *heap_ptr; -static void *heap_end; -/* Initialize the BEEBS heap pointers */ -static void -init_heap (void) +void +initialise_benchmark (void) { - heap_ptr = (void *) heap; - heap_end = heap_ptr + HEAP_SIZE; } -/* BEEBS version of malloc. - This is primarily to reduce library and OS dependencies. Malloc is - generally not used in embedded code, or if it is, only in well defined - contexts to pre-allocate a fixed amount of memory. So this simplistic - implementation is just fine. */ +struct ilist *the_list; -static void * -malloc_beebs (size_t size) +int benchmark() { - void *new_ptr = heap_ptr; - - if (((heap_ptr + size) > heap_end) || (0 == size)) - return NULL; - else + volatile int cnt; + int j; + + for (j = 0; j < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); j++) + { + int i; + struct ilist *l; + struct sglib_iListType_iterator it; + + init_heap_beebs ((void *) heap, HEAP_SIZE); + the_list = NULL; + for (i = 0; i < 100; i++) { + l = malloc_beebs (sizeof (struct ilist)); + l->i = array [i]; + + /* Insert the new element into the list while keeping it sorted. */ + sglib_iListType_add (&the_list, l); + } + + cnt = 0; + + for (l = sglib_iListType_it_init (&it, the_list); + l != NULL; + l = sglib_iListType_it_next (&it)) { - heap_ptr += size; - return new_ptr; + cnt++; } -} - -/* BEEBS version of free. + } - For our simplified version of memory handling, free can just do nothing. */ - -static void -free_beebs (void *ptr) -{ -} - -void -initialise_benchmark (void) -{ - init_heap (); + return cnt; } - -int benchmark() -{ - int i; - struct ilist *l, *the_list; +int verify_benchmark(int r) { + struct ilist *l; struct sglib_iListType_iterator it; - int cnt = 0; + int i = 0; - the_list = NULL; - for (i = 1; i < 100; i++) { - l = malloc_beebs (sizeof (struct ilist)); - l->i = array [i]; + for (l = sglib_iListType_it_init (&it, the_list); + l != NULL; + l = sglib_iListType_it_next (&it)) + { + if (l->i != i) + return 0; - /* Insert the new element into the list while keeping it sorted. */ - sglib_iListType_add (&the_list, l); - } + i++; + } - for (l = sglib_iListType_it_init (&it, the_list); l != NULL; l = sglib_iListType_it_next (&it)) { - cnt += l->i; - } - - for(l = sglib_iListType_it_init (&it, the_list); l != NULL; l = sglib_iListType_it_next (&it)) { - free_beebs (l); - } - - return cnt; -} - -int verify_benchmark(int r) { - int expected = 4936; - if (r != expected) - return 0; - return 1; + return (100 == r) && check_heap_beebs ((void *) heap); } diff --git a/src/sglib-listsort/Makefile.am b/src/sglib-listsort/Makefile.am index 5fc6cc66..7a8d93ff 100644 --- a/src/sglib-listsort/Makefile.am +++ b/src/sglib-listsort/Makefile.am @@ -34,7 +34,8 @@ libsglib_listsort_la_SOURCES = listsort.c sglib.h sglib_listsort_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libsglib-listsort.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) diff --git a/src/sglib-listsort/Makefile.in b/src/sglib-listsort/Makefile.in index 84e0cbe0..a51093eb 100644 --- a/src/sglib-listsort/Makefile.in +++ b/src/sglib-listsort/Makefile.in @@ -172,6 +172,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_SGLIB_LISTSORT_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_SGLIB_LISTSORT_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_SGLIB_LISTSORT_TRUE@ libsglib-listsort.la \ +@ENABLED_BENCHMARK_SGLIB_LISTSORT_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_SGLIB_LISTSORT_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_SGLIB_LISTSORT_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_SGLIB_LISTSORT_TRUE@ $(am__DEPENDENCIES_1) @@ -395,7 +396,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_SGLIB_LISTSORT_TRUE@sglib_listsort_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_SGLIB_LISTSORT_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_SGLIB_LISTSORT_TRUE@ libsglib-listsort.la \ -@ENABLED_BENCHMARK_SGLIB_LISTSORT_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_SGLIB_LISTSORT_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_SGLIB_LISTSORT_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/sglib-listsort/listsort.c b/src/sglib-listsort/listsort.c index 7e677df9..50637678 100644 --- a/src/sglib-listsort/listsort.c +++ b/src/sglib-listsort/listsort.c @@ -27,7 +27,7 @@ /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) +#define LOCAL_SCALE_FACTOR 246 struct ilist { @@ -45,90 +45,59 @@ int array[100] = {14, 66, 12, 41, 86, 69, 19, 77, 68, 38, 26, 42, 37, 23, 17, 29 /* BEEBS heap is just an array */ -#include - #define HEAP_SIZE 8192 static char heap[HEAP_SIZE]; -static void *heap_ptr; -static void *heap_end; -/* Initialize the BEEBS heap pointers */ -static void -init_heap (void) +void +initialise_benchmark (void) { - heap_ptr = (void *) heap; - heap_end = heap_ptr + HEAP_SIZE; } -/* BEEBS version of malloc. - - This is primarily to reduce library and OS dependencies. Malloc is - generally not used in embedded code, or if it is, only in well defined - contexts to pre-allocate a fixed amount of memory. So this simplistic - implementation is just fine. */ - -static void * -malloc_beebs (size_t size) -{ - void *new_ptr = heap_ptr; - - if (((heap_ptr + size) > heap_end) || (0 == size)) - return NULL; - else - { - heap_ptr += size; - return new_ptr; - } -} -/* BEEBS version of free. +struct ilist *the_list; - For our simplified version of memory handling, free can just do nothing. */ -static void -free_beebs (void *ptr) +int benchmark() { -} + volatile int cnt; + int j; + + for (j = 0; j < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); j++) + { + int i; + struct ilist *l; + + init_heap_beebs ((void *) heap, HEAP_SIZE); + the_list = NULL; + + for (i=0; i<100; i++) { + l = malloc_beebs(sizeof(struct ilist)); + l->i = array[i]; + SGLIB_LIST_ADD(struct ilist, the_list, l, next_ptr); + } + // it is useless, but anyway, get parameters in the right order + SGLIB_LIST_REVERSE(struct ilist, the_list, next_ptr); + // now sort them + SGLIB_LIST_SORT(struct ilist, the_list, ILIST_COMPARATOR, next_ptr); + // Count the list + cnt = 0; + + SGLIB_LIST_MAP_ON_ELEMENTS(struct ilist, the_list, ll, next_ptr, { + cnt++; + }); + } -void -initialise_benchmark (void) -{ - init_heap (); + return cnt; } - -int benchmark() +int verify_benchmark(int r) { - int i; - struct ilist *l, *the_list; - int cnt = 0; - - the_list = NULL; - for (i=0; i<100; i++) { - l = malloc_beebs(sizeof(struct ilist)); - l->i = array[i]; - SGLIB_LIST_ADD(struct ilist, the_list, l, next_ptr); - } - // it is useless, but anyway, get parameters in the right order - SGLIB_LIST_REVERSE(struct ilist, the_list, next_ptr); - // now sort them - SGLIB_LIST_SORT(struct ilist, the_list, ILIST_COMPARATOR, next_ptr); - // print the list - SGLIB_LIST_MAP_ON_ELEMENTS(struct ilist, the_list, ll, next_ptr, { - cnt += ll->i; - }); - // free all + int i = 0; + SGLIB_LIST_MAP_ON_ELEMENTS(struct ilist, the_list, ll, next_ptr, { - free_beebs(ll); - }); - return cnt; -} + if (i != ll->i) return 0; i++;}); -int verify_benchmark(int r) { - int expected = 4950; - if (r != expected) - return 0; - return 1; + return (100 == r) && check_heap_beebs ((void *) heap); } diff --git a/src/sglib-queue/Makefile.am b/src/sglib-queue/Makefile.am index 031751c6..66aa610b 100644 --- a/src/sglib-queue/Makefile.am +++ b/src/sglib-queue/Makefile.am @@ -34,7 +34,8 @@ libsglib_queue_la_SOURCES = queue.c sglib.h sglib_queue_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libsglib-queue.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) diff --git a/src/sglib-queue/Makefile.in b/src/sglib-queue/Makefile.in index a6d8d095..fb6799b8 100644 --- a/src/sglib-queue/Makefile.in +++ b/src/sglib-queue/Makefile.in @@ -173,6 +173,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_SGLIB_QUEUE_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_SGLIB_QUEUE_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_SGLIB_QUEUE_TRUE@ libsglib-queue.la \ +@ENABLED_BENCHMARK_SGLIB_QUEUE_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_SGLIB_QUEUE_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_SGLIB_QUEUE_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_SGLIB_QUEUE_TRUE@ $(am__DEPENDENCIES_1) @@ -396,7 +397,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_SGLIB_QUEUE_TRUE@sglib_queue_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_SGLIB_QUEUE_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_SGLIB_QUEUE_TRUE@ libsglib-queue.la \ -@ENABLED_BENCHMARK_SGLIB_QUEUE_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_SGLIB_QUEUE_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_SGLIB_QUEUE_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/sglib-queue/queue.c b/src/sglib-queue/queue.c index 4d3eda67..2d81ba24 100644 --- a/src/sglib-queue/queue.c +++ b/src/sglib-queue/queue.c @@ -1,4 +1,3 @@ - /* BEEBS queue benchmark Copyright (C) 2014 Embecosm Limited and University of Bristol @@ -28,7 +27,7 @@ /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) +#define LOCAL_SCALE_FACTOR 133 #define MAX_PARAMS 101 @@ -50,39 +49,41 @@ initialise_benchmark (void) int benchmark() { - int i, ai,aj, n; - int a[MAX_PARAMS]; - int cnt = 0; - - // echo parameters using a queue - SGLIB_QUEUE_INIT(int, a, ai, aj); - for (i=0; i<100; i++) { - n = array[i]; - SGLIB_QUEUE_ADD(int, a, n, ai, aj, MAX_PARAMS); - } - while(! SGLIB_QUEUE_IS_EMPTY(int, a, ai, aj)) { - cnt += SGLIB_QUEUE_FIRST_ELEMENT(int, a, ai, aj); - SGLIB_QUEUE_DELETE(int, a, ai, aj, MAX_PARAMS); - } - - // print parameters in descending order - SGLIB_HEAP_INIT(int, a, ai); - for (i=0; i<100; i++) { - n = array[i]; - SGLIB_HEAP_ADD(int, a, n, ai, MAX_PARAMS, SGLIB_NUMERIC_COMPARATOR); - } - while(! SGLIB_HEAP_IS_EMPTY(int, a, ai)) { - cnt += SGLIB_HEAP_FIRST_ELEMENT(int, a, ai); - SGLIB_HEAP_DELETE(int, a, ai, MAX_PARAMS, SGLIB_NUMERIC_COMPARATOR); - } - + volatile int cnt; + int j; + + for (j = 0; j < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); j++) + { + int i, ai,aj, n; + int a[MAX_PARAMS]; + cnt = 0; + + // echo parameters using a queue + SGLIB_QUEUE_INIT(int, a, ai, aj); + for (i=0; i<100; i++) { + n = array[i]; + SGLIB_QUEUE_ADD(int, a, n, ai, aj, MAX_PARAMS); + } + while(! SGLIB_QUEUE_IS_EMPTY(int, a, ai, aj)) { + cnt += SGLIB_QUEUE_FIRST_ELEMENT(int, a, ai, aj); + SGLIB_QUEUE_DELETE(int, a, ai, aj, MAX_PARAMS); + } + + // print parameters in descending order + SGLIB_HEAP_INIT(int, a, ai); + for (i=0; i<100; i++) { + n = array[i]; + SGLIB_HEAP_ADD(int, a, n, ai, MAX_PARAMS, SGLIB_NUMERIC_COMPARATOR); + } + while(! SGLIB_HEAP_IS_EMPTY(int, a, ai)) { + cnt += SGLIB_HEAP_FIRST_ELEMENT(int, a, ai); + SGLIB_HEAP_DELETE(int, a, ai, MAX_PARAMS, SGLIB_NUMERIC_COMPARATOR); + } + } return cnt; } int verify_benchmark(int r) { - int expected = 9900; - if (r != expected) - return 0; - return 1; + return 9900 == r; } diff --git a/src/sglib-rbtree/Makefile.am b/src/sglib-rbtree/Makefile.am index bb34c5c8..4c4d3f65 100644 --- a/src/sglib-rbtree/Makefile.am +++ b/src/sglib-rbtree/Makefile.am @@ -34,7 +34,8 @@ libsglib_rbtree_la_SOURCES = rbtree.c sglib.h sglib_rbtree_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libsglib-rbtree.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) diff --git a/src/sglib-rbtree/Makefile.in b/src/sglib-rbtree/Makefile.in index 2a0888ce..21813110 100644 --- a/src/sglib-rbtree/Makefile.in +++ b/src/sglib-rbtree/Makefile.in @@ -173,6 +173,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_SGLIB_RBTREE_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_SGLIB_RBTREE_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_SGLIB_RBTREE_TRUE@ libsglib-rbtree.la \ +@ENABLED_BENCHMARK_SGLIB_RBTREE_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_SGLIB_RBTREE_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_SGLIB_RBTREE_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_SGLIB_RBTREE_TRUE@ $(am__DEPENDENCIES_1) @@ -396,7 +397,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_SGLIB_RBTREE_TRUE@sglib_rbtree_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_SGLIB_RBTREE_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_SGLIB_RBTREE_TRUE@ libsglib-rbtree.la \ -@ENABLED_BENCHMARK_SGLIB_RBTREE_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_SGLIB_RBTREE_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_SGLIB_RBTREE_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/sglib-rbtree/rbtree.c b/src/sglib-rbtree/rbtree.c index 2744f2e8..703c371f 100644 --- a/src/sglib-rbtree/rbtree.c +++ b/src/sglib-rbtree/rbtree.c @@ -28,7 +28,7 @@ /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) +#define LOCAL_SCALE_FACTOR 85 typedef struct rbtree { @@ -51,91 +51,51 @@ int array[100] = {14, 66, 12, 41, 86, 69, 19, 77, 68, 38, 26, 42, 37, 23, 17, 29 /* BEEBS heap is just an array */ -#include - #define HEAP_SIZE 8192 static char heap[HEAP_SIZE]; -static void *heap_ptr; -static void *heap_end; - -/* Initialize the BEEBS heap pointers */ - -static void -init_heap (void) -{ - heap_ptr = (void *) heap; - heap_end = heap_ptr + HEAP_SIZE; -} - -/* BEEBS version of malloc. - - This is primarily to reduce library and OS dependencies. Malloc is - generally not used in embedded code, or if it is, only in well defined - contexts to pre-allocate a fixed amount of memory. So this simplistic - implementation is just fine. */ - -static void * -malloc_beebs (size_t size) -{ - void *new_ptr = heap_ptr; - - if (((heap_ptr + size) > heap_end) || (0 == size)) - return NULL; - else - { - heap_ptr += size; - return new_ptr; - } -} -/* BEEBS version of free. - - For our simplified version of memory handling, free can just do nothing. */ - -static void -free_beebs (void *ptr) -{ -} void initialise_benchmark (void) { - init_heap (); } - int benchmark() { - int i; - struct rbtree e, *t, *the_tree, *te; - struct sglib_rbtree_iterator it; - int cnt = 0; - - the_tree = NULL; - for (i=0; i<100; i++) { - e.n = array[i]; - if (sglib_rbtree_find_member(the_tree, &e)==NULL) { - t = malloc_beebs(sizeof(struct rbtree)); - t->n = array[i]; - sglib_rbtree_add(&the_tree, t); - } - } - - for(te=sglib_rbtree_it_init_inorder(&it,the_tree); te!=NULL; te=sglib_rbtree_it_next(&it)) { - cnt += te->n; - } + volatile int cnt; + int j; + + for (j = 0; j < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); j++) + { + int i; + struct rbtree e, *t, *the_tree, *te; + struct sglib_rbtree_iterator it; + cnt = 0; + + init_heap_beebs ((void *) heap, HEAP_SIZE); + the_tree = NULL; + for (i=0; i<100; i++) { + e.n = array[i]; + if (sglib_rbtree_find_member(the_tree, &e)==NULL) { + t = malloc_beebs(sizeof(struct rbtree)); + t->n = array[i]; + sglib_rbtree_add(&the_tree, t); + } + } - for(te=sglib_rbtree_it_init(&it,the_tree); te!=NULL; te=sglib_rbtree_it_next(&it)) { - free_beebs(te); - } + for(te=sglib_rbtree_it_init_inorder(&it,the_tree); + te!=NULL; + te=sglib_rbtree_it_next(&it)) + { + cnt += te->n; + } + } return cnt; } + int verify_benchmark(int r) { - int expected = 4950; - if (r != expected) - return 0; - return 1; + return (4950 == r) && check_heap_beebs ((void *) heap); } diff --git a/src/slre/Makefile.am b/src/slre/Makefile.am index f58d004e..adbfaf43 100644 --- a/src/slre/Makefile.am +++ b/src/slre/Makefile.am @@ -34,7 +34,8 @@ libslre_la_SOURCES = libslre.c slre.h slre_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libslre.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) diff --git a/src/slre/Makefile.in b/src/slre/Makefile.in index 034a4102..9a38c66b 100644 --- a/src/slre/Makefile.in +++ b/src/slre/Makefile.in @@ -170,7 +170,9 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_SLRE_TRUE@slre_DEPENDENCIES = \ @ENABLED_BENCHMARK_SLRE_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_SLRE_TRUE@ $(top_builddir)/support/libsupport.la \ -@ENABLED_BENCHMARK_SLRE_TRUE@ libslre.la $(am__DEPENDENCIES_1) \ +@ENABLED_BENCHMARK_SLRE_TRUE@ libslre.la \ +@ENABLED_BENCHMARK_SLRE_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_SLRE_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_SLRE_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_SLRE_TRUE@ $(am__DEPENDENCIES_1) AM_V_P = $(am__v_P_@AM_V@) @@ -392,7 +394,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_SLRE_TRUE@slre_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_SLRE_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_SLRE_TRUE@ libslre.la \ -@ENABLED_BENCHMARK_SLRE_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_SLRE_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_SLRE_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/slre/libslre.c b/src/slre/libslre.c index d70394b5..c29b06d8 100644 --- a/src/slre/libslre.c +++ b/src/slre/libslre.c @@ -1,4 +1,3 @@ - /* BEEBS slre benchmark Copyright (c) 2004-2013 Sergey Lyubka @@ -27,7 +26,7 @@ /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) +#define LOCAL_SCALE_FACTOR 131 #include #include @@ -462,25 +461,28 @@ initialise_benchmark (void) } - int benchmark() { - int i; - int len = strlen(text); - struct slre_cap captures; - volatile int ret=0; - - for(i = 0; i < 4; ++i) - { - ret += slre_match(regexes[i], text, len, &captures, 1); - } + volatile int ret; + int j; + + for (j = 0; j < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); j++) + { + int i; + int len = strlen(text); + struct slre_cap captures; + ret=0; + + for(i = 0; i < 4; ++i) + { + ret += slre_match(regexes[i], text, len, &captures, 1); + } + } return ret; } + int verify_benchmark(int r) { - int expected = 102; - if (r != expected) - return 0; - return 1; + return 102 == r; } diff --git a/src/sqrt/Makefile.am b/src/sqrt/Makefile.am index 350946f0..7dfb3292 100644 --- a/src/sqrt/Makefile.am +++ b/src/sqrt/Makefile.am @@ -34,7 +34,8 @@ libsqrt_la_SOURCES = libsqrt.c sqrt_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libsqrt.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) diff --git a/src/sqrt/Makefile.in b/src/sqrt/Makefile.in index f1c30424..567c5f34 100644 --- a/src/sqrt/Makefile.in +++ b/src/sqrt/Makefile.in @@ -170,7 +170,9 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_SQRT_TRUE@sqrt_DEPENDENCIES = \ @ENABLED_BENCHMARK_SQRT_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_SQRT_TRUE@ $(top_builddir)/support/libsupport.la \ -@ENABLED_BENCHMARK_SQRT_TRUE@ libsqrt.la $(am__DEPENDENCIES_1) \ +@ENABLED_BENCHMARK_SQRT_TRUE@ libsqrt.la \ +@ENABLED_BENCHMARK_SQRT_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_SQRT_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_SQRT_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_SQRT_TRUE@ $(am__DEPENDENCIES_1) AM_V_P = $(am__v_P_@AM_V@) @@ -392,7 +394,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_SQRT_TRUE@sqrt_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_SQRT_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_SQRT_TRUE@ libsqrt.la \ -@ENABLED_BENCHMARK_SQRT_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_SQRT_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_SQRT_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/sqrt/libsqrt.c b/src/sqrt/libsqrt.c index 31125935..bc93f46c 100644 --- a/src/sqrt/libsqrt.c +++ b/src/sqrt/libsqrt.c @@ -1,4 +1,3 @@ - /* BEEBS sqrt benchmark Copyright (C) 2014 Embecosm Limited and University of Bristol @@ -24,7 +23,7 @@ /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 10) +#define LOCAL_SCALE_FACTOR 3 /* MDH WCET BENCHMARK SUITE. */ @@ -126,17 +125,21 @@ initialise_benchmark (void) int benchmark() { - float i = 0.0; - volatile float accum = 0.0; + volatile float accum; + int j; + + for (j = 0; j < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); j++) + { + float i = 0.0; + accum = 0.0; + + for(i = 0.0; i < 10000.0; i += 100.0) + accum += sqrtfcn(i); + } - for(i = 0.0; i < 10000.; i += 100.) - accum += sqrtfcn(i); - return (int)(accum*100000); + return (int) accum; } int verify_benchmark(int r) { - int expected = 661462912; - if (r != expected) - return 0; - return 1; + return 6614 == r; } diff --git a/src/st/Makefile.am b/src/st/Makefile.am index 49268069..574810b7 100644 --- a/src/st/Makefile.am +++ b/src/st/Makefile.am @@ -34,7 +34,8 @@ libst_la_SOURCES = libst.c st_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libst.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) \ + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) \ $(LIBM) endif diff --git a/src/st/Makefile.in b/src/st/Makefile.in index 434052ee..f5cbedef 100644 --- a/src/st/Makefile.in +++ b/src/st/Makefile.in @@ -169,7 +169,9 @@ st_OBJECTS = $(am_st_OBJECTS) am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_ST_TRUE@st_DEPENDENCIES = $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_ST_TRUE@ $(top_builddir)/support/libsupport.la \ -@ENABLED_BENCHMARK_ST_TRUE@ libst.la $(am__DEPENDENCIES_1) \ +@ENABLED_BENCHMARK_ST_TRUE@ libst.la \ +@ENABLED_BENCHMARK_ST_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_ST_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_ST_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_ST_TRUE@ $(am__DEPENDENCIES_1) $(LIBM) AM_V_P = $(am__v_P_@AM_V@) @@ -391,7 +393,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_ST_TRUE@st_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_ST_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_ST_TRUE@ libst.la \ -@ENABLED_BENCHMARK_ST_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) \ +@ENABLED_BENCHMARK_ST_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_ST_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) \ @ENABLED_BENCHMARK_ST_TRUE@ $(LIBM) all: all-am diff --git a/src/st/libst.c b/src/st/libst.c index 208530ac..30099f4a 100644 --- a/src/st/libst.c +++ b/src/st/libst.c @@ -1,4 +1,3 @@ - /* BEEBS st benchmark Copyright (C) 2014 Embecosm Limited and University of Bristol @@ -24,7 +23,7 @@ /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 8) +#define LOCAL_SCALE_FACTOR 11 /* stats.c */ @@ -76,41 +75,28 @@ initialise_benchmark (void) int benchmark() { -#ifdef POUT - long StartTime, StopTime; - float TotalTime; -#endif - - double MeanA, MeanB, VarA, VarB, StddevA, StddevB /*, Coef*/; - - InitSeed (); -#ifdef POUT - printf ("\n *** Statictics TEST ***\n\n"); - StartTime = ttime(); -#endif - - Initialize(ArrayA); - Calc_Sum_Mean(ArrayA, &SumA, &MeanA); - Calc_Var_Stddev(ArrayA, MeanA, &VarA, &StddevA); - - Initialize(ArrayB); - Calc_Sum_Mean(ArrayB, &SumB, &MeanB); - Calc_Var_Stddev(ArrayB, MeanB, &VarB, &StddevB); - - /* Coef will have to be used globally in Calc_LinCorrCoef since it would - be beyond the 6 registers used for passing parameters - */ - Calc_LinCorrCoef(ArrayA, ArrayB, MeanA, MeanB /*, &Coef*/); - -#ifdef POUT - StopTime = ttime(); - TotalTime = (StopTime - StartTime) / 1000.0; - printf(" Sum A = %12.4f, Sum B = %12.4f\n", SumA, SumB); - printf(" Mean A = %12.4f, Mean B = %12.4f\n", MeanA, MeanB); - printf("Variance A = %12.4f, Variance B = %12.4f\n", VarA, VarB); - printf(" Std Dev A = %12.4f, Variance B = %12.4f\n", StddevA, StddevB); - printf("\nLinear Correlation Coefficient = %f\n", Coef); -#endif + int i; + + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + { + double MeanA, MeanB, VarA, VarB, StddevA, StddevB /*, Coef*/; + + InitSeed (); + + Initialize(ArrayA); + Calc_Sum_Mean(ArrayA, &SumA, &MeanA); + Calc_Var_Stddev(ArrayA, MeanA, &VarA, &StddevA); + + Initialize(ArrayB); + Calc_Sum_Mean(ArrayB, &SumB, &MeanB); + Calc_Var_Stddev(ArrayB, MeanB, &VarB, &StddevB); + + /* Coef will have to be used globally in Calc_LinCorrCoef since it would + be beyond the 6 registers used for passing parameters + */ + Calc_LinCorrCoef(ArrayA, ArrayB, MeanA, MeanB /*, &Coef*/); + } + return 0; } @@ -195,21 +181,11 @@ int RandomInteger() } int verify_benchmark(int unused) { - double expSumA = 4999.002470660901963128708302974700927734375; - double expSumB = 4996.843113032735345768742263317108154296875; - double expCoef = 0.99990005485361932446863875156850554049015045166016; - if (expSumA != SumA) { - //printf("%.50f\n, %.50f\n\n", SumA, expSumA); - return 0; - } - if(expSumB != SumB) { - //printf("%.50f\n, %.50f\n\n", SumB, expSumB); - return 0; - } - if(expCoef != Coef) { - //printf("%.50f\n, %.50f\n\n", Coef, expCoef); - return 0; - } - - return 1; + double expSumA = 4999.00247066090196; + double expSumB = 4996.84311303273534; + double expCoef = 0.999900054853619324; + + return (fabs (expSumA - SumA) < 1.0e13) + && (fabs (expSumB - SumB) < 1.0e-13) + && (fabs (expCoef - Coef) < 1.0e-17); } diff --git a/src/statemate/Makefile.am b/src/statemate/Makefile.am index 5e746339..820c68a2 100644 --- a/src/statemate/Makefile.am +++ b/src/statemate/Makefile.am @@ -34,7 +34,8 @@ libstatemate_la_SOURCES = libstatemate.c statemate_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libstatemate.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) diff --git a/src/statemate/Makefile.in b/src/statemate/Makefile.in index 86c29a8e..680c5ff3 100644 --- a/src/statemate/Makefile.in +++ b/src/statemate/Makefile.in @@ -172,6 +172,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_STATEMATE_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_STATEMATE_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_STATEMATE_TRUE@ libstatemate.la \ +@ENABLED_BENCHMARK_STATEMATE_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_STATEMATE_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_STATEMATE_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_STATEMATE_TRUE@ $(am__DEPENDENCIES_1) @@ -395,7 +396,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_STATEMATE_TRUE@statemate_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_STATEMATE_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_STATEMATE_TRUE@ libstatemate.la \ -@ENABLED_BENCHMARK_STATEMATE_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_STATEMATE_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_STATEMATE_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/statemate/libstatemate.c b/src/statemate/libstatemate.c index 23d60667..2fa953f6 100644 --- a/src/statemate/libstatemate.c +++ b/src/statemate/libstatemate.c @@ -19,11 +19,12 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ +#include #include "support.h" /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) +#define LOCAL_SCALE_FACTOR 5347 /* MDH WCET BENCHMARK SUITE. File version $Id: statemate.c,v 1.3 2005/11/11 10:32:32 ael01 Exp $ */ @@ -1294,23 +1295,30 @@ void FH_DU(void) int benchmark(void) { - interface(); - FH_DU(); + int i; + + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + { + memset (Bitlist, 0, 64 * sizeof (Bitlist[0])); + init(); + + interface(); + FH_DU(); + } return 0; } void initialise_benchmark() { - int i; - for (i=0; i<64; i++) { - Bitlist[i] = 0; - } - init(); } int verify_benchmark(int unused) { - char expected[64] = {0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + char expected[64] = { + 0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + }; int i; + for (i=0; i<64; i++) { if (Bitlist[i] != expected[i]) return 0; diff --git a/src/stb_perlin/Makefile.am b/src/stb_perlin/Makefile.am index 640512e2..5ff97f9f 100644 --- a/src/stb_perlin/Makefile.am +++ b/src/stb_perlin/Makefile.am @@ -34,7 +34,8 @@ libstb_perlin_la_SOURCES = libstb_perlin.c stb_perlin_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libstb_perlin.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) \ + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) \ $(LIBM) endif diff --git a/src/stb_perlin/Makefile.in b/src/stb_perlin/Makefile.in index b49e37a4..2437f40c 100644 --- a/src/stb_perlin/Makefile.in +++ b/src/stb_perlin/Makefile.in @@ -172,6 +172,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_STB_PERLIN_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_STB_PERLIN_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_STB_PERLIN_TRUE@ libstb_perlin.la \ +@ENABLED_BENCHMARK_STB_PERLIN_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_STB_PERLIN_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_STB_PERLIN_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_STB_PERLIN_TRUE@ $(am__DEPENDENCIES_1) \ @@ -396,7 +397,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_STB_PERLIN_TRUE@stb_perlin_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_STB_PERLIN_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_STB_PERLIN_TRUE@ libstb_perlin.la \ -@ENABLED_BENCHMARK_STB_PERLIN_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) \ +@ENABLED_BENCHMARK_STB_PERLIN_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_STB_PERLIN_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) \ @ENABLED_BENCHMARK_STB_PERLIN_TRUE@ $(LIBM) all: all-am diff --git a/src/stb_perlin/libstb_perlin.c b/src/stb_perlin/libstb_perlin.c index cf2f9be4..ee6c5555 100644 --- a/src/stb_perlin/libstb_perlin.c +++ b/src/stb_perlin/libstb_perlin.c @@ -1,5 +1,3 @@ - - /* -*- mode: C++; c-file-style: "gnu-mode" -*- */ /* BEEBS perlin noise benchmark @@ -32,7 +30,7 @@ /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 10) +#define LOCAL_SCALE_FACTOR 4 /* Not same permutation table as Perlin's reference to avoid copyright issues; @@ -176,27 +174,53 @@ float stb_perlin_noise3(float x, float y, float z, int x_wrap, int y_wrap, int z #define PX_LIM 10 -static const float expected[PX_LIM][PX_LIM] = -{ - {0, -0.0077039809, -0.0463358946, -0.114156149, -0.190464064, -0.25, -0.273023993, -0.251076102, -0.188415885, -0.0991439149}, - {0.0991439074, 0.0914399251, 0.0486288741, -0.0293106586, -0.121270522, -0.200000048, -0.242842749, -0.238228917, -0.187921792, -0.105018668}, - {0.188415855, 0.184891015, 0.142079949, 0.0571305156, -0.0497226715, -0.15000008, -0.217995092, -0.237974435, -0.207558259, -0.137281746}, - {0.251076072, 0.257670492, 0.221869349, 0.136919931, 0.0202583969, -0.0999999046, -0.195655048, -0.246107936, -0.243134528, -0.192748934}, - {0.273024023, 0.295270383, 0.274362564, 0.199221492, 0.0825599432, -0.0499999821, -0.169228643, -0.25001502, -0.277515233, -0.251722753}, - {0.25, 0.29143998, 0.292080045, 0.236919835, 0.132559896, 0, -0.132559896, -0.23691988, -0.292080224, -0.29144001}, - {0.19046405, 0.251722723, 0.277515113, 0.25001502, 0.169228613, 0.0499999523, -0.0825599432, -0.199221492, -0.274362803, -0.295270443}, - {0.114156127, 0.192748874, 0.243134409, 0.246107906, 0.195655018, 0.0999999046, -0.0202584267, -0.136919975, -0.221869588, -0.257670581}, - {0.0463357568, 0.137281597, 0.207558081, 0.237974346, 0.217995077, 0.150000095, 0.0497227311, -0.0571305752, -0.142080128, -0.184891045}, - {0.00770395994, 0.105018653, 0.187921703, 0.238228887, 0.242842719, 0.200000048, 0.121270508, 0.0293106437, -0.0486289859, -0.0914399624} -}; - +static float res[PX_LIM][PX_LIM]; /* This benchmark does not support verification */ int -verify_benchmark (int res __attribute ((unused)) ) +verify_benchmark (int result __attribute ((unused)) ) { - return -1; + static const float exp[PX_LIM][PX_LIM] = { + { 0.0000000000, -0.0077039809, -0.0463358946, -0.1141561490, -0.1904640640, + -0.2500000000, -0.2730239930, -0.2510761020, -0.1884158850, -0.0991439149 + }, + { 0.0991439074, 0.0914399251, 0.0486288741, -0.0293106586, -0.1212705220, + -0.2000000480, -0.2428427490, -0.2382289170, -0.1879217920, -0.1050186680 + }, + { 0.1884158550, 0.1848910150, 0.1420799490, 0.0571305156, -0.0497226715, + -0.1500000800, -0.2179950920, -0.2379744350, -0.2075582590, -0.1372817460 + }, + { 0.2510760720, 0.2576704920, 0.2218693490, 0.1369199310, 0.0202583969, + -0.0999999046, -0.1956550480, -0.2461079360, -0.2431345280, -0.1927489340 + }, + { 0.2730240230, 0.2952703830, 0.2743625640, 0.1992214920, 0.0825599432, + -0.0499999821, -0.1692286430, -0.2500150200, -0.2775152330, -0.2517227530 + }, + { 0.2500000000, 0.2914399800, 0.2920800450, 0.2369198350, 0.1325598960, + 0.0000000000, -0.1325598960, -0.2369198800, -0.2920802240, -0.2914400100 + }, + { 0.1904640500, 0.2517227230, 0.2775151130, 0.2500150200, 0.1692286130, + 0.0499999523, -0.0825599432, -0.1992214920, -0.2743628030, -0.2952704430 + }, + { 0.1141561270, 0.1927488740, 0.2431344090, 0.2461079060, 0.1956550180, + 0.0999999046, -0.0202584267, -0.1369199750, -0.2218695880, -0.2576705810 + }, + { 0.0463357568, 0.1372815970, 0.2075580810, 0.2379743460, 0.2179950770, + 0.1500000950, 0.0497227311, -0.0571305752, -0.1420801280, -0.1848910450 + }, + { 0.00770395994, 0.1050186530, 0.1879217030, 0.2382288870, 0.2428427190, + 0.2000000480, 0.1212705080, 0.0293106437, -0.0486289859, -0.0914399624} + }; + + int xpx, ypx; + + for (ypx = 0; ypx < PX_LIM; ypx++) + for (xpx = 0; xpx < PX_LIM; xpx++) + if (fabs (res[ypx][xpx] - exp[ypx][xpx]) > 1.0e-6) + return 0; + + return 1; } @@ -209,25 +233,24 @@ initialise_benchmark (void) int benchmark(void) { - int xpx, ypx; - float x, y, out; - int ret = 0; + int i; + + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + { + int xpx, ypx; + float x, y; - /* Calculate a plane of noise */ - for (ypx = 0; ypx < PX_LIM; ++ypx) + /* Calculate a plane of noise */ + for (ypx = 0; ypx < PX_LIM; ++ypx) { - for (xpx = 0; xpx < PX_LIM; ++xpx) - { - x = (float)xpx * NOISE_STEP + NOISE_START_XY; - y = (float)ypx * NOISE_STEP + NOISE_START_XY; - out = stb_perlin_noise3(x, y, NOISE_Z, 0, 0, 0); - if (out != expected[ypx][xpx]) - { - ret = 1; - } - } + for (xpx = 0; xpx < PX_LIM; ++xpx) + { + x = (float)xpx * NOISE_STEP + NOISE_START_XY; + y = (float)ypx * NOISE_STEP + NOISE_START_XY; + res[ypx][xpx] = stb_perlin_noise3(x, y, NOISE_Z, 0, 0, 0); + } } + } - return ret; + return 0; } - diff --git a/src/stringsearch1/Makefile.am b/src/stringsearch1/Makefile.am index ec8d533e..014a49f6 100644 --- a/src/stringsearch1/Makefile.am +++ b/src/stringsearch1/Makefile.am @@ -34,6 +34,7 @@ libstringsearch1_la_SOURCES = stringsearch1.c fast.fwd.inc.c fast.rev.d12.c stringsearch1_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libstringsearch1.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) endif diff --git a/src/stringsearch1/Makefile.in b/src/stringsearch1/Makefile.in index 2d56c74d..0b5417c7 100644 --- a/src/stringsearch1/Makefile.in +++ b/src/stringsearch1/Makefile.in @@ -176,6 +176,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_STRINGSEARCH1_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_STRINGSEARCH1_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_STRINGSEARCH1_TRUE@ libstringsearch1.la \ +@ENABLED_BENCHMARK_STRINGSEARCH1_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_STRINGSEARCH1_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_STRINGSEARCH1_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_STRINGSEARCH1_TRUE@ $(am__DEPENDENCIES_1) @@ -399,7 +400,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_STRINGSEARCH1_TRUE@stringsearch1_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_STRINGSEARCH1_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_STRINGSEARCH1_TRUE@ libstringsearch1.la \ -@ENABLED_BENCHMARK_STRINGSEARCH1_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_STRINGSEARCH1_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_STRINGSEARCH1_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/stringsearch1/stringsearch1.c b/src/stringsearch1/stringsearch1.c index ef75ec27..6f7cdea3 100644 --- a/src/stringsearch1/stringsearch1.c +++ b/src/stringsearch1/stringsearch1.c @@ -26,7 +26,7 @@ /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) +#define LOCAL_SCALE_FACTOR 568 #ifndef CHARTYPE #define CHARTYPE unsigned char @@ -44,11 +44,18 @@ static int size; int benchmark (void) { - int r; - prep1((CHARTYPE *) search, size); - r = exec1((CHARTYPE *) buf, strlen(buf)); - prep2((CHARTYPE *) search, size); - return exec2((CHARTYPE *) buf, strlen(buf)) * r; + volatile int r; + int i; + + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + { + prep1((CHARTYPE *) search, size); + r = exec1((CHARTYPE *) buf, strlen(buf)); + prep2((CHARTYPE *) search, size); + r *= exec2((CHARTYPE *) buf, strlen(buf)); + } + + return r; } void initialise_benchmark() { @@ -56,8 +63,5 @@ void initialise_benchmark() { } int verify_benchmark(int r) { - int expected = 36; - if (r != expected) - return 0; - return 1; + return 36 == r; } diff --git a/src/strstr/Makefile.am b/src/strstr/Makefile.am index 90889c54..fb0fad7f 100644 --- a/src/strstr/Makefile.am +++ b/src/strstr/Makefile.am @@ -34,7 +34,8 @@ libstrstr_la_SOURCES = libstrstr.c strstr_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libstrstr.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) diff --git a/src/strstr/Makefile.in b/src/strstr/Makefile.in index 4e8b781b..c757ccaf 100644 --- a/src/strstr/Makefile.in +++ b/src/strstr/Makefile.in @@ -171,6 +171,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_STRSTR_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_STRSTR_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_STRSTR_TRUE@ libstrstr.la \ +@ENABLED_BENCHMARK_STRSTR_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_STRSTR_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_STRSTR_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_STRSTR_TRUE@ $(am__DEPENDENCIES_1) @@ -393,7 +394,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_STRSTR_TRUE@strstr_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_STRSTR_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_STRSTR_TRUE@ libstrstr.la \ -@ENABLED_BENCHMARK_STRSTR_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_STRSTR_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_STRSTR_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/strstr/libstrstr.c b/src/strstr/libstrstr.c index 22a3773c..2d402df4 100644 --- a/src/strstr/libstrstr.c +++ b/src/strstr/libstrstr.c @@ -1,4 +1,3 @@ - /* BEEBS strstr benchmark Copyright (C) 1994,1996,1997,2000,2001,2003 Free Software Foundation, Inc. @@ -36,7 +35,7 @@ /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) +#define LOCAL_SCALE_FACTOR 4705 typedef unsigned chartype; @@ -137,17 +136,22 @@ initialise_benchmark (void) char *substr = "abba"; int benchmark() { - char *f = text; - int n=0; + int n; + int i; - do - { - f = strstr(f+1, substr); - n++; - } while(f); + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + { + char *f = text; + n=0; + + do + { + f = strstr(f+1, substr); + n++; + } while(f); + } return n; - } int verify_benchmark(int r) { diff --git a/src/tarai/Makefile.am b/src/tarai/Makefile.am index 93d14919..8d134afe 100644 --- a/src/tarai/Makefile.am +++ b/src/tarai/Makefile.am @@ -34,6 +34,7 @@ libtarai_la_SOURCES = libtarai.c tarai_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libtarai.la \ + $(top_builddir)/support/libbeebsc.la \ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) diff --git a/src/tarai/Makefile.in b/src/tarai/Makefile.in index e971f835..b55122c5 100644 --- a/src/tarai/Makefile.in +++ b/src/tarai/Makefile.in @@ -171,6 +171,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_TARAI_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_TARAI_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_TARAI_TRUE@ libtarai.la \ +@ENABLED_BENCHMARK_TARAI_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_TARAI_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_TARAI_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_TARAI_TRUE@ $(am__DEPENDENCIES_1) @@ -393,6 +394,7 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_TARAI_TRUE@tarai_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_TARAI_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_TARAI_TRUE@ libtarai.la \ +@ENABLED_BENCHMARK_TARAI_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_TARAI_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/tarai/libtarai.c b/src/tarai/libtarai.c index 98139ec7..a7b815b2 100644 --- a/src/tarai/libtarai.c +++ b/src/tarai/libtarai.c @@ -23,7 +23,7 @@ /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) +#define LOCAL_SCALE_FACTOR 6655 int tarai(int x, int y, int z) { @@ -51,12 +51,13 @@ int x, y, z; int benchmark() { - volatile int cnt=0; + volatile int cnt; + int i; + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) cnt = tarai(x, y, z); - return cnt; - + return cnt; } void initialise_benchmark() { @@ -66,8 +67,5 @@ void initialise_benchmark() { } int verify_benchmark(int r) { - int expected = 9; - if (r != expected) - return 0; - return 1; + return 9 == r; } diff --git a/src/template/.gitignore b/src/template/.gitignore deleted file mode 100644 index 3236cba6..00000000 --- a/src/template/.gitignore +++ /dev/null @@ -1 +0,0 @@ -template diff --git a/src/template/Makefile.am b/src/template/Makefile.am deleted file mode 100644 index fcba275a..00000000 --- a/src/template/Makefile.am +++ /dev/null @@ -1,53 +0,0 @@ -# Makefile.am for building a BEEBS benchmark -# -# Copyright (C) 2013 Embecosm Limited and University of Bristol -# -# This file is part of the Bristol/Embecosm Embedded Benchmark Suite. -# -# Contributor: James Pallister -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# SPDX-License-Identifier: GPL-3.0-or-later - -# Change every instance of template to the name of your benchmark - -# To get automake to use this file, add the following to toplevel configure.ac -# AC_CONFIG_FILES([src/template/Makefile]) -# and add the following line to toplevel Makefile.am -# SUBDIRS+=src/template - - -# Make sure your sources include the headers as well as the C/C++ source -# files, so they go into the distribution. If there are other files that are -# needed, they should go in EXTRA_SOURCES. - -if ENABLED_BENCHMARK_TEMPLATE - -include $(top_srcdir)/src/common.mk.am - -bin_PROGRAMS = template -noinst_LTLIBRARIES = libtemplate.la - -template_SOURCES = -libtemplate_la_SOURCES = libtemplate.c - -template_LDADD = $(DUMMY_CRT0) \ - $(top_builddir)/support/libsupport.la \ - libtemplate.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) - - - -endif diff --git a/src/template/Makefile.in b/src/template/Makefile.in deleted file mode 100644 index 436fcd72..00000000 --- a/src/template/Makefile.in +++ /dev/null @@ -1,759 +0,0 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2014 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -# Makefile.am for building a BEEBS benchmark -# -# Copyright (C) 2013 Embecosm Limited and University of Bristol -# -# This file is part of the Bristol/Embecosm Embedded Benchmark Suite. -# -# Contributor: James Pallister -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# SPDX-License-Identifier: GPL-3.0-or-later - -# Change every instance of template to the name of your benchmark - -# To get automake to use this file, add the following to toplevel configure.ac -# AC_CONFIG_FILES([src/template/Makefile]) -# and add the following line to toplevel Makefile.am -# SUBDIRS+=src/template - -# Make sure your sources include the headers as well as the C/C++ source -# files, so they go into the distribution. If there are other files that are -# needed, they should go in EXTRA_SOURCES. - -# Common makefile.am fragments for building a BEEBS benchmark -# -# Copyright (C) 2013 Embecosm Limited and University of Bristol -# -# This file is part of the Bristol/Embecosm Embedded Benchmark Suite. -# -# Contributor: James Pallister -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# If there is a benchmark calibration file, this specifies the shifting -# of the repeat factor. If grep doesn't find the program, then we specify -# 0 as the default. This is the default if a calibration file is not found - - -VPATH = @srcdir@ -am__is_gnu_make = { \ - if test -z '$(MAKELEVEL)'; then \ - false; \ - elif test -n '$(MAKE_HOST)'; then \ - true; \ - elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ - true; \ - else \ - false; \ - fi; \ -} -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -target_triplet = @target@ -@ENABLED_BENCHMARK_TEMPLATE_TRUE@bin_PROGRAMS = template$(EXEEXT) -subdir = src/template -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ - $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ - $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ - $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -LTLIBRARIES = $(noinst_LTLIBRARIES) -libtemplate_la_LIBADD = -am__libtemplate_la_SOURCES_DIST = libtemplate.c -@ENABLED_BENCHMARK_TEMPLATE_TRUE@am_libtemplate_la_OBJECTS = \ -@ENABLED_BENCHMARK_TEMPLATE_TRUE@ libtemplate.lo -libtemplate_la_OBJECTS = $(am_libtemplate_la_OBJECTS) -AM_V_lt = $(am__v_lt_@AM_V@) -am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) -am__v_lt_0 = --silent -am__v_lt_1 = -@ENABLED_BENCHMARK_TEMPLATE_TRUE@am_libtemplate_la_rpath = -am__installdirs = "$(DESTDIR)$(bindir)" -PROGRAMS = $(bin_PROGRAMS) -am_template_OBJECTS = -template_OBJECTS = $(am_template_OBJECTS) -am__DEPENDENCIES_1 = -@ENABLED_BENCHMARK_TEMPLATE_TRUE@template_DEPENDENCIES = \ -@ENABLED_BENCHMARK_TEMPLATE_TRUE@ $(am__DEPENDENCIES_1) \ -@ENABLED_BENCHMARK_TEMPLATE_TRUE@ $(top_builddir)/support/libsupport.la \ -@ENABLED_BENCHMARK_TEMPLATE_TRUE@ libtemplate.la \ -@ENABLED_BENCHMARK_TEMPLATE_TRUE@ $(am__DEPENDENCIES_1) \ -@ENABLED_BENCHMARK_TEMPLATE_TRUE@ $(am__DEPENDENCIES_1) \ -@ENABLED_BENCHMARK_TEMPLATE_TRUE@ $(am__DEPENDENCIES_1) -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) -depcomp = $(SHELL) $(top_srcdir)/depcomp -am__depfiles_maybe = depfiles -am__mv = mv -f -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CFLAGS) $(CFLAGS) -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -am__v_CC_1 = -CCLD = $(CC) -LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CCLD = $(am__v_CCLD_@AM_V@) -am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -am__v_CCLD_1 = -SOURCES = $(libtemplate_la_SOURCES) $(template_SOURCES) -DIST_SOURCES = $(am__libtemplate_la_SOURCES_DIST) $(template_SOURCES) -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -ETAGS = etags -CTAGS = ctags -am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \ - $(top_srcdir)/src/common.mk.am -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AR = @AR@ -ARCH = @ARCH@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -BENCHMARKS = @BENCHMARKS@ -BOARD = @BOARD@ -CC = @CC@ -CCAS = @CCAS@ -CCASDEPMODE = @CCASDEPMODE@ -CCASFLAGS = @CCASFLAGS@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CHIP = @CHIP@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEJAGNU = @DEJAGNU@ -DEPDIR = @DEPDIR@ -DLLTOOL = @DLLTOOL@ -DSYMUTIL = @DSYMUTIL@ -DUMMY_COMPILERRT = @DUMMY_COMPILERRT@ -DUMMY_CRT0 = @DUMMY_CRT0@ -DUMMY_LIBC = @DUMMY_LIBC@ -DUMMY_LIBGCC = @DUMMY_LIBGCC@ -DUMMY_LIBM = @DUMMY_LIBM@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LIBTOOL_DEPS = @LIBTOOL_DEPS@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MKDIR_P = @MKDIR_P@ -NM = @NM@ -NMEDIT = @NMEDIT@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -RANLIB = @RANLIB@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -VERSION = @VERSION@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target = @target@ -target_alias = @target_alias@ -target_cpu = @target_cpu@ -target_os = @target_os@ -target_vendor = @target_vendor@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -@CALIBRATION_FALSE@@ENABLED_BENCHMARK_TEMPLATE_TRUE@calib = echo 0 -@CALIBRATION_TRUE@@ENABLED_BENCHMARK_TEMPLATE_TRUE@calib = (egrep "^\b$(bin_PROGRAMS)\b" \ -@CALIBRATION_TRUE@@ENABLED_BENCHMARK_TEMPLATE_TRUE@ $(top_srcdir)/config/@ARCH@/boards/@BOARD@/calibration \ -@CALIBRATION_TRUE@@ENABLED_BENCHMARK_TEMPLATE_TRUE@ || echo "0 0") | cut -d " " -f 2 - -@ENABLED_BENCHMARK_TEMPLATE_TRUE@AM_CPPFLAGS = "-DCALIB_SCALE=$(shell $(calib))" \ -@ENABLED_BENCHMARK_TEMPLATE_TRUE@ -I $(top_srcdir)/support \ -@ENABLED_BENCHMARK_TEMPLATE_TRUE@ -I $(top_srcdir)/config/@ARCH@/boards/@BOARD@ \ -@ENABLED_BENCHMARK_TEMPLATE_TRUE@ -I $(top_srcdir)/config/@ARCH@/chips/@CHIP@ \ -@ENABLED_BENCHMARK_TEMPLATE_TRUE@ @CPPFLAGS@ - - -# Setup a $(LIBM) variable that we can use instead of either -# $(DUMMY_LIBM) or -lm. This way we don't risk pulling in -# parts of the real libm if we want to use $(DUMMY_LIBM). -@ENABLED_BENCHMARK_TEMPLATE_TRUE@LIBM = $(if $(DUMMY_LIBM),$(DUMMY_LIBM),-lm) -@ENABLED_BENCHMARK_TEMPLATE_TRUE@noinst_LTLIBRARIES = libtemplate.la -@ENABLED_BENCHMARK_TEMPLATE_TRUE@template_SOURCES = -@ENABLED_BENCHMARK_TEMPLATE_TRUE@libtemplate_la_SOURCES = libtemplate.c -@ENABLED_BENCHMARK_TEMPLATE_TRUE@template_LDADD = $(DUMMY_CRT0) \ -@ENABLED_BENCHMARK_TEMPLATE_TRUE@ $(top_builddir)/support/libsupport.la \ -@ENABLED_BENCHMARK_TEMPLATE_TRUE@ libtemplate.la \ -@ENABLED_BENCHMARK_TEMPLATE_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) - -all: all-am - -.SUFFIXES: -.SUFFIXES: .c .lo .o .obj -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/src/common.mk.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/template/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu src/template/Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; -$(top_srcdir)/src/common.mk.am $(am__empty): - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -clean-noinstLTLIBRARIES: - -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) - @list='$(noinst_LTLIBRARIES)'; \ - locs=`for p in $$list; do echo $$p; done | \ - sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ - sort -u`; \ - test -z "$$locs" || { \ - echo rm -f $${locs}; \ - rm -f $${locs}; \ - } - -libtemplate.la: $(libtemplate_la_OBJECTS) $(libtemplate_la_DEPENDENCIES) $(EXTRA_libtemplate_la_DEPENDENCIES) - $(AM_V_CCLD)$(LINK) $(am_libtemplate_la_rpath) $(libtemplate_la_OBJECTS) $(libtemplate_la_LIBADD) $(LIBS) -install-binPROGRAMS: $(bin_PROGRAMS) - @$(NORMAL_INSTALL) - @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ - fi; \ - for p in $$list; do echo "$$p $$p"; done | \ - sed 's/$(EXEEXT)$$//' | \ - while read p p1; do if test -f $$p \ - || test -f $$p1 \ - ; then echo "$$p"; echo "$$p"; else :; fi; \ - done | \ - sed -e 'p;s,.*/,,;n;h' \ - -e 's|.*|.|' \ - -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ - sed 'N;N;N;s,\n, ,g' | \ - $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ - { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ - if ($$2 == $$4) files[d] = files[d] " " $$1; \ - else { print "f", $$3 "/" $$4, $$1; } } \ - END { for (d in files) print "f", d, files[d] }' | \ - while read type dir files; do \ - if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ - test -z "$$files" || { \ - echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ - $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ - } \ - ; done - -uninstall-binPROGRAMS: - @$(NORMAL_UNINSTALL) - @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ - files=`for p in $$list; do echo "$$p"; done | \ - sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ - -e 's/$$/$(EXEEXT)/' \ - `; \ - test -n "$$list" || exit 0; \ - echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(bindir)" && rm -f $$files - -clean-binPROGRAMS: - @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ - echo " rm -f" $$list; \ - rm -f $$list || exit $$?; \ - test -n "$(EXEEXT)" || exit 0; \ - list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ - echo " rm -f" $$list; \ - rm -f $$list - -template$(EXEEXT): $(template_OBJECTS) $(template_DEPENDENCIES) $(EXTRA_template_DEPENDENCIES) - @rm -f template$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(template_OBJECTS) $(template_LDADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtemplate.Plo@am__quote@ - -.c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< - -.c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` - -.c.lo: -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-am -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-am - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscopelist: cscopelist-am - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) -installdirs: - for dir in "$(DESTDIR)$(bindir)"; do \ - test -z "$$dir" || $(MKDIR_P) "$$dir"; \ - done -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-binPROGRAMS clean-generic clean-libtool \ - clean-noinstLTLIBRARIES mostlyclean-am - -distclean: distclean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: install-binPROGRAMS - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: uninstall-binPROGRAMS - -.MAKE: install-am install-strip - -.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ - clean-binPROGRAMS clean-generic clean-libtool \ - clean-noinstLTLIBRARIES cscopelist-am ctags ctags-am distclean \ - distclean-compile distclean-generic distclean-libtool \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-binPROGRAMS install-data \ - install-data-am install-dvi install-dvi-am install-exec \ - install-exec-am install-html install-html-am install-info \ - install-info-am install-man install-pdf install-pdf-am \ - install-ps install-ps-am install-strip installcheck \ - installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags tags-am uninstall uninstall-am uninstall-binPROGRAMS - -.PRECIOUS: Makefile - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/src/template/libtemplate.c b/src/template/libtemplate.c deleted file mode 100644 index f38ba526..00000000 --- a/src/template/libtemplate.c +++ /dev/null @@ -1,57 +0,0 @@ - - -/* -*- mode: C++; c-file-style: "gnu-mode" -*- */ -/* BEEBS template benchmark - - *** Put any preceding copyright here *** - Copyright (C) 2013 Embecosm Limited and University of Bristol - - Contributor Jeremy Bennett - - This file is part of the Bristol/Embecosm Embedded Benchmark Suite. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#include "support.h" - -/* This scale factor will be changed to equalise the runtime of the - benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) - - - - -/* This benchmark does not support verification */ - -int -verify_benchmark (int res __attribute ((unused)) ) -{ - return -1; -} - - -void -initialise_benchmark (void) -{ -} - - -int -benchmark (void) -{ - /* Code to benchmark goes here */ - return 0; -} - - diff --git a/src/trio-snprintf/Makefile.am b/src/trio-snprintf/Makefile.am index 4e1f9b72..9a94ab11 100644 --- a/src/trio-snprintf/Makefile.am +++ b/src/trio-snprintf/Makefile.am @@ -36,7 +36,8 @@ libtrio_snprintf_la_SOURCES = trio.c trio.h trio_test.c triostr.c triostr.h \ trio_snprintf_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libtrio-snprintf.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) libtrio_snprintf_la_CPPFLAGS = -DTRIO_EXTENSION=0 -DTRIO_DEPRECATED=0 \ -DTRIO_MICROSOFT=0 -DTRIO_ERRORS=0 \ -DTRIO_FEATURE_FLOAT=0 -DTRIO_SNPRINTF \ diff --git a/src/trio-snprintf/Makefile.in b/src/trio-snprintf/Makefile.in index d1663dbb..12bf2fa8 100644 --- a/src/trio-snprintf/Makefile.in +++ b/src/trio-snprintf/Makefile.in @@ -175,6 +175,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_TRIO_SNPRINTF_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_TRIO_SNPRINTF_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_TRIO_SNPRINTF_TRUE@ libtrio-snprintf.la \ +@ENABLED_BENCHMARK_TRIO_SNPRINTF_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_TRIO_SNPRINTF_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_TRIO_SNPRINTF_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_TRIO_SNPRINTF_TRUE@ $(am__DEPENDENCIES_1) @@ -400,7 +401,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_TRIO_SNPRINTF_TRUE@trio_snprintf_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_TRIO_SNPRINTF_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_TRIO_SNPRINTF_TRUE@ libtrio-snprintf.la \ -@ENABLED_BENCHMARK_TRIO_SNPRINTF_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_TRIO_SNPRINTF_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_TRIO_SNPRINTF_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) @ENABLED_BENCHMARK_TRIO_SNPRINTF_TRUE@libtrio_snprintf_la_CPPFLAGS = -DTRIO_EXTENSION=0 -DTRIO_DEPRECATED=0 \ @ENABLED_BENCHMARK_TRIO_SNPRINTF_TRUE@ -DTRIO_MICROSOFT=0 -DTRIO_ERRORS=0 \ diff --git a/src/trio-snprintf/trio.c b/src/trio-snprintf/trio.c deleted file mode 120000 index c8308b41..00000000 --- a/src/trio-snprintf/trio.c +++ /dev/null @@ -1 +0,0 @@ -../trio/trio.c \ No newline at end of file diff --git a/src/trio-snprintf/trio.c b/src/trio-snprintf/trio.c new file mode 100644 index 00000000..b8837707 --- /dev/null +++ b/src/trio-snprintf/trio.c @@ -0,0 +1,7758 @@ +/* BEEBS trio benchmark + + Copyright (C) 2014 Embecosm Limited and University of Bristol + + This file is part of the Bristol/Embecosm Embedded Benchmark Suite. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* The original source of this file was from: + * http://daniel.haxx.se/projects/trio/ + * and is covered by the following copyright and licence: + * + * Copyright (C) 1998, 2009 Bjorn Reese and Daniel Stenberg. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND + * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. + * + ************************************************************************* + * + * A note to trio contributors: + * + * Avoid heap allocation at all costs to ensure that the trio functions + * are async-safe. The exceptions are the printf/fprintf functions, which + * uses fputc, and the asprintf functions and the modifier, which + * by design are required to allocate form the heap. + * + ************************************************************************/ + +/* + * TODO: + * - Scan is probably too permissive about its modifiers. + * - C escapes in %#[] ? + * - Multibyte characters (done for format parsing, except scan groups) + * - Complex numbers? (C99 _Complex) + * - Boolean values? (C99 _Bool) + * - C99 NaN(n-char-sequence) missing. The n-char-sequence can be used + * to print the mantissa, e.g. NaN(0xc000000000000000) + * - Should we support the GNU %a alloc modifier? GNU has an ugly hack + * for %a, because C99 used %a for other purposes. If specified as + * %as or %a[ it is interpreted as the alloc modifier, otherwise as + * the C99 hex-float. This means that you cannot scan %as as a hex-float + * immediately followed by an 's'. + * - Scanning of collating symbols. + */ + +/************************************************************************* + * Trio include files + */ +#include "triodef.h" +#include "trio.h" +#include "triop.h" + +#if defined(TRIO_EMBED_NAN) +# define TRIO_PUBLIC_NAN static +# if TRIO_FEATURE_FLOAT +# define TRIO_FUNC_NAN +# define TRIO_FUNC_NINF +# define TRIO_FUNC_PINF +# define TRIO_FUNC_FPCLASSIFY_AND_SIGNBIT +# define TRIO_FUNC_ISINF +# endif +#endif + +#if defined(TRIO_EMBED_STRING) +# define TRIO_PUBLIC_STRING static +# define TRIO_FUNC_LENGTH +# define TRIO_FUNC_LENGTH_MAX +# define TRIO_FUNC_TO_LONG +# if TRIO_FEATURE_LOCALE +# define TRIO_FUNC_COPY_MAX +# endif +# if TRIO_FEATURE_DYNAMICSTRING +# define TRIO_FUNC_XSTRING_DUPLICATE +# endif +# if TRIO_EXTENSION && TRIO_FEATURE_SCANF +# define TRIO_FUNC_EQUAL_LOCALE +# endif +# if TRIO_FEATURE_ERRNO +# define TRIO_FUNC_ERROR +# endif +# if TRIO_FEATURE_FLOAT && TRIO_FEATURE_SCANF +# define TRIO_FUNC_TO_DOUBLE +# endif +# if TRIO_FEATURE_DYNAMICSTRING +# define TRIO_FUNC_STRING_EXTRACT +# endif +# if TRIO_FEATURE_DYNAMICSTRING +# define TRIO_FUNC_STRING_TERMINATE +# endif +# if TRIO_FEATURE_USER_DEFINED +# define TRIO_FUNC_DUPLICATE +# endif +# if TRIO_FEATURE_DYNAMICSTRING +# define TRIO_FUNC_STRING_DESTROY +# endif +# if TRIO_FEATURE_USER_DEFINED +# define TRIO_FUNC_DESTROY +# endif +# if TRIO_FEATURE_USER_DEFINED || (TRIO_FEATURE_FLOAT && TRIO_FEATURE_SCANF) +# define TRIO_FUNC_EQUAL +# endif +# if TRIO_FEATURE_USER_DEFINED || TRIO_FEATURE_SCANF +# define TRIO_FUNC_EQUAL_CASE +# endif +# if (TRIO_EXTENSION && TRIO_FEATURE_SCANF) +# define TRIO_FUNC_EQUAL_MAX +# endif +# if TRIO_FEATURE_SCANF +# define TRIO_FUNC_TO_UPPER +# endif +# if TRIO_FEATURE_DYNAMICSTRING +# define TRIO_FUNC_XSTRING_APPEND_CHAR +# endif +#endif +#include "triostr.h" + +/************************************************************************** + * + * Definitions + * + *************************************************************************/ + +#include +#if TRIO_FEATURE_FLOAT +# include +# include +#endif + +#if defined(__STDC_ISO_10646__) || defined(MB_LEN_MAX) || defined(USE_MULTIBYTE) || TRIO_FEATURE_WIDECHAR +# if !defined(TRIO_PLATFORM_WINCE) +# define TRIO_COMPILER_SUPPORTS_MULTIBYTE +# if !defined(MB_LEN_MAX) +# define MB_LEN_MAX 6 +# endif +# endif +#endif + +#if (TRIO_COMPILER_VISUALC - 0 >= 1100) || defined(TRIO_COMPILER_BORLAND) +# define TRIO_COMPILER_SUPPORTS_VISUALC_INT +#endif + +#if TRIO_FEATURE_FLOAT +# if defined(PREDEF_STANDARD_C99) \ + || defined(PREDEF_STANDARD_UNIX03) +# if !defined(HAVE_FLOORL) && !defined(TRIO_NO_FLOORL) +# define HAVE_FLOORL +# endif +# if !defined(HAVE_CEILL) && !defined(TRIO_NO_CEILL) +# define HAVE_CEILL +# endif +# if !defined(HAVE_POWL) && !defined(TRIO_NO_POWL) +# define HAVE_POWL +# endif +# if !defined(HAVE_FMODL) && !defined(TRIO_NO_FMODL) +# define HAVE_FMODL +# endif +# if !defined(HAVE_LOG10L) && !defined(TRIO_NO_LOG10L) +# define HAVE_LOG10L +# endif +# endif +# if defined(TRIO_COMPILER_VISUALC) +# if defined(floorl) +# define HAVE_FLOORL +# endif +# if defined(ceill) +# define HAVE_CEILL +# endif +# if defined(powl) +# define HAVE_POWL +# endif +# if defined(fmodl) +# define HAVE_FMODL +# endif +# if defined(log10l) +# define HAVE_LOG10L +# endif +# endif +#endif + +/************************************************************************* + * Generic definitions + */ + +#if !(defined(DEBUG) || defined(NDEBUG)) +# define NDEBUG +#endif + +#include +#include +#if defined(PREDEF_STANDARD_C99) && !defined(isascii) +# define isascii(x) ((x) & 0x7F) +#endif +#if defined(TRIO_COMPILER_ANCIENT) +# include +#else +# include +#endif +#include +#if defined(TRIO_PLATFORM_WINCE) +extern int errno; +#else +# include +#endif + +#ifndef NULL +# define NULL 0 +#endif +#define NIL ((char)0) +#ifndef FALSE +# define FALSE (1 == 0) +# define TRUE (! FALSE) +#endif +#define BOOLEAN_T int + +/* mincore() can be used for debugging purposes */ +#define VALID(x) (NULL != (x)) + +#if TRIO_FEATURE_ERRORCODE + /* + * Encode the error code and the position. This is decoded + * with TRIO_ERROR_CODE and TRIO_ERROR_POSITION. + */ +# define TRIO_ERROR_RETURN(x,y) (- ((x) + ((y) << 8))) +#else +# define TRIO_ERROR_RETURN(x,y) (-1) +#endif + +typedef unsigned long trio_flags_t; + + +/************************************************************************* + * Platform specific definitions + */ +#if defined(TRIO_PLATFORM_UNIX) +# include +# include +# include +# if !defined(TRIO_FEATURE_LOCALE) +# define USE_LOCALE +# endif +#endif /* TRIO_PLATFORM_UNIX */ +#if defined(TRIO_PLATFORM_VMS) +# include +#endif +#if defined(TRIO_PLATFORM_WIN32) +# if defined(TRIO_PLATFORM_WINCE) +int read(int handle, char *buffer, unsigned int length); +int write(int handle, const char *buffer, unsigned int length); +# else +# include +# define read _read +# define write _write +# endif +#endif /* TRIO_PLATFORM_WIN32 */ + +#if TRIO_FEATURE_WIDECHAR +# if defined(PREDEF_STANDARD_C94) +# include +# include +typedef wchar_t trio_wchar_t; +typedef wint_t trio_wint_t; +# else +typedef char trio_wchar_t; +typedef int trio_wint_t; +# define WCONST(x) L ## x +# define WEOF EOF +# define iswalnum(x) isalnum(x) +# define iswalpha(x) isalpha(x) +# define iswcntrl(x) iscntrl(x) +# define iswdigit(x) isdigit(x) +# define iswgraph(x) isgraph(x) +# define iswlower(x) islower(x) +# define iswprint(x) isprint(x) +# define iswpunct(x) ispunct(x) +# define iswspace(x) isspace(x) +# define iswupper(x) isupper(x) +# define iswxdigit(x) isxdigit(x) +# endif +#endif + + +/************************************************************************* + * Compiler dependent definitions + */ + +/* Support for long long */ +#ifndef __cplusplus +# if !defined(USE_LONGLONG) +# if defined(TRIO_COMPILER_GCC) && !defined(__STRICT_ANSI__) +# define USE_LONGLONG +# else +# if defined(TRIO_COMPILER_SUNPRO) +# define USE_LONGLONG +# else +# if defined(TRIO_COMPILER_MSVC) && (_MSC_VER >= 1400) +# define USE_LONGLONG +# else +# if defined(_LONG_LONG) || defined(_LONGLONG) +# define USE_LONGLONG +# endif +# endif +# endif +# endif +# endif +#endif + +/* The extra long numbers */ +#if defined(USE_LONGLONG) +typedef signed long long int trio_longlong_t; +typedef unsigned long long int trio_ulonglong_t; +#else +# if defined(TRIO_COMPILER_SUPPORTS_VISUALC_INT) +typedef signed __int64 trio_longlong_t; +typedef unsigned __int64 trio_ulonglong_t; +# else +typedef TRIO_SIGNED long int trio_longlong_t; +typedef unsigned long int trio_ulonglong_t; +# endif +#endif + +/* Maximal and fixed integer types */ +#if defined(PREDEF_STANDARD_C99) +# include +typedef intmax_t trio_intmax_t; +typedef uintmax_t trio_uintmax_t; +typedef int8_t trio_int8_t; +typedef int16_t trio_int16_t; +typedef int32_t trio_int32_t; +typedef int64_t trio_int64_t; +#else +# if defined(PREDEF_STANDARD_UNIX98) +# include +typedef intmax_t trio_intmax_t; +typedef uintmax_t trio_uintmax_t; +typedef int8_t trio_int8_t; +typedef int16_t trio_int16_t; +typedef int32_t trio_int32_t; +typedef int64_t trio_int64_t; +# else +# if defined(TRIO_COMPILER_SUPPORTS_VISUALC_INT) +typedef trio_longlong_t trio_intmax_t; +typedef trio_ulonglong_t trio_uintmax_t; +typedef __int8 trio_int8_t; +typedef __int16 trio_int16_t; +typedef __int32 trio_int32_t; +typedef __int64 trio_int64_t; +# else +typedef trio_longlong_t trio_intmax_t; +typedef trio_ulonglong_t trio_uintmax_t; +# if defined(TRIO_INT8_T) +typedef TRIO_INT8_T trio_int8_t; +# else +typedef TRIO_SIGNED char trio_int8_t; +# endif +# if defined(TRIO_INT16_T) +typedef TRIO_INT16_T trio_int16_t; +# else +typedef TRIO_SIGNED short trio_int16_t; +# endif +# if defined(TRIO_INT32_T) +typedef TRIO_INT32_T trio_int32_t; +# else +typedef TRIO_SIGNED int trio_int32_t; +# endif +# if defined(TRIO_INT64_T) +typedef TRIO_INT64_T trio_int64_t; +# else +typedef trio_longlong_t trio_int64_t; +# endif +# endif +# endif +#endif + +#if defined(HAVE_FLOORL) +# define trio_floor(x) floorl((x)) +#else +# define trio_floor(x) floor((double)(x)) +#endif + +#if defined(HAVE_CEILL) +# define trio_ceil(x) ceill((x)) +#else +# define trio_ceil(x) ceil((double)(x)) +#endif + +#if defined(HAVE_FMODL) +# define trio_fmod(x,y) fmodl((x),(y)) +#else +# define trio_fmod(x,y) fmod((double)(x),(double)(y)) +#endif + +#if defined(HAVE_POWL) +# define trio_pow(x,y) powl((x),(y)) +#else +# define trio_pow(x,y) pow((double)(x),(double)(y)) +#endif + +#if defined(HAVE_LOG10L) +# define trio_log10(x) log10l((x)) +#else +# define trio_log10(x) log10((double)(x)) +#endif + +#if TRIO_FEATURE_FLOAT +# define TRIO_FABS(x) (((x) < 0.0) ? -(x) : (x)) +#endif + +/************************************************************************* + * Internal Definitions + */ + +#if TRIO_FEATURE_FLOAT + +# if !defined(DECIMAL_DIG) +# define DECIMAL_DIG DBL_DIG +# endif + +/* Long double sizes */ +# ifdef LDBL_DIG +# define MAX_MANTISSA_DIGITS LDBL_DIG +# define MAX_EXPONENT_DIGITS 4 +# define MAX_DOUBLE_DIGITS LDBL_MAX_10_EXP +# else +# define MAX_MANTISSA_DIGITS DECIMAL_DIG +# define MAX_EXPONENT_DIGITS 3 +# define MAX_DOUBLE_DIGITS DBL_MAX_10_EXP +# endif + +# if defined(TRIO_COMPILER_ANCIENT) || !defined(LDBL_DIG) +# undef LDBL_DIG +# undef LDBL_MANT_DIG +# undef LDBL_EPSILON +# define LDBL_DIG DBL_DIG +# define LDBL_MANT_DIG DBL_MANT_DIG +# define LDBL_EPSILON DBL_EPSILON +# endif + +#endif /* TRIO_FEATURE_FLOAT */ + +/* The maximal number of digits is for base 2 */ +#define MAX_CHARS_IN(x) (sizeof(x) * CHAR_BIT) +/* The width of a pointer. The number of bits in a hex digit is 4 */ +#define POINTER_WIDTH ((sizeof("0x") - 1) + sizeof(trio_pointer_t) * CHAR_BIT / 4) + +#if TRIO_FEATURE_FLOAT +/* Infinite and Not-A-Number for floating-point */ +# define INFINITE_LOWER "inf" +# define INFINITE_UPPER "INF" +# define LONG_INFINITE_LOWER "infinite" +# define LONG_INFINITE_UPPER "INFINITE" +# define NAN_LOWER "nan" +# define NAN_UPPER "NAN" +#endif + +/* Various constants */ +enum { + TYPE_PRINT = 1, +#if TRIO_FEATURE_SCANF + TYPE_SCAN = 2, +#endif + + /* Flags. FLAGS_LAST must be less than ULONG_MAX */ + FLAGS_NEW = 0, + FLAGS_STICKY = 1, + FLAGS_SPACE = 2 * FLAGS_STICKY, + FLAGS_SHOWSIGN = 2 * FLAGS_SPACE, + FLAGS_LEFTADJUST = 2 * FLAGS_SHOWSIGN, + FLAGS_ALTERNATIVE = 2 * FLAGS_LEFTADJUST, + FLAGS_SHORT = 2 * FLAGS_ALTERNATIVE, + FLAGS_SHORTSHORT = 2 * FLAGS_SHORT, + FLAGS_LONG = 2 * FLAGS_SHORTSHORT, + FLAGS_QUAD = 2 * FLAGS_LONG, + FLAGS_LONGDOUBLE = 2 * FLAGS_QUAD, + FLAGS_SIZE_T = 2 * FLAGS_LONGDOUBLE, + FLAGS_PTRDIFF_T = 2 * FLAGS_SIZE_T, + FLAGS_INTMAX_T = 2 * FLAGS_PTRDIFF_T, + FLAGS_NILPADDING = 2 * FLAGS_INTMAX_T, + FLAGS_UNSIGNED = 2 * FLAGS_NILPADDING, + FLAGS_UPPER = 2UL * FLAGS_UNSIGNED, + FLAGS_WIDTH = 2 * FLAGS_UPPER, + FLAGS_WIDTH_PARAMETER = 2 * FLAGS_WIDTH, + FLAGS_PRECISION = 2 * FLAGS_WIDTH_PARAMETER, + FLAGS_PRECISION_PARAMETER = 2 * FLAGS_PRECISION, + FLAGS_BASE = 2 * FLAGS_PRECISION_PARAMETER, + FLAGS_BASE_PARAMETER = 2 * FLAGS_BASE, + FLAGS_FLOAT_E = 2 * FLAGS_BASE_PARAMETER, + FLAGS_FLOAT_G = 2 * FLAGS_FLOAT_E, + FLAGS_QUOTE = 2 * FLAGS_FLOAT_G, + FLAGS_WIDECHAR = 2 * FLAGS_QUOTE, + FLAGS_IGNORE = 2 * FLAGS_WIDECHAR, + FLAGS_IGNORE_PARAMETER = 2 * FLAGS_IGNORE, + FLAGS_VARSIZE_PARAMETER = 2 * FLAGS_IGNORE_PARAMETER, + FLAGS_FIXED_SIZE = 2 * FLAGS_VARSIZE_PARAMETER, + FLAGS_LAST = FLAGS_FIXED_SIZE, + /* Reused flags */ + FLAGS_EXCLUDE = FLAGS_SHORT, + FLAGS_USER_DEFINED = FLAGS_IGNORE, + FLAGS_USER_DEFINED_PARAMETER = FLAGS_IGNORE_PARAMETER, + FLAGS_ROUNDING = FLAGS_INTMAX_T, + /* Compounded flags */ + FLAGS_ALL_VARSIZES = FLAGS_LONG | FLAGS_QUAD | FLAGS_INTMAX_T | FLAGS_PTRDIFF_T | FLAGS_SIZE_T, + FLAGS_ALL_SIZES = FLAGS_ALL_VARSIZES | FLAGS_SHORTSHORT | FLAGS_SHORT, + + NO_POSITION = -1, + NO_WIDTH = 0, + NO_PRECISION = -1, + NO_SIZE = -1, + + /* Do not change these */ + NO_BASE = -1, + MIN_BASE = 2, + MAX_BASE = 36, + BASE_BINARY = 2, + BASE_OCTAL = 8, + BASE_DECIMAL = 10, + BASE_HEX = 16, + + /* Maximal number of allowed parameters */ + MAX_PARAMETERS = 64, + /* Maximal number of characters in class */ + MAX_CHARACTER_CLASS = UCHAR_MAX + 1, + +#if TRIO_FEATURE_USER_DEFINED + /* Maximal string lengths for user-defined specifiers */ + MAX_USER_NAME = 64, + MAX_USER_DATA = 256, +#endif + + /* Maximal length of locale separator strings */ + MAX_LOCALE_SEPARATOR_LENGTH = MB_LEN_MAX, + /* Maximal number of integers in grouping */ + MAX_LOCALE_GROUPS = 64 +}; + +#define NO_GROUPING ((int)CHAR_MAX) + +/* Fundamental formatting parameter types */ +#define FORMAT_SENTINEL -1 /* marks end of parameters array */ +#define FORMAT_UNKNOWN 0 +#define FORMAT_INT 1 +#define FORMAT_DOUBLE 2 +#define FORMAT_CHAR 3 +#define FORMAT_STRING 4 +#define FORMAT_POINTER 5 +#define FORMAT_COUNT 6 +#define FORMAT_PARAMETER 7 +#define FORMAT_GROUP 8 +#define FORMAT_ERRNO 9 +#define FORMAT_USER_DEFINED 10 + +/* Character constants */ +#define CHAR_IDENTIFIER '%' +#define CHAR_ALT_IDENTIFIER '$' +#define CHAR_BACKSLASH '\\' +#define CHAR_QUOTE '\"' +#define CHAR_ADJUST ' ' + +#if TRIO_EXTENSION +/* Character class expressions */ +# define CLASS_ALNUM "[:alnum:]" +# define CLASS_ALPHA "[:alpha:]" +# define CLASS_BLANK "[:blank:]" +# define CLASS_CNTRL "[:cntrl:]" +# define CLASS_DIGIT "[:digit:]" +# define CLASS_GRAPH "[:graph:]" +# define CLASS_LOWER "[:lower:]" +# define CLASS_PRINT "[:print:]" +# define CLASS_PUNCT "[:punct:]" +# define CLASS_SPACE "[:space:]" +# define CLASS_UPPER "[:upper:]" +# define CLASS_XDIGIT "[:xdigit:]" +#endif + +/* + * SPECIFIERS: + * + * + * a Hex-float + * A Hex-float + * c Character + * C Widechar character (wint_t) + * d Decimal + * e Float + * E Float + * F Float + * F Float + * g Float + * G Float + * i Integer + * m Error message + * n Count + * o Octal + * p Pointer + * s String + * S Widechar string (wchar_t *) + * u Unsigned + * x Hex + * X Hex + * [] Group + * <> User-defined + * + * Reserved: + * + * D Binary Coded Decimal %D(length,precision) (OS/390) + */ +#define SPECIFIER_CHAR 'c' +#define SPECIFIER_STRING 's' +#define SPECIFIER_DECIMAL 'd' +#define SPECIFIER_INTEGER 'i' +#define SPECIFIER_UNSIGNED 'u' +#define SPECIFIER_OCTAL 'o' +#define SPECIFIER_HEX 'x' +#define SPECIFIER_HEX_UPPER 'X' +#if TRIO_FEATURE_FLOAT +# define SPECIFIER_FLOAT_E 'e' +# define SPECIFIER_FLOAT_E_UPPER 'E' +# define SPECIFIER_FLOAT_F 'f' +# define SPECIFIER_FLOAT_F_UPPER 'F' +# define SPECIFIER_FLOAT_G 'g' +# define SPECIFIER_FLOAT_G_UPPER 'G' +#endif +#define SPECIFIER_POINTER 'p' +#if TRIO_FEATURE_SCANF +# define SPECIFIER_GROUP '[' +# define SPECIFIER_UNGROUP ']' +#endif +#define SPECIFIER_COUNT 'n' +#if TRIO_UNIX98 +# define SPECIFIER_CHAR_UPPER 'C' +# define SPECIFIER_STRING_UPPER 'S' +#endif +#define SPECIFIER_HEXFLOAT 'a' +#define SPECIFIER_HEXFLOAT_UPPER 'A' +#define SPECIFIER_ERRNO 'm' +#if TRIO_FEATURE_BINARY +# define SPECIFIER_BINARY 'b' +# define SPECIFIER_BINARY_UPPER 'B' +#endif +#if TRIO_FEATURE_USER_DEFINED +# define SPECIFIER_USER_DEFINED_BEGIN '<' +# define SPECIFIER_USER_DEFINED_END '>' +# define SPECIFIER_USER_DEFINED_SEPARATOR ':' +# define SPECIFIER_USER_DEFINED_EXTRA '|' +#endif + +/* + * QUALIFIERS: + * + * + * Numbers = d,i,o,u,x,X + * Float = a,A,e,E,f,F,g,G + * String = s + * Char = c + * + * + * 9$ Position + * Use the 9th parameter. 9 can be any number between 1 and + * the maximal argument + * + * 9 Width + * Set width to 9. 9 can be any number, but must not be postfixed + * by '$' + * + * h Short + * Numbers: + * (unsigned) short int + * + * hh Short short + * Numbers: + * (unsigned) char + * + * l Long + * Numbers: + * (unsigned) long int + * String: + * as the S specifier + * Char: + * as the C specifier + * + * ll Long Long + * Numbers: + * (unsigned) long long int + * + * L Long Double + * Float + * long double + * + * # Alternative + * Float: + * Decimal-point is always present + * String: + * non-printable characters are handled as \number + * + * Spacing + * + * + Sign + * + * - Alignment + * + * . Precision + * + * * Parameter + * print: use parameter + * scan: no parameter (ignore) + * + * q Quad + * + * Z size_t + * + * w Widechar + * + * ' Thousands/quote + * Numbers: + * Integer part grouped in thousands + * Binary numbers: + * Number grouped in nibbles (4 bits) + * String: + * Quoted string + * + * j intmax_t + * t prtdiff_t + * z size_t + * + * ! Sticky + * @ Parameter (for both print and scan) + * + * I n-bit Integer + * Numbers: + * The following options exists + * I8 = 8-bit integer + * I16 = 16-bit integer + * I32 = 32-bit integer + * I64 = 64-bit integer + */ +#define QUALIFIER_POSITION '$' +#define QUALIFIER_SHORT 'h' +#define QUALIFIER_LONG 'l' +#define QUALIFIER_LONG_UPPER 'L' +#define QUALIFIER_ALTERNATIVE '#' +#define QUALIFIER_SPACE ' ' +#define QUALIFIER_PLUS '+' +#define QUALIFIER_MINUS '-' +#define QUALIFIER_DOT '.' +#define QUALIFIER_STAR '*' +#define QUALIFIER_CIRCUMFLEX '^' /* For scanlists */ +#define QUALIFIER_SIZE_T 'z' +#define QUALIFIER_PTRDIFF_T 't' +#define QUALIFIER_INTMAX_T 'j' +#define QUALIFIER_QUAD 'q' +#define QUALIFIER_SIZE_T_UPPER 'Z' +#if TRIO_MISC +# define QUALIFIER_WIDECHAR 'w' +#endif +#define QUALIFIER_FIXED_SIZE 'I' +#define QUALIFIER_QUOTE '\'' +#define QUALIFIER_STICKY '!' +#define QUALIFIER_VARSIZE '&' /* This should remain undocumented */ +#define QUALIFIER_ROUNDING_UPPER 'R' +#if TRIO_EXTENSION +# define QUALIFIER_PARAM '@' /* Experimental */ +# define QUALIFIER_COLON ':' /* For scanlists */ +# define QUALIFIER_EQUAL '=' /* For scanlists */ +#endif + + +/************************************************************************* + * + * Internal Structures + * + *************************************************************************/ + +/* Parameters */ +typedef struct { + /* An indication of which entry in the data union is used */ + int type; + /* The flags */ + trio_flags_t flags; + /* The width qualifier */ + int width; + /* The precision qualifier */ + int precision; + /* The base qualifier */ + int base; + /* Base from specifier */ + int baseSpecifier; + /* The size for the variable size qualifier */ + int varsize; + /* Offset of the first character of the specifier */ + int beginOffset; + /* Offset of the first character after the specifier */ + int endOffset; + /* Position in the argument list that this parameter refers to */ + int position; + /* The data from the argument list */ + union { + char *string; +#if TRIO_FEATURE_WIDECHAR + trio_wchar_t *wstring; +#endif + trio_pointer_t pointer; + union { + trio_intmax_t as_signed; + trio_uintmax_t as_unsigned; + } number; +#if TRIO_FEATURE_FLOAT + double doubleNumber; + double *doublePointer; + trio_long_double_t longdoubleNumber; + trio_long_double_t *longdoublePointer; +#endif + int errorNumber; + } data; +#if TRIO_FEATURE_USER_DEFINED + /* For the user-defined specifier */ + union { + char namespace[MAX_USER_NAME]; + int handler; /* if flags & FLAGS_USER_DEFINED_PARAMETER */ + } user_defined; + char user_data[MAX_USER_DATA]; +#endif +} trio_parameter_t; + +/* Container for customized functions */ +typedef struct { + union { + trio_outstream_t out; + trio_instream_t in; + } stream; + trio_pointer_t closure; +} trio_custom_t; + +/* General trio "class" */ +typedef struct _trio_class_t { + /* + * The function to write characters to a stream. + */ + void (*OutStream) TRIO_PROTO((struct _trio_class_t *, int)); + /* + * The function to read characters from a stream. + */ + void (*InStream) TRIO_PROTO((struct _trio_class_t *, int *)); + /* + * The function to undo read characters from a stream. + */ + void (*UndoStream) TRIO_PROTO((struct _trio_class_t *)); + /* + * The current location in the stream. + */ + trio_pointer_t location; + /* + * The character currently being processed. + */ + int current; + /* + * The number of characters that would have been written/read + * if there had been sufficient space. + */ + int processed; + union { + /* + * The number of characters that are actually written. Processed and + * committed will only differ for the *nprintf functions. + */ + int committed; + /* + * The number of look-ahead characters read. + */ + int cached; + } actually; + /* + * The upper limit of characters that may be written/read. + */ + int max; + /* + * The last output error that was detected. + */ + int error; +} trio_class_t; + +/* References (for user-defined callbacks) */ +typedef struct _trio_reference_t { + trio_class_t *data; + trio_parameter_t *parameter; +} trio_reference_t; + +#if TRIO_FEATURE_USER_DEFINED +/* Registered entries (for user-defined callbacks) */ +typedef struct _trio_userdef_t { + struct _trio_userdef_t *next; + trio_callback_t callback; + char *name; +} trio_userdef_t; +#endif + +/************************************************************************* + * + * Internal Variables + * + *************************************************************************/ + +#if TRIO_FEATURE_FLOAT +/* + * Need this to workaround a parser bug in HP C/iX compiler that fails + * to resolves macro definitions that includes type 'long double', + * e.g: va_arg(arg_ptr, long double) + */ +# if defined(TRIO_PLATFORM_MPEIX) +static TRIO_CONST trio_long_double_t ___dummy_long_double = 0; +# endif +#endif + +static TRIO_CONST char internalNullString[] = "(nil)"; + +#if defined(USE_LOCALE) +static struct lconv *internalLocaleValues = NULL; +#endif + +/* + * UNIX98 says "in a locale where the radix character is not defined, + * the radix character defaults to a period (.)" + */ +#if TRIO_FEATURE_FLOAT || TRIO_FEATURE_LOCALE || defined(USE_LOCALE) +static int internalDecimalPointLength = 1; +static char internalDecimalPoint = '.'; +static char internalDecimalPointString[MAX_LOCALE_SEPARATOR_LENGTH + 1] = "."; +#endif +#if TRIO_FEATURE_QUOTE || TRIO_FEATURE_LOCALE || TRIO_EXTENSION +static int internalThousandSeparatorLength = 1; +static char internalThousandSeparator[MAX_LOCALE_SEPARATOR_LENGTH + 1] = ","; +static char internalGrouping[MAX_LOCALE_GROUPS] = { (char)NO_GROUPING }; +#endif + +static TRIO_CONST char internalDigitsLower[] = "0123456789abcdefghijklmnopqrstuvwxyz"; +static TRIO_CONST char internalDigitsUpper[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; +#if TRIO_FEATURE_SCANF +static BOOLEAN_T internalDigitsUnconverted = TRUE; +static int internalDigitArray[128]; +# if TRIO_EXTENSION +static BOOLEAN_T internalCollationUnconverted = TRUE; +static char internalCollationArray[MAX_CHARACTER_CLASS][MAX_CHARACTER_CLASS]; +# endif +#endif + +#if TRIO_FEATURE_USER_DEFINED +static TRIO_VOLATILE trio_callback_t internalEnterCriticalRegion = NULL; +static TRIO_VOLATILE trio_callback_t internalLeaveCriticalRegion = NULL; +static trio_userdef_t *internalUserDef = NULL; +#endif + + +/************************************************************************* + * + * Internal Functions + * + ************************************************************************/ + +#if defined(TRIO_EMBED_STRING) +# include "triostr.c" +#endif + +/************************************************************************* + * TrioInitializeParameter + * + * Description: + * Initialize a trio_parameter_t struct. + */ +TRIO_PRIVATE void +TrioInitializeParameter +TRIO_ARGS1((parameter), + trio_parameter_t *parameter) +{ + parameter->type = FORMAT_UNKNOWN; + parameter->flags = 0; + parameter->width = 0; + parameter->precision = 0; + parameter->base = 0; + parameter->baseSpecifier = 0; + parameter->varsize = 0; + parameter->beginOffset = 0; + parameter->endOffset = 0; + parameter->position = 0; + parameter->data.pointer = 0; +#if TRIO_FEATURE_USER_DEFINED + parameter->user_defined.handler = 0; + parameter->user_data[0] = 0; +#endif +} + +/************************************************************************* + * TrioCopyParameter + * + * Description: + * Copies one trio_parameter_t struct to another. + */ +TRIO_PRIVATE void +TrioCopyParameter +TRIO_ARGS2((target, source), + trio_parameter_t *target, + TRIO_CONST trio_parameter_t *source) +{ +#if TRIO_FEATURE_USER_DEFINED + size_t i; +#endif + + target->type = source->type; + target->flags = source->flags; + target->width = source->width; + target->precision = source->precision; + target->base = source->base; + target->baseSpecifier = source->baseSpecifier; + target->varsize = source->varsize; + target->beginOffset = source->beginOffset; + target->endOffset = source->endOffset; + target->position = source->position; + target->data = source->data; + +#if TRIO_FEATURE_USER_DEFINED + target->user_defined = source->user_defined; + + for (i = 0U; i < sizeof(target->user_data); ++i) + { + if ((target->user_data[i] = source->user_data[i]) == NIL) + break; + } +#endif +} + +/************************************************************************* + * TrioIsQualifier + * + * Description: + * Remember to add all new qualifiers to this function. + * QUALIFIER_POSITION must not be added. + */ +TRIO_PRIVATE BOOLEAN_T +TrioIsQualifier +TRIO_ARGS1((character), + TRIO_CONST char character) +{ + /* QUALIFIER_POSITION is not included */ + switch (character) + { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + case QUALIFIER_PLUS: + case QUALIFIER_MINUS: + case QUALIFIER_SPACE: + case QUALIFIER_DOT: + case QUALIFIER_STAR: + case QUALIFIER_ALTERNATIVE: + case QUALIFIER_SHORT: + case QUALIFIER_LONG: + case QUALIFIER_CIRCUMFLEX: + case QUALIFIER_LONG_UPPER: + case QUALIFIER_SIZE_T: + case QUALIFIER_PTRDIFF_T: + case QUALIFIER_INTMAX_T: + case QUALIFIER_QUAD: + case QUALIFIER_SIZE_T_UPPER: +#if defined(QUALIFIER_WIDECHAR) + case QUALIFIER_WIDECHAR: +#endif + case QUALIFIER_QUOTE: + case QUALIFIER_STICKY: + case QUALIFIER_VARSIZE: +#if defined(QUALIFIER_PARAM) + case QUALIFIER_PARAM: +#endif + case QUALIFIER_FIXED_SIZE: + case QUALIFIER_ROUNDING_UPPER: + return TRUE; + default: + return FALSE; + } +} + +/************************************************************************* + * TrioSetLocale + */ +#if defined(USE_LOCALE) +TRIO_PRIVATE void +TrioSetLocale(TRIO_NOARGS) +{ + internalLocaleValues = (struct lconv *)localeconv(); + if (internalLocaleValues) + { + if ((internalLocaleValues->decimal_point) && + (internalLocaleValues->decimal_point[0] != NIL)) + { + internalDecimalPointLength = trio_length(internalLocaleValues->decimal_point); + if (internalDecimalPointLength == 1) + { + internalDecimalPoint = internalLocaleValues->decimal_point[0]; + } + else + { + internalDecimalPoint = NIL; + trio_copy_max(internalDecimalPointString, + sizeof(internalDecimalPointString), + internalLocaleValues->decimal_point); + } + } +# if TRIO_EXTENSION + if ((internalLocaleValues->thousands_sep) && + (internalLocaleValues->thousands_sep[0] != NIL)) + { + trio_copy_max(internalThousandSeparator, + sizeof(internalThousandSeparator), + internalLocaleValues->thousands_sep); + internalThousandSeparatorLength = trio_length(internalThousandSeparator); + } +# endif +# if TRIO_EXTENSION + if ((internalLocaleValues->grouping) && + (internalLocaleValues->grouping[0] != NIL)) + { + trio_copy_max(internalGrouping, + sizeof(internalGrouping), + internalLocaleValues->grouping); + } +# endif + } +} +#endif /* defined(USE_LOCALE) */ + +#if TRIO_FEATURE_FLOAT && TRIO_FEATURE_QUOTE +TRIO_PRIVATE int +TrioCalcThousandSeparatorLength +TRIO_ARGS1((digits), + int digits) +{ + int count = 0; + int step = NO_GROUPING; + char *groupingPointer = internalGrouping; + + while (digits > 0) + { + if (*groupingPointer == CHAR_MAX) + { + /* Disable grouping */ + break; /* while */ + } + else if (*groupingPointer == 0) + { + /* Repeat last group */ + if (step == NO_GROUPING) + { + /* Error in locale */ + break; /* while */ + } + } + else + { + step = *groupingPointer++; + } + if (digits > step) + count += internalThousandSeparatorLength; + digits -= step; + } + return count; +} +#endif /* TRIO_FEATURE_FLOAT && TRIO_FEATURE_QUOTE */ + +#if TRIO_FEATURE_QUOTE +TRIO_PRIVATE BOOLEAN_T +TrioFollowedBySeparator +TRIO_ARGS1((position), + int position) +{ + int step = 0; + char *groupingPointer = internalGrouping; + + position--; + if (position == 0) + return FALSE; + while (position > 0) + { + if (*groupingPointer == CHAR_MAX) + { + /* Disable grouping */ + break; /* while */ + } + else if (*groupingPointer != 0) + { + step = *groupingPointer++; + } + if (step == 0) + break; + position -= step; + } + return (position == 0); +} +#endif /* TRIO_FEATURE_QUOTE */ + +/************************************************************************* + * TrioGetPosition + * + * Get the %n$ position. + */ +TRIO_PRIVATE int +TrioGetPosition +TRIO_ARGS2((format, offsetPointer), + TRIO_CONST char *format, + int *offsetPointer) +{ +#if TRIO_FEATURE_POSITIONAL + char *tmpformat; + int number = 0; + int offset = *offsetPointer; + + number = (int)trio_to_long(&format[offset], &tmpformat, BASE_DECIMAL); + offset = (int)(tmpformat - format); + if ((number != 0) && (QUALIFIER_POSITION == format[offset++])) + { + *offsetPointer = offset; + /* + * number is decreased by 1, because n$ starts from 1, whereas + * the array it is indexing starts from 0. + */ + return number - 1; + } +#endif + return NO_POSITION; +} + +/************************************************************************* + * TrioFindNamespace + * + * Find registered user-defined specifier. + * The prev argument is used for optimization only. + */ +#if TRIO_FEATURE_USER_DEFINED +TRIO_PRIVATE trio_userdef_t * +TrioFindNamespace +TRIO_ARGS2((name, prev), + TRIO_CONST char *name, + trio_userdef_t **prev) +{ + trio_userdef_t *def; + + if (internalEnterCriticalRegion) + (void)internalEnterCriticalRegion(NULL); + + for (def = internalUserDef; def; def = def->next) + { + /* Case-sensitive string comparison */ + if (trio_equal_case(def->name, name)) + break; + + if (prev) + *prev = def; + } + + if (internalLeaveCriticalRegion) + (void)internalLeaveCriticalRegion(NULL); + + return def; +} +#endif + +/************************************************************************* + * TrioPower + * + * Description: + * Calculate pow(base, exponent), where number and exponent are integers. + */ +#if TRIO_FEATURE_FLOAT +TRIO_PRIVATE trio_long_double_t +TrioPower +TRIO_ARGS2((number, exponent), + int number, + int exponent) +{ + trio_long_double_t result; + + if (number == 10) + { + switch (exponent) + { + /* Speed up calculation of common cases */ + case 0: + result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E-1); + break; + case 1: + result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+0); + break; + case 2: + result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+1); + break; + case 3: + result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+2); + break; + case 4: + result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+3); + break; + case 5: + result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+4); + break; + case 6: + result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+5); + break; + case 7: + result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+6); + break; + case 8: + result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+7); + break; + case 9: + result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+8); + break; + default: + result = trio_pow((trio_long_double_t)number, + (trio_long_double_t)exponent); + break; + } + } + else + { + return trio_pow((trio_long_double_t)number, + (trio_long_double_t)exponent); + } + return result; +} +#endif /* TRIO_FEATURE_FLOAT */ + +/************************************************************************* + * TrioLogarithm + */ +#if TRIO_FEATURE_FLOAT +TRIO_PRIVATE trio_long_double_t +TrioLogarithm +TRIO_ARGS2((number, base), + trio_long_double_t number, + int base) +{ + trio_long_double_t result; + + if (number <= 0.0) + { + /* xlC crashes on log(0) */ + result = (number == 0.0) ? trio_ninf() : trio_nan(); + } + else + { + if (base == 10) + { + result = trio_log10(number); + } + else + { + result = trio_log10(number) / trio_log10((double)base); + } + } + return result; +} +#endif /* TRIO_FEATURE_FLOAT */ + +/************************************************************************* + * TrioLogarithmBase + */ +#if TRIO_FEATURE_FLOAT +TRIO_PRIVATE double +TrioLogarithmBase +TRIO_ARGS1((base), + int base) +{ + switch (base) + { + case BASE_BINARY : return 1.0; + case BASE_OCTAL : return 3.0; + case BASE_DECIMAL: return 3.321928094887362345; + case BASE_HEX : return 4.0; + default : return TrioLogarithm((double)base, 2); + } +} +#endif /* TRIO_FEATURE_FLOAT */ + +/************************************************************************* + * TrioParseQualifiers + * + * Description: + * Parse the qualifiers of a potential conversion specifier + */ +TRIO_PRIVATE int +TrioParseQualifiers +TRIO_ARGS4((type, format, offset, parameter), + int type, + TRIO_CONST char *format, + int offset, + trio_parameter_t *parameter) +{ + char ch; + int dots = 0; /* Count number of dots in modifier part */ + char *tmpformat; + + parameter->beginOffset = offset - 1; + parameter->flags = FLAGS_NEW; + parameter->position = TrioGetPosition(format, &offset); + + /* Default values */ + parameter->width = NO_WIDTH; + parameter->precision = NO_PRECISION; + parameter->base = NO_BASE; + parameter->varsize = NO_SIZE; + + while (TrioIsQualifier(format[offset])) + { + ch = format[offset++]; + + switch (ch) + { + case QUALIFIER_SPACE: + parameter->flags |= FLAGS_SPACE; + break; + + case QUALIFIER_PLUS: + parameter->flags |= FLAGS_SHOWSIGN; + break; + + case QUALIFIER_MINUS: + parameter->flags |= FLAGS_LEFTADJUST; + parameter->flags &= ~FLAGS_NILPADDING; + break; + + case QUALIFIER_ALTERNATIVE: + parameter->flags |= FLAGS_ALTERNATIVE; + break; + + case QUALIFIER_DOT: + if (dots == 0) /* Precision */ + { + dots++; + + /* Skip if no precision */ + if (QUALIFIER_DOT == format[offset]) + break; + + /* After the first dot we have the precision */ + parameter->flags |= FLAGS_PRECISION; + if ((QUALIFIER_STAR == format[offset]) +#if defined(QUALIFIER_PARAM) + || (QUALIFIER_PARAM == format[offset]) +#endif + ) + { + offset++; + parameter->flags |= FLAGS_PRECISION_PARAMETER; + parameter->precision = TrioGetPosition(format, &offset); + } + else + { + parameter->precision = trio_to_long(&format[offset], + &tmpformat, + BASE_DECIMAL); + offset = (int)(tmpformat - format); + } + } + else if (dots == 1) /* Base */ + { + dots++; + + /* After the second dot we have the base */ + parameter->flags |= FLAGS_BASE; + if ((QUALIFIER_STAR == format[offset]) +#if defined(QUALIFIER_PARAM) + || (QUALIFIER_PARAM == format[offset]) +#endif + ) + { + offset++; + parameter->flags |= FLAGS_BASE_PARAMETER; + parameter->base = TrioGetPosition(format, &offset); + } + else + { + parameter->base = trio_to_long(&format[offset], + &tmpformat, + BASE_DECIMAL); + if (parameter->base > MAX_BASE) + return TRIO_ERROR_RETURN(TRIO_EINVAL, offset); + offset = (int)(tmpformat - format); + } + } + else + { + return TRIO_ERROR_RETURN(TRIO_EINVAL, offset); + } + break; /* QUALIFIER_DOT */ + +#if defined(QUALIFIER_PARAM) + case QUALIFIER_PARAM: + parameter->type = TYPE_PRINT; + /* FALLTHROUGH */ +#endif + case QUALIFIER_STAR: + /* This has different meanings for print and scan */ + if (TYPE_PRINT == type) + { + /* Read with from parameter */ + int width = TrioGetPosition(format, &offset); + parameter->flags |= (FLAGS_WIDTH | FLAGS_WIDTH_PARAMETER); + if (NO_POSITION != width) + parameter->width = width; + /* else keep parameter->width = NO_WIDTH which != NO_POSITION */ + } +#if TRIO_FEATURE_SCANF + else + { + /* Scan, but do not store result */ + parameter->flags |= FLAGS_IGNORE; + } +#endif + break; /* QUALIFIER_STAR */ + + case '0': + if (! (parameter->flags & FLAGS_LEFTADJUST)) + parameter->flags |= FLAGS_NILPADDING; + /* FALLTHROUGH */ + case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + parameter->flags |= FLAGS_WIDTH; + /* + * &format[offset - 1] is used to "rewind" the read + * character from format + */ + parameter->width = trio_to_long(&format[offset - 1], + &tmpformat, + BASE_DECIMAL); + offset = (int)(tmpformat - format); + break; + + case QUALIFIER_SHORT: + if (parameter->flags & FLAGS_SHORTSHORT) + return TRIO_ERROR_RETURN(TRIO_EINVAL, offset); + else if (parameter->flags & FLAGS_SHORT) + parameter->flags |= FLAGS_SHORTSHORT; + else + parameter->flags |= FLAGS_SHORT; + break; + + case QUALIFIER_LONG: + if (parameter->flags & FLAGS_QUAD) + return TRIO_ERROR_RETURN(TRIO_EINVAL, offset); + else if (parameter->flags & FLAGS_LONG) + parameter->flags |= FLAGS_QUAD; + else + parameter->flags |= FLAGS_LONG; + break; + +#if TRIO_FEATURE_LONGDOUBLE + case QUALIFIER_LONG_UPPER: + parameter->flags |= FLAGS_LONGDOUBLE; + break; +#endif + +#if TRIO_FEATURE_SIZE_T + case QUALIFIER_SIZE_T: + parameter->flags |= FLAGS_SIZE_T; + /* Modify flags for later truncation of number */ + if (sizeof(size_t) == sizeof(trio_ulonglong_t)) + parameter->flags |= FLAGS_QUAD; + else if (sizeof(size_t) == sizeof(long)) + parameter->flags |= FLAGS_LONG; + break; +#endif + +#if TRIO_FEATURE_PTRDIFF_T + case QUALIFIER_PTRDIFF_T: + parameter->flags |= FLAGS_PTRDIFF_T; + if (sizeof(ptrdiff_t) == sizeof(trio_ulonglong_t)) + parameter->flags |= FLAGS_QUAD; + else if (sizeof(ptrdiff_t) == sizeof(long)) + parameter->flags |= FLAGS_LONG; + break; +#endif + +#if TRIO_FEATURE_INTMAX_T + case QUALIFIER_INTMAX_T: + parameter->flags |= FLAGS_INTMAX_T; + if (sizeof(trio_intmax_t) == sizeof(trio_ulonglong_t)) + parameter->flags |= FLAGS_QUAD; + else if (sizeof(trio_intmax_t) == sizeof(long)) + parameter->flags |= FLAGS_LONG; + break; +#endif + +#if TRIO_FEATURE_QUAD + case QUALIFIER_QUAD: + parameter->flags |= FLAGS_QUAD; + break; +#endif + +#if TRIO_FEATURE_FIXED_SIZE + case QUALIFIER_FIXED_SIZE: + if (parameter->flags & FLAGS_FIXED_SIZE) + return TRIO_ERROR_RETURN(TRIO_EINVAL, offset); + + if (parameter->flags & (FLAGS_ALL_SIZES | + FLAGS_LONGDOUBLE | + FLAGS_WIDECHAR | + FLAGS_VARSIZE_PARAMETER)) + return TRIO_ERROR_RETURN(TRIO_EINVAL, offset); + + if ((format[offset] == '6') && + (format[offset + 1] == '4')) + { + parameter->varsize = sizeof(trio_int64_t); + offset += 2; + } + else if ((format[offset] == '3') && + (format[offset + 1] == '2')) + { + parameter->varsize = sizeof(trio_int32_t); + offset += 2; + } + else if ((format[offset] == '1') && + (format[offset + 1] == '6')) + { + parameter->varsize = sizeof(trio_int16_t); + offset += 2; + } + else if (format[offset] == '8') + { + parameter->varsize = sizeof(trio_int8_t); + offset++; + } + else + return TRIO_ERROR_RETURN(TRIO_EINVAL, offset); + + parameter->flags |= FLAGS_FIXED_SIZE; + break; +#endif /* TRIO_FEATURE_FIXED_SIZE */ + +#if defined(QUALIFIER_WIDECHAR) + case QUALIFIER_WIDECHAR: + parameter->flags |= FLAGS_WIDECHAR; + break; +#endif + +#if TRIO_FEATURE_SIZE_T_UPPER + case QUALIFIER_SIZE_T_UPPER: + break; +#endif + +#if TRIO_FEATURE_QUOTE + case QUALIFIER_QUOTE: + parameter->flags |= FLAGS_QUOTE; + break; +#endif + +#if TRIO_FEATURE_STICKY + case QUALIFIER_STICKY: + parameter->flags |= FLAGS_STICKY; + break; +#endif + +#if TRIO_FEATURE_VARSIZE + case QUALIFIER_VARSIZE: + parameter->flags |= FLAGS_VARSIZE_PARAMETER; + break; +#endif + +#if TRIO_FEATURE_ROUNDING + case QUALIFIER_ROUNDING_UPPER: + parameter->flags |= FLAGS_ROUNDING; + break; +#endif + + default: + /* Bail out completely to make the error more obvious */ + return TRIO_ERROR_RETURN(TRIO_EINVAL, offset); + } + } /* while qualifier */ + + parameter->endOffset = offset; + + return 0; +} + +/************************************************************************* + * TrioParseSpecifier + * + * Description: + * Parse the specifier part of a potential conversion specifier + */ +TRIO_PRIVATE int +TrioParseSpecifier +TRIO_ARGS4((type, format, offset, parameter), + int type, + TRIO_CONST char *format, + int offset, + trio_parameter_t *parameter) +{ + parameter->baseSpecifier = NO_BASE; + + switch (format[offset++]) + { +#if defined(SPECIFIER_CHAR_UPPER) + case SPECIFIER_CHAR_UPPER: + parameter->flags |= FLAGS_WIDECHAR; + /* FALLTHROUGH */ +#endif + case SPECIFIER_CHAR: + if (parameter->flags & FLAGS_LONG) + parameter->flags |= FLAGS_WIDECHAR; + else if (parameter->flags & FLAGS_SHORT) + parameter->flags &= ~FLAGS_WIDECHAR; + parameter->type = FORMAT_CHAR; + break; + +#if defined(SPECIFIER_STRING_UPPER) + case SPECIFIER_STRING_UPPER: + parameter->flags |= FLAGS_WIDECHAR; + /* FALLTHROUGH */ +#endif + case SPECIFIER_STRING: + if (parameter->flags & FLAGS_LONG) + parameter->flags |= FLAGS_WIDECHAR; + else if (parameter->flags & FLAGS_SHORT) + parameter->flags &= ~FLAGS_WIDECHAR; + parameter->type = FORMAT_STRING; + break; + +#if defined(SPECIFIER_GROUP) + case SPECIFIER_GROUP: + if (TYPE_SCAN == type) + { + int depth = 1; + parameter->type = FORMAT_GROUP; + if (format[offset] == QUALIFIER_CIRCUMFLEX) + offset++; + if (format[offset] == SPECIFIER_UNGROUP) + offset++; + if (format[offset] == QUALIFIER_MINUS) + offset++; + /* Skip nested brackets */ + while (format[offset] != NIL) + { + if (format[offset] == SPECIFIER_GROUP) + { + depth++; + } + else if (format[offset] == SPECIFIER_UNGROUP) + { + if (--depth <= 0) + { + offset++; + break; + } + } + offset++; + } + } + break; +#endif /* defined(SPECIFIER_GROUP) */ + + case SPECIFIER_INTEGER: + parameter->type = FORMAT_INT; + break; + + case SPECIFIER_UNSIGNED: + parameter->flags |= FLAGS_UNSIGNED; + parameter->type = FORMAT_INT; + break; + + case SPECIFIER_DECIMAL: + parameter->baseSpecifier = BASE_DECIMAL; + parameter->type = FORMAT_INT; + break; + + case SPECIFIER_OCTAL: + parameter->flags |= FLAGS_UNSIGNED; + parameter->baseSpecifier = BASE_OCTAL; + parameter->type = FORMAT_INT; + break; + +#if TRIO_FEATURE_BINARY + case SPECIFIER_BINARY_UPPER: + parameter->flags |= FLAGS_UPPER; + /* FALLTHROUGH */ + case SPECIFIER_BINARY: + parameter->flags |= FLAGS_NILPADDING; + parameter->baseSpecifier = BASE_BINARY; + parameter->type = FORMAT_INT; + break; +#endif + + case SPECIFIER_HEX_UPPER: + parameter->flags |= FLAGS_UPPER; + /* FALLTHROUGH */ + case SPECIFIER_HEX: + parameter->flags |= FLAGS_UNSIGNED; + parameter->baseSpecifier = BASE_HEX; + parameter->type = FORMAT_INT; + break; + +#if defined(SPECIFIER_FLOAT_E) +# if defined(SPECIFIER_FLOAT_E_UPPER) + case SPECIFIER_FLOAT_E_UPPER: + parameter->flags |= FLAGS_UPPER; + /* FALLTHROUGH */ +# endif + case SPECIFIER_FLOAT_E: + parameter->flags |= FLAGS_FLOAT_E; + parameter->type = FORMAT_DOUBLE; + break; +#endif + +#if defined(SPECIFIER_FLOAT_G) +# if defined(SPECIFIER_FLOAT_G_UPPER) + case SPECIFIER_FLOAT_G_UPPER: + parameter->flags |= FLAGS_UPPER; + /* FALLTHROUGH */ +# endif + case SPECIFIER_FLOAT_G: + parameter->flags |= FLAGS_FLOAT_G; + parameter->type = FORMAT_DOUBLE; + break; +#endif + +#if defined(SPECIFIER_FLOAT_F) +# if defined(SPECIFIER_FLOAT_F_UPPER) + case SPECIFIER_FLOAT_F_UPPER: + parameter->flags |= FLAGS_UPPER; + /* FALLTHROUGH */ +# endif + case SPECIFIER_FLOAT_F: + parameter->type = FORMAT_DOUBLE; + break; +#endif + +#if defined(TRIO_COMPILER_VISUALC) +# pragma warning( push ) +# pragma warning( disable : 4127 ) /* Conditional expression is constant */ +#endif + case SPECIFIER_POINTER: + if (sizeof(trio_pointer_t) == sizeof(trio_ulonglong_t)) + parameter->flags |= FLAGS_QUAD; + else if (sizeof(trio_pointer_t) == sizeof(long)) + parameter->flags |= FLAGS_LONG; + parameter->type = FORMAT_POINTER; + break; +#if defined(TRIO_COMPILER_VISUALC) +# pragma warning( pop ) +#endif + + case SPECIFIER_COUNT: + parameter->type = FORMAT_COUNT; + break; + +#if TRIO_FEATURE_HEXFLOAT + case SPECIFIER_HEXFLOAT_UPPER: + parameter->flags |= FLAGS_UPPER; + /* FALLTHROUGH */ + case SPECIFIER_HEXFLOAT: + parameter->baseSpecifier = BASE_HEX; + parameter->type = FORMAT_DOUBLE; + break; +#endif + +#if TRIO_FEATURE_ERRNO + case SPECIFIER_ERRNO: + parameter->type = FORMAT_ERRNO; + break; +#endif + +#if TRIO_FEATURE_USER_DEFINED + case SPECIFIER_USER_DEFINED_BEGIN: + { + unsigned int max; + int without_namespace = TRUE; + char* tmpformat = (char *)&format[offset]; + int ch; + + parameter->type = FORMAT_USER_DEFINED; + parameter->user_defined.namespace[0] = NIL; + + while ((ch = format[offset]) != NIL) + { + offset++; + if ((ch == SPECIFIER_USER_DEFINED_END) || (ch == SPECIFIER_USER_DEFINED_EXTRA)) + { + if (without_namespace) + /* No namespace, handler will be passed as an argument */ + parameter->flags |= FLAGS_USER_DEFINED_PARAMETER; + + /* Copy the user data */ + max = (unsigned int)(&format[offset] - tmpformat); + if (max > MAX_USER_DATA) + max = MAX_USER_DATA; + trio_copy_max(parameter->user_data, max, tmpformat); + + /* Skip extra data (which is only there to keep the compiler happy) */ + while ((ch != NIL) && (ch != SPECIFIER_USER_DEFINED_END)) + ch = format[offset++]; + + break; /* while */ + } + + if (ch == SPECIFIER_USER_DEFINED_SEPARATOR) + { + without_namespace = FALSE; + /* Copy the namespace for later looking-up */ + max = (int)(&format[offset] - tmpformat); + if (max > MAX_USER_NAME) + max = MAX_USER_NAME; + trio_copy_max(parameter->user_defined.namespace, max, tmpformat); + tmpformat = (char *)&format[offset]; + } + } + + if (ch != SPECIFIER_USER_DEFINED_END) + return TRIO_ERROR_RETURN(TRIO_EINVAL, offset); + } + break; +#endif /* TRIO_FEATURE_USER_DEFINED */ + + default: + /* Bail out completely to make the error more obvious */ + return TRIO_ERROR_RETURN(TRIO_EINVAL, offset); + } + + parameter->endOffset = offset; + + return 0; +} + +/************************************************************************* + * TrioParse + * + * Description: + * Parse the format string + */ +TRIO_PRIVATE int +TrioParse +TRIO_ARGS5((type, format, parameters, arglist, argarray), + int type, + TRIO_CONST char *format, + trio_parameter_t *parameters, + va_list arglist, + trio_pointer_t *argarray) +{ + /* Count the number of times a parameter is referenced */ + unsigned short usedEntries[MAX_PARAMETERS]; + /* Parameter counters */ + int parameterPosition; + int maxParam = -1; + /* Utility variables */ + int offset; /* Offset into formatting string */ + BOOLEAN_T positional; /* Does the specifier have a positional? */ +#if TRIO_FEATURE_STICKY + BOOLEAN_T gotSticky = FALSE; /* Are there any sticky modifiers at all? */ +#endif + /* + * indices specifies the order in which the parameters must be + * read from the va_args (this is necessary to handle positionals) + */ + int indices[MAX_PARAMETERS]; + int pos = 0; + /* Various variables */ + int save_errno; + int i = -1; + int num; + trio_parameter_t workParameter; + int status; + + /* + * The 'parameters' array is not initialized, but we need to + * know which entries we have used. + */ + memset(usedEntries, 0, sizeof(usedEntries)); + + save_errno = errno; + offset = 0; + parameterPosition = 0; + + while (format[offset]) + { + TrioInitializeParameter(&workParameter); + + switch(format[offset++]) { + + case CHAR_IDENTIFIER: + { + if (CHAR_IDENTIFIER == format[offset]) + { + /* skip double "%" */ + offset++; + continue; /* while */ + } + + status = TrioParseQualifiers(type, format, offset, &workParameter); + if (status < 0) + return status; /* Return qualifier syntax error */ + + status = TrioParseSpecifier(type, format, workParameter.endOffset, &workParameter); + if (status < 0) + return status; /* Return specifier syntax error */ + } + break; + +#if TRIO_EXTENSION + case CHAR_ALT_IDENTIFIER: + { + status = TrioParseQualifiers(type, format, offset, &workParameter); + if (status < 0) + continue; /* False alert, not a user defined specifier */ + + status = TrioParseSpecifier(type, format, workParameter.endOffset, &workParameter); + if ((status < 0) || (FORMAT_USER_DEFINED != workParameter.type)) + continue; /* False alert, not a user defined specifier */ + } + break; +#endif + + default: + continue; /* while */ + } + + /* now handle the parsed conversion specification */ + positional = (NO_POSITION != workParameter.position); + + /* + * Parameters only need the type and value. The value is + * read later. + */ + if (workParameter.flags & FLAGS_WIDTH_PARAMETER) + { + if (workParameter.width == NO_WIDTH) + { + workParameter.width = parameterPosition++; + } + else + { + if (! positional) + workParameter.position = workParameter.width + 1; + } + + usedEntries[workParameter.width] += 1; + if (workParameter.width > maxParam) + maxParam = workParameter.width; + parameters[pos].type = FORMAT_PARAMETER; + parameters[pos].flags = 0; + indices[workParameter.width] = pos; + workParameter.width = pos++; + } + if (workParameter.flags & FLAGS_PRECISION_PARAMETER) + { + if (workParameter.precision == NO_PRECISION) + { + workParameter.precision = parameterPosition++; + } + else + { + if (! positional) + workParameter.position = workParameter.precision + 1; + } + + usedEntries[workParameter.precision] += 1; + if (workParameter.precision > maxParam) + maxParam = workParameter.precision; + parameters[pos].type = FORMAT_PARAMETER; + parameters[pos].flags = 0; + indices[workParameter.precision] = pos; + workParameter.precision = pos++; + } + if (workParameter.flags & FLAGS_BASE_PARAMETER) + { + if (workParameter.base == NO_BASE) + { + workParameter.base = parameterPosition++; + } + else + { + if (! positional) + workParameter.position = workParameter.base + 1; + } + + usedEntries[workParameter.base] += 1; + if (workParameter.base > maxParam) + maxParam = workParameter.base; + parameters[pos].type = FORMAT_PARAMETER; + parameters[pos].flags = 0; + indices[workParameter.base] = pos; + workParameter.base = pos++; + } +#if TRIO_FEATURE_VARSIZE + if (workParameter.flags & FLAGS_VARSIZE_PARAMETER) + { + workParameter.varsize = parameterPosition++; + + usedEntries[workParameter.varsize] += 1; + if (workParameter.varsize > maxParam) + maxParam = workParameter.varsize; + parameters[pos].type = FORMAT_PARAMETER; + parameters[pos].flags = 0; + indices[workParameter.varsize] = pos; + workParameter.varsize = pos++; + } +#endif +#if TRIO_FEATURE_USER_DEFINED + if (workParameter.flags & FLAGS_USER_DEFINED_PARAMETER) + { + workParameter.user_defined.handler = parameterPosition++; + + usedEntries[workParameter.user_defined.handler] += 1; + if (workParameter.user_defined.handler > maxParam) + maxParam = workParameter.user_defined.handler; + parameters[pos].type = FORMAT_PARAMETER; + parameters[pos].flags = FLAGS_USER_DEFINED; + indices[workParameter.user_defined.handler] = pos; + workParameter.user_defined.handler = pos++; + } +#endif + + if (NO_POSITION == workParameter.position) + { + workParameter.position = parameterPosition++; + } + + if (workParameter.position > maxParam) + maxParam = workParameter.position; + + if (workParameter.position >= MAX_PARAMETERS) + { + /* Bail out completely to make the error more obvious */ + return TRIO_ERROR_RETURN(TRIO_ETOOMANY, offset); + } + + indices[workParameter.position] = pos; + + /* Count the number of times this entry has been used */ + usedEntries[workParameter.position] += 1; + + /* Find last sticky parameters */ +#if TRIO_FEATURE_STICKY + if (workParameter.flags & FLAGS_STICKY) + { + gotSticky = TRUE; + } + else if (gotSticky) + { + for (i = pos - 1; i >= 0; i--) + { + if (parameters[i].type == FORMAT_PARAMETER) + continue; + if ((parameters[i].flags & FLAGS_STICKY) && + (parameters[i].type == workParameter.type)) + { + /* Do not overwrite current qualifiers */ + workParameter.flags |= (parameters[i].flags & (unsigned long)~FLAGS_STICKY); + if (workParameter.width == NO_WIDTH) + workParameter.width = parameters[i].width; + if (workParameter.precision == NO_PRECISION) + workParameter.precision = parameters[i].precision; + if (workParameter.base == NO_BASE) + workParameter.base = parameters[i].base; + break; + } + } + } +#endif + + if (workParameter.base == NO_BASE) + workParameter.base = BASE_DECIMAL; + + offset = workParameter.endOffset; + + TrioCopyParameter(¶meters[pos++], &workParameter); + } /* while format characters left */ + + parameters[pos].type = FORMAT_SENTINEL; /* end parameter array with sentinel */ + parameters[pos].beginOffset = offset; + + for (num = 0; num <= maxParam; num++) + { + if (usedEntries[num] != 1) + { + if (usedEntries[num] == 0) /* gap detected */ + return TRIO_ERROR_RETURN(TRIO_EGAP, num); + else /* double references detected */ + return TRIO_ERROR_RETURN(TRIO_EDBLREF, num); + } + + i = indices[num]; + + /* + * FORMAT_PARAMETERS are only present if they must be read, + * so it makes no sense to check the ignore flag (besides, + * the flags variable is not set for that particular type) + */ + if ((parameters[i].type != FORMAT_PARAMETER) && + (parameters[i].flags & FLAGS_IGNORE)) + continue; /* for all arguments */ + + /* + * The stack arguments are read according to ANSI C89 + * default argument promotions: + * + * char = int + * short = int + * unsigned char = unsigned int + * unsigned short = unsigned int + * float = double + * + * In addition to the ANSI C89 these types are read (the + * default argument promotions of C99 has not been + * considered yet) + * + * long long + * long double + * size_t + * ptrdiff_t + * intmax_t + */ + switch (parameters[i].type) + { + case FORMAT_GROUP: + case FORMAT_STRING: +#if TRIO_FEATURE_WIDECHAR + if (parameters[i].flags & FLAGS_WIDECHAR) + { + parameters[i].data.wstring = (argarray == NULL) + ? va_arg(arglist, trio_wchar_t *) + : (trio_wchar_t *)(argarray[num]); + } + else +#endif + { + parameters[i].data.string = (argarray == NULL) + ? va_arg(arglist, char *) + : (char *)(argarray[num]); + } + break; + +#if TRIO_FEATURE_USER_DEFINED + case FORMAT_USER_DEFINED: +#endif + case FORMAT_POINTER: + case FORMAT_COUNT: + case FORMAT_UNKNOWN: + parameters[i].data.pointer = (argarray == NULL) + ? va_arg(arglist, trio_pointer_t ) + : argarray[num]; + break; + + case FORMAT_CHAR: + case FORMAT_INT: +#if TRIO_FEATURE_SCANF + if (TYPE_SCAN == type) + { + if (argarray == NULL) + parameters[i].data.pointer = + (trio_pointer_t)va_arg(arglist, trio_pointer_t); + else + { + if (parameters[i].type == FORMAT_CHAR) + parameters[i].data.pointer = + (trio_pointer_t)((char *)argarray[num]); + else if (parameters[i].flags & FLAGS_SHORT) + parameters[i].data.pointer = + (trio_pointer_t)((short *)argarray[num]); + else + parameters[i].data.pointer = + (trio_pointer_t)((int *)argarray[num]); + } + } + else +#endif /* TRIO_FEATURE_SCANF */ + { +#if TRIO_FEATURE_VARSIZE || TRIO_FEATURE_FIXED_SIZE + if (parameters[i].flags + & (FLAGS_VARSIZE_PARAMETER | FLAGS_FIXED_SIZE)) + { + int varsize; + if (parameters[i].flags & FLAGS_VARSIZE_PARAMETER) + { + /* + * Variable sizes are mapped onto the fixed sizes, in + * accordance with integer promotion. + * + * Please note that this may not be portable, as we + * only guess the size, not the layout of the numbers. + * For example, if int is little-endian, and long is + * big-endian, then this will fail. + */ + varsize = (int)parameters[parameters[i].varsize].data.number.as_unsigned; + } + else + { + /* Used for the I modifiers */ + varsize = parameters[i].varsize; + } + parameters[i].flags &= ~FLAGS_ALL_VARSIZES; + + if (varsize <= (int)sizeof(int)) + ; + else if (varsize <= (int)sizeof(long)) + parameters[i].flags |= FLAGS_LONG; +#if TRIO_FEATURE_INTMAX_T + else if (varsize <= (int)sizeof(trio_longlong_t)) + parameters[i].flags |= FLAGS_QUAD; + else + parameters[i].flags |= FLAGS_INTMAX_T; +#else + else + parameters[i].flags |= FLAGS_QUAD; +#endif + } +#endif /* TRIO_FEATURE_VARSIZE */ +#if TRIO_FEATURE_SIZE_T || TRIO_FEATURE_SIZE_T_UPPER + if (parameters[i].flags & FLAGS_SIZE_T) + parameters[i].data.number.as_unsigned = (argarray == NULL) + ? (trio_uintmax_t)va_arg(arglist, size_t) + : (trio_uintmax_t)(*((size_t *)argarray[num])); + else +#endif +#if TRIO_FEATURE_PTRDIFF_T + if (parameters[i].flags & FLAGS_PTRDIFF_T) + parameters[i].data.number.as_unsigned = (argarray == NULL) + ? (trio_uintmax_t)va_arg(arglist, ptrdiff_t) + : (trio_uintmax_t)(*((ptrdiff_t *)argarray[num])); + else +#endif +#if TRIO_FEATURE_INTMAX_T + if (parameters[i].flags & FLAGS_INTMAX_T) + parameters[i].data.number.as_unsigned = (argarray == NULL) + ? (trio_uintmax_t)va_arg(arglist, trio_intmax_t) + : (trio_uintmax_t)(*((trio_intmax_t *)argarray[num])); + else +#endif + if (parameters[i].flags & FLAGS_QUAD) + parameters[i].data.number.as_unsigned = (argarray == NULL) + ? (trio_uintmax_t)va_arg(arglist, trio_ulonglong_t) + : (trio_uintmax_t)(*((trio_ulonglong_t *)argarray[num])); + else if (parameters[i].flags & FLAGS_LONG) + parameters[i].data.number.as_unsigned = (argarray == NULL) + ? (trio_uintmax_t)va_arg(arglist, long) + : (trio_uintmax_t)(*((long *)argarray[num])); + else + { + if (argarray == NULL) + parameters[i].data.number.as_unsigned = (trio_uintmax_t)va_arg(arglist, int); + else + { + if (parameters[i].type == FORMAT_CHAR) + parameters[i].data.number.as_unsigned = (trio_uintmax_t)(*((char *)argarray[num])); + else if (parameters[i].flags & FLAGS_SHORT) + parameters[i].data.number.as_unsigned = (trio_uintmax_t)(*((short *)argarray[num])); + else + parameters[i].data.number.as_unsigned = (trio_uintmax_t)(*((int *)argarray[num])); + } + } + } + break; + + case FORMAT_PARAMETER: + /* + * The parameter for the user-defined specifier is a pointer, + * whereas the rest (width, precision, base) uses an integer. + */ + if (parameters[i].flags & FLAGS_USER_DEFINED) + parameters[i].data.pointer = (argarray == NULL) + ? va_arg(arglist, trio_pointer_t ) + : argarray[num]; + else + parameters[i].data.number.as_unsigned = (argarray == NULL) + ? (trio_uintmax_t)va_arg(arglist, int) + : (trio_uintmax_t)(*((int *)argarray[num])); + break; + +#if TRIO_FEATURE_FLOAT + case FORMAT_DOUBLE: +# if TRIO_FEATURE_SCANF + if (TYPE_SCAN == type) + { + if (parameters[i].flags & FLAGS_LONGDOUBLE) + parameters[i].data.longdoublePointer = (argarray == NULL) + ? va_arg(arglist, trio_long_double_t *) + : (trio_long_double_t *)argarray[num]; + else + { + if (parameters[i].flags & FLAGS_LONG) + parameters[i].data.doublePointer = (argarray == NULL) + ? va_arg(arglist, double *) + : (double *)argarray[num]; + else + parameters[i].data.doublePointer = (argarray == NULL) + ? (double *)va_arg(arglist, float *) + : (double *)((float *)argarray[num]); + } + } + else +# endif /* TRIO_FEATURE_SCANF */ + { + if (parameters[i].flags & FLAGS_LONGDOUBLE) + parameters[i].data.longdoubleNumber = (argarray == NULL) + ? va_arg(arglist, trio_long_double_t) + : (trio_long_double_t)(*((trio_long_double_t *)argarray[num])); + else + { + if (argarray == NULL) + parameters[i].data.longdoubleNumber = + (trio_long_double_t)va_arg(arglist, double); + else + { + if (parameters[i].flags & FLAGS_SHORT) + parameters[i].data.longdoubleNumber = + (trio_long_double_t)(*((float *)argarray[num])); + else + parameters[i].data.longdoubleNumber = + (trio_long_double_t)(*((double *)argarray[num])); + } + } + } + break; +#endif /* TRIO_FEATURE_FLOAT */ + +#if TRIO_FEATURE_ERRNO + case FORMAT_ERRNO: + parameters[i].data.errorNumber = save_errno; + break; +#endif + + default: + break; + } + } /* for all specifiers */ + return num; +} + + +/************************************************************************* + * + * FORMATTING + * + ************************************************************************/ + + +/************************************************************************* + * TrioWriteNumber + * + * Description: + * Output a number. + * The complexity of this function is a result of the complexity + * of the dependencies of the flags. + */ +TRIO_PRIVATE void +TrioWriteNumber +TRIO_ARGS6((self, number, flags, width, precision, base), + trio_class_t *self, + trio_uintmax_t number, + trio_flags_t flags, + int width, + int precision, + int base) +{ + BOOLEAN_T isNegative; + BOOLEAN_T isNumberZero; + BOOLEAN_T isPrecisionZero; + BOOLEAN_T ignoreNumber; + char buffer[MAX_CHARS_IN(trio_uintmax_t) * (1 + MAX_LOCALE_SEPARATOR_LENGTH) + 1]; + char *bufferend; + char *pointer; + TRIO_CONST char *digits; + int i; +#if TRIO_FEATURE_QUOTE + int length; + char *p; +#endif + int count; + int digitOffset; + + assert(VALID(self)); + assert(VALID(self->OutStream)); + assert(((base >= MIN_BASE) && (base <= MAX_BASE)) || (base == NO_BASE)); + + digits = (flags & FLAGS_UPPER) ? internalDigitsUpper : internalDigitsLower; + if (base == NO_BASE) + base = BASE_DECIMAL; + + isNumberZero = (number == 0); + isPrecisionZero = (precision == 0); + ignoreNumber = (isNumberZero + && isPrecisionZero + && !((flags & FLAGS_ALTERNATIVE) && (base == BASE_OCTAL))); + + if (flags & FLAGS_UNSIGNED) + { + isNegative = FALSE; + flags &= ~FLAGS_SHOWSIGN; + } + else + { + isNegative = ((trio_intmax_t)number < 0); + if (isNegative) + number = -((trio_intmax_t)number); + } + + if (flags & FLAGS_QUAD) + number &= (trio_ulonglong_t)-1; + else if (flags & FLAGS_LONG) + number &= (unsigned long)-1; + else + number &= (unsigned int)-1; + + /* Build number */ + pointer = bufferend = &buffer[sizeof(buffer) - 1]; + *pointer-- = NIL; + for (i = 1; i < (int)sizeof(buffer); i++) + { + digitOffset = number % base; + *pointer-- = digits[digitOffset]; + number /= base; + if (number == 0) + break; + +#if TRIO_FEATURE_QUOTE + if ((flags & FLAGS_QUOTE) && TrioFollowedBySeparator(i + 1)) + { + /* + * We are building the number from the least significant + * to the most significant digit, so we have to copy the + * thousand separator backwards + */ + length = internalThousandSeparatorLength; + if (((int)(pointer - buffer) - length) > 0) + { + p = &internalThousandSeparator[length - 1]; + while (length-- > 0) + *pointer-- = *p--; + } + } +#endif + } + + if (! ignoreNumber) + { + /* Adjust width */ + width -= (bufferend - pointer) - 1; + } + + /* Adjust precision */ + if (NO_PRECISION != precision) + { + precision -= (bufferend - pointer) - 1; + if (precision < 0) + precision = 0; + flags |= FLAGS_NILPADDING; + } + + /* Calculate padding */ + count = (! ((flags & FLAGS_LEFTADJUST) || (precision == NO_PRECISION))) + ? precision + : 0; + + /* Adjust width further */ + if (isNegative || (flags & FLAGS_SHOWSIGN) || (flags & FLAGS_SPACE)) + width--; + if ((flags & FLAGS_ALTERNATIVE) && !isNumberZero) + { + switch (base) + { + case BASE_BINARY: + case BASE_HEX: + width -= 2; + break; + case BASE_OCTAL: + if (!(flags & FLAGS_NILPADDING) || (count == 0)) + width--; + break; + default: + break; + } + } + + /* Output prefixes spaces if needed */ + if (! ((flags & FLAGS_LEFTADJUST) || + ((flags & FLAGS_NILPADDING) && (precision == NO_PRECISION)))) + { + while (width-- > count) + self->OutStream(self, CHAR_ADJUST); + } + + /* width has been adjusted for signs and alternatives */ + if (isNegative) + self->OutStream(self, '-'); + else if (flags & FLAGS_SHOWSIGN) + self->OutStream(self, '+'); + else if (flags & FLAGS_SPACE) + self->OutStream(self, ' '); + + /* Prefix is not written when the value is zero */ + if ((flags & FLAGS_ALTERNATIVE) && !isNumberZero) + { + switch (base) + { + case BASE_BINARY: + self->OutStream(self, '0'); + self->OutStream(self, (flags & FLAGS_UPPER) ? 'B' : 'b'); + break; + + case BASE_OCTAL: + if (!(flags & FLAGS_NILPADDING) || (count == 0)) + self->OutStream(self, '0'); + break; + + case BASE_HEX: + self->OutStream(self, '0'); + self->OutStream(self, (flags & FLAGS_UPPER) ? 'X' : 'x'); + break; + + default: + break; + } /* switch base */ + } + + /* Output prefixed zero padding if needed */ + if (flags & FLAGS_NILPADDING) + { + if (precision == NO_PRECISION) + precision = width; + while (precision-- > 0) + { + self->OutStream(self, '0'); + width--; + } + } + + if (! ignoreNumber) + { + /* Output the number itself */ + while (*(++pointer)) + { + self->OutStream(self, *pointer); + } + } + + /* Output trailing spaces if needed */ + if (flags & FLAGS_LEFTADJUST) + { + while (width-- > 0) + self->OutStream(self, CHAR_ADJUST); + } +} + +/************************************************************************* + * TrioWriteStringCharacter + * + * Description: + * Output a single character of a string + */ +TRIO_PRIVATE void +TrioWriteStringCharacter +TRIO_ARGS3((self, ch, flags), + trio_class_t *self, + int ch, + trio_flags_t flags) +{ + if (flags & FLAGS_ALTERNATIVE) + { + if (! isprint(ch)) + { + /* + * Non-printable characters are converted to C escapes or + * \number, if no C escape exists. + */ + self->OutStream(self, CHAR_BACKSLASH); + switch (ch) + { + case '\007': self->OutStream(self, 'a'); break; + case '\b': self->OutStream(self, 'b'); break; + case '\f': self->OutStream(self, 'f'); break; + case '\n': self->OutStream(self, 'n'); break; + case '\r': self->OutStream(self, 'r'); break; + case '\t': self->OutStream(self, 't'); break; + case '\v': self->OutStream(self, 'v'); break; + case '\\': self->OutStream(self, '\\'); break; + default: + self->OutStream(self, 'x'); + TrioWriteNumber(self, (trio_uintmax_t)ch, + FLAGS_UNSIGNED | FLAGS_NILPADDING, + 2, 2, BASE_HEX); + break; + } + } + else if (ch == CHAR_BACKSLASH) + { + self->OutStream(self, CHAR_BACKSLASH); + self->OutStream(self, CHAR_BACKSLASH); + } + else + { + self->OutStream(self, ch); + } + } + else + { + self->OutStream(self, ch); + } +} + +/************************************************************************* + * TrioWriteString + * + * Description: + * Output a string + */ +TRIO_PRIVATE void +TrioWriteString +TRIO_ARGS5((self, string, flags, width, precision), + trio_class_t *self, + TRIO_CONST char *string, + trio_flags_t flags, + int width, + int precision) +{ + int length; + int ch; + + assert(VALID(self)); + assert(VALID(self->OutStream)); + + if (string == NULL) + { + string = internalNullString; + length = sizeof(internalNullString) - 1; +#if TRIO_FEATURE_QUOTE + /* Disable quoting for the null pointer */ + flags &= (~FLAGS_QUOTE); +#endif + width = 0; + } + else + { + if (precision == 0) + { + length = trio_length(string); + } + else + { + length = trio_length_max(string, precision); + } + } + if ((NO_PRECISION != precision) && + (precision < length)) + { + length = precision; + } + width -= length; + +#if TRIO_FEATURE_QUOTE + if (flags & FLAGS_QUOTE) + self->OutStream(self, CHAR_QUOTE); +#endif + + if (! (flags & FLAGS_LEFTADJUST)) + { + while (width-- > 0) + self->OutStream(self, CHAR_ADJUST); + } + + while (length-- > 0) + { + /* The ctype parameters must be an unsigned char (or EOF) */ + ch = (int)((unsigned char)(*string++)); + TrioWriteStringCharacter(self, ch, flags); + } + + if (flags & FLAGS_LEFTADJUST) + { + while (width-- > 0) + self->OutStream(self, CHAR_ADJUST); + } +#if TRIO_FEATURE_QUOTE + if (flags & FLAGS_QUOTE) + self->OutStream(self, CHAR_QUOTE); +#endif +} + +/************************************************************************* + * TrioWriteWideStringCharacter + * + * Description: + * Output a wide string as a multi-byte sequence + */ +#if TRIO_FEATURE_WIDECHAR +TRIO_PRIVATE int +TrioWriteWideStringCharacter +TRIO_ARGS4((self, wch, flags, width), + trio_class_t *self, + trio_wchar_t wch, + trio_flags_t flags, + int width) +{ + int size; + int i; + int ch; + char *string; + char buffer[MB_LEN_MAX + 1]; + + if (width == NO_WIDTH) + width = sizeof(buffer); + + size = wctomb(buffer, wch); + if ((size <= 0) || (size > width) || (buffer[0] == NIL)) + return 0; + + string = buffer; + i = size; + while ((width >= i) && (width-- > 0) && (i-- > 0)) + { + /* The ctype parameters must be an unsigned char (or EOF) */ + ch = (int)((unsigned char)(*string++)); + TrioWriteStringCharacter(self, ch, flags); + } + return size; +} +#endif /* TRIO_FEATURE_WIDECHAR */ + +/************************************************************************* + * TrioWriteWideString + * + * Description: + * Output a wide character string as a multi-byte string + */ +#if TRIO_FEATURE_WIDECHAR +TRIO_PRIVATE void +TrioWriteWideString +TRIO_ARGS5((self, wstring, flags, width, precision), + trio_class_t *self, + TRIO_CONST trio_wchar_t *wstring, + trio_flags_t flags, + int width, + int precision) +{ + int length; + int size; + + assert(VALID(self)); + assert(VALID(self->OutStream)); + +#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE) + /* Required by TrioWriteWideStringCharacter */ + (void)mblen(NULL, 0); +#endif + + if (wstring == NULL) + { + TrioWriteString(self, NULL, flags, width, precision); + return; + } + + if (NO_PRECISION == precision) + { + length = INT_MAX; + } + else + { + length = precision; + width -= length; + } + +#if TRIO_FEATURE_QUOTE + if (flags & FLAGS_QUOTE) + self->OutStream(self, CHAR_QUOTE); +#endif + + if (! (flags & FLAGS_LEFTADJUST)) + { + while (width-- > 0) + self->OutStream(self, CHAR_ADJUST); + } + + while (length > 0) + { + size = TrioWriteWideStringCharacter(self, *wstring++, flags, length); + if (size == 0) + break; /* while */ + length -= size; + } + + if (flags & FLAGS_LEFTADJUST) + { + while (width-- > 0) + self->OutStream(self, CHAR_ADJUST); + } +#if TRIO_FEATURE_QUOTE + if (flags & FLAGS_QUOTE) + self->OutStream(self, CHAR_QUOTE); +#endif +} +#endif /* TRIO_FEATURE_WIDECHAR */ + +/************************************************************************* + * TrioWriteDouble + * + * http://wwwold.dkuug.dk/JTC1/SC22/WG14/www/docs/dr_211.htm + * + * "5.2.4.2.2 paragraph #4 + * + * The accuracy [...] is implementation defined, as is the accuracy + * of the conversion between floating-point internal representations + * and string representations performed by the libray routine in + * " + */ +/* FIXME: handle all instances of constant long-double number (L) + * and *l() math functions. + */ +#if TRIO_FEATURE_FLOAT +TRIO_PRIVATE void +TrioWriteDouble +TRIO_ARGS6((self, number, flags, width, precision, base), + trio_class_t *self, + trio_long_double_t number, + trio_flags_t flags, + int width, + int precision, + int base) +{ + trio_long_double_t integerNumber; + trio_long_double_t fractionNumber; + trio_long_double_t workNumber; + int integerDigits; + int fractionDigits; + int exponentDigits; + int workDigits; + int baseDigits; + int integerThreshold; + int fractionThreshold; + int expectedWidth; + int exponent = 0; + unsigned int uExponent = 0; + int exponentBase; + trio_long_double_t dblBase; + trio_long_double_t dblFractionBase; + trio_long_double_t integerAdjust; + trio_long_double_t fractionAdjust; + trio_long_double_t workFractionNumber; + trio_long_double_t workFractionAdjust; + int fractionDigitsInspect; + BOOLEAN_T isNegative; + BOOLEAN_T isExponentNegative = FALSE; + BOOLEAN_T requireTwoDigitExponent; + BOOLEAN_T isHex; + TRIO_CONST char *digits; +# if TRIO_FEATURE_QUOTE + char *groupingPointer; +# endif + int i; + int offset; + BOOLEAN_T hasOnlyZeroes; + int leadingFractionZeroes = -1; + register int trailingZeroes; + BOOLEAN_T keepTrailingZeroes; + BOOLEAN_T keepDecimalPoint; + trio_long_double_t epsilon; + BOOLEAN_T adjustNumber = FALSE; + + assert(VALID(self)); + assert(VALID(self->OutStream)); + assert(((base >= MIN_BASE) && (base <= MAX_BASE)) || (base == NO_BASE)); + + /* Determine sign and look for special quantities */ + switch (trio_fpclassify_and_signbit(number, &isNegative)) + { + case TRIO_FP_NAN: + TrioWriteString(self, + (flags & FLAGS_UPPER) + ? NAN_UPPER + : NAN_LOWER, + flags, width, precision); + return; + + case TRIO_FP_INFINITE: + if (isNegative) + { + /* Negative infinity */ + TrioWriteString(self, + (flags & FLAGS_UPPER) + ? "-" INFINITE_UPPER + : "-" INFINITE_LOWER, + flags, width, precision); + return; + } + else + { + /* Positive infinity */ + TrioWriteString(self, + (flags & FLAGS_UPPER) + ? INFINITE_UPPER + : INFINITE_LOWER, + flags, width, precision); + return; + } + + default: + /* Finitude */ + break; + } + + /* Normal numbers */ + if (flags & FLAGS_LONGDOUBLE) + { + baseDigits = (base == 10) + ? LDBL_DIG + : (int)trio_floor(LDBL_MANT_DIG / TrioLogarithmBase(base)); + epsilon = LDBL_EPSILON; + } + else if (flags & FLAGS_SHORT) + { + baseDigits = (base == BASE_DECIMAL) + ? FLT_DIG + : (int)trio_floor(FLT_MANT_DIG / TrioLogarithmBase(base)); + epsilon = FLT_EPSILON; + } + else + { + baseDigits = (base == BASE_DECIMAL) + ? DBL_DIG + : (int)trio_floor(DBL_MANT_DIG / TrioLogarithmBase(base)); + epsilon = DBL_EPSILON; + } + + digits = (flags & FLAGS_UPPER) ? internalDigitsUpper : internalDigitsLower; + isHex = (base == BASE_HEX); + if (base == NO_BASE) + base = BASE_DECIMAL; + dblBase = (trio_long_double_t)base; + keepTrailingZeroes = !( (flags & FLAGS_ROUNDING) || + ( (flags & FLAGS_FLOAT_G) && + !(flags & FLAGS_ALTERNATIVE) ) ); + +# if TRIO_FEATURE_ROUNDING + if (flags & FLAGS_ROUNDING) + { + precision = baseDigits; + } +# endif + + if (precision == NO_PRECISION) + { + if (isHex) + { + keepTrailingZeroes = FALSE; + precision = FLT_MANT_DIG; + } + else + { + precision = FLT_DIG; + } + } + + if (isNegative) + { + number = -number; + } + + if (isHex) + { + flags |= FLAGS_FLOAT_E; + } + + reprocess: + + if (flags & FLAGS_FLOAT_G) + { + if (precision == 0) + precision = 1; + + if ( (number < TRIO_SUFFIX_LONG(1.0E-4)) || + (number >= TrioPower(base, (trio_long_double_t)precision)) ) + { + /* Use scientific notation */ + flags |= FLAGS_FLOAT_E; + } + else if (number < 1.0) + { + /* + * Use normal notation. If the integer part of the number is + * zero, then adjust the precision to include leading fractional + * zeros. + */ + workNumber = TrioLogarithm(number, base); + workNumber = TRIO_FABS(workNumber); + if (workNumber - trio_floor(workNumber) < epsilon) + workNumber--; + leadingFractionZeroes = (int)trio_floor(workNumber); + } + } + + if (flags & FLAGS_FLOAT_E) + { + /* Scale the number */ + workNumber = TrioLogarithm(number, base); + if (trio_isinf(workNumber) == -1) + { + exponent = 0; + /* Undo setting */ + if (flags & FLAGS_FLOAT_G) + flags &= ~FLAGS_FLOAT_E; + } + else + { + exponent = (int)trio_floor(workNumber); + workNumber = number; + /* + * The expression A * 10^-B is equivalent to A / 10^B but the former + * usually gives better accuracy. + */ + workNumber *= TrioPower(dblBase, (trio_long_double_t)-exponent); + if (trio_isinf(workNumber)) { + /* + * Scaling is done it two steps to avoid problems with subnormal + * numbers. + */ + workNumber /= TrioPower(dblBase, (trio_long_double_t)(exponent / 2)); + workNumber /= TrioPower(dblBase, (trio_long_double_t)(exponent - (exponent / 2))); + } + number = workNumber; + isExponentNegative = (exponent < 0); + uExponent = (isExponentNegative) ? -exponent : exponent; + if (isHex) + uExponent *= 4; /* log16(2) */ +#if TRIO_FEATURE_QUOTE + /* No thousand separators */ + flags &= ~FLAGS_QUOTE; +#endif + } + } + + integerNumber = trio_floor(number); + fractionNumber = number - integerNumber; + + /* + * Truncated number. + * + * Precision is number of significant digits for FLOAT_G and number of + * fractional digits for others. + */ + integerDigits = 1; + if (integerNumber > epsilon) + { + integerDigits += (int)TrioLogarithm(integerNumber, base); + } + + fractionDigits = precision; + if (flags & FLAGS_FLOAT_G) + { + if (leadingFractionZeroes > 0) + { + fractionDigits += leadingFractionZeroes; + } + if ((integerNumber > epsilon) || (number <= epsilon)) + { + fractionDigits -= integerDigits; + } + } + + dblFractionBase = TrioPower(base, fractionDigits); + + if (integerNumber < 1.0) + { + workNumber = number * dblFractionBase + TRIO_SUFFIX_LONG(0.5); + if (trio_floor(number * dblFractionBase) != trio_floor(workNumber)) + { + adjustNumber = TRUE; + /* Remove a leading fraction zero if fraction is rounded up */ + if ((int)TrioLogarithm(number * dblFractionBase, base) != (int)TrioLogarithm(workNumber, base)) + { + --leadingFractionZeroes; + } + } + workNumber /= dblFractionBase; + } + else + { + workNumber = number + TRIO_SUFFIX_LONG(0.5) / dblFractionBase; + adjustNumber = (trio_floor(number) != trio_floor(workNumber)); + } + if (adjustNumber) + { + if ((flags & FLAGS_FLOAT_G) && !(flags & FLAGS_FLOAT_E)) + { + /* The adjustment may require a change to scientific notation */ + if ( (workNumber < TRIO_SUFFIX_LONG(1.0E-4)) || + (workNumber >= TrioPower(base, (trio_long_double_t)precision)) ) + { + /* Use scientific notation */ + flags |= FLAGS_FLOAT_E; + goto reprocess; + } + } + + if (flags & FLAGS_FLOAT_E) + { + workDigits = 1 + TrioLogarithm(trio_floor(workNumber), base); + if (integerDigits == workDigits) + { + /* Adjust if the same number of digits are used */ + number += TRIO_SUFFIX_LONG(0.5) / dblFractionBase; + integerNumber = trio_floor(number); + fractionNumber = number - integerNumber; + } + else + { + /* Adjust if number was rounded up one digit (ie. 0.99 to 1.00) */ + exponent++; + isExponentNegative = (exponent < 0); + uExponent = (isExponentNegative) ? -exponent : exponent; + if (isHex) + uExponent *= 4; /* log16(2) */ + workNumber = (number + TRIO_SUFFIX_LONG(0.5) / dblFractionBase) / dblBase; + integerNumber = trio_floor(workNumber); + fractionNumber = workNumber - integerNumber; + } + } + else + { + if (workNumber > 1.0) + { + /* Adjust if number was rounded up one digit (ie. 99 to 100) */ + integerNumber = trio_floor(workNumber); + fractionNumber = 0.0; + integerDigits = (integerNumber > epsilon) + ? 1 + (int)TrioLogarithm(integerNumber, base) + : 1; + if (flags & FLAGS_FLOAT_G) + { + if (flags & FLAGS_ALTERNATIVE) + { + if ((integerNumber > epsilon) || (number <= epsilon)) + { + fractionDigits -= integerDigits; + } + } + else + { + fractionDigits = 0; + } + } + } + else + { + integerNumber = trio_floor(workNumber); + fractionNumber = workNumber - integerNumber; + if (flags & FLAGS_FLOAT_G) + { + if (flags & FLAGS_ALTERNATIVE) + { + fractionDigits = precision; + if (leadingFractionZeroes > 0) + { + fractionDigits += leadingFractionZeroes; + } + if ((integerNumber > epsilon) || (number <= epsilon)) + { + fractionDigits -= integerDigits; + } + } + } + } + } + } + + /* Estimate accuracy */ + integerAdjust = fractionAdjust = TRIO_SUFFIX_LONG(0.5); +# if TRIO_FEATURE_ROUNDING + if (flags & FLAGS_ROUNDING) + { + if (integerDigits > baseDigits) + { + integerThreshold = baseDigits; + fractionDigits = 0; + dblFractionBase = 1.0; + fractionThreshold = 0; + precision = 0; /* Disable decimal-point */ + integerAdjust = TrioPower(base, integerDigits - integerThreshold - 1); + fractionAdjust = 0.0; + } + else + { + integerThreshold = integerDigits; + fractionThreshold = fractionDigits - integerThreshold; + fractionAdjust = 1.0; + } + } + else +# endif + { + integerThreshold = INT_MAX; + fractionThreshold = INT_MAX; + } + + /* + * Calculate expected width. + * sign + integer part + thousands separators + decimal point + * + fraction + exponent + */ + fractionAdjust /= dblFractionBase; + hasOnlyZeroes = (trio_floor((fractionNumber + fractionAdjust) * + dblFractionBase) < epsilon); + keepDecimalPoint = ( (flags & FLAGS_ALTERNATIVE) || + !((precision == 0) || + (!keepTrailingZeroes && hasOnlyZeroes)) ); + + expectedWidth = integerDigits + fractionDigits; + + if (!keepTrailingZeroes) + { + trailingZeroes = 0; + workFractionNumber = fractionNumber; + workFractionAdjust = fractionAdjust; + fractionDigitsInspect = fractionDigits; + + if (integerDigits > integerThreshold) + { + fractionDigitsInspect = 0; + } + else if (fractionThreshold <= fractionDigits) + { + fractionDigitsInspect = fractionThreshold + 1; + } + + trailingZeroes = fractionDigits - fractionDigitsInspect; + for (i = 0; i < fractionDigitsInspect; i++) + { + workFractionNumber *= dblBase; + workFractionAdjust *= dblBase; + workNumber = trio_floor(workFractionNumber + workFractionAdjust); + workFractionNumber -= workNumber; + offset = (int)trio_fmod(workNumber, dblBase); + if (offset == 0) + { + trailingZeroes++; + } + else + { + trailingZeroes = 0; + } + } + expectedWidth -= trailingZeroes; + } + + if (keepDecimalPoint) + { + expectedWidth += internalDecimalPointLength; + } + +#if TRIO_FEATURE_QUOTE + if (flags & FLAGS_QUOTE) + { + expectedWidth += TrioCalcThousandSeparatorLength(integerDigits); + } +#endif + + if (isNegative || (flags & FLAGS_SHOWSIGN) || (flags & FLAGS_SPACE)) + { + expectedWidth += sizeof("-") - 1; + } + + exponentDigits = 0; + if (flags & FLAGS_FLOAT_E) + { + exponentDigits = (uExponent == 0) + ? 1 + : (int)trio_ceil(TrioLogarithm((double)(uExponent + 1), + (isHex) ? 10 : base)); + } + requireTwoDigitExponent = ((base == BASE_DECIMAL) && (exponentDigits == 1)); + if (exponentDigits > 0) + { + expectedWidth += exponentDigits; + expectedWidth += (requireTwoDigitExponent + ? sizeof("E+0") - 1 + : sizeof("E+") - 1); + } + + if (isHex) + { + expectedWidth += sizeof("0X") - 1; + } + + /* Output prefixing */ + if (flags & FLAGS_NILPADDING) + { + /* Leading zeros must be after sign */ + if (isNegative) + self->OutStream(self, '-'); + else if (flags & FLAGS_SHOWSIGN) + self->OutStream(self, '+'); + else if (flags & FLAGS_SPACE) + self->OutStream(self, ' '); + if (isHex) + { + self->OutStream(self, '0'); + self->OutStream(self, (flags & FLAGS_UPPER) ? 'X' : 'x'); + } + if (!(flags & FLAGS_LEFTADJUST)) + { + for (i = expectedWidth; i < width; i++) + { + self->OutStream(self, '0'); + } + } + } + else + { + /* Leading spaces must be before sign */ + if (!(flags & FLAGS_LEFTADJUST)) + { + for (i = expectedWidth; i < width; i++) + { + self->OutStream(self, CHAR_ADJUST); + } + } + if (isNegative) + self->OutStream(self, '-'); + else if (flags & FLAGS_SHOWSIGN) + self->OutStream(self, '+'); + else if (flags & FLAGS_SPACE) + self->OutStream(self, ' '); + if (isHex) + { + self->OutStream(self, '0'); + self->OutStream(self, (flags & FLAGS_UPPER) ? 'X' : 'x'); + } + } + + /* Output the integer part and thousand separators */ + for (i = 0; i < integerDigits; i++) + { + workNumber = trio_floor(((integerNumber + integerAdjust) + / TrioPower(base, integerDigits - i - 1))); + if (i > integerThreshold) + { + /* Beyond accuracy */ + self->OutStream(self, digits[0]); + } + else + { + self->OutStream(self, digits[(int)trio_fmod(workNumber, dblBase)]); + } + +#if TRIO_FEATURE_QUOTE + if (((flags & (FLAGS_FLOAT_E | FLAGS_QUOTE)) == FLAGS_QUOTE) + && TrioFollowedBySeparator(integerDigits - i)) + { + for (groupingPointer = internalThousandSeparator; + *groupingPointer != NIL; + groupingPointer++) + { + self->OutStream(self, *groupingPointer); + } + } +#endif + } + + /* Insert decimal point and build the fraction part */ + trailingZeroes = 0; + + if (keepDecimalPoint) + { + if (internalDecimalPoint) + { + self->OutStream(self, internalDecimalPoint); + } + else + { + for (i = 0; i < internalDecimalPointLength; i++) + { + self->OutStream(self, internalDecimalPointString[i]); + } + } + } + + for (i = 0; i < fractionDigits; i++) + { + if ((integerDigits > integerThreshold) || (i > fractionThreshold)) + { + /* Beyond accuracy */ + trailingZeroes++; + } + else + { + fractionNumber *= dblBase; + fractionAdjust *= dblBase; + workNumber = trio_floor(fractionNumber + fractionAdjust); + if (workNumber > fractionNumber) + { + /* fractionNumber should never become negative */ + fractionNumber = 0.0; + fractionAdjust = 0.0; + } + else + { + fractionNumber -= workNumber; + } + offset = (int)trio_fmod(workNumber, dblBase); + if (offset == 0) + { + trailingZeroes++; + } + else + { + while (trailingZeroes > 0) + { + /* Not trailing zeroes after all */ + self->OutStream(self, digits[0]); + trailingZeroes--; + } + self->OutStream(self, digits[offset]); + } + } + } + + if (keepTrailingZeroes) + { + while (trailingZeroes > 0) + { + self->OutStream(self, digits[0]); + trailingZeroes--; + } + } + + /* Output exponent */ + if (exponentDigits > 0) + { + self->OutStream(self, + isHex + ? ((flags & FLAGS_UPPER) ? 'P' : 'p') + : ((flags & FLAGS_UPPER) ? 'E' : 'e')); + self->OutStream(self, (isExponentNegative) ? '-' : '+'); + + /* The exponent must contain at least two digits */ + if (requireTwoDigitExponent) + self->OutStream(self, '0'); + + if (isHex) + base = 10; + exponentBase = (int)TrioPower(base, exponentDigits - 1); + for (i = 0; i < exponentDigits; i++) + { + self->OutStream(self, digits[(uExponent / exponentBase) % base]); + exponentBase /= base; + } + } + /* Output trailing spaces */ + if (flags & FLAGS_LEFTADJUST) + { + for (i = expectedWidth; i < width; i++) + { + self->OutStream(self, CHAR_ADJUST); + } + } +} +#endif /* TRIO_FEATURE_FLOAT */ + +/************************************************************************* + * TrioFormatProcess + * + * Description: + * This is the main engine for formatting output + */ +TRIO_PRIVATE int +TrioFormatProcess +TRIO_ARGS3((data, format, parameters), + trio_class_t *data, + TRIO_CONST char *format, + trio_parameter_t *parameters) +{ + int i; +#if TRIO_FEATURE_ERRNO + TRIO_CONST char *string; +#endif + trio_pointer_t pointer; + trio_flags_t flags; + int width; + int precision; + int base; + int offset; + + offset = 0; + i = 0; + + for (;;) + { + /* Skip the parameter entries */ + while (parameters[i].type == FORMAT_PARAMETER) + i++; + + /* Copy non conversion-specifier part of format string */ + while (offset < parameters[i].beginOffset) + { + if (CHAR_IDENTIFIER == format[offset] && CHAR_IDENTIFIER == format[offset + 1]) + { + data->OutStream(data, CHAR_IDENTIFIER); + offset += 2; + } + else + { + data->OutStream(data, format[offset++]); + } + } + + /* Abort if we reached end of format string */ + if (parameters[i].type == FORMAT_SENTINEL) + break; + + /* Ouput parameter */ + flags = parameters[i].flags; + + /* Find width */ + width = parameters[i].width; + if (flags & FLAGS_WIDTH_PARAMETER) + { + /* Get width from parameter list */ + width = (int)parameters[width].data.number.as_signed; + if (width < 0) + { + /* + * A negative width is the same as the - flag and + * a positive width. + */ + flags |= FLAGS_LEFTADJUST; + flags &= ~FLAGS_NILPADDING; + width = -width; + } + } + + /* Find precision */ + if (flags & FLAGS_PRECISION) + { + precision = parameters[i].precision; + if (flags & FLAGS_PRECISION_PARAMETER) + { + /* Get precision from parameter list */ + precision = (int)parameters[precision].data.number.as_signed; + if (precision < 0) + { + /* + * A negative precision is the same as no + * precision + */ + precision = NO_PRECISION; + } + } + } + else + { + precision = NO_PRECISION; + } + + /* Find base */ + if (NO_BASE != parameters[i].baseSpecifier) + { + /* Base from specifier has priority */ + base = parameters[i].baseSpecifier; + } + else if (flags & FLAGS_BASE_PARAMETER) + { + /* Get base from parameter list */ + base = parameters[i].base; + base = (int)parameters[base].data.number.as_signed; + } + else + { + /* Use base from format string */ + base = parameters[i].base; + } + + switch (parameters[i].type) + { + case FORMAT_CHAR: +#if TRIO_FEATURE_QUOTE + if (flags & FLAGS_QUOTE) + data->OutStream(data, CHAR_QUOTE); +#endif + if (! (flags & FLAGS_LEFTADJUST)) + { + while (--width > 0) + data->OutStream(data, CHAR_ADJUST); + } +#if TRIO_FEATURE_WIDECHAR + if (flags & FLAGS_WIDECHAR) + { + TrioWriteWideStringCharacter(data, + (trio_wchar_t)parameters[i].data.number.as_signed, + flags, + NO_WIDTH); + } + else +#endif + { + TrioWriteStringCharacter(data, + (int)parameters[i].data.number.as_signed, + flags); + } + + if (flags & FLAGS_LEFTADJUST) + { + while(--width > 0) + data->OutStream(data, CHAR_ADJUST); + } +#if TRIO_FEATURE_QUOTE + if (flags & FLAGS_QUOTE) + data->OutStream(data, CHAR_QUOTE); +#endif + + break; /* FORMAT_CHAR */ + + case FORMAT_INT: + TrioWriteNumber(data, + parameters[i].data.number.as_unsigned, + flags, + width, + precision, + base); + + break; /* FORMAT_INT */ + +#if TRIO_FEATURE_FLOAT + case FORMAT_DOUBLE: + TrioWriteDouble(data, + parameters[i].data.longdoubleNumber, + flags, + width, + precision, + base); + break; /* FORMAT_DOUBLE */ +#endif + + case FORMAT_STRING: +#if TRIO_FEATURE_WIDECHAR + if (flags & FLAGS_WIDECHAR) + { + TrioWriteWideString(data, + parameters[i].data.wstring, + flags, + width, + precision); + } + else +#endif + { + TrioWriteString(data, + parameters[i].data.string, + flags, + width, + precision); + } + break; /* FORMAT_STRING */ + + case FORMAT_POINTER: + { + trio_reference_t reference; + + reference.data = data; + reference.parameter = ¶meters[i]; + trio_print_pointer(&reference, parameters[i].data.pointer); + } + break; /* FORMAT_POINTER */ + + case FORMAT_COUNT: + pointer = parameters[i].data.pointer; + if (NULL != pointer) + { + /* + * C99 paragraph 7.19.6.1.8 says "the number of + * characters written to the output stream so far by + * this call", which is data->actually.committed + */ +#if TRIO_FEATURE_SIZE_T || TRIO_FEATURE_SIZE_T_UPPER + if (flags & FLAGS_SIZE_T) + *(size_t *)pointer = (size_t)data->actually.committed; + else +#endif +#if TRIO_FEATURE_PTRDIFF_T + if (flags & FLAGS_PTRDIFF_T) + *(ptrdiff_t *)pointer = (ptrdiff_t)data->actually.committed; + else +#endif +#if TRIO_FEATURE_INTMAX_T + if (flags & FLAGS_INTMAX_T) + *(trio_intmax_t *)pointer = (trio_intmax_t)data->actually.committed; + else +#endif + if (flags & FLAGS_QUAD) + { + *(trio_ulonglong_t *)pointer = (trio_ulonglong_t)data->actually.committed; + } + else if (flags & FLAGS_LONG) + { + *(long int *)pointer = (long int)data->actually.committed; + } + else if (flags & FLAGS_SHORT) + { + *(short int *)pointer = (short int)data->actually.committed; + } + else + { + *(int *)pointer = (int)data->actually.committed; + } + } + break; /* FORMAT_COUNT */ + + case FORMAT_PARAMETER: + break; /* FORMAT_PARAMETER */ + +#if TRIO_FEATURE_ERRNO + case FORMAT_ERRNO: + string = trio_error(parameters[i].data.errorNumber); + if (string) + { + TrioWriteString(data, + string, + flags, + width, + precision); + } + else + { + data->OutStream(data, '#'); + TrioWriteNumber(data, + (trio_uintmax_t)parameters[i].data.errorNumber, + flags, + width, + precision, + BASE_DECIMAL); + } + break; /* FORMAT_ERRNO */ +#endif /* TRIO_FEATURE_ERRNO */ + +#if TRIO_FEATURE_USER_DEFINED + case FORMAT_USER_DEFINED: + { + trio_reference_t reference; + trio_userdef_t *def = NULL; + + if (parameters[i].flags & FLAGS_USER_DEFINED_PARAMETER) + { + /* Use handle */ + if ((i > 0) || + (parameters[i - 1].type == FORMAT_PARAMETER)) + def = (trio_userdef_t *)parameters[i - 1].data.pointer; + } + else + { + /* Look up namespace */ + def = TrioFindNamespace(parameters[i].user_defined.namespace, NULL); + } + if (def) + { + reference.data = data; + reference.parameter = ¶meters[i]; + def->callback(&reference); + } + } + break; +#endif /* TRIO_FEATURE_USER_DEFINED */ + + default: + break; + } /* switch parameter type */ + + /* Prepare for next */ + offset = parameters[i].endOffset; + i++; + } + + return data->processed; +} + +/************************************************************************* + * TrioFormatRef + */ +#if TRIO_EXTENSION +TRIO_PRIVATE int +TrioFormatRef +TRIO_ARGS4((reference, format, arglist, argarray), + trio_reference_t *reference, + TRIO_CONST char *format, + va_list arglist, + trio_pointer_t *argarray) +{ + int status; + trio_parameter_t parameters[MAX_PARAMETERS]; + + status = TrioParse(TYPE_PRINT, format, parameters, arglist, argarray); + if (status < 0) + return status; + + status = TrioFormatProcess(reference->data, format, parameters); + if (reference->data->error != 0) + { + status = reference->data->error; + } + return status; +} +#endif /* TRIO_EXTENSION */ + +/************************************************************************* + * TrioFormat + */ +TRIO_PRIVATE int +TrioFormat +TRIO_ARGS6((destination, destinationSize, OutStream, format, arglist, argarray), + trio_pointer_t destination, + size_t destinationSize, + void (*OutStream) TRIO_PROTO((trio_class_t *, int)), + TRIO_CONST char *format, + va_list arglist, + trio_pointer_t *argarray) +{ + int status; + trio_class_t data; + trio_parameter_t parameters[MAX_PARAMETERS]; + + assert(VALID(OutStream)); + assert(VALID(format)); + + memset(&data, 0, sizeof(data)); + data.OutStream = OutStream; + data.location = destination; + data.max = destinationSize; + data.error = 0; + +#if defined(USE_LOCALE) + if (NULL == internalLocaleValues) + { + TrioSetLocale(); + } +#endif + + status = TrioParse(TYPE_PRINT, format, parameters, arglist, argarray); + if (status < 0) + return status; + + status = TrioFormatProcess(&data, format, parameters); + if (data.error != 0) + { + status = data.error; + } + return status; +} + +/************************************************************************* + * TrioOutStreamFile + */ +#if TRIO_FEATURE_FILE || TRIO_FEATURE_STDIO +TRIO_PRIVATE void +TrioOutStreamFile +TRIO_ARGS2((self, output), + trio_class_t *self, + int output) +{ + FILE *file; + + assert(VALID(self)); + assert(VALID(self->location)); + + file = (FILE *)self->location; + self->processed++; + if (fputc(output, file) == EOF) + { + self->error = TRIO_ERROR_RETURN(TRIO_EOF, 0); + } + else + { + self->actually.committed++; + } +} +#endif /* TRIO_FEATURE_FILE || TRIO_FEATURE_STDIO */ + +/************************************************************************* + * TrioOutStreamFileDescriptor + */ +#if TRIO_FEATURE_FD +TRIO_PRIVATE void +TrioOutStreamFileDescriptor +TRIO_ARGS2((self, output), + trio_class_t *self, + int output) +{ + int fd; + char ch; + + assert(VALID(self)); + + fd = *((int *)self->location); + ch = (char)output; + self->processed++; + if (write(fd, &ch, sizeof(char)) == -1) + { + self->error = TRIO_ERROR_RETURN(TRIO_ERRNO, 0); + } + else + { + self->actually.committed++; + } +} +#endif /* TRIO_FEATURE_FD */ + +/************************************************************************* + * TrioOutStreamCustom + */ +#if TRIO_FEATURE_CLOSURE +TRIO_PRIVATE void +TrioOutStreamCustom +TRIO_ARGS2((self, output), + trio_class_t *self, + int output) +{ + int status; + trio_custom_t *data; + + assert(VALID(self)); + assert(VALID(self->location)); + + data = (trio_custom_t *)self->location; + if (data->stream.out) + { + status = (data->stream.out)(data->closure, output); + if (status >= 0) + { + self->actually.committed++; + } + else + { + if (self->error == 0) + { + self->error = TRIO_ERROR_RETURN(TRIO_ECUSTOM, -status); + } + } + } + self->processed++; +} +#endif /* TRIO_FEATURE_CLOSURE */ + +/************************************************************************* + * TrioOutStreamString + */ +TRIO_PRIVATE void +TrioOutStreamString +TRIO_ARGS2((self, output), + trio_class_t *self, + int output) +{ + char **buffer; + + assert(VALID(self)); + assert(VALID(self->location)); + + buffer = (char **)self->location; + **buffer = (char)output; + (*buffer)++; + self->processed++; + self->actually.committed++; +} + +/************************************************************************* + * TrioOutStreamStringMax + */ +TRIO_PRIVATE void +TrioOutStreamStringMax +TRIO_ARGS2((self, output), + trio_class_t *self, + int output) +{ + char **buffer; + + assert(VALID(self)); + assert(VALID(self->location)); + + buffer = (char **)self->location; + + if (self->processed < self->max) + { + **buffer = (char)output; + (*buffer)++; + self->actually.committed++; + } + self->processed++; +} + +/************************************************************************* + * TrioOutStreamStringDynamic + */ +#if TRIO_FEATURE_DYNAMICSTRING +TRIO_PRIVATE void +TrioOutStreamStringDynamic +TRIO_ARGS2((self, output), + trio_class_t *self, + int output) +{ + assert(VALID(self)); + assert(VALID(self->location)); + + if (self->error == 0) + { + trio_xstring_append_char((trio_string_t *)self->location, + (char)output); + self->actually.committed++; + } + /* The processed variable must always be increased */ + self->processed++; +} +#endif /* TRIO_FEATURE_DYNAMICSTRING */ + +/************************************************************************* + * + * Formatted printing functions + * + ************************************************************************/ + +#if defined(TRIO_DOCUMENTATION) +# include "doc/doc_printf.h" +#endif +/** @addtogroup Printf + @{ +*/ + +/************************************************************************* + * printf + */ + +/** + Print to standard output stream. + + @param format Formatting string. + @param ... Arguments. + @return Number of printed characters. + */ +#if TRIO_FEATURE_STDIO +TRIO_PUBLIC int +trio_printf +TRIO_VARGS2((format, va_alist), + TRIO_CONST char *format, + TRIO_VA_DECL) +{ + int status; + va_list args; + + assert(VALID(format)); + + TRIO_VA_START(args, format); + status = TrioFormat(stdout, 0, TrioOutStreamFile, format, args, NULL); + TRIO_VA_END(args); + return status; +} +#endif /* TRIO_FEATURE_STDIO */ + +/** + Print to standard output stream. + + @param format Formatting string. + @param args Arguments. + @return Number of printed characters. + */ +#if TRIO_FEATURE_STDIO +TRIO_PUBLIC int +trio_vprintf +TRIO_ARGS2((format, args), + TRIO_CONST char *format, + va_list args) +{ + assert(VALID(format)); + + return TrioFormat(stdout, 0, TrioOutStreamFile, format, args, NULL); +} +#endif /* TRIO_FEATURE_STDIO */ + +/** + Print to standard output stream. + + @param format Formatting string. + @param args Arguments. + @return Number of printed characters. + */ +#if TRIO_FEATURE_STDIO +TRIO_PUBLIC int +trio_printfv +TRIO_ARGS2((format, args), + TRIO_CONST char *format, + trio_pointer_t * args) +{ + static va_list unused; + + assert(VALID(format)); + + return TrioFormat(stdout, 0, TrioOutStreamFile, format, unused, args); +} +#endif /* TRIO_FEATURE_STDIO */ + +/************************************************************************* + * fprintf + */ + +/** + Print to file. + + @param file File pointer. + @param format Formatting string. + @param ... Arguments. + @return Number of printed characters. + */ +#if TRIO_FEATURE_FILE +TRIO_PUBLIC int +trio_fprintf +TRIO_VARGS3((file, format, va_alist), + FILE *file, + TRIO_CONST char *format, + TRIO_VA_DECL) +{ + int status; + va_list args; + + assert(VALID(file)); + assert(VALID(format)); + + TRIO_VA_START(args, format); + status = TrioFormat(file, 0, TrioOutStreamFile, format, args, NULL); + TRIO_VA_END(args); + return status; +} +#endif /* TRIO_FEATURE_FILE */ + +/** + Print to file. + + @param file File pointer. + @param format Formatting string. + @param args Arguments. + @return Number of printed characters. + */ +#if TRIO_FEATURE_FILE +TRIO_PUBLIC int +trio_vfprintf +TRIO_ARGS3((file, format, args), + FILE *file, + TRIO_CONST char *format, + va_list args) +{ + assert(VALID(file)); + assert(VALID(format)); + + return TrioFormat(file, 0, TrioOutStreamFile, format, args, NULL); +} +#endif /* TRIO_FEATURE_FILE */ + +/** + Print to file. + + @param file File pointer. + @param format Formatting string. + @param args Arguments. + @return Number of printed characters. + */ +#if TRIO_FEATURE_FILE +TRIO_PUBLIC int +trio_fprintfv +TRIO_ARGS3((file, format, args), + FILE *file, + TRIO_CONST char *format, + trio_pointer_t * args) +{ + static va_list unused; + + assert(VALID(file)); + assert(VALID(format)); + + return TrioFormat(file, 0, TrioOutStreamFile, format, unused, args); +} +#endif /* TRIO_FEATURE_FILE */ + +/************************************************************************* + * dprintf + */ + +/** + Print to file descriptor. + + @param fd File descriptor. + @param format Formatting string. + @param ... Arguments. + @return Number of printed characters. + */ +#if TRIO_FEATURE_FD +TRIO_PUBLIC int +trio_dprintf +TRIO_VARGS3((fd, format, va_alist), + int fd, + TRIO_CONST char *format, + TRIO_VA_DECL) +{ + int status; + va_list args; + + assert(VALID(format)); + + TRIO_VA_START(args, format); + status = TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, args, NULL); + TRIO_VA_END(args); + return status; +} +#endif /* TRIO_FEATURE_FD */ + +/** + Print to file descriptor. + + @param fd File descriptor. + @param format Formatting string. + @param args Arguments. + @return Number of printed characters. + */ +#if TRIO_FEATURE_FD +TRIO_PUBLIC int +trio_vdprintf +TRIO_ARGS3((fd, format, args), + int fd, + TRIO_CONST char *format, + va_list args) +{ + assert(VALID(format)); + + return TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, args, NULL); +} +#endif /* TRIO_FEATURE_FD */ + +/** + Print to file descriptor. + + @param fd File descriptor. + @param format Formatting string. + @param args Arguments. + @return Number of printed characters. + */ +#if TRIO_FEATURE_FD +TRIO_PUBLIC int +trio_dprintfv +TRIO_ARGS3((fd, format, args), + int fd, + TRIO_CONST char *format, + trio_pointer_t *args) +{ + static va_list unused; + + assert(VALID(format)); + + return TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, unused, args); +} +#endif /* TRIO_FEATURE_FD */ + +/************************************************************************* + * cprintf + */ +#if TRIO_FEATURE_CLOSURE +TRIO_PUBLIC int +trio_cprintf +TRIO_VARGS4((stream, closure, format, va_alist), + trio_outstream_t stream, + trio_pointer_t closure, + TRIO_CONST char *format, + TRIO_VA_DECL) +{ + int status; + va_list args; + trio_custom_t data; + + assert(VALID(stream)); + assert(VALID(format)); + + TRIO_VA_START(args, format); + data.stream.out = stream; + data.closure = closure; + status = TrioFormat(&data, 0, TrioOutStreamCustom, format, args, NULL); + TRIO_VA_END(args); + return status; +} +#endif /* TRIO_FEATURE_CLOSURE */ + +#if TRIO_FEATURE_CLOSURE +TRIO_PUBLIC int +trio_vcprintf +TRIO_ARGS4((stream, closure, format, args), + trio_outstream_t stream, + trio_pointer_t closure, + TRIO_CONST char *format, + va_list args) +{ + trio_custom_t data; + + assert(VALID(stream)); + assert(VALID(format)); + + data.stream.out = stream; + data.closure = closure; + return TrioFormat(&data, 0, TrioOutStreamCustom, format, args, NULL); +} +#endif /* TRIO_FEATURE_CLOSURE */ + +#if TRIO_FEATURE_CLOSURE +TRIO_PUBLIC int +trio_cprintfv +TRIO_ARGS4((stream, closure, format, args), + trio_outstream_t stream, + trio_pointer_t closure, + TRIO_CONST char *format, + void **args) +{ + static va_list unused; + trio_custom_t data; + + assert(VALID(stream)); + assert(VALID(format)); + + data.stream.out = stream; + data.closure = closure; + return TrioFormat(&data, 0, TrioOutStreamCustom, format, unused, args); +} +#endif /* TRIO_FEATURE_CLOSURE */ + +/************************************************************************* + * sprintf + */ + +/** + Print to string. + + @param buffer Output string. + @param format Formatting string. + @param ... Arguments. + @return Number of printed characters. + */ +TRIO_PUBLIC int +trio_sprintf +TRIO_VARGS3((buffer, format, va_alist), + char *buffer, + TRIO_CONST char *format, + TRIO_VA_DECL) +{ + int status; + va_list args; + + assert(VALID(buffer)); + assert(VALID(format)); + + TRIO_VA_START(args, format); + status = TrioFormat(&buffer, 0, TrioOutStreamString, format, args, NULL); + *buffer = NIL; /* Terminate with NIL character */ + TRIO_VA_END(args); + return status; +} + +/** + Print to string. + + @param buffer Output string. + @param format Formatting string. + @param args Arguments. + @return Number of printed characters. + */ +TRIO_PUBLIC int +trio_vsprintf +TRIO_ARGS3((buffer, format, args), + char *buffer, + TRIO_CONST char *format, + va_list args) +{ + int status; + + assert(VALID(buffer)); + assert(VALID(format)); + + status = TrioFormat(&buffer, 0, TrioOutStreamString, format, args, NULL); + *buffer = NIL; + return status; +} + +/** + Print to string. + + @param buffer Output string. + @param format Formatting string. + @param args Arguments. + @return Number of printed characters. + */ +TRIO_PUBLIC int +trio_sprintfv +TRIO_ARGS3((buffer, format, args), + char *buffer, + TRIO_CONST char *format, + trio_pointer_t *args) +{ + static va_list unused; + int status; + + assert(VALID(buffer)); + assert(VALID(format)); + + status = TrioFormat(&buffer, 0, TrioOutStreamString, format, unused, args); + *buffer = NIL; + return status; +} + +/************************************************************************* + * snprintf + */ + +/** + Print at most @p max characters to string. + + @param buffer Output string. + @param max Maximum number of characters to print. + @param format Formatting string. + @param ... Arguments. + @return Number of printed characters. + */ +TRIO_PUBLIC int +trio_snprintf +TRIO_VARGS4((buffer, max, format, va_alist), + char *buffer, + size_t max, + TRIO_CONST char *format, + TRIO_VA_DECL) +{ + int status; + va_list args; + + assert(VALID(buffer) || (max == 0)); + assert(VALID(format)); + + TRIO_VA_START(args, format); + status = TrioFormat(&buffer, max > 0 ? max - 1 : 0, + TrioOutStreamStringMax, format, args, NULL); + if (max > 0) + *buffer = NIL; + TRIO_VA_END(args); + return status; +} + +/** + Print at most @p max characters to string. + + @param buffer Output string. + @param max Maximum number of characters to print. + @param format Formatting string. + @param args Arguments. + @return Number of printed characters. + */ +TRIO_PUBLIC int +trio_vsnprintf +TRIO_ARGS4((buffer, max, format, args), + char *buffer, + size_t max, + TRIO_CONST char *format, + va_list args) +{ + int status; + + assert(VALID(buffer) || (max == 0)); + assert(VALID(format)); + + status = TrioFormat(&buffer, max > 0 ? max - 1 : 0, + TrioOutStreamStringMax, format, args, NULL); + if (max > 0) + *buffer = NIL; + return status; +} + +/** + Print at most @p max characters to string. + + @param buffer Output string. + @param max Maximum number of characters to print. + @param format Formatting string. + @param args Arguments. + @return Number of printed characters. + */ +TRIO_PUBLIC int +trio_snprintfv +TRIO_ARGS4((buffer, max, format, args), + char *buffer, + size_t max, + TRIO_CONST char *format, + trio_pointer_t *args) +{ + static va_list unused; + int status; + + assert(VALID(buffer) || (max == 0)); + assert(VALID(format)); + + status = TrioFormat(&buffer, max > 0 ? max - 1 : 0, + TrioOutStreamStringMax, format, unused, args); + if (max > 0) + *buffer = NIL; + return status; +} + +/************************************************************************* + * snprintfcat + * Appends the new string to the buffer string overwriting the '\0' + * character at the end of buffer. + */ +#if TRIO_EXTENSION +TRIO_PUBLIC int +trio_snprintfcat +TRIO_VARGS4((buffer, max, format, va_alist), + char *buffer, + size_t max, + TRIO_CONST char *format, + TRIO_VA_DECL) +{ + int status; + va_list args; + size_t buf_len; + + TRIO_VA_START(args, format); + + assert(VALID(buffer)); + assert(VALID(format)); + + buf_len = trio_length(buffer); + buffer = &buffer[buf_len]; + + status = TrioFormat(&buffer, max - 1 - buf_len, + TrioOutStreamStringMax, format, args, NULL); + TRIO_VA_END(args); + *buffer = NIL; + return status; +} +#endif + +#if TRIO_EXTENSION +TRIO_PUBLIC int +trio_vsnprintfcat +TRIO_ARGS4((buffer, max, format, args), + char *buffer, + size_t max, + TRIO_CONST char *format, + va_list args) +{ + int status; + size_t buf_len; + + assert(VALID(buffer)); + assert(VALID(format)); + + buf_len = trio_length(buffer); + buffer = &buffer[buf_len]; + status = TrioFormat(&buffer, max - 1 - buf_len, + TrioOutStreamStringMax, format, args, NULL); + *buffer = NIL; + return status; +} +#endif + +/************************************************************************* + * trio_aprintf + */ + +#if TRIO_DEPRECATED && TRIO_FEATURE_DYNAMICSTRING +TRIO_PUBLIC char * +trio_aprintf +TRIO_VARGS2((format, va_alist), + TRIO_CONST char *format, + TRIO_VA_DECL) +{ + va_list args; + trio_string_t *info; + char *result = NULL; + + assert(VALID(format)); + + info = trio_xstring_duplicate(""); + if (info) + { + TRIO_VA_START(args, format); + (void)TrioFormat(info, 0, TrioOutStreamStringDynamic, + format, args, NULL); + TRIO_VA_END(args); + + trio_string_terminate(info); + result = trio_string_extract(info); + trio_string_destroy(info); + } + return result; +} +#endif /* TRIO_DEPRECATED && TRIO_FEATURE_DYNAMICSTRING */ + +#if TRIO_DEPRECATED && TRIO_FEATURE_DYNAMICSTRING +TRIO_PUBLIC char * +trio_vaprintf +TRIO_ARGS2((format, args), + TRIO_CONST char *format, + va_list args) +{ + trio_string_t *info; + char *result = NULL; + + assert(VALID(format)); + + info = trio_xstring_duplicate(""); + if (info) + { + (void)TrioFormat(info, 0, TrioOutStreamStringDynamic, + format, args, NULL); + trio_string_terminate(info); + result = trio_string_extract(info); + trio_string_destroy(info); + } + return result; +} +#endif /* TRIO_DEPRECATED && TRIO_FEATURE_DYNAMICSTRING */ + +/** + Allocate and print to string. + The memory allocated and returned by @p result must be freed by the + calling application. + + @param result Output string. + @param format Formatting string. + @param ... Arguments. + @return Number of printed characters. + */ +#if TRIO_FEATURE_DYNAMICSTRING +TRIO_PUBLIC int +trio_asprintf +TRIO_VARGS3((result, format, va_alist), + char **result, + TRIO_CONST char *format, + TRIO_VA_DECL) +{ + va_list args; + int status; + trio_string_t *info; + + assert(VALID(format)); + + *result = NULL; + + info = trio_xstring_duplicate(""); + if (info == NULL) + { + status = TRIO_ERROR_RETURN(TRIO_ENOMEM, 0); + } + else + { + TRIO_VA_START(args, format); + status = TrioFormat(info, 0, TrioOutStreamStringDynamic, + format, args, NULL); + TRIO_VA_END(args); + if (status >= 0) + { + trio_string_terminate(info); + *result = trio_string_extract(info); + } + trio_string_destroy(info); + } + return status; +} +#endif /* TRIO_FEATURE_DYNAMICSTRING */ + +/** + Allocate and print to string. + The memory allocated and returned by @p result must be freed by the + calling application. + + @param result Output string. + @param format Formatting string. + @param args Arguments. + @return Number of printed characters. + */ +#if TRIO_FEATURE_DYNAMICSTRING +TRIO_PUBLIC int +trio_vasprintf +TRIO_ARGS3((result, format, args), + char **result, + TRIO_CONST char *format, + va_list args) +{ + int status; + trio_string_t *info; + + assert(VALID(format)); + + *result = NULL; + + info = trio_xstring_duplicate(""); + if (info == NULL) + { + status = TRIO_ERROR_RETURN(TRIO_ENOMEM, 0); + } + else + { + status = TrioFormat(info, 0, TrioOutStreamStringDynamic, + format, args, NULL); + if (status >= 0) + { + trio_string_terminate(info); + *result = trio_string_extract(info); + } + trio_string_destroy(info); + } + return status; +} +#endif /* TRIO_FEATURE_DYNAMICSTRING */ + +/** + Allocate and print to string. + The memory allocated and returned by @p result must be freed by the + calling application. + + @param result Output string. + @param format Formatting string. + @param args Arguments. + @return Number of printed characters. + */ +#if TRIO_FEATURE_DYNAMICSTRING +TRIO_PUBLIC int +trio_asprintfv +TRIO_ARGS3((result, format, args), + char **result, + TRIO_CONST char *format, + trio_pointer_t * args) +{ + static va_list unused; + int status; + trio_string_t *info; + + assert(VALID(format)); + + *result = NULL; + + info = trio_xstring_duplicate(""); + if (info == NULL) + { + status = TRIO_ERROR_RETURN(TRIO_ENOMEM, 0); + } + else + { + status = TrioFormat(info, 0, TrioOutStreamStringDynamic, + format, unused, args); + if (status >= 0) + { + trio_string_terminate(info); + *result = trio_string_extract(info); + } + trio_string_destroy(info); + } + return status; +} +#endif /* TRIO_FEATURE_DYNAMICSTRING */ + +/** @} End of Printf documentation module */ + +/************************************************************************* + * + * CALLBACK + * + ************************************************************************/ + +#if defined(TRIO_DOCUMENTATION) +# include "doc/doc_register.h" +#endif +/** + @addtogroup UserDefined + @{ +*/ + +#if TRIO_FEATURE_USER_DEFINED + +/************************************************************************* + * trio_register + */ + +/** + Register new user-defined specifier. + + @param callback + @param name + @return Handle. + */ +TRIO_PUBLIC trio_pointer_t +trio_register +TRIO_ARGS2((callback, name), + trio_callback_t callback, + TRIO_CONST char *name) +{ + trio_userdef_t *def; + trio_userdef_t *prev = NULL; + + if (callback == NULL) + return NULL; + + if (name) + { + /* Handle built-in namespaces */ + if (name[0] == ':') + { + if (trio_equal(name, ":enter")) + { + internalEnterCriticalRegion = callback; + } + else if (trio_equal(name, ":leave")) + { + internalLeaveCriticalRegion = callback; + } + return NULL; + } + + /* Bail out if namespace is too long */ + if (trio_length(name) >= MAX_USER_NAME) + return NULL; + + /* Bail out if namespace already is registered */ + def = TrioFindNamespace(name, &prev); + if (def) + return NULL; + } + + def = (trio_userdef_t *)TRIO_MALLOC(sizeof(trio_userdef_t)); + if (def) + { + if (internalEnterCriticalRegion) + (void)internalEnterCriticalRegion(NULL); + + if (name) + { + /* Link into internal list */ + if (prev == NULL) + internalUserDef = def; + else + prev->next = def; + } + /* Initialize */ + def->callback = callback; + def->name = (name == NULL) + ? NULL + : trio_duplicate(name); + def->next = NULL; + + if (internalLeaveCriticalRegion) + (void)internalLeaveCriticalRegion(NULL); + } + return (trio_pointer_t)def; +} + +/** + Unregister an existing user-defined specifier. + + @param handle + */ +void +trio_unregister +TRIO_ARGS1((handle), + trio_pointer_t handle) +{ + trio_userdef_t *self = (trio_userdef_t *)handle; + trio_userdef_t *def; + trio_userdef_t *prev = NULL; + + assert(VALID(self)); + + if (self->name) + { + def = TrioFindNamespace(self->name, &prev); + if (def) + { + if (internalEnterCriticalRegion) + (void)internalEnterCriticalRegion(NULL); + + if (prev == NULL) + internalUserDef = internalUserDef->next; + else + prev->next = def->next; + + if (internalLeaveCriticalRegion) + (void)internalLeaveCriticalRegion(NULL); + } + trio_destroy(self->name); + } + TRIO_FREE(self); +} + +/************************************************************************* + * trio_get_format [public] + */ +TRIO_CONST char * +trio_get_format +TRIO_ARGS1((ref), + trio_pointer_t ref) +{ +#if TRIO_FEATURE_USER_DEFINED + assert(((trio_reference_t *)ref)->parameter->type == FORMAT_USER_DEFINED); +#endif + + return (((trio_reference_t *)ref)->parameter->user_data); +} + +/************************************************************************* + * trio_get_argument [public] + */ +TRIO_CONST trio_pointer_t +trio_get_argument +TRIO_ARGS1((ref), + trio_pointer_t ref) +{ +#if TRIO_FEATURE_USER_DEFINED + assert(((trio_reference_t *)ref)->parameter->type == FORMAT_USER_DEFINED); +#endif + + return ((trio_reference_t *)ref)->parameter->data.pointer; +} + +/************************************************************************* + * trio_get_width / trio_set_width [public] + */ +int +trio_get_width +TRIO_ARGS1((ref), + trio_pointer_t ref) +{ + return ((trio_reference_t *)ref)->parameter->width; +} + +void +trio_set_width +TRIO_ARGS2((ref, width), + trio_pointer_t ref, + int width) +{ + ((trio_reference_t *)ref)->parameter->width = width; +} + +/************************************************************************* + * trio_get_precision / trio_set_precision [public] + */ +int +trio_get_precision +TRIO_ARGS1((ref), + trio_pointer_t ref) +{ + return (((trio_reference_t *)ref)->parameter->precision); +} + +void +trio_set_precision +TRIO_ARGS2((ref, precision), + trio_pointer_t ref, + int precision) +{ + ((trio_reference_t *)ref)->parameter->precision = precision; +} + +/************************************************************************* + * trio_get_base / trio_set_base [public] + */ +int +trio_get_base +TRIO_ARGS1((ref), + trio_pointer_t ref) +{ + return (((trio_reference_t *)ref)->parameter->base); +} + +void +trio_set_base +TRIO_ARGS2((ref, base), + trio_pointer_t ref, + int base) +{ + ((trio_reference_t *)ref)->parameter->base = base; +} + +/************************************************************************* + * trio_get_long / trio_set_long [public] + */ +int +trio_get_long +TRIO_ARGS1((ref), + trio_pointer_t ref) +{ + return (((trio_reference_t *)ref)->parameter->flags & FLAGS_LONG) + ? TRUE + : FALSE; +} + +void +trio_set_long +TRIO_ARGS2((ref, is_long), + trio_pointer_t ref, + int is_long) +{ + if (is_long) + ((trio_reference_t *)ref)->parameter->flags |= FLAGS_LONG; + else + ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_LONG; +} + +/************************************************************************* + * trio_get_longlong / trio_set_longlong [public] + */ +int +trio_get_longlong +TRIO_ARGS1((ref), + trio_pointer_t ref) +{ + return (((trio_reference_t *)ref)->parameter->flags & FLAGS_QUAD) + ? TRUE + : FALSE; +} + +void +trio_set_longlong +TRIO_ARGS2((ref, is_longlong), + trio_pointer_t ref, + int is_longlong) +{ + if (is_longlong) + ((trio_reference_t *)ref)->parameter->flags |= FLAGS_QUAD; + else + ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_QUAD; +} + +/************************************************************************* + * trio_get_longdouble / trio_set_longdouble [public] + */ +# if TRIO_FEATURE_FLOAT +int +trio_get_longdouble +TRIO_ARGS1((ref), + trio_pointer_t ref) +{ + return (((trio_reference_t *)ref)->parameter->flags & FLAGS_LONGDOUBLE) + ? TRUE + : FALSE; +} + +void +trio_set_longdouble +TRIO_ARGS2((ref, is_longdouble), + trio_pointer_t ref, + int is_longdouble) +{ + if (is_longdouble) + ((trio_reference_t *)ref)->parameter->flags |= FLAGS_LONGDOUBLE; + else + ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_LONGDOUBLE; +} +# endif /* TRIO_FEATURE_FLOAT */ + +/************************************************************************* + * trio_get_short / trio_set_short [public] + */ +int +trio_get_short +TRIO_ARGS1((ref), + trio_pointer_t ref) +{ + return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SHORT) + ? TRUE + : FALSE; +} + +void +trio_set_short +TRIO_ARGS2((ref, is_short), + trio_pointer_t ref, + int is_short) +{ + if (is_short) + ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SHORT; + else + ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SHORT; +} + +/************************************************************************* + * trio_get_shortshort / trio_set_shortshort [public] + */ +int +trio_get_shortshort +TRIO_ARGS1((ref), + trio_pointer_t ref) +{ + return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SHORTSHORT) + ? TRUE + : FALSE; +} + +void +trio_set_shortshort +TRIO_ARGS2((ref, is_shortshort), + trio_pointer_t ref, + int is_shortshort) +{ + if (is_shortshort) + ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SHORTSHORT; + else + ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SHORTSHORT; +} + +/************************************************************************* + * trio_get_alternative / trio_set_alternative [public] + */ +int +trio_get_alternative +TRIO_ARGS1((ref), + trio_pointer_t ref) +{ + return (((trio_reference_t *)ref)->parameter->flags & FLAGS_ALTERNATIVE) + ? TRUE + : FALSE; +} + +void +trio_set_alternative +TRIO_ARGS2((ref, is_alternative), + trio_pointer_t ref, + int is_alternative) +{ + if (is_alternative) + ((trio_reference_t *)ref)->parameter->flags |= FLAGS_ALTERNATIVE; + else + ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_ALTERNATIVE; +} + +/************************************************************************* + * trio_get_alignment / trio_set_alignment [public] + */ +int +trio_get_alignment +TRIO_ARGS1((ref), + trio_pointer_t ref) +{ + return (((trio_reference_t *)ref)->parameter->flags & FLAGS_LEFTADJUST) + ? TRUE + : FALSE; +} + +void +trio_set_alignment +TRIO_ARGS2((ref, is_leftaligned), + trio_pointer_t ref, + int is_leftaligned) +{ + if (is_leftaligned) + ((trio_reference_t *)ref)->parameter->flags |= FLAGS_LEFTADJUST; + else + ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_LEFTADJUST; +} + +/************************************************************************* + * trio_get_spacing /trio_set_spacing [public] + */ +int +trio_get_spacing +TRIO_ARGS1((ref), + trio_pointer_t ref) +{ + return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SPACE) + ? TRUE + : FALSE; +} + +void +trio_set_spacing +TRIO_ARGS2((ref, is_space), + trio_pointer_t ref, + int is_space) +{ + if (is_space) + ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SPACE; + else + ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SPACE; +} + +/************************************************************************* + * trio_get_sign / trio_set_sign [public] + */ +int +trio_get_sign +TRIO_ARGS1((ref), + trio_pointer_t ref) +{ + return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SHOWSIGN) + ? TRUE + : FALSE; +} + +void +trio_set_sign +TRIO_ARGS2((ref, is_sign), + trio_pointer_t ref, + int is_sign) +{ + if (is_sign) + ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SHOWSIGN; + else + ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SHOWSIGN; +} + +/************************************************************************* + * trio_get_padding / trio_set_padding [public] + */ +int +trio_get_padding +TRIO_ARGS1((ref), + trio_pointer_t ref) +{ + return (((trio_reference_t *)ref)->parameter->flags & FLAGS_NILPADDING) + ? TRUE + : FALSE; +} + +void +trio_set_padding +TRIO_ARGS2((ref, is_padding), + trio_pointer_t ref, + int is_padding) +{ + if (is_padding) + ((trio_reference_t *)ref)->parameter->flags |= FLAGS_NILPADDING; + else + ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_NILPADDING; +} + +/************************************************************************* + * trio_get_quote / trio_set_quote [public] + */ +# if TRIO_FEATURE_QUOTE +int +trio_get_quote +TRIO_ARGS1((ref), + trio_pointer_t ref) +{ + return (((trio_reference_t *)ref)->parameter->flags & FLAGS_QUOTE) + ? TRUE + : FALSE; +} + +void +trio_set_quote +TRIO_ARGS2((ref, is_quote), + trio_pointer_t ref, + int is_quote) +{ + if (is_quote) + ((trio_reference_t *)ref)->parameter->flags |= FLAGS_QUOTE; + else + ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_QUOTE; +} +#endif /* TRIO_FEATURE_QUOTE */ + +/************************************************************************* + * trio_get_upper / trio_set_upper [public] + */ +int +trio_get_upper +TRIO_ARGS1((ref), + trio_pointer_t ref) +{ + return (((trio_reference_t *)ref)->parameter->flags & FLAGS_UPPER) + ? TRUE + : FALSE; +} + +void +trio_set_upper +TRIO_ARGS2((ref, is_upper), + trio_pointer_t ref, + int is_upper) +{ + if (is_upper) + ((trio_reference_t *)ref)->parameter->flags |= FLAGS_UPPER; + else + ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_UPPER; +} + +/************************************************************************* + * trio_get_largest / trio_set_largest [public] + */ +#if TRIO_FEATURE_INTMAX_T +int +trio_get_largest +TRIO_ARGS1((ref), + trio_pointer_t ref) +{ + return (((trio_reference_t *)ref)->parameter->flags & FLAGS_INTMAX_T) + ? TRUE + : FALSE; +} + +void +trio_set_largest +TRIO_ARGS2((ref, is_largest), + trio_pointer_t ref, + int is_largest) +{ + if (is_largest) + ((trio_reference_t *)ref)->parameter->flags |= FLAGS_INTMAX_T; + else + ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_INTMAX_T; +} +#endif /* TRIO_FEATURE_INTMAX_T */ + +/************************************************************************* + * trio_get_ptrdiff / trio_set_ptrdiff [public] + */ +#if TRIO_FEATURE_PTRDIFF_T +int +trio_get_ptrdiff +TRIO_ARGS1((ref), + trio_pointer_t ref) +{ + return (((trio_reference_t *)ref)->parameter->flags & FLAGS_PTRDIFF_T) + ? TRUE + : FALSE; +} + +void +trio_set_ptrdiff +TRIO_ARGS2((ref, is_ptrdiff), + trio_pointer_t ref, + int is_ptrdiff) +{ + if (is_ptrdiff) + ((trio_reference_t *)ref)->parameter->flags |= FLAGS_PTRDIFF_T; + else + ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_PTRDIFF_T; +} +#endif /* TRIO_FEATURE_PTRDIFF_T */ + +/************************************************************************* + * trio_get_size / trio_set_size [public] + */ +#if TRIO_FEATURE_SIZE_T +int +trio_get_size +TRIO_ARGS1((ref), + trio_pointer_t ref) +{ + return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SIZE_T) + ? TRUE + : FALSE; +} + +void +trio_set_size +TRIO_ARGS2((ref, is_size), + trio_pointer_t ref, + int is_size) +{ + if (is_size) + ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SIZE_T; + else + ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SIZE_T; +} +#endif /* TRIO_FEATURE_SIZE_T */ + +/************************************************************************* + * trio_print_int [public] + */ +void +trio_print_int +TRIO_ARGS2((ref, number), + trio_pointer_t ref, + int number) +{ + trio_reference_t *self = (trio_reference_t *)ref; + + TrioWriteNumber(self->data, + (trio_uintmax_t)number, + self->parameter->flags, + self->parameter->width, + self->parameter->precision, + self->parameter->base); +} + +/************************************************************************* + * trio_print_uint [public] + */ +void +trio_print_uint +TRIO_ARGS2((ref, number), + trio_pointer_t ref, + unsigned int number) +{ + trio_reference_t *self = (trio_reference_t *)ref; + + TrioWriteNumber(self->data, + (trio_uintmax_t)number, + self->parameter->flags | FLAGS_UNSIGNED, + self->parameter->width, + self->parameter->precision, + self->parameter->base); +} + +/************************************************************************* + * trio_print_double [public] + */ +#if TRIO_FEATURE_FLOAT +void +trio_print_double +TRIO_ARGS2((ref, number), + trio_pointer_t ref, + double number) +{ + trio_reference_t *self = (trio_reference_t *)ref; + + TrioWriteDouble(self->data, + number, + self->parameter->flags, + self->parameter->width, + self->parameter->precision, + self->parameter->base); +} +#endif /* TRIO_FEATURE_FLOAT */ + +/************************************************************************* + * trio_print_string [public] + */ +void +trio_print_string +TRIO_ARGS2((ref, string), + trio_pointer_t ref, + TRIO_CONST char *string) +{ + trio_reference_t *self = (trio_reference_t *)ref; + + TrioWriteString(self->data, + string, + self->parameter->flags, + self->parameter->width, + self->parameter->precision); +} + +/************************************************************************* + * trio_print_ref [public] + */ +int +trio_print_ref +TRIO_VARGS3((ref, format, va_alist), + trio_pointer_t ref, + TRIO_CONST char *format, + TRIO_VA_DECL) +{ + int status; + va_list arglist; + + assert(VALID(format)); + + TRIO_VA_START(arglist, format); + status = TrioFormatRef((trio_reference_t *)ref, format, arglist, NULL); + TRIO_VA_END(arglist); + return status; +} + +/************************************************************************* + * trio_vprint_ref [public] + */ +int +trio_vprint_ref +TRIO_ARGS3((ref, format, arglist), + trio_pointer_t ref, + TRIO_CONST char *format, + va_list arglist) +{ + assert(VALID(format)); + + return TrioFormatRef((trio_reference_t *)ref, format, arglist, NULL); +} + +/************************************************************************* + * trio_printv_ref [public] + */ +int +trio_printv_ref +TRIO_ARGS3((ref, format, argarray), + trio_pointer_t ref, + TRIO_CONST char *format, + trio_pointer_t *argarray) +{ + static va_list unused; + + assert(VALID(format)); + + return TrioFormatRef((trio_reference_t *)ref, format, unused, argarray); +} + +#endif + +/************************************************************************* + * trio_print_pointer [public] + */ +void +trio_print_pointer +TRIO_ARGS2((ref, pointer), + trio_pointer_t ref, + trio_pointer_t pointer) +{ + trio_reference_t *self = (trio_reference_t *)ref; + trio_flags_t flags; + trio_uintmax_t number; + + if (NULL == pointer) + { + TRIO_CONST char *string = internalNullString; + while (*string) + self->data->OutStream(self->data, *string++); + } + else + { + /* + * The subtraction of the null pointer is a workaround + * to avoid a compiler warning. The performance overhead + * is negligible (and likely to be removed by an + * optimizing compiler). The (char *) casting is done + * to please ANSI C++. + */ + number = (trio_uintmax_t)((char *)pointer - (char *)0); + /* Shrink to size of pointer */ + number &= (trio_uintmax_t)-1; + flags = self->parameter->flags; + flags |= (FLAGS_UNSIGNED | FLAGS_ALTERNATIVE | + FLAGS_NILPADDING); + TrioWriteNumber(self->data, + number, + flags, + POINTER_WIDTH, + NO_PRECISION, + BASE_HEX); + } +} + +/** @} End of UserDefined documentation module */ + +/************************************************************************* + * + * LOCALES + * + ************************************************************************/ + +/************************************************************************* + * trio_locale_set_decimal_point + * + * Decimal point can only be one character. The input argument is a + * string to enable multibyte characters. At most MB_LEN_MAX characters + * will be used. + */ +#if TRIO_FEATURE_LOCALE +TRIO_PUBLIC void +trio_locale_set_decimal_point +TRIO_ARGS1((decimalPoint), + char *decimalPoint) +{ +#if defined(USE_LOCALE) + if (NULL == internalLocaleValues) + { + TrioSetLocale(); + } +#endif + internalDecimalPointLength = trio_length(decimalPoint); + if (internalDecimalPointLength == 1) + { + internalDecimalPoint = *decimalPoint; + } + else + { + internalDecimalPoint = NIL; + trio_copy_max(internalDecimalPointString, + sizeof(internalDecimalPointString), + decimalPoint); + } +} +#endif + +/************************************************************************* + * trio_locale_set_thousand_separator + * + * See trio_locale_set_decimal_point + */ +#if TRIO_FEATURE_LOCALE || TRIO_EXTENSION +TRIO_PUBLIC void +trio_locale_set_thousand_separator +TRIO_ARGS1((thousandSeparator), + char *thousandSeparator) +{ +# if defined(USE_LOCALE) + if (NULL == internalLocaleValues) + { + TrioSetLocale(); + } +# endif + trio_copy_max(internalThousandSeparator, + sizeof(internalThousandSeparator), + thousandSeparator); + internalThousandSeparatorLength = trio_length(internalThousandSeparator); +} +#endif + +/************************************************************************* + * trio_locale_set_grouping + * + * Array of bytes. Reversed order. + * + * CHAR_MAX : No further grouping + * 0 : Repeat last group for the remaining digits (not necessary + * as C strings are zero-terminated) + * n : Set current group to n + * + * Same order as the grouping attribute in LC_NUMERIC. + */ +#if TRIO_FEATURE_LOCALE || TRIO_EXTENSION +TRIO_PUBLIC void +trio_locale_set_grouping +TRIO_ARGS1((grouping), + char *grouping) +{ +# if defined(USE_LOCALE) + if (NULL == internalLocaleValues) + { + TrioSetLocale(); + } +# endif + trio_copy_max(internalGrouping, + sizeof(internalGrouping), + grouping); +} +#endif + + +/************************************************************************* + * + * SCANNING + * + ************************************************************************/ + +#if TRIO_FEATURE_SCANF + +/************************************************************************* + * TrioSkipWhitespaces + */ +TRIO_PRIVATE int +TrioSkipWhitespaces +TRIO_ARGS1((self), + trio_class_t *self) +{ + int ch; + + ch = self->current; + while (isspace(ch)) + { + self->InStream(self, &ch); + } + return ch; +} + +/************************************************************************* + * TrioGetCollation + */ +#if TRIO_EXTENSION +TRIO_PRIVATE void +TrioGetCollation(TRIO_NOARGS) +{ + int i; + int j; + int k; + char first[2]; + char second[2]; + + /* This is computationally expensive */ + first[1] = NIL; + second[1] = NIL; + for (i = 0; i < MAX_CHARACTER_CLASS; i++) + { + k = 0; + first[0] = (char)i; + for (j = 0; j < MAX_CHARACTER_CLASS; j++) + { + second[0] = (char)j; + if (trio_equal_locale(first, second)) + internalCollationArray[i][k++] = (char)j; + } + internalCollationArray[i][k] = NIL; + } +} +#endif + +/************************************************************************* + * TrioGetCharacterClass + * + * FIXME: + * multibyte + */ +TRIO_PRIVATE int +TrioGetCharacterClass +TRIO_ARGS4((format, offsetPointer, flagsPointer, characterclass), + TRIO_CONST char *format, + int *offsetPointer, + trio_flags_t *flagsPointer, + int *characterclass) +{ + int offset = *offsetPointer; + int i; + char ch; + char range_begin; + char range_end; + + *flagsPointer &= ~FLAGS_EXCLUDE; + + if (format[offset] == QUALIFIER_CIRCUMFLEX) + { + *flagsPointer |= FLAGS_EXCLUDE; + offset++; + } + /* + * If the ungroup character is at the beginning of the scanlist, + * it will be part of the class, and a second ungroup character + * must follow to end the group. + */ + if (format[offset] == SPECIFIER_UNGROUP) + { + characterclass[(int)SPECIFIER_UNGROUP]++; + offset++; + } + /* + * Minus is used to specify ranges. To include minus in the class, + * it must be at the beginning of the list + */ + if (format[offset] == QUALIFIER_MINUS) + { + characterclass[(int)QUALIFIER_MINUS]++; + offset++; + } + /* Collect characters */ + for (ch = format[offset]; + (ch != SPECIFIER_UNGROUP) && (ch != NIL); + ch = format[++offset]) + { + switch (ch) + { + case QUALIFIER_MINUS: /* Scanlist ranges */ + + /* + * Both C99 and UNIX98 describes ranges as implementation- + * defined. + * + * We support the following behaviour (although this may + * change as we become wiser) + * - only increasing ranges, ie. [a-b] but not [b-a] + * - transitive ranges, ie. [a-b-c] == [a-c] + * - trailing minus, ie. [a-] is interpreted as an 'a' + * and a '-' + * - duplicates (although we can easily convert these + * into errors) + */ + range_begin = format[offset - 1]; + range_end = format[++offset]; + if (range_end == SPECIFIER_UNGROUP) + { + /* Trailing minus is included */ + characterclass[(int)ch]++; + ch = range_end; + break; /* for */ + } + if (range_end == NIL) + return TRIO_ERROR_RETURN(TRIO_EINVAL, offset); + if (range_begin > range_end) + return TRIO_ERROR_RETURN(TRIO_ERANGE, offset); + + for (i = (int)range_begin; i <= (int)range_end; i++) + characterclass[i]++; + + ch = range_end; + break; + +#if TRIO_EXTENSION + + case SPECIFIER_GROUP: + + switch (format[offset + 1]) + { + case QUALIFIER_DOT: /* Collating symbol */ + /* + * FIXME: This will be easier to implement when multibyte + * characters have been implemented. Until now, we ignore + * this feature. + */ + for (i = offset + 2; ; i++) + { + if (format[i] == NIL) + /* Error in syntax */ + return -1; + else if (format[i] == QUALIFIER_DOT) + break; /* for */ + } + if (format[++i] != SPECIFIER_UNGROUP) + return -1; + + offset = i; + break; + + case QUALIFIER_EQUAL: /* Equivalence class expressions */ + { + unsigned int j; + unsigned int k; + + if (internalCollationUnconverted) + { + /* Lazy evaluation of collation array */ + TrioGetCollation(); + internalCollationUnconverted = FALSE; + } + for (i = offset + 2; ; i++) + { + if (format[i] == NIL) + /* Error in syntax */ + return -1; + else if (format[i] == QUALIFIER_EQUAL) + break; /* for */ + else + { + /* Mark any equivalent character */ + k = (unsigned int)format[i]; + for (j = 0; internalCollationArray[k][j] != NIL; j++) + characterclass[(int)internalCollationArray[k][j]]++; + } + } + if (format[++i] != SPECIFIER_UNGROUP) + return -1; + + offset = i; + } + break; + + case QUALIFIER_COLON: /* Character class expressions */ + + if (trio_equal_max(CLASS_ALNUM, sizeof(CLASS_ALNUM) - 1, + &format[offset])) + { + for (i = 0; i < MAX_CHARACTER_CLASS; i++) + if (isalnum(i)) + characterclass[i]++; + offset += sizeof(CLASS_ALNUM) - 1; + } + else if (trio_equal_max(CLASS_ALPHA, sizeof(CLASS_ALPHA) - 1, + &format[offset])) + { + for (i = 0; i < MAX_CHARACTER_CLASS; i++) + if (isalpha(i)) + characterclass[i]++; + offset += sizeof(CLASS_ALPHA) - 1; + } + else if (trio_equal_max(CLASS_CNTRL, sizeof(CLASS_CNTRL) - 1, + &format[offset])) + { + for (i = 0; i < MAX_CHARACTER_CLASS; i++) + if (iscntrl(i)) + characterclass[i]++; + offset += sizeof(CLASS_CNTRL) - 1; + } + else if (trio_equal_max(CLASS_DIGIT, sizeof(CLASS_DIGIT) - 1, + &format[offset])) + { + for (i = 0; i < MAX_CHARACTER_CLASS; i++) + if (isdigit(i)) + characterclass[i]++; + offset += sizeof(CLASS_DIGIT) - 1; + } + else if (trio_equal_max(CLASS_GRAPH, sizeof(CLASS_GRAPH) - 1, + &format[offset])) + { + for (i = 0; i < MAX_CHARACTER_CLASS; i++) + if (isgraph(i)) + characterclass[i]++; + offset += sizeof(CLASS_GRAPH) - 1; + } + else if (trio_equal_max(CLASS_LOWER, sizeof(CLASS_LOWER) - 1, + &format[offset])) + { + for (i = 0; i < MAX_CHARACTER_CLASS; i++) + if (islower(i)) + characterclass[i]++; + offset += sizeof(CLASS_LOWER) - 1; + } + else if (trio_equal_max(CLASS_PRINT, sizeof(CLASS_PRINT) - 1, + &format[offset])) + { + for (i = 0; i < MAX_CHARACTER_CLASS; i++) + if (isprint(i)) + characterclass[i]++; + offset += sizeof(CLASS_PRINT) - 1; + } + else if (trio_equal_max(CLASS_PUNCT, sizeof(CLASS_PUNCT) - 1, + &format[offset])) + { + for (i = 0; i < MAX_CHARACTER_CLASS; i++) + if (ispunct(i)) + characterclass[i]++; + offset += sizeof(CLASS_PUNCT) - 1; + } + else if (trio_equal_max(CLASS_SPACE, sizeof(CLASS_SPACE) - 1, + &format[offset])) + { + for (i = 0; i < MAX_CHARACTER_CLASS; i++) + if (isspace(i)) + characterclass[i]++; + offset += sizeof(CLASS_SPACE) - 1; + } + else if (trio_equal_max(CLASS_UPPER, sizeof(CLASS_UPPER) - 1, + &format[offset])) + { + for (i = 0; i < MAX_CHARACTER_CLASS; i++) + if (isupper(i)) + characterclass[i]++; + offset += sizeof(CLASS_UPPER) - 1; + } + else if (trio_equal_max(CLASS_XDIGIT, sizeof(CLASS_XDIGIT) - 1, + &format[offset])) + { + for (i = 0; i < MAX_CHARACTER_CLASS; i++) + if (isxdigit(i)) + characterclass[i]++; + offset += sizeof(CLASS_XDIGIT) - 1; + } + else + { + characterclass[(int)ch]++; + } + break; + + default: + characterclass[(int)ch]++; + break; + } + break; + +#endif /* TRIO_EXTENSION */ + + default: + characterclass[(int)ch]++; + break; + } + } + return 0; +} + +/************************************************************************* + * TrioReadNumber + * + * We implement our own number conversion in preference of strtol and + * strtoul, because we must handle 'long long' and thousand separators. + */ +TRIO_PRIVATE BOOLEAN_T +TrioReadNumber +TRIO_ARGS5((self, target, flags, width, base), + trio_class_t *self, + trio_uintmax_t *target, + trio_flags_t flags, + int width, + int base) +{ + trio_uintmax_t number = 0; + int digit; + int count; + BOOLEAN_T isNegative = FALSE; + BOOLEAN_T gotNumber = FALSE; + int j; + + assert(VALID(self)); + assert(VALID(self->InStream)); + assert((base >= MIN_BASE && base <= MAX_BASE) || (base == NO_BASE)); + + if (internalDigitsUnconverted) + { + /* Lazy evaluation of digits array */ + memset(internalDigitArray, -1, sizeof(internalDigitArray)); + for (j = 0; j < (int)sizeof(internalDigitsLower) - 1; j++) + { + internalDigitArray[(int)internalDigitsLower[j]] = j; + internalDigitArray[(int)internalDigitsUpper[j]] = j; + } + internalDigitsUnconverted = FALSE; + } + + TrioSkipWhitespaces(self); + + /* Leading sign */ + if (self->current == '+') + { + self->InStream(self, NULL); + } + else if (self->current == '-') + { + self->InStream(self, NULL); + isNegative = TRUE; + } + + count = self->processed; + + if (flags & FLAGS_ALTERNATIVE) + { + switch (base) + { + case NO_BASE: + case BASE_OCTAL: + case BASE_HEX: + case BASE_BINARY: + if (self->current == '0') + { + self->InStream(self, NULL); + if (self->current) + { + if ((base == BASE_HEX) && + (trio_to_upper(self->current) == 'X')) + { + self->InStream(self, NULL); + } + else if ((base == BASE_BINARY) && + (trio_to_upper(self->current) == 'B')) + { + self->InStream(self, NULL); + } + } + } + else + return FALSE; + break; + default: + break; + } + } + + while (((width == NO_WIDTH) || (self->processed - count < width)) && + (! ((self->current == EOF) || isspace(self->current)))) + { + if (isascii(self->current)) + { + digit = internalDigitArray[self->current]; + /* Abort if digit is not allowed in the specified base */ + if ((digit == -1) || (digit >= base)) + break; + } +#if TRIO_FEATURE_QUOTE + else if (flags & FLAGS_QUOTE) + { + /* Compare with thousands separator */ + for (j = 0; internalThousandSeparator[j] && self->current; j++) + { + if (internalThousandSeparator[j] != self->current) + break; + + self->InStream(self, NULL); + } + if (internalThousandSeparator[j]) + break; /* Mismatch */ + else + continue; /* Match */ + } +#endif + else + break; + + number *= base; + number += digit; + gotNumber = TRUE; /* we need at least one digit */ + + self->InStream(self, NULL); + } + + /* Was anything read at all? */ + if (!gotNumber) + return FALSE; + + if (target) + *target = (isNegative) ? (trio_uintmax_t)(-((trio_intmax_t)number)) : number; + return TRUE; +} + +/************************************************************************* + * TrioReadChar + */ +TRIO_PRIVATE int +TrioReadChar +TRIO_ARGS4((self, target, flags, width), + trio_class_t *self, + char *target, + trio_flags_t flags, + int width) +{ + int i; + char ch; + trio_uintmax_t number; + + assert(VALID(self)); + assert(VALID(self->InStream)); + + for (i = 0; + (self->current != EOF) && (i < width); + i++) + { + ch = (char)self->current; + self->InStream(self, NULL); + if ((flags & FLAGS_ALTERNATIVE) && (ch == CHAR_BACKSLASH)) + { + switch (self->current) + { + case '\\': ch = '\\'; break; + case 'a': ch = '\007'; break; + case 'b': ch = '\b'; break; + case 'f': ch = '\f'; break; + case 'n': ch = '\n'; break; + case 'r': ch = '\r'; break; + case 't': ch = '\t'; break; + case 'v': ch = '\v'; break; + default: + if (isdigit(self->current)) + { + /* Read octal number */ + if (!TrioReadNumber(self, &number, 0, 3, BASE_OCTAL)) + return 0; + ch = (char)number; + } + else if (trio_to_upper(self->current) == 'X') + { + /* Read hexadecimal number */ + self->InStream(self, NULL); + if (!TrioReadNumber(self, &number, 0, 2, BASE_HEX)) + return 0; + ch = (char)number; + } + else + { + ch = (char)self->current; + } + break; + } + } + + if (target) + target[i] = ch; + } + return i + 1; +} + +/************************************************************************* + * TrioReadString + */ +TRIO_PRIVATE BOOLEAN_T +TrioReadString +TRIO_ARGS4((self, target, flags, width), + trio_class_t *self, + char *target, + trio_flags_t flags, + int width) +{ + int i; + + assert(VALID(self)); + assert(VALID(self->InStream)); + + TrioSkipWhitespaces(self); + + /* + * Continue until end of string is reached, a whitespace is encountered, + * or width is exceeded + */ + for (i = 0; + ((width == NO_WIDTH) || (i < width)) && + (! ((self->current == EOF) || isspace(self->current))); + i++) + { + if (TrioReadChar(self, (target ? &target[i] : 0), flags, 1) == 0) + break; /* for */ + } + if (target) + target[i] = NIL; + return TRUE; +} + +/************************************************************************* + * TrioReadWideChar + */ +#if TRIO_FEATURE_WIDECHAR +TRIO_PRIVATE int +TrioReadWideChar +TRIO_ARGS4((self, target, flags, width), + trio_class_t *self, + trio_wchar_t *target, + trio_flags_t flags, + int width) +{ + int i; + int j; + int size; + int amount = 0; + trio_wchar_t wch; + char buffer[MB_LEN_MAX + 1]; + + assert(VALID(self)); + assert(VALID(self->InStream)); + + for (i = 0; + (self->current != EOF) && (i < width); + i++) + { + if (isascii(self->current)) + { + if (TrioReadChar(self, buffer, flags, 1) == 0) + return 0; + buffer[1] = NIL; + } + else + { + /* + * Collect a multibyte character, by enlarging buffer until + * it contains a fully legal multibyte character, or the + * buffer is full. + */ + j = 0; + do + { + buffer[j++] = (char)self->current; + buffer[j] = NIL; + self->InStream(self, NULL); + } + while ((j < (int)sizeof(buffer)) && (mblen(buffer, (size_t)j) != j)); + } + if (target) + { + size = mbtowc(&wch, buffer, sizeof(buffer)); + if (size > 0) + target[i] = wch; + } + amount += size; + self->InStream(self, NULL); + } + return amount; +} +#endif /* TRIO_FEATURE_WIDECHAR */ + +/************************************************************************* + * TrioReadWideString + */ +#if TRIO_FEATURE_WIDECHAR +TRIO_PRIVATE BOOLEAN_T +TrioReadWideString +TRIO_ARGS4((self, target, flags, width), + trio_class_t *self, + trio_wchar_t *target, + trio_flags_t flags, + int width) +{ + int i; + int size; + + assert(VALID(self)); + assert(VALID(self->InStream)); + + TrioSkipWhitespaces(self); + +#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE) + /* Required by TrioReadWideChar */ + (void)mblen(NULL, 0); +#endif + + /* + * Continue until end of string is reached, a whitespace is encountered, + * or width is exceeded + */ + for (i = 0; + ((width == NO_WIDTH) || (i < width)) && + (! ((self->current == EOF) || isspace(self->current))); + ) + { + size = TrioReadWideChar(self, &target[i], flags, 1); + if (size == 0) + break; /* for */ + + i += size; + } + if (target) + target[i] = WCONST('\0'); + return TRUE; +} +#endif /* TRIO_FEATURE_WIDECHAR */ + +/************************************************************************* + * TrioReadGroup + * + * Reads non-empty character groups. + * + * FIXME: characterclass does not work with multibyte characters + */ +TRIO_PRIVATE BOOLEAN_T +TrioReadGroup +TRIO_ARGS5((self, target, characterclass, flags, width), + trio_class_t *self, + char *target, + int *characterclass, + trio_flags_t flags, + int width) +{ + int ch; + int i; + + assert(VALID(self)); + assert(VALID(self->InStream)); + + ch = self->current; + for (i = 0; + ((width == NO_WIDTH) || (i < width)) && + (! ((ch == EOF) || + (((flags & FLAGS_EXCLUDE) != 0) ^ (characterclass[ch] == 0)))); + i++) + { + if (target) + target[i] = (char)ch; + self->InStream(self, &ch); + } + + if (i == 0) + return FALSE; + + /* Terminate the string if input saved */ + if (target) + target[i] = NIL; + return TRUE; +} + +/************************************************************************* + * TrioReadDouble + * + * FIXME: + * add long double + * handle base + */ +#if TRIO_FEATURE_FLOAT +TRIO_PRIVATE BOOLEAN_T +TrioReadDouble +TRIO_ARGS4((self, target, flags, width), + trio_class_t *self, + trio_pointer_t target, + trio_flags_t flags, + int width) +{ + int ch; + char doubleString[512]; + int offset = 0; + int start; +# if TRIO_FEATURE_QUOTE + int j; +# endif + BOOLEAN_T isHex = FALSE; + trio_long_double_t infinity; + + doubleString[0] = 0; + + if ((width == NO_WIDTH) || (width > (int)sizeof(doubleString) - 1)) + width = sizeof(doubleString) - 1; + + TrioSkipWhitespaces(self); + + /* + * Read entire double number from stream. trio_to_double requires + * a string as input, but InStream can be anything, so we have to + * collect all characters. + */ + ch = self->current; + if ((ch == '+') || (ch == '-')) + { + doubleString[offset++] = (char)ch; + self->InStream(self, &ch); + width--; + } + + start = offset; + switch (ch) + { + case 'n': + case 'N': + /* Not-a-number */ + if (offset != 0) + break; + /* FALLTHROUGH */ + case 'i': + case 'I': + /* Infinity */ + while (isalpha(ch) && (offset - start < width)) + { + doubleString[offset++] = (char)ch; + self->InStream(self, &ch); + } + doubleString[offset] = NIL; + + /* Case insensitive string comparison */ + if (trio_equal(&doubleString[start], INFINITE_UPPER) || + trio_equal(&doubleString[start], LONG_INFINITE_UPPER)) + { + infinity = ((start == 1) && (doubleString[0] == '-')) + ? trio_ninf() + : trio_pinf(); + if (flags & FLAGS_LONGDOUBLE) + { + *((trio_long_double_t *)target) = infinity; + } + else if (flags & FLAGS_LONG) + { + *((double *)target) = infinity; + } + else + { + *((float *)target) = infinity; + } + return TRUE; + } + if (trio_equal(doubleString, NAN_UPPER)) + { + /* NaN must not have a preceeding + nor - */ + if (flags & FLAGS_LONGDOUBLE) + { + *((trio_long_double_t *)target) = trio_nan(); + } + else if (flags & FLAGS_LONG) + { + *((double *)target) = trio_nan(); + } + else + { + *((float *)target) = trio_nan(); + } + return TRUE; + } + return FALSE; + + case '0': + doubleString[offset++] = (char)ch; + self->InStream(self, &ch); + if (trio_to_upper(ch) == 'X') + { + isHex = TRUE; + doubleString[offset++] = (char)ch; + self->InStream(self, &ch); + } + break; + + default: + break; + } + + while ((ch != EOF) && (offset - start < width)) + { + /* Integer part */ + if (isHex ? isxdigit(ch) : isdigit(ch)) + { + doubleString[offset++] = (char)ch; + self->InStream(self, &ch); + } +# if TRIO_FEATURE_QUOTE + else if (flags & FLAGS_QUOTE) + { + /* Compare with thousands separator */ + for (j = 0; internalThousandSeparator[j] && self->current; j++) + { + if (internalThousandSeparator[j] != self->current) + break; + + self->InStream(self, &ch); + } + if (internalThousandSeparator[j]) + break; /* Mismatch */ + else + continue; /* Match */ + } +# endif + else + break; /* while */ + } + if (ch == '.') + { + /* Decimal part */ + doubleString[offset++] = (char)ch; + self->InStream(self, &ch); + while ((isHex ? isxdigit(ch) : isdigit(ch)) && + (offset - start < width)) + { + doubleString[offset++] = (char)ch; + self->InStream(self, &ch); + } + } + if (isHex ? (trio_to_upper(ch) == 'P') : (trio_to_upper(ch) == 'E')) + { + /* Exponent */ + doubleString[offset++] = (char)ch; + self->InStream(self, &ch); + if ((ch == '+') || (ch == '-')) + { + doubleString[offset++] = (char)ch; + self->InStream(self, &ch); + } + while (isdigit(ch) && (offset - start < width)) + { + doubleString[offset++] = (char)ch; + self->InStream(self, &ch); + } + } + + if ((offset == start) || (*doubleString == NIL)) + return FALSE; + + doubleString[offset] = 0; + + if (flags & FLAGS_LONGDOUBLE) + { + *((trio_long_double_t *)target) = trio_to_long_double(doubleString, NULL); + } + else if (flags & FLAGS_LONG) + { + *((double *)target) = trio_to_double(doubleString, NULL); + } + else + { + *((float *)target) = trio_to_float(doubleString, NULL); + } + return TRUE; +} +#endif /* TRIO_FEATURE_FLOAT */ + +/************************************************************************* + * TrioReadPointer + */ +TRIO_PRIVATE BOOLEAN_T +TrioReadPointer +TRIO_ARGS3((self, target, flags), + trio_class_t *self, + trio_pointer_t *target, + trio_flags_t flags) +{ + trio_uintmax_t number; + char buffer[sizeof(internalNullString)]; + + flags |= (FLAGS_UNSIGNED | FLAGS_ALTERNATIVE | FLAGS_NILPADDING); + + if (TrioReadNumber(self, + &number, + flags, + POINTER_WIDTH, + BASE_HEX)) + { + if (target) + { +#if defined(TRIO_COMPILER_GCC) || defined(TRIO_COMPILER_MIPSPRO) + /* + * The strange assignment of number is a workaround for a compiler + * warning + */ + *target = &((char *)0)[number]; +#else + *target = (trio_pointer_t)number; +#endif + } + return TRUE; + } + else if (TrioReadString(self, + (flags & FLAGS_IGNORE) + ? NULL + : buffer, + 0, + sizeof(internalNullString) - 1)) + { + if (trio_equal_case(buffer, internalNullString)) + { + if (target) + *target = NULL; + return TRUE; + } + } + return FALSE; +} + +/************************************************************************* + * TrioScanProcess + */ +TRIO_PRIVATE int +TrioScanProcess +TRIO_ARGS3((data, format, parameters), + trio_class_t *data, + TRIO_CONST char *format, + trio_parameter_t *parameters) +{ + int status; + int assignment; + int ch; + int offset; /* Offset of format string */ + int i; /* Offset of current parameter */ + trio_flags_t flags; + int width; + int base; + trio_pointer_t pointer; + + /* Return on empty format string */ + if (format[0] == NIL) + return 0; + + status = 0; + assignment = 0; + i = 0; + offset = 0; + data->InStream(data, &ch); + + for (;;) + { + /* Skip the parameter entries */ + while (parameters[i].type == FORMAT_PARAMETER) + { + assert(i <= MAX_PARAMETERS); + i++; + } + + /* Compare non conversion-specifier part of format string */ + while (offset < parameters[i].beginOffset) + { + if ((CHAR_IDENTIFIER == format[offset]) && + (CHAR_IDENTIFIER == format[offset + 1])) + { + /* Two % in format matches one % in input stream */ + if (CHAR_IDENTIFIER == ch) + { + data->InStream(data, &ch); + offset += 2; + continue; /* while format chars left */ + } + else + { + status = TRIO_ERROR_RETURN(TRIO_EINVAL, offset); + goto end; + } + } + else /* Not an % identifier */ + { + if (isspace((int)format[offset])) + { + /* Whitespaces may match any amount of whitespaces */ + ch = TrioSkipWhitespaces(data); + } + else if (ch == format[offset]) + { + data->InStream(data, &ch); + } + else + { + status = assignment; + goto end; + } + + offset++; + } + } + + if (parameters[i].type == FORMAT_SENTINEL) + break; + + if ((EOF == ch) && (parameters[i].type != FORMAT_COUNT)) + { + status = (assignment > 0) ? assignment : EOF; + goto end; + } + + flags = parameters[i].flags; + + /* Find width */ + width = parameters[i].width; + if (flags & FLAGS_WIDTH_PARAMETER) + { + /* Get width from parameter list */ + width = (int)parameters[width].data.number.as_signed; + } + + /* Find base */ + if (NO_BASE != parameters[i].baseSpecifier) + { + /* Base from specifier has priority */ + base = parameters[i].baseSpecifier; + } + else if (flags & FLAGS_BASE_PARAMETER) + { + /* Get base from parameter list */ + base = parameters[i].base; + base = (int)parameters[base].data.number.as_signed; + } + else + { + /* Use base from format string */ + base = parameters[i].base; + } + + switch (parameters[i].type) + { + case FORMAT_INT: + { + trio_uintmax_t number; + + if (0 == base) + base = BASE_DECIMAL; + + if (!TrioReadNumber(data, + &number, + flags, + width, + base)) + { + status = assignment; + goto end; + } + + if (!(flags & FLAGS_IGNORE)) + { + assignment++; + + pointer = parameters[i].data.pointer; +#if TRIO_FEATURE_SIZE_T || TRIO_FEATURE_SIZE_T_UPPER + if (flags & FLAGS_SIZE_T) + *(size_t *)pointer = (size_t)number; + else +#endif +#if TRIO_FEATURE_PTRDIFF_T + if (flags & FLAGS_PTRDIFF_T) + *(ptrdiff_t *)pointer = (ptrdiff_t)number; + else +#endif +#if TRIO_FEATURE_INTMAX_T + if (flags & FLAGS_INTMAX_T) + *(trio_intmax_t *)pointer = (trio_intmax_t)number; + else +#endif + if (flags & FLAGS_QUAD) + *(trio_ulonglong_t *)pointer = (trio_ulonglong_t)number; + else if (flags & FLAGS_LONG) + *(long int *)pointer = (long int)number; + else if (flags & FLAGS_SHORT) + *(short int *)pointer = (short int)number; + else + *(int *)pointer = (int)number; + } + } + break; /* FORMAT_INT */ + + case FORMAT_STRING: +#if TRIO_FEATURE_WIDECHAR + if (flags & FLAGS_WIDECHAR) + { + if (!TrioReadWideString(data, + (flags & FLAGS_IGNORE) + ? NULL + : parameters[i].data.wstring, + flags, + width)) + { + status = assignment; + goto end; + } + } + else +#endif + { + if (!TrioReadString(data, + (flags & FLAGS_IGNORE) + ? NULL + : parameters[i].data.string, + flags, + width)) + { + status = assignment; + goto end; + } + } + if (!(flags & FLAGS_IGNORE)) + assignment++; + break; /* FORMAT_STRING */ + +#if TRIO_FEATURE_FLOAT + case FORMAT_DOUBLE: + { + if (flags & FLAGS_IGNORE) + { + pointer = NULL; + } + else + { + pointer = (flags & FLAGS_LONGDOUBLE) + ? (trio_pointer_t)parameters[i].data.longdoublePointer + : (trio_pointer_t)parameters[i].data.doublePointer; + } + if (!TrioReadDouble(data, pointer, flags, width)) + { + status = assignment; + goto end; + } + if (!(flags & FLAGS_IGNORE)) + { + assignment++; + } + break; /* FORMAT_DOUBLE */ + } +#endif + + case FORMAT_GROUP: + { + int characterclass[MAX_CHARACTER_CLASS + 1]; + + /* Skip over modifiers */ + while (format[offset] != SPECIFIER_GROUP) + { + offset++; + } + /* Skip over group specifier */ + offset++; + + memset(characterclass, 0, sizeof(characterclass)); + status = TrioGetCharacterClass(format, + &offset, + &flags, + characterclass); + if (status < 0) + goto end; + + if (!TrioReadGroup(data, + (flags & FLAGS_IGNORE) + ? NULL + : parameters[i].data.string, + characterclass, + flags, + parameters[i].width)) + { + status = assignment; + goto end; + } + if (!(flags & FLAGS_IGNORE)) + assignment++; + } + break; /* FORMAT_GROUP */ + + case FORMAT_COUNT: + pointer = parameters[i].data.pointer; + if (NULL != pointer) + { + int count = data->processed; + if (ch != EOF) + count--; /* a character is read, but is not consumed yet */ +#if TRIO_FEATURE_SIZE_T || TRIO_FEATURE_SIZE_T_UPPER + if (flags & FLAGS_SIZE_T) + *(size_t *)pointer = (size_t)count; + else +#endif +#if TRIO_FEATURE_PTRDIFF_T + if (flags & FLAGS_PTRDIFF_T) + *(ptrdiff_t *)pointer = (ptrdiff_t)count; + else +#endif +#if TRIO_FEATURE_INTMAX_T + if (flags & FLAGS_INTMAX_T) + *(trio_intmax_t *)pointer = (trio_intmax_t)count; + else +#endif + if (flags & FLAGS_QUAD) + { + *(trio_ulonglong_t *)pointer = (trio_ulonglong_t)count; + } + else if (flags & FLAGS_LONG) + { + *(long int *)pointer = (long int)count; + } + else if (flags & FLAGS_SHORT) + { + *(short int *)pointer = (short int)count; + } + else + { + *(int *)pointer = (int)count; + } + } + break; /* FORMAT_COUNT */ + + case FORMAT_CHAR: +#if TRIO_FEATURE_WIDECHAR + if (flags & FLAGS_WIDECHAR) + { + if (TrioReadWideChar(data, + (flags & FLAGS_IGNORE) + ? NULL + : parameters[i].data.wstring, + flags, + (width == NO_WIDTH) ? 1 : width) == 0) + { + status = assignment; + goto end; + } + } + else +#endif + { + if (TrioReadChar(data, + (flags & FLAGS_IGNORE) + ? NULL + : parameters[i].data.string, + flags, + (width == NO_WIDTH) ? 1 : width) == 0) + { + status = assignment; + goto end; + } + } + if (!(flags & FLAGS_IGNORE)) + assignment++; + break; /* FORMAT_CHAR */ + + case FORMAT_POINTER: + if (!TrioReadPointer(data, + (flags & FLAGS_IGNORE) + ? NULL + : (trio_pointer_t *)parameters[i].data.pointer, + flags)) + { + status = assignment; + goto end; + } + if (!(flags & FLAGS_IGNORE)) + assignment++; + break; /* FORMAT_POINTER */ + + case FORMAT_PARAMETER: + break; /* FORMAT_PARAMETER */ + + default: + status = TRIO_ERROR_RETURN(TRIO_EINVAL, offset); + goto end; + } + + ch = data->current; + offset = parameters[i].endOffset; + i++; + } + + status = assignment; + end: + if (data->UndoStream) + data->UndoStream(data); + return status; +} + +/************************************************************************* + * TrioScan + */ +TRIO_PRIVATE int +TrioScan +TRIO_ARGS7((source, sourceSize, InStream, UndoStream, format, arglist, argarray), + trio_pointer_t source, + size_t sourceSize, + void (*InStream) TRIO_PROTO((trio_class_t *, int *)), + void (*UndoStream) TRIO_PROTO((trio_class_t *)), + TRIO_CONST char *format, + va_list arglist, + trio_pointer_t *argarray) +{ + int status; + trio_parameter_t parameters[MAX_PARAMETERS]; + trio_class_t data; + + assert(VALID(InStream)); + assert(VALID(format)); + + memset(&data, 0, sizeof(data)); + data.InStream = InStream; + data.UndoStream = UndoStream; + data.location = (trio_pointer_t)source; + data.max = sourceSize; + data.error = 0; + +#if defined(USE_LOCALE) + if (NULL == internalLocaleValues) + { + TrioSetLocale(); + } +#endif + + status = TrioParse(TYPE_SCAN, format, parameters, arglist, argarray); + if (status < 0) + return status; + + status = TrioScanProcess(&data, format, parameters); + if (data.error != 0) + { + status = data.error; + } + return status; +} + +/************************************************************************* + * TrioInStreamFile + */ +#if TRIO_FEATURE_FILE || TRIO_FEATURE_STDIO +TRIO_PRIVATE void +TrioInStreamFile +TRIO_ARGS2((self, intPointer), + trio_class_t *self, + int *intPointer) +{ + FILE *file = (FILE *)self->location; + + assert(VALID(self)); + assert(VALID(file)); + + self->actually.cached = 0; + + /* The initial value of self->current is zero */ + if (self->current == EOF) + { + self->error = (ferror(file)) + ? TRIO_ERROR_RETURN(TRIO_ERRNO, 0) + : TRIO_ERROR_RETURN(TRIO_EOF, 0); + } + else + { + self->processed++; + self->actually.cached++; + } + + self->current = fgetc(file); + + if (VALID(intPointer)) + { + *intPointer = self->current; + } +} +#endif /* TRIO_FEATURE_FILE || TRIO_FEATURE_STDIO */ + +/************************************************************************* + * TrioUndoStreamFile + */ +#if TRIO_FEATURE_FILE || TRIO_FEATURE_STDIO +TRIO_PRIVATE void +TrioUndoStreamFile +TRIO_ARGS1((self), + trio_class_t *self) +{ + FILE *file = (FILE *)self->location; + + assert(VALID(self)); + assert(VALID(file)); + + if (self->actually.cached > 0) + { + assert(self->actually.cached == 1); + + self->current = ungetc(self->current, file); + self->actually.cached = 0; + } +} +#endif /* TRIO_FEATURE_FILE || TRIO_FEATURE_STDIO */ + +/************************************************************************* + * TrioInStreamFileDescriptor + */ +#if TRIO_FEATURE_FD +TRIO_PRIVATE void +TrioInStreamFileDescriptor +TRIO_ARGS2((self, intPointer), + trio_class_t *self, + int *intPointer) +{ + int fd = *((int *)self->location); + int size; + unsigned char input; + + assert(VALID(self)); + + self->actually.cached = 0; + + size = read(fd, &input, sizeof(char)); + if (size == -1) + { + self->error = TRIO_ERROR_RETURN(TRIO_ERRNO, 0); + self->current = EOF; + } + else + { + self->current = (size == 0) ? EOF : input; + } + if (self->current != EOF) + { + self->actually.cached++; + self->processed++; + } + + if (VALID(intPointer)) + { + *intPointer = self->current; + } +} +#endif /* TRIO_FEATURE_FD */ + +/************************************************************************* + * TrioInStreamCustom + */ +#if TRIO_FEATURE_CLOSURE +TRIO_PRIVATE void +TrioInStreamCustom +TRIO_ARGS2((self, intPointer), + trio_class_t *self, + int *intPointer) +{ + trio_custom_t *data; + + assert(VALID(self)); + assert(VALID(self->location)); + + self->actually.cached = 0; + + data = (trio_custom_t *)self->location; + + self->current = (data->stream.in == NULL) + ? NIL + : (data->stream.in)(data->closure); + + if (self->current == NIL) + { + self->current = EOF; + } + else + { + self->processed++; + self->actually.cached++; + } + + if (VALID(intPointer)) + { + *intPointer = self->current; + } +} +#endif /* TRIO_FEATURE_CLOSURE */ + +/************************************************************************* + * TrioInStreamString + */ +TRIO_PRIVATE void +TrioInStreamString +TRIO_ARGS2((self, intPointer), + trio_class_t *self, + int *intPointer) +{ + unsigned char **buffer; + + assert(VALID(self)); + assert(VALID(self->location)); + + self->actually.cached = 0; + + buffer = (unsigned char **)self->location; + self->current = (*buffer)[0]; + if (self->current == NIL) + { + self->current = EOF; + } + else + { + (*buffer)++; + self->processed++; + self->actually.cached++; + } + + if (VALID(intPointer)) + { + *intPointer = self->current; + } +} + +/************************************************************************* + * + * Formatted scanning functions + * + ************************************************************************/ + +#if defined(TRIO_DOCUMENTATION) +# include "doc/doc_scanf.h" +#endif +/** @addtogroup Scanf + @{ +*/ + +/************************************************************************* + * scanf + */ + +/** + Scan characters from standard input stream. + + @param format Formatting string. + @param ... Arguments. + @return Number of scanned characters. + */ +#if TRIO_FEATURE_STDIO +TRIO_PUBLIC int +trio_scanf +TRIO_VARGS2((format, va_alist), + TRIO_CONST char *format, + TRIO_VA_DECL) +{ + int status; + va_list args; + + assert(VALID(format)); + + TRIO_VA_START(args, format); + status = TrioScan((trio_pointer_t)stdin, 0, + TrioInStreamFile, + TrioUndoStreamFile, + format, args, NULL); + TRIO_VA_END(args); + return status; +} +#endif /* TRIO_FEATURE_STDIO */ + +/** + Scan characters from standard input stream. + + @param format Formatting string. + @param args Arguments. + @return Number of scanned characters. + */ +#if TRIO_FEATURE_STDIO +TRIO_PUBLIC int +trio_vscanf +TRIO_ARGS2((format, args), + TRIO_CONST char *format, + va_list args) +{ + assert(VALID(format)); + + return TrioScan((trio_pointer_t)stdin, 0, + TrioInStreamFile, + TrioUndoStreamFile, + format, args, NULL); +} +#endif /* TRIO_FEATURE_STDIO */ + +/** + Scan characters from standard input stream. + + @param format Formatting string. + @param args Arguments. + @return Number of scanned characters. + */ +#if TRIO_FEATURE_STDIO +TRIO_PUBLIC int +trio_scanfv +TRIO_ARGS2((format, args), + TRIO_CONST char *format, + trio_pointer_t *args) +{ + static va_list unused; + + assert(VALID(format)); + + return TrioScan((trio_pointer_t)stdin, 0, + TrioInStreamFile, + TrioUndoStreamFile, + format, unused, args); +} +#endif /* TRIO_FEATURE_STDIO */ + +/************************************************************************* + * fscanf + */ + +/** + Scan characters from file. + + @param file File pointer. + @param format Formatting string. + @param ... Arguments. + @return Number of scanned characters. + */ +#if TRIO_FEATURE_FILE +TRIO_PUBLIC int +trio_fscanf +TRIO_VARGS3((file, format, va_alist), + FILE *file, + TRIO_CONST char *format, + TRIO_VA_DECL) +{ + int status; + va_list args; + + assert(VALID(file)); + assert(VALID(format)); + + TRIO_VA_START(args, format); + status = TrioScan((trio_pointer_t)file, 0, + TrioInStreamFile, + TrioUndoStreamFile, + format, args, NULL); + TRIO_VA_END(args); + return status; +} +#endif /* TRIO_FEATURE_FILE */ + +/** + Scan characters from file. + + @param file File pointer. + @param format Formatting string. + @param args Arguments. + @return Number of scanned characters. + */ +#if TRIO_FEATURE_FILE +TRIO_PUBLIC int +trio_vfscanf +TRIO_ARGS3((file, format, args), + FILE *file, + TRIO_CONST char *format, + va_list args) +{ + assert(VALID(file)); + assert(VALID(format)); + + return TrioScan((trio_pointer_t)file, 0, + TrioInStreamFile, + TrioUndoStreamFile, + format, args, NULL); +} +#endif /* TRIO_FEATURE_FILE */ + +/** + Scan characters from file. + + @param file File pointer. + @param format Formatting string. + @param args Arguments. + @return Number of scanned characters. + */ +#if TRIO_FEATURE_FILE +TRIO_PUBLIC int +trio_fscanfv +TRIO_ARGS3((file, format, args), + FILE *file, + TRIO_CONST char *format, + trio_pointer_t *args) +{ + static va_list unused; + + assert(VALID(file)); + assert(VALID(format)); + + return TrioScan((trio_pointer_t)file, 0, + TrioInStreamFile, + TrioUndoStreamFile, + format, unused, args); +} +#endif /* TRIO_FEATURE_FILE */ + +/************************************************************************* + * dscanf + */ + +/** + Scan characters from file descriptor. + + @param fd File descriptor. + @param format Formatting string. + @param ... Arguments. + @return Number of scanned characters. + */ +#if TRIO_FEATURE_FD +TRIO_PUBLIC int +trio_dscanf +TRIO_VARGS3((fd, format, va_alist), + int fd, + TRIO_CONST char *format, + TRIO_VA_DECL) +{ + int status; + va_list args; + + assert(VALID(format)); + + TRIO_VA_START(args, format); + status = TrioScan((trio_pointer_t)&fd, 0, + TrioInStreamFileDescriptor, + NULL, + format, args, NULL); + TRIO_VA_END(args); + return status; +} +#endif /* TRIO_FEATURE_FD */ + +/** + Scan characters from file descriptor. + + @param fd File descriptor. + @param format Formatting string. + @param args Arguments. + @return Number of scanned characters. + */ +#if TRIO_FEATURE_FD +TRIO_PUBLIC int +trio_vdscanf +TRIO_ARGS3((fd, format, args), + int fd, + TRIO_CONST char *format, + va_list args) +{ + assert(VALID(format)); + + return TrioScan((trio_pointer_t)&fd, 0, + TrioInStreamFileDescriptor, + NULL, + format, args, NULL); +} +#endif /* TRIO_FEATURE_FD */ + +/** + Scan characters from file descriptor. + + @param fd File descriptor. + @param format Formatting string. + @param args Arguments. + @return Number of scanned characters. + */ +#if TRIO_FEATURE_FD +TRIO_PUBLIC int +trio_dscanfv +TRIO_ARGS3((fd, format, args), + int fd, + TRIO_CONST char *format, + trio_pointer_t *args) +{ + static va_list unused; + + assert(VALID(format)); + + return TrioScan((trio_pointer_t)&fd, 0, + TrioInStreamFileDescriptor, + NULL, + format, unused, args); +} +#endif /* TRIO_FEATURE_FD */ + +/************************************************************************* + * cscanf + */ +#if TRIO_FEATURE_CLOSURE +TRIO_PUBLIC int +trio_cscanf +TRIO_VARGS4((stream, closure, format, va_alist), + trio_instream_t stream, + trio_pointer_t closure, + TRIO_CONST char *format, + TRIO_VA_DECL) +{ + int status; + va_list args; + trio_custom_t data; + + assert(VALID(stream)); + assert(VALID(format)); + + TRIO_VA_START(args, format); + data.stream.in = stream; + data.closure = closure; + status = TrioScan(&data, 0, TrioInStreamCustom, NULL, format, args, NULL); + TRIO_VA_END(args); + return status; +} +#endif /* TRIO_FEATURE_CLOSURE */ + +#if TRIO_FEATURE_CLOSURE +TRIO_PUBLIC int +trio_vcscanf +TRIO_ARGS4((stream, closure, format, args), + trio_instream_t stream, + trio_pointer_t closure, + TRIO_CONST char *format, + va_list args) +{ + trio_custom_t data; + + assert(VALID(stream)); + assert(VALID(format)); + + data.stream.in = stream; + data.closure = closure; + return TrioScan(&data, 0, TrioInStreamCustom, NULL, format, args, NULL); +} +#endif /* TRIO_FEATURE_CLOSURE */ + +#if TRIO_FEATURE_CLOSURE +TRIO_PUBLIC int +trio_cscanfv +TRIO_ARGS4((stream, closure, format, args), + trio_instream_t stream, + trio_pointer_t closure, + TRIO_CONST char *format, + trio_pointer_t *args) +{ + static va_list unused; + trio_custom_t data; + + assert(VALID(stream)); + assert(VALID(format)); + + data.stream.in = stream; + data.closure = closure; + return TrioScan(&data, 0, TrioInStreamCustom, NULL, format, unused, args); +} +#endif /* TRIO_FEATURE_CLOSURE */ + +/************************************************************************* + * sscanf + */ + +/** + Scan characters from string. + + @param buffer Input string. + @param format Formatting string. + @param ... Arguments. + @return Number of scanned characters. + */ +TRIO_PUBLIC int +trio_sscanf +TRIO_VARGS3((buffer, format, va_alist), + TRIO_CONST char *buffer, + TRIO_CONST char *format, + TRIO_VA_DECL) +{ + int status; + va_list args; + + assert(VALID(buffer)); + assert(VALID(format)); + + TRIO_VA_START(args, format); + status = TrioScan((trio_pointer_t)&buffer, 0, + TrioInStreamString, + NULL, + format, args, NULL); + TRIO_VA_END(args); + return status; +} + +/** + Scan characters from string. + + @param buffer Input string. + @param format Formatting string. + @param args Arguments. + @return Number of scanned characters. + */ +TRIO_PUBLIC int +trio_vsscanf +TRIO_ARGS3((buffer, format, args), + TRIO_CONST char *buffer, + TRIO_CONST char *format, + va_list args) +{ + assert(VALID(buffer)); + assert(VALID(format)); + + return TrioScan((trio_pointer_t)&buffer, 0, + TrioInStreamString, + NULL, + format, args, NULL); +} + +/** + Scan characters from string. + + @param buffer Input string. + @param format Formatting string. + @param args Arguments. + @return Number of scanned characters. + */ +TRIO_PUBLIC int +trio_sscanfv +TRIO_ARGS3((buffer, format, args), + TRIO_CONST char *buffer, + TRIO_CONST char *format, + trio_pointer_t *args) +{ + static va_list unused; + + assert(VALID(buffer)); + assert(VALID(format)); + + return TrioScan((trio_pointer_t)&buffer, 0, + TrioInStreamString, + NULL, + format, unused, args); +} + +#endif /* TRIO_FEATURE_SCANF */ + +/** @} End of Scanf documentation module */ + +/************************************************************************* + * trio_strerror + */ +TRIO_PUBLIC TRIO_CONST char * +trio_strerror +TRIO_ARGS1((errorcode), + int errorcode) +{ +#if TRIO_FEATURE_STRERR + /* Textual versions of the error codes */ + switch (TRIO_ERROR_CODE(errorcode)) + { + case TRIO_EOF: + return "End of file"; + case TRIO_EINVAL: + return "Invalid argument"; + case TRIO_ETOOMANY: + return "Too many arguments"; + case TRIO_EDBLREF: + return "Double reference"; + case TRIO_EGAP: + return "Reference gap"; + case TRIO_ENOMEM: + return "Out of memory"; + case TRIO_ERANGE: + return "Invalid range"; + case TRIO_ECUSTOM: + return "Custom error"; + default: + return "Unknown"; + } +#else + return "Unknown"; +#endif +} diff --git a/src/trio-snprintf/trio.h b/src/trio-snprintf/trio.h deleted file mode 120000 index 89bccb7f..00000000 --- a/src/trio-snprintf/trio.h +++ /dev/null @@ -1 +0,0 @@ -../trio/trio.h \ No newline at end of file diff --git a/src/trio-snprintf/trio.h b/src/trio-snprintf/trio.h new file mode 100644 index 00000000..1844ea60 --- /dev/null +++ b/src/trio-snprintf/trio.h @@ -0,0 +1,260 @@ +/* BEEBS trio benchmark + + Copyright (C) 2014 Embecosm Limited and University of Bristol + + This file is part of the Bristol/Embecosm Embedded Benchmark Suite. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* The original source of this file was from: + * http://daniel.haxx.se/projects/trio/ + * and is covered by the following copyright and licence: + * + * Copyright (C) 1998 Bjorn Reese and Daniel Stenberg. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND + * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. + * + ************************************************************************* + * + * http://ctrio.sourceforge.net/ + * + ************************************************************************/ + +#ifndef TRIO_TRIO_H +#define TRIO_TRIO_H + +#if !defined(WITHOUT_TRIO) + +/* + * Use autoconf defines if present. Packages using trio must define + * HAVE_CONFIG_H as a compiler option themselves. + */ +#if defined(HAVE_CONFIG_H) +# include +#endif + +#include "beebsc.h" +#include "triop.h" + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Error codes. + * + * Remember to add a textual description to trio_strerror. + */ +enum { + TRIO_EOF = 1, + TRIO_EINVAL = 2, + TRIO_ETOOMANY = 3, + TRIO_EDBLREF = 4, + TRIO_EGAP = 5, + TRIO_ENOMEM = 6, + TRIO_ERANGE = 7, + TRIO_ERRNO = 8, + TRIO_ECUSTOM = 9 +}; + +/* Error macros */ +#define TRIO_ERROR_CODE(x) ((-(x)) & 0x00FF) +#define TRIO_ERROR_POSITION(x) ((-(x)) >> 8) +#define TRIO_ERROR_NAME(x) trio_strerror(x) + +typedef int (*trio_outstream_t) TRIO_PROTO((trio_pointer_t, int)); +typedef int (*trio_instream_t) TRIO_PROTO((trio_pointer_t)); + +TRIO_CONST char *trio_strerror TRIO_PROTO((int)); + +/************************************************************************* + * Print Functions + */ + +int trio_printf TRIO_PROTO((TRIO_CONST char *format, ...)); +int trio_vprintf TRIO_PROTO((TRIO_CONST char *format, va_list args)); +int trio_printfv TRIO_PROTO((TRIO_CONST char *format, void **args)); + +int trio_fprintf TRIO_PROTO((FILE *file, TRIO_CONST char *format, ...)); +int trio_vfprintf TRIO_PROTO((FILE *file, TRIO_CONST char *format, va_list args)); +int trio_fprintfv TRIO_PROTO((FILE *file, TRIO_CONST char *format, void **args)); + +int trio_dprintf TRIO_PROTO((int fd, TRIO_CONST char *format, ...)); +int trio_vdprintf TRIO_PROTO((int fd, TRIO_CONST char *format, va_list args)); +int trio_dprintfv TRIO_PROTO((int fd, TRIO_CONST char *format, void **args)); + +int trio_cprintf TRIO_PROTO((trio_outstream_t stream, trio_pointer_t closure, + TRIO_CONST char *format, ...)); +int trio_vcprintf TRIO_PROTO((trio_outstream_t stream, trio_pointer_t closure, + TRIO_CONST char *format, va_list args)); +int trio_cprintfv TRIO_PROTO((trio_outstream_t stream, trio_pointer_t closure, + TRIO_CONST char *format, void **args)); + +int trio_sprintf TRIO_PROTO((char *buffer, TRIO_CONST char *format, ...)); +int trio_vsprintf TRIO_PROTO((char *buffer, TRIO_CONST char *format, va_list args)); +int trio_sprintfv TRIO_PROTO((char *buffer, TRIO_CONST char *format, void **args)); + +int trio_snprintf TRIO_PROTO((char *buffer, size_t max, TRIO_CONST char *format, ...)); +int trio_vsnprintf TRIO_PROTO((char *buffer, size_t bufferSize, TRIO_CONST char *format, + va_list args)); +int trio_snprintfv TRIO_PROTO((char *buffer, size_t bufferSize, TRIO_CONST char *format, + void **args)); + +int trio_snprintfcat TRIO_PROTO((char *buffer, size_t max, TRIO_CONST char *format, ...)); +int trio_vsnprintfcat TRIO_PROTO((char *buffer, size_t bufferSize, TRIO_CONST char *format, + va_list args)); + +#if defined(TRIO_DEPRECATED) +char *trio_aprintf TRIO_PROTO((TRIO_CONST char *format, ...)); +char *trio_vaprintf TRIO_PROTO((TRIO_CONST char *format, va_list args)); +#endif + +int trio_asprintf TRIO_PROTO((char **ret, TRIO_CONST char *format, ...)); +int trio_vasprintf TRIO_PROTO((char **ret, TRIO_CONST char *format, va_list args)); +int trio_asprintfv TRIO_PROTO((char **result, TRIO_CONST char *format, trio_pointer_t * args)); + +/************************************************************************* + * Scan Functions + */ +int trio_scanf TRIO_PROTO((TRIO_CONST char *format, ...)); +int trio_vscanf TRIO_PROTO((TRIO_CONST char *format, va_list args)); +int trio_scanfv TRIO_PROTO((TRIO_CONST char *format, void **args)); + +int trio_fscanf TRIO_PROTO((FILE *file, TRIO_CONST char *format, ...)); +int trio_vfscanf TRIO_PROTO((FILE *file, TRIO_CONST char *format, va_list args)); +int trio_fscanfv TRIO_PROTO((FILE *file, TRIO_CONST char *format, void **args)); + +int trio_dscanf TRIO_PROTO((int fd, TRIO_CONST char *format, ...)); +int trio_vdscanf TRIO_PROTO((int fd, TRIO_CONST char *format, va_list args)); +int trio_dscanfv TRIO_PROTO((int fd, TRIO_CONST char *format, void **args)); + +int trio_cscanf TRIO_PROTO((trio_instream_t stream, trio_pointer_t closure, + TRIO_CONST char *format, ...)); +int trio_vcscanf TRIO_PROTO((trio_instream_t stream, trio_pointer_t closure, + TRIO_CONST char *format, va_list args)); +int trio_cscanfv TRIO_PROTO((trio_instream_t stream, trio_pointer_t closure, + TRIO_CONST char *format, void **args)); + +int trio_sscanf TRIO_PROTO((TRIO_CONST char *buffer, TRIO_CONST char *format, ...)); +int trio_vsscanf TRIO_PROTO((TRIO_CONST char *buffer, TRIO_CONST char *format, va_list args)); +int trio_sscanfv TRIO_PROTO((TRIO_CONST char *buffer, TRIO_CONST char *format, void **args)); + +/************************************************************************* + * Locale Functions + */ +void trio_locale_set_decimal_point TRIO_PROTO((char *decimalPoint)); +void trio_locale_set_thousand_separator TRIO_PROTO((char *thousandSeparator)); +void trio_locale_set_grouping TRIO_PROTO((char *grouping)); + +/************************************************************************* + * Renaming + */ +#ifdef TRIO_REPLACE_STDIO +/* Replace the functions */ +#ifndef HAVE_PRINTF +# undef printf +# define printf trio_printf +#endif +#ifndef HAVE_VPRINTF +# undef vprintf +# define vprintf trio_vprintf +#endif +#ifndef HAVE_FPRINTF +# undef fprintf +# define fprintf trio_fprintf +#endif +#ifndef HAVE_VFPRINTF +# undef vfprintf +# define vfprintf trio_vfprintf +#endif +#ifndef HAVE_SPRINTF +# undef sprintf +# define sprintf trio_sprintf +#endif +#ifndef HAVE_VSPRINTF +# undef vsprintf +# define vsprintf trio_vsprintf +#endif +#ifndef HAVE_SNPRINTF +# undef snprintf +# define snprintf trio_snprintf +#endif +#ifndef HAVE_VSNPRINTF +# undef vsnprintf +# define vsnprintf trio_vsnprintf +#endif +#ifndef HAVE_SCANF +# undef scanf +# define scanf trio_scanf +#endif +#ifndef HAVE_VSCANF +# undef vscanf +# define vscanf trio_vscanf +#endif +#ifndef HAVE_FSCANF +# undef fscanf +# define fscanf trio_fscanf +#endif +#ifndef HAVE_VFSCANF +# undef vfscanf +# define vfscanf trio_vfscanf +#endif +#ifndef HAVE_SSCANF +# undef sscanf +# define sscanf trio_sscanf +#endif +#ifndef HAVE_VSSCANF +# undef vsscanf +# define vsscanf trio_vsscanf +#endif +/* These aren't stdio functions, but we make them look similar */ +#undef dprintf +#define dprintf trio_dprintf +#undef vdprintf +#define vdprintf trio_vdprintf +#undef aprintf +#define aprintf trio_aprintf +#undef vaprintf +#define vaprintf trio_vaprintf +#undef asprintf +#define asprintf trio_asprintf +#undef vasprintf +#define vasprintf trio_vasprintf +#undef dscanf +#define dscanf trio_dscanf +#undef vdscanf +#define vdscanf trio_vdscanf +#endif + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* WITHOUT_TRIO */ + +void init_heap (void); +void *malloc_beebs (size_t size); +void *realloc_beebs (void *ptr, size_t size); +void free_beebs (void *ptr); + +#endif /* TRIO_TRIO_H */ diff --git a/src/trio-snprintf/trio_test.c b/src/trio-snprintf/trio_test.c deleted file mode 120000 index 9260d6fd..00000000 --- a/src/trio-snprintf/trio_test.c +++ /dev/null @@ -1 +0,0 @@ -../trio/trio_test.c \ No newline at end of file diff --git a/src/trio-snprintf/trio_test.c b/src/trio-snprintf/trio_test.c new file mode 100644 index 00000000..4bd321a5 --- /dev/null +++ b/src/trio-snprintf/trio_test.c @@ -0,0 +1,75 @@ +/* BEEBS template benchmark + + Copyright (C) 2014 Embecosm Limited and University of Bristol + + Contributor James Pallister + + This file is part of the Bristol/Embecosm Embedded Benchmark Suite. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include +#include "support.h" +#include "trio.h" + +/* This scale factor will be changed to equalise the runtime of the + benchmarks. */ +#define LOCAL_SCALE_FACTOR 433 + + +/* BEEBS heap is just an array */ + +#define HEAP_SIZE 8192 +static char heap[HEAP_SIZE]; + +char output[5][20]; + + +int +verify_benchmark (int res __attribute ((unused)) ) +{ + int i; + char exp[5][20] = { "123", "123", " 123", "0007b", " 10" }; + + for (i = 0; i < 5; i++) + if (0 != strcmp (exp[i], output[i])) + return 0; + + return 1; +} + + +void +initialise_benchmark (void) +{ +} + +int +benchmark (void) +{ + int i; + + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + { + init_heap_beebs ((void *) heap, HEAP_SIZE); + + trio_snprintf(output[0], 20, "%d", 123); + trio_snprintf(output[1], 20, "%ld", 123); + trio_snprintf(output[2], 20, "%5d", 123); + trio_snprintf(output[3], 20, "%05x", 123); + trio_snprintf(output[4], 20, "%*d", 5, 10); + } + + return 0; +} diff --git a/src/trio-snprintf/triodef.h b/src/trio-snprintf/triodef.h deleted file mode 120000 index 085f7c57..00000000 --- a/src/trio-snprintf/triodef.h +++ /dev/null @@ -1 +0,0 @@ -../trio/triodef.h \ No newline at end of file diff --git a/src/trio-snprintf/triodef.h b/src/trio-snprintf/triodef.h new file mode 100644 index 00000000..037c1da7 --- /dev/null +++ b/src/trio-snprintf/triodef.h @@ -0,0 +1,354 @@ +/* BEEBS trio benchmark + + Copyright (C) 2014 Embecosm Limited and University of Bristol + + This file is part of the Bristol/Embecosm Embedded Benchmark Suite. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* The original source of this file was from: + * http://daniel.haxx.se/projects/trio/ + * and is covered by the following copyright and licence: + * + * Copyright (C) 2001 Bjorn Reese + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND + * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. + * + ************************************************************************/ + +#ifndef TRIO_TRIODEF_H +#define TRIO_TRIODEF_H + +/************************************************************************* + * Compiler support detection + */ + +#if defined(__GNUC__) +# define TRIO_COMPILER_GCC +#endif + +#if defined(__SUNPRO_CC) +# define TRIO_COMPILER_SUNPRO __SUNPRO_CC +#else +# if defined(__SUNPRO_C) +# define TRIO_COMPILER_SUNPRO __SUNPRO_C +# endif +#endif + +#if defined(__xlC__) || defined(__IBMC__) || defined(__IBMCPP__) +# define TRIO_COMPILER_XLC +#else +# if defined(_AIX) && !defined(__GNUC__) +# define TRIO_COMPILER_XLC /* Workaround for old xlc */ +# endif +#endif + +#if defined(__DECC) || defined(__DECCXX) +# define TRIO_COMPILER_DECC +#else +# if defined(__osf__) && defined(__LANGUAGE_C__) && !defined(__GNUC__) +# define TRIO_COMPILER_DECC /* Workaround for old DEC C compilers */ +# endif +#endif + +#if defined(__HP_aCC) || defined(__HP_cc) +# define TRIO_COMPILER_HP +#endif + +#if defined(sgi) || defined(__sgi) +# define TRIO_COMPILER_MIPSPRO +#endif + +#if defined(_MSC_VER) +# define TRIO_COMPILER_MSVC +#endif + +#if defined(__BORLANDC__) +# define TRIO_COMPILER_BCB +#endif + +/************************************************************************* + * Platform support detection + */ + +#if defined(VMS) || defined(__VMS) +# define TRIO_PLATFORM_VMS +#endif + +#if defined(unix) || defined(__unix) || defined(__unix__) +# define TRIO_PLATFORM_UNIX +#endif + +#if defined(TRIO_COMPILER_XLC) || defined(_AIX) +# define TRIO_PLATFORM_UNIX +#endif + +#if defined(TRIO_COMPILER_DECC) || defined(__osf___) +# if !defined(TRIO_PLATFORM_VMS) +# define TRIO_PLATFORM_UNIX +# endif +#endif + +#if defined(__NetBSD__) +# define TRIO_PLATFORM_UNIX +#endif + +#if defined(__Lynx__) +# define TRIO_PLATFORM_UNIX +# define TRIO_PLATFORM_LYNX +#endif + +#if defined(__APPLE__) && defined(__MACH__) +# define TRIO_PLATFORM_UNIX +#endif + +#if defined(__QNX__) +# define TRIO_PLATFORM_UNIX +# define TRIO_PLATFORM_QNX +#endif + +#if defined(__CYGWIN__) +# define TRIO_PLATFORM_UNIX +#endif + +#if defined(AMIGA) && defined(TRIO_COMPILER_GCC) +# define TRIO_PLATFORM_UNIX +#endif + +#if defined(TRIO_COMPILER_MSVC) || defined(WIN32) || defined(_WIN32) +# define TRIO_PLATFORM_WIN32 +#endif + +#if defined(_WIN32_WCE) +# define TRIO_PLATFORM_WINCE +#endif + +#if defined(mpeix) || defined(__mpexl) +# define TRIO_PLATFORM_MPEIX +#endif + +#if defined(_AIX) +# define TRIO_PLATFORM_AIX +#endif + +#if defined(__hpux) +# define TRIO_PLATFORM_HPUX +#endif + +#if defined(sun) || defined(__sun__) +# if defined(__SVR4) || defined(__svr4__) +# define TRIO_PLATFORM_SOLARIS +# else +# define TRIO_PLATFORM_SUNOS +# endif +#endif + +/************************************************************************* + * Standards support detection + */ + +#if defined(__STDC__) \ + || defined(_MSC_EXTENSIONS) \ + || defined(TRIO_COMPILER_BCB) +# define PREDEF_STANDARD_C89 +#endif +#if defined(__STDC_VERSION__) +# define PREDEF_STANDARD_C90 +#endif +#if (__STDC_VERSION__ - 0 >= 199409L) +# define PREDEF_STANDARD_C94 +#endif +#if (__STDC_VERSION__ - 0 >= 199901L) +# define PREDEF_STANDARD_C99 +#endif +#if defined(TRIO_COMPILER_SUNPRO) && (TRIO_COMPILER_SUNPRO >= 0x420) +# if !defined(PREDEF_STANDARD_C94) +# define PREDEF_STANDARD_C94 +# endif +#endif + +#if defined(__cplusplus) +# define PREDEF_STANDARD_CXX +#endif +#if __cplusplus - 0 >= 199711L +# define PREDEF_STANDARD_CXX89 +#endif + +#if defined(TRIO_PLATFORM_UNIX) +# include +#endif + +#if defined(_POSIX_VERSION) +# define PREDEF_STANDARD_POSIX _POSIX_VERSION +# if (_POSIX_VERSION >= 199506L) +# define PREDEF_STANDARD_POSIX_1996 +# endif +#endif + +#if (_XOPEN_VERSION - 0 >= 3) || defined(_XOPEN_XPG3) +# define PREDEF_STANDARD_XPG3 +#endif +#if (_XOPEN_VERSION - 0 >= 4) || defined(_XOPEN_XPG4) +# define PREDEF_STANDARD_XPG4 +#endif +#if (_XOPEN_VERSION - 0 > 4) \ + || (defined(_XOPEN_UNIX) && (_XOPEN_VERSION - 0 == 4)) +# define PREDEF_STANDARD_UNIX95 +#endif +#if (_XOPEN_VERSION - 0 >= 500) +# define PREDEF_STANDARD_UNIX98 +#endif +#if (_XOPEN_VERSION - 0 >= 600) +# define PREDEF_STANDARD_UNIX03 +#endif + +/************************************************************************* + * Generic defines + */ + +#if !defined(TRIO_PUBLIC) +# define TRIO_PUBLIC +#endif +#if !defined(TRIO_PRIVATE) +# define TRIO_PRIVATE static +#endif + +#if !(defined(PREDEF_STANDARD_C89) || defined(PREDEF_STANDARD_CXX)) +# define TRIO_COMPILER_ANCIENT +#endif + +#if defined(TRIO_COMPILER_ANCIENT) +# define TRIO_CONST +# define TRIO_VOLATILE +# define TRIO_SIGNED +typedef double trio_long_double_t; +typedef char * trio_pointer_t; +# define TRIO_SUFFIX_LONG(x) x +# define TRIO_PROTO(x) () +# define TRIO_NOARGS +# define TRIO_ARGS1(list,a1) list a1; +# define TRIO_ARGS2(list,a1,a2) list a1; a2; +# define TRIO_ARGS3(list,a1,a2,a3) list a1; a2; a3; +# define TRIO_ARGS4(list,a1,a2,a3,a4) list a1; a2; a3; a4; +# define TRIO_ARGS5(list,a1,a2,a3,a4,a5) list a1; a2; a3; a4; a5; +# define TRIO_ARGS6(list,a1,a2,a3,a4,a5,a6) list a1; a2; a3; a4; a5; a6; +# define TRIO_ARGS7(list,a1,a2,a3,a4,a5,a6,a7) list a1; a2; a3; a4; a5; a6; a7; +# define TRIO_VARGS2(list,a1,a2) list a1; a2 +# define TRIO_VARGS3(list,a1,a2,a3) list a1; a2; a3 +# define TRIO_VARGS4(list,a1,a2,a3,a4) list a1; a2; a3; a4 +# define TRIO_VARGS5(list,a1,a2,a3,a4,a5) list a1; a2; a3; a4; a5 +# define TRIO_VA_DECL va_dcl +# define TRIO_VA_START(x,y) va_start(x) +# define TRIO_VA_END(x) va_end(x) +#else /* ANSI C */ +# define TRIO_CONST const +# define TRIO_VOLATILE volatile +# define TRIO_SIGNED signed +typedef long double trio_long_double_t; +typedef void * trio_pointer_t; +# define TRIO_SUFFIX_LONG(x) x ## L +# define TRIO_PROTO(x) x +# define TRIO_NOARGS void +# define TRIO_ARGS1(list,a1) (a1) +# define TRIO_ARGS2(list,a1,a2) (a1,a2) +# define TRIO_ARGS3(list,a1,a2,a3) (a1,a2,a3) +# define TRIO_ARGS4(list,a1,a2,a3,a4) (a1,a2,a3,a4) +# define TRIO_ARGS5(list,a1,a2,a3,a4,a5) (a1,a2,a3,a4,a5) +# define TRIO_ARGS6(list,a1,a2,a3,a4,a5,a6) (a1,a2,a3,a4,a5,a6) +# define TRIO_ARGS7(list,a1,a2,a3,a4,a5,a6,a7) (a1,a2,a3,a4,a5,a6,a7) +# define TRIO_VARGS2 TRIO_ARGS2 +# define TRIO_VARGS3 TRIO_ARGS3 +# define TRIO_VARGS4 TRIO_ARGS4 +# define TRIO_VARGS5 TRIO_ARGS5 +# define TRIO_VA_DECL ... +# define TRIO_VA_START(x,y) va_start(x,y) +# define TRIO_VA_END(x) va_end(x) +#endif + +#if defined(PREDEF_STANDARD_C99) || defined(PREDEF_STANDARD_CXX) +# define TRIO_INLINE inline +#else +# if defined(TRIO_COMPILER_GCC) +# define TRIO_INLINE __inline__ +# endif +# if defined(TRIO_COMPILER_MSVC) +# define TRIO_INLINE _inline +# endif +# if defined(TRIO_COMPILER_BCB) +# define TRIO_INLINE __inline +# endif +#endif +#if !defined(TRIO_INLINE) +# define TRIO_INLINE +#endif + +/************************************************************************* + * Workarounds + */ + +#if defined(TRIO_PLATFORM_VMS) +/* + * Computations done with constants at compile time can trigger these + * even when compiling with IEEE enabled. + */ +# pragma message disable (UNDERFLOW, FLOATOVERFL) + +# if (__CRTL_VER < 80210001) +/* + * Although the compiler supports C99 language constructs, the C + * run-time library does not contain all C99 functions. + */ +# if defined(PREDEF_STANDARD_C99) +# undef PREDEF_STANDARD_C99 +# endif +# endif +#endif + +/* + * Not all preprocessors supports the LL token. + */ +#if defined(TRIO_COMPILER_MSVC) || defined(TRIO_COMPILER_BCB) +#else +# define TRIO_COMPILER_SUPPORTS_LL +#endif + +#if defined(__CYGWIN__) +/* + * Cygwin defines the macros for hosted C99, but does not support certain + * long double math functions. + */ +# include +# define TRIO_CYGWIN_VERSION_API CYGWIN_VERSION_API_MAJOR * 1000 + \ + CYGWIN_VERSION_API_MINOR +/* + * Please change the version number below when the Cygwin API supports + * long double math functions (powl, fmodl, etc.) + */ +# if TRIO_CYGWIN_VERSION_API < 99999999 +# define TRIO_NO_FLOORL 1 +# define TRIO_NO_CEILL 1 +# define TRIO_NO_POWL 1 +# define TRIO_NO_FMODL 1 +# define TRIO_NO_LOG10L 1 +# endif +#endif + +#endif /* TRIO_TRIODEF_H */ diff --git a/src/trio-snprintf/triop.h b/src/trio-snprintf/triop.h deleted file mode 120000 index 58444347..00000000 --- a/src/trio-snprintf/triop.h +++ /dev/null @@ -1 +0,0 @@ -../trio/triop.h \ No newline at end of file diff --git a/src/trio-snprintf/triop.h b/src/trio-snprintf/triop.h new file mode 100644 index 00000000..60aaacef --- /dev/null +++ b/src/trio-snprintf/triop.h @@ -0,0 +1,491 @@ +/* BEEBS trio benchmark + + Copyright (C) 2014 Embecosm Limited and University of Bristol + + This file is part of the Bristol/Embecosm Embedded Benchmark Suite. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* The original source of this file was from: + * http://daniel.haxx.se/projects/trio/ + * and is covered by the following copyright and licence: + * + * Copyright (C) 2000 Bjorn Reese and Daniel Stenberg. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND + * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. + * + ************************************************************************ + * + * Private functions, types, etc. used for callback functions. + * + * The ref pointer is an opaque type and should remain as such. + * Private data must only be accessible through the getter and + * setter functions. + * + ************************************************************************/ + +#ifndef TRIO_TRIOP_H +#define TRIO_TRIOP_H + +#include "triodef.h" + +#include +#if defined(TRIO_COMPILER_ANCIENT) +# include +#else +# include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/************************************************************************* + * Supported standards + */ + +/* + * TRIO_C99 (=0 or =1) + * + * Define this to 0 to disable C99 format specifier extensions, or + * define to 1 to enable them. The format specifiers that are + * disabled by this switch are labelled with [C99] in the format + * specifier documentation. + */ +#if !defined(TRIO_C99) +# define TRIO_C99 1 +#endif + +/* + * TRIO_BSD (=0 or =1) + * + * Define this to 0 to disable BSD format specifier extensions, or + * define to 1 to enable them. The format specifiers that are + * disabled by this switch are labelled with [BSD] in the format + * specifier documentation. + */ +#if !defined(TRIO_BSD) +# define TRIO_BSD 1 +#endif + +/* + * TRIO_GNU (=0 or =1) + * + * Define this to 0 to disable GNU format specifier extensions, or + * define to 1 to enable them. The format specifiers that are + * disabled by this switch are labelled with [GNU] in the format + * specifier documentation. + */ +#if !defined(TRIO_GNU) +# define TRIO_GNU 1 +#endif + +/* + * TRIO_MISC (=0 or =1) + * + * Define this to 0 to disable miscellaneous format specifier + * extensions, or define to 1 to enable them. The format specifiers + * that are disabled by this switch are labelled with [MISC] in the + * format specifier documentation. + */ +#if !defined(TRIO_MISC) +# define TRIO_MISC 1 +#endif + +/* + * TRIO_UNIX98 (=0 or =1) + * + * Define this to 0 to disable UNIX98 format specifier extensions, + * or define to 1 to enable them. The format specifiers that are + * disabled by this switch are labelled with [UNIX98] in the format + * specifier documentation. + */ +#if !defined(TRIO_UNIX98) +# define TRIO_UNIX98 1 +#endif + +/* + * TRIO_MICROSOFT (=0 or =1) + * + * Define this to 0 to disable Microsoft Visual C format specifier + * extensions, or define to 1 to enable them. The format specifiers + * that are disabled by this switch are labelled with [MSVC] in the + * format specifier documentation. + */ +#if !defined(TRIO_MICROSOFT) +# define TRIO_MICROSOFT 1 +#endif + +/* + * TRIO_EXTENSION (=0 or =1) + * + * Define this to 0 to disable Trio-specific extensions, or define + * to 1 to enable them. This has two effects: it controls whether + * or not the Trio user-defined formating mechanism + * (trio_register() etc) is supported, and it enables or disables + * Trio's own format specifier extensions. The format specifiers + * that are disabled by this switch are labelled with [TRIO] in + * the format specifier documentation. + */ +#if !defined(TRIO_EXTENSION) +# define TRIO_EXTENSION 1 +#endif + +/* + * TRIO_DEPRECATED (=0 or =1) + * + * Define this to 0 to disable deprecated functionality, or define + * to 1 to enable them. + */ +#if !defined(TRIO_DEPRECATED) +# define TRIO_DEPRECATED 1 +#endif + +/************************************************************************* + * Features + */ + +#if defined(TRIO_SNPRINTF_ONLY) +# define TRIO_FEATURE_SCANF 0 +# define TRIO_FEATURE_FILE 0 +# define TRIO_FEATURE_STDIO 0 +# define TRIO_FEATURE_FD 0 +# define TRIO_FEATURE_DYNAMICSTRING 0 +# define TRIO_FEATURE_CLOSURE 0 +# define TRIO_FEATURE_STRERR 0 +# define TRIO_FEATURE_LOCALE 0 +# define TRIO_EMBED_NAN 1 +# define TRIO_EMBED_STRING 1 +#endif + +/* + * TRIO_FEATURE_SCANF (=0 or =1) + * + * Define this to 0 to disable all the scanf() variants, or define to 1 + * to enable them. + */ +#if !defined(TRIO_FEATURE_SCANF) +# define TRIO_FEATURE_SCANF 1 +#endif + +/* + * TRIO_FEATURE_FILE (=0 or =1) + * + * Define this to 0 to disable compilation of the trio_fprintf() and + * trio_fscanf() family of functions, or define to 1 to enable them. + * + * This may be useful on an embedded platform with no filesystem. + * Note that trio_printf() uses fwrite to write to stdout, so if you + * do not have an implementation of fwrite() at all then you must also + * define TRIO_FEATURE_STDIO to 0. + */ +#if !defined(TRIO_FEATURE_FILE) +# define TRIO_FEATURE_FILE 1 +#endif + +/* + * TRIO_FEATURE_STDIO (=0 or =1) + * + * Define this to 0 to disable compilation of the trio_printf() and + * trio_scanf() family of functions, or define to 1 to enable them. + * + * This may be useful on an embedded platform with no standard I/O. + */ +#if !defined(TRIO_FEATURE_STDIO) +# define TRIO_FEATURE_STDIO 1 +#endif + +/* + * TRIO_FEATURE_FD (=0 or =1) + * + * Define this to 0 to disable compilation of the trio_dprintf() and + * trio_dscanf() family of functions, or define to 1 to enable them. + * + * This may be useful on an embedded platform with no filesystem, or on + * a platform that supports file I/O using FILE* but not using raw file + * descriptors. + */ +#if !defined(TRIO_FEATURE_FD) +# define TRIO_FEATURE_FD 1 +#endif + +/* + * TRIO_FEATURE_DYNAMICSTRING (=0 or =1) + * + * Define this to 0 to disable compilation of the trio_aprintf() + * family of functions, or define to 1 to enable them. + * + * If you define both this and TRIO_MINIMAL to 0, then Trio will never + * call malloc or free. + */ +#if !defined(TRIO_FEATURE_DYNAMICSTRING) +# define TRIO_FEATURE_DYNAMICSTRING 1 +#endif + +/* + * TRIO_FEATURE_CLOSURE (=0 or =1) + * + * Define this to 0 to disable compilation of the trio_cprintf() and + * trio_cscanf() family of functions, or define to 1 to enable them. + * + * These functions are rarely needed. This saves a (small) amount of code. + */ +#if !defined(TRIO_FEATURE_CLOSURE) +# define TRIO_FEATURE_CLOSURE 1 +#endif + +/* + * TRIO_FEATURE_ERRORCODE (=0 or =1) + * + * Define this to 0 to return -1 from the print and scan function on + * error, or define to 1 to return a negative number with debugging + * information as part of the return code. + * + * If enabled, the return code will be a negative number, which encodes + * an error code and an error location. These can be decoded with the + * TRIO_ERROR_CODE and TRIO_ERROR_POSITION macros. + */ +#if defined(TRIO_ERRORS) +# define TRIO_FEATURE_ERRORCODE TRIO_ERRORS +#endif +#if !defined(TRIO_FEATURE_ERRORCODE) +# define TRIO_FEATURE_ERRORCODE 1 +#endif + +/* + * TRIO_FEATURE_STRERR (=0 or =1) + * + * Define this to 0 if you do not use trio_strerror(), or define to 1 if + * you do use it. + * + * This saves a (small) amount of code. + */ +#if !defined(TRIO_FEATURE_STRERR) +# define TRIO_FEATURE_STRERR 1 +#endif + +/* + * TRIO_FEATURE_FLOAT (=0 or =1) + * + * Define this to 0 to disable all floating-point support, or define + * to 1 to enable it. + * + * This is useful in restricted embedded platforms that do not support + * floating-point. Obviously you cannot use floating-point format + * specifiers if you define this. + * + * Do not compile trionan.c if you disable this. + */ +#if !defined(TRIO_FEATURE_FLOAT) +# define TRIO_FEATURE_FLOAT 1 +#endif + +/* + * TRIO_FEATURE_LOCALE (=0 or =1) + * + * Define this to 0 to disable customized locale support, or define + * to 1 to enable it. + * + * This saves a (small) amount of code. + */ +#if !defined(TRIO_FEATURE_LOCALE) +# define TRIO_FEATURE_LOCALE 1 +#endif + +/* + * TRIO_MINIMAL + * + * Define this to disable building the public trionan.h and triostr.h. + * If you define this, then you must not compile trionan.c and triostr.c + * separately. + */ +#if defined(TRIO_MINIMAL) +# if !defined(TRIO_EMBED_NAN) +# define TRIO_EMBED_NAN +# endif +# if !defined(TRIO_EMBED_STRING) +# define TRIO_EMBED_STRING +# endif +#endif + +/* Does not work yet. Do not enable */ +#ifndef TRIO_FEATURE_WIDECHAR +# define TRIO_FEATURE_WIDECHAR 0 +#endif + +/************************************************************************* + * Mapping standards to internal features + */ + +#if !defined(TRIO_FEATURE_HEXFLOAT) +# define TRIO_FEATURE_HEXFLOAT (TRIO_C99 && TRIO_FEATURE_FLOAT) +#endif + +#if !defined(TRIO_FEATURE_LONGDOUBLE) +# define TRIO_FEATURE_LONGDOUBLE TRIO_FEATURE_FLOAT +#endif + +#if !defined(TRIO_FEATURE_ERRNO) +# define TRIO_FEATURE_ERRNO TRIO_GNU +#endif + +#if !defined(TRIO_FEATURE_QUAD) +# define TRIO_FEATURE_QUAD (TRIO_BSD || TRIO_GNU) +#endif + +#if !defined(TRIO_FEATURE_SIZE_T) +# define TRIO_FEATURE_SIZE_T TRIO_C99 +#endif + +#if !defined(TRIO_FEATURE_SIZE_T_UPPER) +# define TRIO_FEATURE_SIZE_T_UPPER TRIO_GNU +#endif + +#if !defined(TRIO_FEATURE_PTRDIFF_T) +# define TRIO_FEATURE_PTRDIFF_T TRIO_C99 +#endif + +#if !defined(TRIO_FEATURE_INTMAX_T) +# define TRIO_FEATURE_INTMAX_T TRIO_C99 +#endif + +#if !defined(TRIO_FEATURE_FIXED_SIZE) +# define TRIO_FEATURE_FIXED_SIZE TRIO_MICROSOFT +#endif + +#if !defined(TRIO_FEATURE_POSITIONAL) +# define TRIO_FEATURE_POSITIONAL TRIO_UNIX98 +#endif + +#if !defined(TRIO_FEATURE_USER_DEFINED) +# define TRIO_FEATURE_USER_DEFINED TRIO_EXTENSION +#endif + +#if !defined(TRIO_FEATURE_BINARY) +# define TRIO_FEATURE_BINARY TRIO_EXTENSION +#endif + +#if !defined(TRIO_FEATURE_QUOTE) +# define TRIO_FEATURE_QUOTE TRIO_EXTENSION +#endif + +#if !defined(TRIO_FEATURE_STICKY) +# define TRIO_FEATURE_STICKY TRIO_EXTENSION +#endif + +#if !defined(TRIO_FEATURE_VARSIZE) +# define TRIO_FEATURE_VARSIZE TRIO_EXTENSION +#endif + +#if !defined(TRIO_FEATURE_ROUNDING) +# define TRIO_FEATURE_ROUNDING TRIO_EXTENSION +#endif + +/************************************************************************* + * Memory handling + */ +#ifndef TRIO_MALLOC +# define TRIO_MALLOC(n) malloc_beebs(n) +#endif +#ifndef TRIO_REALLOC +# define TRIO_REALLOC(x,n) realloc_beebs((x),(n)) +#endif +#ifndef TRIO_FREE +# define TRIO_FREE(x) free_beebs(x) +#endif + + +/************************************************************************* + * User-defined specifiers + */ + +typedef int (*trio_callback_t) TRIO_PROTO((trio_pointer_t)); + +trio_pointer_t trio_register TRIO_PROTO((trio_callback_t callback, const char *name)); +void trio_unregister TRIO_PROTO((trio_pointer_t handle)); + +TRIO_CONST char *trio_get_format TRIO_PROTO((trio_pointer_t ref)); +TRIO_CONST trio_pointer_t trio_get_argument TRIO_PROTO((trio_pointer_t ref)); + +/* Modifiers */ +int trio_get_width TRIO_PROTO((trio_pointer_t ref)); +void trio_set_width TRIO_PROTO((trio_pointer_t ref, int width)); +int trio_get_precision TRIO_PROTO((trio_pointer_t ref)); +void trio_set_precision TRIO_PROTO((trio_pointer_t ref, int precision)); +int trio_get_base TRIO_PROTO((trio_pointer_t ref)); +void trio_set_base TRIO_PROTO((trio_pointer_t ref, int base)); +int trio_get_padding TRIO_PROTO((trio_pointer_t ref)); +void trio_set_padding TRIO_PROTO((trio_pointer_t ref, int is_padding)); +int trio_get_short TRIO_PROTO((trio_pointer_t ref)); /* h */ +void trio_set_shortshort TRIO_PROTO((trio_pointer_t ref, int is_shortshort)); +int trio_get_shortshort TRIO_PROTO((trio_pointer_t ref)); /* hh */ +void trio_set_short TRIO_PROTO((trio_pointer_t ref, int is_short)); +int trio_get_long TRIO_PROTO((trio_pointer_t ref)); /* l */ +void trio_set_long TRIO_PROTO((trio_pointer_t ref, int is_long)); +int trio_get_longlong TRIO_PROTO((trio_pointer_t ref)); /* ll */ +void trio_set_longlong TRIO_PROTO((trio_pointer_t ref, int is_longlong)); +int trio_get_longdouble TRIO_PROTO((trio_pointer_t ref)); /* L */ +void trio_set_longdouble TRIO_PROTO((trio_pointer_t ref, int is_longdouble)); +int trio_get_alternative TRIO_PROTO((trio_pointer_t ref)); /* # */ +void trio_set_alternative TRIO_PROTO((trio_pointer_t ref, int is_alternative)); +int trio_get_alignment TRIO_PROTO((trio_pointer_t ref)); /* - */ +void trio_set_alignment TRIO_PROTO((trio_pointer_t ref, int is_leftaligned)); +int trio_get_spacing TRIO_PROTO((trio_pointer_t ref)); /* (space) */ +void trio_set_spacing TRIO_PROTO((trio_pointer_t ref, int is_space)); +int trio_get_sign TRIO_PROTO((trio_pointer_t ref)); /* + */ +void trio_set_sign TRIO_PROTO((trio_pointer_t ref, int is_showsign)); +#if TRIO_FEATURE_QUOTE +int trio_get_quote TRIO_PROTO((trio_pointer_t ref)); /* ' */ +void trio_set_quote TRIO_PROTO((trio_pointer_t ref, int is_quote)); +#endif +int trio_get_upper TRIO_PROTO((trio_pointer_t ref)); +void trio_set_upper TRIO_PROTO((trio_pointer_t ref, int is_upper)); +#if TRIO_FEATURE_INTMAX_T +int trio_get_largest TRIO_PROTO((trio_pointer_t ref)); /* j */ +void trio_set_largest TRIO_PROTO((trio_pointer_t ref, int is_largest)); +#endif +#if TRIO_FEATURE_PTRDIFF_T +int trio_get_ptrdiff TRIO_PROTO((trio_pointer_t ref)); /* t */ +void trio_set_ptrdiff TRIO_PROTO((trio_pointer_t ref, int is_ptrdiff)); +#endif +#if TRIO_FEATURE_SIZE_T +int trio_get_size TRIO_PROTO((trio_pointer_t ref)); /* z / Z */ +void trio_set_size TRIO_PROTO((trio_pointer_t ref, int is_size)); +#endif + +/* Printing */ +int trio_print_ref TRIO_PROTO((trio_pointer_t ref, const char *format, ...)); +int trio_vprint_ref TRIO_PROTO((trio_pointer_t ref, const char *format, va_list args)); +int trio_printv_ref TRIO_PROTO((trio_pointer_t ref, const char *format, trio_pointer_t *args)); + +void trio_print_int TRIO_PROTO((trio_pointer_t ref, int number)); +void trio_print_uint TRIO_PROTO((trio_pointer_t ref, unsigned int number)); +/* void trio_print_long TRIO_PROTO((trio_pointer_t ref, long number)); */ +/* void trio_print_ulong TRIO_PROTO((trio_pointer_t ref, unsigned long number)); */ +void trio_print_double TRIO_PROTO((trio_pointer_t ref, double number)); +void trio_print_string TRIO_PROTO((trio_pointer_t ref, TRIO_CONST char *string)); +void trio_print_pointer TRIO_PROTO((trio_pointer_t ref, trio_pointer_t pointer)); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* TRIO_TRIOP_H */ diff --git a/src/trio-snprintf/triostr.c b/src/trio-snprintf/triostr.c deleted file mode 120000 index 56efe157..00000000 --- a/src/trio-snprintf/triostr.c +++ /dev/null @@ -1 +0,0 @@ -../trio/triostr.c \ No newline at end of file diff --git a/src/trio-snprintf/triostr.c b/src/trio-snprintf/triostr.c new file mode 100644 index 00000000..c42822d9 --- /dev/null +++ b/src/trio-snprintf/triostr.c @@ -0,0 +1,2404 @@ +/* BEEBS trio benchmark + + Copyright (C) 2014 Embecosm Limited and University of Bristol + + This file is part of the Bristol/Embecosm Embedded Benchmark Suite. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* The original source of this file was from: + * http://daniel.haxx.se/projects/trio/ + * and is covered by the following copyright and licence: + * + * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND + * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. + * + ************************************************************************/ + +/************************************************************************* + * Include files + */ + +#if defined(HAVE_CONFIG_H) +# include +#endif +#include +#include +#include +#include +#include "triodef.h" +#include "triostr.h" +#if defined(TRIO_FUNC_TO_LONG_DOUBLE) +# define USE_MATH +#endif +#if defined(USE_MATH) +# include +#endif + +/************************************************************************* + * Definitions + */ + +#if !defined(TRIO_PUBLIC_STRING) +# define TRIO_PUBLIC_STRING TRIO_PUBLIC +#endif +#if !defined(TRIO_PRIVATE_STRING) +# define TRIO_PRIVATE_STRING TRIO_PRIVATE +#endif + +#if !defined(NULL) +# define NULL 0 +#endif +#if !defined(NIL) +# define NIL ((char)0) +#endif +#if !defined(FALSE) +# define FALSE (1 == 0) +# define TRUE (! FALSE) +#endif +#if !defined(BOOLEAN_T) +# define BOOLEAN_T int +#endif + +#if defined(USE_MATH) +# if defined(PREDEF_STANDARD_C99) +# if defined(TRIO_COMPILER_DECC) +# if (TRIO_COMPILER_DECC - 0 > 80000000) +/* + * The OSF/1 runtime that comes with the DECC compiler does not support + * hexfloats conversion. + */ +# define USE_STRTOD +# define USE_STRTOF +# endif +# else +# define USE_STRTOD +# define USE_STRTOF +# endif +# else +# if defined(TRIO_COMPILER_VISUALC) +# define USE_STRTOD +# endif +#endif +#endif + +#if defined(TRIO_PLATFORM_UNIX) +# if defined(PREDEF_STANDARD_UNIX95) +# define USE_STRCASECMP +# define USE_STRNCASECMP +# endif +# if defined(TRIO_PLATFORM_SUNOS) +# define USE_SYS_ERRLIST +# else +# define USE_STRERROR +# endif +# if defined(TRIO_PLATFORM_QNX) +# define strcasecmp(x,y) stricmp(x,y) +# define strncasecmp(x,y,n) strnicmp(x,y,n) +# endif +#endif + +#if defined(TRIO_PLATFORM_WIN32) +# define USE_STRCASECMP +# if defined(TRIO_PLATFORM_WINCE) +# define strcasecmp(x,y) _stricmp(x,y) +# else +# define strcasecmp(x,y) strcmpi(x,y) +# endif +#endif + +#if !defined(HAVE_CONFIG_H) +# if !(defined(TRIO_PLATFORM_SUNOS)) +# define HAVE_TOLOWER +# define HAVE_TOUPPER +# endif +#endif + +#if defined(USE_MATH) && !defined(TRIO_NO_POWL) +# if !defined(HAVE_POWL) +# if defined(PREDEF_STANDARD_C99) \ + || defined(PREDEF_STANDARD_UNIX03) +# define HAVE_POWL +# else +# if defined(TRIO_COMPILER_VISUALC) +# if defined(powl) +# define HAVE_POWL +# endif +# endif +# endif +# endif +#endif + +#if defined(HAVE_POWL) +# define trio_powl(x,y) powl((x),(y)) +#else +# define trio_powl(x,y) pow((double)(x),(double)(y)) +#endif + +#if defined(TRIO_FUNC_TO_UPPER) \ + || (defined(TRIO_FUNC_EQUAL) && !defined(USE_STRCASECMP)) \ + || (defined(TRIO_FUNC_EQUAL_MAX) && !defined(USE_STRNCASECMP)) \ + || defined(TRIO_FUNC_MATCH) \ + || defined(TRIO_FUNC_TO_LONG_DOUBLE) \ + || defined(TRIO_FUNC_UPPER) +# define TRIO_FUNC_INTERNAL_TO_UPPER +#endif + +/************************************************************************* + * Structures + */ + +struct _trio_string_t +{ + char *content; + size_t length; + size_t allocated; +}; + +/************************************************************************* + * Constants + */ + +#if !defined(TRIO_EMBED_STRING) +static TRIO_CONST char rcsid[] = "@(#)$Id: triostr.c,v 1.36 2010/01/26 13:02:02 breese Exp $"; +#endif + +/************************************************************************* + * Static String Functions + */ + +#if defined(TRIO_DOCUMENTATION) +# include "doc/doc_static.h" +#endif +/** @addtogroup StaticStrings + @{ +*/ + +/* + * internal_duplicate_max + */ +#if defined(TRIO_FUNC_DUPLICATE) \ + || defined(TRIO_FUNC_DUPLICATE_MAX) \ + || defined(TRIO_FUNC_STRING_DUPLICATE) \ + || defined(TRIO_FUNC_XSTRING_DUPLICATE) + +TRIO_PRIVATE_STRING char * +internal_duplicate_max +TRIO_ARGS2((source, size), + TRIO_CONST char *source, + size_t size) +{ + char *target; + + assert(source); + + /* Make room for string plus a terminating zero */ + size++; + target = trio_create(size); + if (target) + { + trio_copy_max(target, size, source); + } + return target; +} + +#endif + +/* + * internal_string_alloc + */ +#if defined(TRIO_FUNC_STRING_CREATE) \ + || defined(TRIO_FUNC_STRING_DUPLICATE) \ + || defined(TRIO_FUNC_XSTRING_DUPLICATE) + +TRIO_PRIVATE_STRING trio_string_t * +internal_string_alloc(TRIO_NOARGS) +{ + trio_string_t *self; + + self = (trio_string_t *)TRIO_MALLOC(sizeof(trio_string_t)); + if (self) + { + self->content = NULL; + self->length = 0; + self->allocated = 0; + } + return self; +} + +#endif + +/* + * internal_string_grow + * + * The size of the string will be increased by 'delta' characters. If + * 'delta' is zero, the size will be doubled. + */ +#if defined(TRIO_FUNC_STRING_CREATE) \ + || defined(TRIO_FUNC_STRING_APPEND) \ + || defined(TRIO_FUNC_XSTRING_APPEND) \ + || defined(TRIO_FUNC_XSTRING_APPEND_CHAR) + +TRIO_PRIVATE_STRING BOOLEAN_T +internal_string_grow +TRIO_ARGS2((self, delta), + trio_string_t *self, + size_t delta) +{ + BOOLEAN_T status = FALSE; + char *new_content; + size_t new_size; + + new_size = (delta == 0) + ? ( (self->allocated == 0) ? 1 : self->allocated * 2 ) + : self->allocated + delta; + + new_content = (char *)TRIO_REALLOC(self->content, new_size); + if (new_content) + { + self->content = new_content; + self->allocated = new_size; + status = TRUE; + } + return status; +} + +#endif + +/* + * internal_string_grow_to + * + * The size of the string will be increased to 'length' plus one characters. + * If 'length' is less than the original size, the original size will be + * used (that is, the size of the string is never decreased). + */ +#if defined(TRIO_FUNC_STRING_APPEND) \ + || defined(TRIO_FUNC_XSTRING_APPEND) \ + || defined(TRIO_FUNC_XSTRING_APPEND_MAX) + +TRIO_PRIVATE_STRING BOOLEAN_T +internal_string_grow_to +TRIO_ARGS2((self, length), + trio_string_t *self, + size_t length) +{ + length++; /* Room for terminating zero */ + return (self->allocated < length) + ? internal_string_grow(self, length - self->allocated) + : TRUE; +} + +#endif + +#if defined(TRIO_FUNC_INTERNAL_TO_UPPER) + +TRIO_PRIVATE_STRING TRIO_INLINE int +internal_to_upper +TRIO_ARGS1((source), + int source) +{ +# if defined(HAVE_TOUPPER) + + return toupper(source); + +# else + + /* Does not handle locales or non-contiguous alphabetic characters */ + return ((source >= (int)'a') && (source <= (int)'z')) + ? source - 'a' + 'A' + : source; + +# endif +} + +#endif + + +/** + Create new string. + + @param size Size of new string. + @return Pointer to string, or NULL if allocation failed. +*/ +#if defined(TRIO_FUNC_CREATE) + +TRIO_PUBLIC_STRING char * +trio_create +TRIO_ARGS1((size), + size_t size) +{ + return (char *)TRIO_MALLOC(size); +} + +#endif + +/** + Destroy string. + + @param string String to be freed. +*/ +#if defined(TRIO_FUNC_DESTROY) + +TRIO_PUBLIC_STRING void +trio_destroy +TRIO_ARGS1((string), + char *string) +{ + if (string) + { + TRIO_FREE(string); + } +} + +#endif + +/** + Count the number of characters in a string. + + @param string String to measure. + @return Number of characters in @p string. +*/ +#if defined(TRIO_FUNC_LENGTH) + +TRIO_PUBLIC_STRING size_t +trio_length +TRIO_ARGS1((string), + TRIO_CONST char *string) +{ + return strlen(string); +} + +#endif + +/** + Count at most @p max characters in a string. + + @param string String to measure. + @param max Maximum number of characters to count. + @return The maximum value of @p max and number of characters in @p string. +*/ +#if defined(TRIO_FUNC_LENGTH_MAX) + +TRIO_PUBLIC_STRING size_t +trio_length_max +TRIO_ARGS2((string, max), + TRIO_CONST char *string, + size_t max) +{ + size_t i; + + for (i = 0; i < max; ++i) + { + if (string[i] == 0) + break; + } + return i; +} + +#endif + +/** + Append @p source at the end of @p target. + + @param target Target string. + @param source Source string. + @return Boolean value indicating success or failure. + + @pre @p target must point to a memory chunk with sufficient room to + contain the @p target string and @p source string. + @pre No boundary checking is performed, so insufficient memory will + result in a buffer overrun. + @post @p target will be zero terminated. +*/ +#if defined(TRIO_FUNC_APPEND) + +TRIO_PUBLIC_STRING int +trio_append +TRIO_ARGS2((target, source), + char *target, + TRIO_CONST char *source) +{ + assert(target); + assert(source); + + return (strcat(target, source) != NULL); +} + +#endif + +/** + Append at most @p max characters from @p source to @p target. + + @param target Target string. + @param max Maximum number of characters to append. + @param source Source string. + @return Boolean value indicating success or failure. + + @pre @p target must point to a memory chuck with sufficient room to + contain the @p target string and the @p source string (at most @p max + characters). + @pre No boundary checking is performed, so insufficient memory will + result in a buffer overrun. + @post @p target will be zero terminated. +*/ +#if defined(TRIO_FUNC_APPEND_MAX) + +TRIO_PUBLIC_STRING int +trio_append_max +TRIO_ARGS3((target, max, source), + char *target, + size_t max, + TRIO_CONST char *source) +{ + size_t length; + + assert(target); + assert(source); + + length = trio_length(target); + + if (max > length) + { + strncat(target, source, max - length - 1); + } + return TRUE; +} + +#endif + +/** + Determine if a string contains a substring. + + @param string String to be searched. + @param substring String to be found. + @return Boolean value indicating success or failure. +*/ +#if defined(TRIO_FUNC_CONTAINS) + +TRIO_PUBLIC_STRING int +trio_contains +TRIO_ARGS2((string, substring), + TRIO_CONST char *string, + TRIO_CONST char *substring) +{ + assert(string); + assert(substring); + + return (0 != strstr(string, substring)); +} + +#endif + +/** + Copy @p source to @p target. + + @param target Target string. + @param source Source string. + @return Boolean value indicating success or failure. + + @pre @p target must point to a memory chunk with sufficient room to + contain the @p source string. + @pre No boundary checking is performed, so insufficient memory will + result in a buffer overrun. + @post @p target will be zero terminated. +*/ +#if defined(TRIO_FUNC_COPY) + +TRIO_PUBLIC_STRING int +trio_copy +TRIO_ARGS2((target, source), + char *target, + TRIO_CONST char *source) +{ + assert(target); + assert(source); + + (void)strcpy(target, source); + return TRUE; +} + +#endif + +/** + Copy at most @p max - 1 characters from @p source to @p target. + + @param target Target string. + @param max Maximum number of characters to append (one of which is + a NUL terminator). In other words @p source must point to at least + @p max - 1 bytes, but @p target must point to at least @p max + bytes. + @param source Source string. + @return Boolean value indicating success or failure. + + @pre @p target must point to a memory chunk with sufficient room to + contain the @p source string and a NUL terminator (at most @p max + bytes total). + @pre No boundary checking is performed, so insufficient memory will + result in a buffer overrun. + @post @p target will be zero terminated. +*/ +#if defined(TRIO_FUNC_COPY_MAX) + +TRIO_PUBLIC_STRING int +trio_copy_max +TRIO_ARGS3((target, max, source), + char *target, + size_t max, + TRIO_CONST char *source) +{ + assert(target); + assert(source); + assert(max > 0); /* Includes != 0 */ + + (void)strncpy(target, source, max - 1); + target[max - 1] = (char)0; + return TRUE; +} + +#endif + +/** + Duplicate @p source. + + @param source Source string. + @return A copy of the @p source string. + + @post @p target will be zero terminated. +*/ +#if defined(TRIO_FUNC_DUPLICATE) + +TRIO_PUBLIC_STRING char * +trio_duplicate +TRIO_ARGS1((source), + TRIO_CONST char *source) +{ + return internal_duplicate_max(source, trio_length(source)); +} + +#endif + +/** + Duplicate at most @p max characters of @p source. + + @param source Source string. + @param max Maximum number of characters to duplicate. + @return A copy of the @p source string. + + @post @p target will be zero terminated. +*/ +#if defined(TRIO_FUNC_DUPLICATE_MAX) + +TRIO_PUBLIC_STRING char * +trio_duplicate_max +TRIO_ARGS2((source, max), + TRIO_CONST char *source, + size_t max) +{ + size_t length; + + assert(source); + assert(max > 0); + + length = trio_length(source); + if (length > max) + { + length = max; + } + return internal_duplicate_max(source, length); +} + +#endif + +/** + Compare if two strings are equal. + + @param first First string. + @param second Second string. + @return Boolean indicating whether the two strings are equal or not. + + Case-insensitive comparison. +*/ +#if defined(TRIO_FUNC_EQUAL) + +TRIO_PUBLIC_STRING int +trio_equal +TRIO_ARGS2((first, second), + TRIO_CONST char *first, + TRIO_CONST char *second) +{ + assert(first); + assert(second); + + if ((first != NULL) && (second != NULL)) + { +# if defined(USE_STRCASECMP) + return (0 == strcasecmp(first, second)); +# else + while ((*first != NIL) && (*second != NIL)) + { + if (internal_to_upper(*first) != internal_to_upper(*second)) + { + break; + } + first++; + second++; + } + return ((*first == NIL) && (*second == NIL)); +# endif + } + return FALSE; +} + +#endif + +/** + Compare if two strings are equal. + + @param first First string. + @param second Second string. + @return Boolean indicating whether the two strings are equal or not. + + Case-sensitive comparison. +*/ +#if defined(TRIO_FUNC_EQUAL_CASE) + +TRIO_PUBLIC_STRING int +trio_equal_case +TRIO_ARGS2((first, second), + TRIO_CONST char *first, + TRIO_CONST char *second) +{ + assert(first); + assert(second); + + if ((first != NULL) && (second != NULL)) + { + return (0 == strcmp(first, second)); + } + return FALSE; +} + +#endif + +/** + Compare if two strings up until the first @p max characters are equal. + + @param first First string. + @param max Maximum number of characters to compare. + @param second Second string. + @return Boolean indicating whether the two strings are equal or not. + + Case-sensitive comparison. +*/ +#if defined(TRIO_FUNC_EQUAL_CASE_MAX) + +TRIO_PUBLIC_STRING int +trio_equal_case_max +TRIO_ARGS3((first, max, second), + TRIO_CONST char *first, + size_t max, + TRIO_CONST char *second) +{ + assert(first); + assert(second); + + if ((first != NULL) && (second != NULL)) + { + return (0 == strncmp(first, second, max)); + } + return FALSE; +} + +#endif + +/** + Compare if two strings are equal. + + @param first First string. + @param second Second string. + @return Boolean indicating whether the two strings are equal or not. + + Collating characters are considered equal. +*/ +#if defined(TRIO_FUNC_EQUAL_LOCALE) + +TRIO_PUBLIC_STRING int +trio_equal_locale +TRIO_ARGS2((first, second), + TRIO_CONST char *first, + TRIO_CONST char *second) +{ + assert(first); + assert(second); + +# if defined(LC_COLLATE) + return (strcoll(first, second) == 0); +# else + return trio_equal(first, second); +# endif +} + +#endif + +/** + Compare if two strings up until the first @p max characters are equal. + + @param first First string. + @param max Maximum number of characters to compare. + @param second Second string. + @return Boolean indicating whether the two strings are equal or not. + + Case-insensitive comparison. +*/ +#if defined(TRIO_FUNC_EQUAL_MAX) + +TRIO_PUBLIC_STRING int +trio_equal_max +TRIO_ARGS3((first, max, second), + TRIO_CONST char *first, + size_t max, + TRIO_CONST char *second) +{ + assert(first); + assert(second); + + if ((first != NULL) && (second != NULL)) + { +# if defined(USE_STRNCASECMP) + return (0 == strncasecmp(first, second, max)); +# else + /* Not adequately tested yet */ + size_t cnt = 0; + while ((*first != NIL) && (*second != NIL) && (cnt <= max)) + { + if (internal_to_upper(*first) != internal_to_upper(*second)) + { + break; + } + first++; + second++; + cnt++; + } + return ((cnt == max) || ((*first == NIL) && (*second == NIL))); +# endif + } + return FALSE; +} + +#endif + +/** + Provide a textual description of an error code (errno). + + @param error_number Error number. + @return Textual description of @p error_number. +*/ +#if defined(TRIO_FUNC_ERROR) + +TRIO_PUBLIC_STRING TRIO_CONST char * +trio_error +TRIO_ARGS1((error_number), + int error_number) +{ +# if defined(USE_STRERROR) + + return strerror(error_number); + +# else +# if defined(USE_SYS_ERRLIST) + + extern char *sys_errlist[]; + extern int sys_nerr; + + return ((error_number < 0) || (error_number >= sys_nerr)) + ? "unknown" + : sys_errlist[error_number]; + +# else + + return "unknown"; + +# endif +# endif +} + +#endif + +/** + Format the date/time according to @p format. + + @param target Target string. + @param max Maximum number of characters to format. + @param format Formatting string. + @param datetime Date/time structure. + @return Number of formatted characters. + + The formatting string accepts the same specifiers as the standard C + function strftime. +*/ +#if defined(TRIO_FUNC_FORMAT_DATE_MAX) + +TRIO_PUBLIC_STRING size_t +trio_format_date_max +TRIO_ARGS4((target, max, format, datetime), + char *target, + size_t max, + TRIO_CONST char *format, + TRIO_CONST struct tm *datetime) +{ + assert(target); + assert(format); + assert(datetime); + assert(max > 0); + + return strftime(target, max, format, datetime); +} + +#endif + +/** + Calculate a hash value for a string. + + @param string String to be calculated on. + @param type Hash function. + @return Calculated hash value. + + @p type can be one of the following + @li @c TRIO_HASH_PLAIN Plain hash function. +*/ +#if defined(TRIO_FUNC_HASH) + +TRIO_PUBLIC_STRING unsigned long +trio_hash +TRIO_ARGS2((string, type), + TRIO_CONST char *string, + int type) +{ + unsigned long value = 0L; + char ch; + + assert(string); + + switch (type) + { + case TRIO_HASH_PLAIN: + while ( (ch = *string++) != NIL ) + { + value *= 31; + value += (unsigned long)ch; + } + break; + default: + assert(FALSE); + break; + } + return value; +} + +#endif + +/** + Find first occurrence of a character in a string. + + @param string String to be searched. + @param character Character to be found. + @return A pointer to the found character, or NULL if character was not found. + */ +#if defined(TRIO_FUNC_INDEX) + +TRIO_PUBLIC_STRING char * +trio_index +TRIO_ARGS2((string, character), + TRIO_CONST char *string, + int character) +{ + assert(string); + + return strchr(string, character); +} + +#endif + +/** + Find last occurrence of a character in a string. + + @param string String to be searched. + @param character Character to be found. + @return A pointer to the found character, or NULL if character was not found. + */ +#if defined(TRIO_FUNC_INDEX_LAST) + +TRIO_PUBLIC_STRING char * +trio_index_last +TRIO_ARGS2((string, character), + TRIO_CONST char *string, + int character) +{ + assert(string); + + return strchr(string, character); +} + +#endif + +/** + Convert the alphabetic letters in the string to lower-case. + + @param target String to be converted. + @return Number of processed characters (converted or not). +*/ +#if defined(TRIO_FUNC_LOWER) + +TRIO_PUBLIC_STRING int +trio_lower +TRIO_ARGS1((target), + char *target) +{ + assert(target); + + return trio_span_function(target, target, trio_to_lower); +} + +#endif + +/** + Compare two strings using wildcards. + + @param string String to be searched. + @param pattern Pattern, including wildcards, to search for. + @return Boolean value indicating success or failure. + + Case-insensitive comparison. + + The following wildcards can be used + @li @c * Match any number of characters. + @li @c ? Match a single character. +*/ +#if defined(TRIO_FUNC_MATCH) + +TRIO_PUBLIC_STRING int +trio_match +TRIO_ARGS2((string, pattern), + TRIO_CONST char *string, + TRIO_CONST char *pattern) +{ + assert(string); + assert(pattern); + + for (; ('*' != *pattern); ++pattern, ++string) + { + if (NIL == *string) + { + return (NIL == *pattern); + } + if ((internal_to_upper((int)*string) != internal_to_upper((int)*pattern)) + && ('?' != *pattern)) + { + return FALSE; + } + } + /* two-line patch to prevent *too* much recursiveness: */ + while ('*' == pattern[1]) + pattern++; + + do + { + if ( trio_match(string, &pattern[1]) ) + { + return TRUE; + } + } + while (*string++); + + return FALSE; +} + +#endif + +/** + Compare two strings using wildcards. + + @param string String to be searched. + @param pattern Pattern, including wildcards, to search for. + @return Boolean value indicating success or failure. + + Case-sensitive comparison. + + The following wildcards can be used + @li @c * Match any number of characters. + @li @c ? Match a single character. +*/ +#if defined(TRIO_FUNC_MATCH_CASE) + +TRIO_PUBLIC_STRING int +trio_match_case +TRIO_ARGS2((string, pattern), + TRIO_CONST char *string, + TRIO_CONST char *pattern) +{ + assert(string); + assert(pattern); + + for (; ('*' != *pattern); ++pattern, ++string) + { + if (NIL == *string) + { + return (NIL == *pattern); + } + if ((*string != *pattern) + && ('?' != *pattern)) + { + return FALSE; + } + } + /* two-line patch to prevent *too* much recursiveness: */ + while ('*' == pattern[1]) + pattern++; + + do + { + if ( trio_match_case(string, &pattern[1]) ) + { + return TRUE; + } + } + while (*string++); + + return FALSE; +} + +#endif + +/** + Execute a function on each character in string. + + @param target Target string. + @param source Source string. + @param Function Function to be executed. + @return Number of processed characters. +*/ +#if defined(TRIO_FUNC_SPAN_FUNCTION) + +TRIO_PUBLIC_STRING size_t +trio_span_function +TRIO_ARGS3((target, source, Function), + char *target, + TRIO_CONST char *source, + int (*Function) TRIO_PROTO((int))) +{ + size_t count = 0; + + assert(target); + assert(source); + assert(Function); + + while (*source != NIL) + { + *target++ = Function(*source++); + count++; + } + return count; +} + +#endif + +/** + Search for a substring in a string. + + @param string String to be searched. + @param substring String to be found. + @return Pointer to first occurrence of @p substring in @p string, or NULL + if no match was found. +*/ +#if defined(TRIO_FUNC_SUBSTRING) + +TRIO_PUBLIC_STRING char * +trio_substring +TRIO_ARGS2((string, substring), + TRIO_CONST char *string, + TRIO_CONST char *substring) +{ + assert(string); + assert(substring); + + return strstr(string, substring); +} + +#endif + +/** + Search for a substring in the first @p max characters of a string. + + @param string String to be searched. + @param max Maximum characters to be searched. + @param substring String to be found. + @return Pointer to first occurrence of @p substring in @p string, or NULL + if no match was found. +*/ +#if defined(TRIO_FUNC_SUBSTRING_MAX) + +TRIO_PUBLIC_STRING char * +trio_substring_max +TRIO_ARGS3((string, max, substring), + TRIO_CONST char *string, + size_t max, + TRIO_CONST char *substring) +{ + size_t count; + size_t size; + char *result = NULL; + + assert(string); + assert(substring); + + size = trio_length(substring); + if (size <= max) + { + for (count = 0; count <= max - size; count++) + { + if (trio_equal_max(substring, size, &string[count])) + { + result = (char *)&string[count]; + break; + } + } + } + return result; +} + +#endif + +/** + Tokenize string. + + @param string String to be tokenized. + @param delimiters String containing list of delimiting characters. + @return Start of new token. + + @warning @p string will be destroyed. +*/ +#if defined(TRIO_FUNC_TOKENIZE) + +TRIO_PUBLIC_STRING char * +trio_tokenize +TRIO_ARGS2((string, delimiters), + char *string, + TRIO_CONST char *delimiters) +{ + assert(delimiters); + + return strtok(string, delimiters); +} + +#endif + +/** + Convert string to floating-point number. + + @param source String to be converted. + @param endp Pointer to end of the converted string. + @return A floating-point number. + + The following Extended Backus-Naur form is used + @verbatim + double ::= [ ] + ( | + | + ) + [ [ ] ] + number ::= 1*( ) + digit ::= ( '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' ) + exponential ::= ( 'e' | 'E' ) + sign ::= ( '-' | '+' ) + decimal_point ::= '.' + @endverbatim +*/ +#if defined(TRIO_FUNC_TO_LONG_DOUBLE) + +/* FIXME: Add EBNF for hex-floats */ +TRIO_PUBLIC_STRING trio_long_double_t +trio_to_long_double +TRIO_ARGS2((source, endp), + TRIO_CONST char *source, + char **endp) +{ +# if defined(USE_STRTOLD) + return strtold(source, endp); +# else + int isNegative = FALSE; + int isExponentNegative = FALSE; + trio_long_double_t integer = 0.0; + trio_long_double_t fraction = 0.0; + unsigned long exponent = 0; + trio_long_double_t base; + trio_long_double_t fracdiv = 1.0; + trio_long_double_t value = 0.0; + + /* First try hex-floats */ + if ((source[0] == '0') && ((source[1] == 'x') || (source[1] == 'X'))) + { + base = 16.0; + source += 2; + while (isxdigit((int)*source)) + { + integer *= base; + integer += (isdigit((int)*source) + ? (*source - '0') + : 10 + (internal_to_upper((int)*source) - 'A')); + source++; + } + if (*source == '.') + { + source++; + while (isxdigit((int)*source)) + { + fracdiv /= base; + fraction += fracdiv * (isdigit((int)*source) + ? (*source - '0') + : 10 + (internal_to_upper((int)*source) - 'A')); + source++; + } + if ((*source == 'p') || (*source == 'P')) + { + source++; + if ((*source == '+') || (*source == '-')) + { + isExponentNegative = (*source == '-'); + source++; + } + while (isdigit((int)*source)) + { + exponent *= 10; + exponent += (*source - '0'); + source++; + } + } + } + /* For later use with exponent */ + base = 2.0; + } + else /* Then try normal decimal floats */ + { + base = 10.0; + isNegative = (*source == '-'); + /* Skip sign */ + if ((*source == '+') || (*source == '-')) + source++; + + /* Integer part */ + while (isdigit((int)*source)) + { + integer *= base; + integer += (*source - '0'); + source++; + } + + if (*source == '.') + { + source++; /* skip decimal point */ + while (isdigit((int)*source)) + { + fracdiv /= base; + fraction += (*source - '0') * fracdiv; + source++; + } + } + if ((*source == 'e') + || (*source == 'E') +# if TRIO_MICROSOFT + || (*source == 'd') + || (*source == 'D') +# endif + ) + { + source++; /* Skip exponential indicator */ + isExponentNegative = (*source == '-'); + if ((*source == '+') || (*source == '-')) + source++; + while (isdigit((int)*source)) + { + exponent *= (int)base; + exponent += (*source - '0'); + source++; + } + } + } + + value = integer + fraction; + if (exponent != 0) + { + if (isExponentNegative) + value /= trio_powl(base, (trio_long_double_t)exponent); + else + value *= trio_powl(base, (trio_long_double_t)exponent); + } + if (isNegative) + value = -value; + + if (endp) + *endp = (char *)source; + return value; +# endif +} + +#endif + +/** + Convert string to floating-point number. + + @param source String to be converted. + @param endp Pointer to end of the converted string. + @return A floating-point number. + + See @ref trio_to_long_double. +*/ +#if defined(TRIO_FUNC_TO_DOUBLE) + +TRIO_PUBLIC_STRING double +trio_to_double +TRIO_ARGS2((source, endp), + TRIO_CONST char *source, + char **endp) +{ +#if defined(USE_STRTOD) + return strtod(source, endp); +#else + return (double)trio_to_long_double(source, endp); +#endif +} + +#endif + +/** + Convert string to floating-point number. + + @param source String to be converted. + @param endp Pointer to end of the converted string. + @return A floating-point number. + + See @ref trio_to_long_double. +*/ +#if defined(TRIO_FUNC_TO_FLOAT) + +TRIO_PUBLIC_STRING float +trio_to_float +TRIO_ARGS2((source, endp), + TRIO_CONST char *source, + char **endp) +{ +# if defined(USE_STRTOF) + return strtof(source, endp); +# else + return (float)trio_to_long_double(source, endp); +# endif +} + +#endif + +/** + Convert string to signed integer. + + @param string String to be converted. + @param endp Pointer to end of converted string. + @param base Radix number of number. +*/ +#if defined(TRIO_FUNC_TO_LONG) + +TRIO_PUBLIC_STRING long +trio_to_long +TRIO_ARGS3((string, endp, base), + TRIO_CONST char *string, + char **endp, + int base) +{ + assert(string); + assert((base >= 2) && (base <= 36)); + + return strtol(string, endp, base); +} + +#endif + +/** + Convert one alphabetic letter to lower-case. + + @param source The letter to be converted. + @return The converted letter. +*/ +#if defined(TRIO_FUNC_TO_LOWER) + +TRIO_PUBLIC_STRING int +trio_to_lower +TRIO_ARGS1((source), + int source) +{ +# if defined(HAVE_TOLOWER) + + return tolower(source); + +# else + + /* Does not handle locales or non-contiguous alphabetic characters */ + return ((source >= (int)'A') && (source <= (int)'Z')) + ? source - 'A' + 'a' + : source; + +# endif +} + +#endif + +/** + Convert string to unsigned integer. + + @param string String to be converted. + @param endp Pointer to end of converted string. + @param base Radix number of number. +*/ +#if defined(TRIO_FUNC_TO_UNSIGNED_LONG) + +TRIO_PUBLIC_STRING unsigned long +trio_to_unsigned_long +TRIO_ARGS3((string, endp, base), + TRIO_CONST char *string, + char **endp, + int base) +{ + assert(string); + assert((base >= 2) && (base <= 36)); + + return strtoul(string, endp, base); +} + +#endif + +/** + Convert one alphabetic letter to upper-case. + + @param source The letter to be converted. + @return The converted letter. +*/ +#if defined(TRIO_FUNC_TO_UPPER) + +TRIO_PUBLIC_STRING int +trio_to_upper +TRIO_ARGS1((source), + int source) +{ + return internal_to_upper(source); +} + +#endif + +/** + Convert the alphabetic letters in the string to upper-case. + + @param target The string to be converted. + @return The number of processed characters (converted or not). +*/ +#if defined(TRIO_FUNC_UPPER) + +TRIO_PUBLIC_STRING int +trio_upper +TRIO_ARGS1((target), + char *target) +{ + assert(target); + + return trio_span_function(target, target, internal_to_upper); +} + +#endif + +/** @} End of StaticStrings */ + + +/************************************************************************* + * Dynamic String Functions + */ + +#if defined(TRIO_DOCUMENTATION) +# include "doc/doc_dynamic.h" +#endif +/** @addtogroup DynamicStrings + @{ +*/ + +/** + Create a new dynamic string. + + @param initial_size Initial size of the buffer. + @return Newly allocated dynamic string, or NULL if memory allocation failed. +*/ +#if defined(TRIO_FUNC_STRING_CREATE) + +TRIO_PUBLIC_STRING trio_string_t * +trio_string_create +TRIO_ARGS1((initial_size), + int initial_size) +{ + trio_string_t *self; + + self = internal_string_alloc(); + if (self) + { + if (internal_string_grow(self, + (size_t)((initial_size > 0) ? initial_size : 1))) + { + self->content[0] = (char)0; + self->allocated = initial_size; + } + else + { + trio_string_destroy(self); + self = NULL; + } + } + return self; +} + +#endif + +/** + Deallocate the dynamic string and its contents. + + @param self Dynamic string +*/ +#if defined(TRIO_FUNC_STRING_DESTROY) + +TRIO_PUBLIC_STRING void +trio_string_destroy +TRIO_ARGS1((self), + trio_string_t *self) +{ + assert(self); + + if (self) + { + trio_destroy(self->content); + TRIO_FREE(self); + } +} + +#endif + +/** + Get a pointer to the content. + + @param self Dynamic string. + @param offset Offset into content. + @return Pointer to the content. + + @p Offset can be zero, positive, or negative. If @p offset is zero, + then the start of the content will be returned. If @p offset is positive, + then a pointer to @p offset number of characters from the beginning of the + content is returned. If @p offset is negative, then a pointer to @p offset + number of characters from the ending of the string, starting at the + terminating zero, is returned. +*/ +#if defined(TRIO_FUNC_STRING_GET) + +TRIO_PUBLIC_STRING char * +trio_string_get +TRIO_ARGS2((self, offset), + trio_string_t *self, + int offset) +{ + char *result = NULL; + + assert(self); + + if (self->content != NULL) + { + if (self->length == 0) + { + (void)trio_string_length(self); + } + if (offset >= 0) + { + if (offset > (int)self->length) + { + offset = self->length; + } + } + else + { + offset += self->length + 1; + if (offset < 0) + { + offset = 0; + } + } + result = &(self->content[offset]); + } + return result; +} + +#endif + +/** + Extract the content. + + @param self Dynamic String + @return Content of dynamic string. + + The content is removed from the dynamic string. This enables destruction + of the dynamic string without deallocation of the content. +*/ +#if defined(TRIO_FUNC_STRING_EXTRACT) + +TRIO_PUBLIC_STRING char * +trio_string_extract +TRIO_ARGS1((self), + trio_string_t *self) +{ + char *result; + + assert(self); + + result = self->content; + /* FIXME: Allocate new empty buffer? */ + self->content = NULL; + self->length = self->allocated = 0; + return result; +} + +#endif + +/** + Set the content of the dynamic string. + + @param self Dynamic String + @param buffer The new content. + + Sets the content of the dynamic string to a copy @p buffer. + An existing content will be deallocated first, if necessary. + + @remark + This function will make a copy of @p buffer. + You are responsible for deallocating @p buffer yourself. +*/ +#if defined(TRIO_FUNC_XSTRING_SET) + +TRIO_PUBLIC_STRING void +trio_xstring_set +TRIO_ARGS2((self, buffer), + trio_string_t *self, + char *buffer) +{ + assert(self); + + trio_destroy(self->content); + self->content = trio_duplicate(buffer); +} + +#endif + +/* + * trio_string_size + */ +#if defined(TRIO_FUNC_STRING_SIZE) + +TRIO_PUBLIC_STRING int +trio_string_size +TRIO_ARGS1((self), + trio_string_t *self) +{ + assert(self); + + return self->allocated; +} + +#endif + +/* + * trio_string_terminate + */ +#if defined(TRIO_FUNC_STRING_TERMINATE) + +TRIO_PUBLIC_STRING void +trio_string_terminate +TRIO_ARGS1((self), + trio_string_t *self) +{ + trio_xstring_append_char(self, 0); +} + +#endif + +/** + Append the second string to the first. + + @param self Dynamic string to be modified. + @param other Dynamic string to copy from. + @return Boolean value indicating success or failure. +*/ +#if defined(TRIO_FUNC_STRING_APPEND) + +TRIO_PUBLIC_STRING int +trio_string_append +TRIO_ARGS2((self, other), + trio_string_t *self, + trio_string_t *other) +{ + size_t length; + + assert(self); + assert(other); + + length = self->length + other->length; + if (!internal_string_grow_to(self, length)) + goto error; + trio_copy(&self->content[self->length], other->content); + self->length = length; + return TRUE; + + error: + return FALSE; +} + +#endif + + +/* + * trio_xstring_append + */ +#if defined(TRIO_FUNC_XSTRING_APPEND) + +TRIO_PUBLIC_STRING int +trio_xstring_append +TRIO_ARGS2((self, other), + trio_string_t *self, + TRIO_CONST char *other) +{ + size_t length; + + assert(self); + assert(other); + + length = self->length + trio_length(other); + if (!internal_string_grow_to(self, length)) + goto error; + trio_copy(&self->content[self->length], other); + self->length = length; + return TRUE; + + error: + return FALSE; +} + +#endif + +/* + * trio_xstring_append_char + */ +#if defined(TRIO_FUNC_XSTRING_APPEND_CHAR) + +TRIO_PUBLIC_STRING int +trio_xstring_append_char +TRIO_ARGS2((self, character), + trio_string_t *self, + char character) +{ + assert(self); + + if ((int)self->length >= trio_string_size(self)) + { + if (!internal_string_grow(self, 0)) + goto error; + } + self->content[self->length] = character; + self->length++; + return TRUE; + + error: + return FALSE; +} + +#endif + +/* + * trio_xstring_append_max + */ +#if defined(TRIO_FUNC_XSTRING_APPEND_MAX) + +TRIO_PUBLIC_STRING int +trio_xstring_append_max +TRIO_ARGS3((self, other, max), + trio_string_t *self, + TRIO_CONST char *other, + size_t max) +{ + size_t length; + + assert(self); + assert(other); + + length = self->length + trio_length_max(other, max); + if (!internal_string_grow_to(self, length)) + goto error; + + /* + * Pass max + 1 since trio_copy_max copies one character less than + * this from the source to make room for a terminating zero. + */ + trio_copy_max(&self->content[self->length], max + 1, other); + self->length = length; + return TRUE; + + error: + return FALSE; +} + +#endif + +/** + Search for the first occurrence of second parameter in the first. + + @param self Dynamic string to be modified. + @param other Dynamic string to copy from. + @return Boolean value indicating success or failure. +*/ +#if defined(TRIO_FUNC_STRING_CONTAINS) + +TRIO_PUBLIC_STRING int +trio_string_contains +TRIO_ARGS2((self, other), + trio_string_t *self, + trio_string_t *other) +{ + assert(self); + assert(other); + + return trio_contains(self->content, other->content); +} + +#endif + +/* + * trio_xstring_contains + */ +#if defined(TRIO_FUNC_XSTRING_CONTAINS) + +TRIO_PUBLIC_STRING int +trio_xstring_contains +TRIO_ARGS2((self, other), + trio_string_t *self, + TRIO_CONST char *other) +{ + assert(self); + assert(other); + + return trio_contains(self->content, other); +} + +#endif + +/* + * trio_string_copy + */ +#if defined(TRIO_FUNC_STRING_COPY) + +TRIO_PUBLIC_STRING int +trio_string_copy +TRIO_ARGS2((self, other), + trio_string_t *self, + trio_string_t *other) +{ + assert(self); + assert(other); + + self->length = 0; + return trio_string_append(self, other); +} + +#endif + + +/* + * trio_xstring_copy + */ +#if defined(TRIO_FUNC_XSTRING_COPY) + +TRIO_PUBLIC_STRING int +trio_xstring_copy +TRIO_ARGS2((self, other), + trio_string_t *self, + TRIO_CONST char *other) +{ + assert(self); + assert(other); + + self->length = 0; + return trio_xstring_append(self, other); +} + +#endif + +/* + * trio_string_duplicate + */ +#if defined(TRIO_FUNC_STRING_DUPLICATE) + +TRIO_PUBLIC_STRING trio_string_t * +trio_string_duplicate +TRIO_ARGS1((other), + trio_string_t *other) +{ + trio_string_t *self; + + assert(other); + + self = internal_string_alloc(); + if (self) + { + self->content = internal_duplicate_max(other->content, other->length); + if (self->content) + { + self->length = other->length; + self->allocated = self->length + 1; + } + else + { + self->length = self->allocated = 0; + } + } + return self; +} + +#endif + +/* + * trio_xstring_duplicate + */ +#if defined(TRIO_FUNC_XSTRING_DUPLICATE) + +TRIO_PUBLIC_STRING trio_string_t * +trio_xstring_duplicate +TRIO_ARGS1((other), + TRIO_CONST char *other) +{ + trio_string_t *self; + + assert(other); + + self = internal_string_alloc(); + if (self) + { + self->content = internal_duplicate_max(other, trio_length(other)); + if (self->content) + { + self->length = trio_length(self->content); + self->allocated = self->length + 1; + } + else + { + self->length = self->allocated = 0; + } + } + return self; +} + +#endif + +/* + * trio_string_equal + */ +#if defined(TRIO_FUNC_STRING_EQUAL) + +TRIO_PUBLIC_STRING int +trio_string_equal +TRIO_ARGS2((self, other), + trio_string_t *self, + trio_string_t *other) +{ + assert(self); + assert(other); + + return trio_equal(self->content, other->content); +} + +#endif + + +/* + * trio_xstring_equal + */ +#if defined(TRIO_FUNC_XSTRING_EQUAL) + +TRIO_PUBLIC_STRING int +trio_xstring_equal +TRIO_ARGS2((self, other), + trio_string_t *self, + TRIO_CONST char *other) +{ + assert(self); + assert(other); + + return trio_equal(self->content, other); +} + +#endif + +/* + * trio_string_equal_max + */ +#if defined(TRIO_FUNC_STRING_EQUAL_MAX) + +TRIO_PUBLIC_STRING int +trio_string_equal_max +TRIO_ARGS3((self, max, other), + trio_string_t *self, + size_t max, + trio_string_t *other) +{ + assert(self); + assert(other); + + return trio_equal_max(self->content, max, other->content); +} +#endif + +/* + * trio_xstring_equal_max + */ +#if defined(TRIO_FUNC_XSTRING_EQUAL_MAX) + +TRIO_PUBLIC_STRING int +trio_xstring_equal_max +TRIO_ARGS3((self, max, other), + trio_string_t *self, + size_t max, + TRIO_CONST char *other) +{ + assert(self); + assert(other); + + return trio_equal_max(self->content, max, other); +} + +#endif + +/* + * trio_string_equal_case + */ +#if defined(TRIO_FUNC_STRING_EQUAL_CASE) + +TRIO_PUBLIC_STRING int +trio_string_equal_case +TRIO_ARGS2((self, other), + trio_string_t *self, + trio_string_t *other) +{ + assert(self); + assert(other); + + return trio_equal_case(self->content, other->content); +} + +#endif + +/* + * trio_xstring_equal_case + */ +#if defined(TRIO_FUNC_XSTRING_EQUAL_CASE) + +TRIO_PUBLIC_STRING int +trio_xstring_equal_case +TRIO_ARGS2((self, other), + trio_string_t *self, + TRIO_CONST char *other) +{ + assert(self); + assert(other); + + return trio_equal_case(self->content, other); +} + +#endif + +/* + * trio_string_equal_case_max + */ +#if defined(TRIO_FUNC_STRING_EQUAL_CASE_MAX) + +TRIO_PUBLIC_STRING int +trio_string_equal_case_max +TRIO_ARGS3((self, max, other), + trio_string_t *self, + size_t max, + trio_string_t *other) +{ + assert(self); + assert(other); + + return trio_equal_case_max(self->content, max, other->content); +} + +#endif + +/* + * trio_xstring_equal_case_max + */ +#if defined(TRIO_FUNC_XSTRING_EQUAL_CASE_MAX) + +TRIO_PUBLIC_STRING int +trio_xstring_equal_case_max +TRIO_ARGS3((self, max, other), + trio_string_t *self, + size_t max, + TRIO_CONST char *other) +{ + assert(self); + assert(other); + + return trio_equal_case_max(self->content, max, other); +} + +#endif + +/* + * trio_string_format_data_max + */ +#if defined(TRIO_FUNC_STRING_FORMAT_DATE_MAX) + +TRIO_PUBLIC_STRING size_t +trio_string_format_date_max +TRIO_ARGS4((self, max, format, datetime), + trio_string_t *self, + size_t max, + TRIO_CONST char *format, + TRIO_CONST struct tm *datetime) +{ + assert(self); + + return trio_format_date_max(self->content, max, format, datetime); +} + +#endif + +/* + * trio_string_index + */ +#if defined(TRIO_FUNC_STRING_INDEX) + +TRIO_PUBLIC_STRING char * +trio_string_index +TRIO_ARGS2((self, character), + trio_string_t *self, + int character) +{ + assert(self); + + return trio_index(self->content, character); +} + +#endif + +/* + * trio_string_index_last + */ +#if defined(TRIO_FUNC_STRING_INDEX_LAST) + +TRIO_PUBLIC_STRING char * +trio_string_index_last +TRIO_ARGS2((self, character), + trio_string_t *self, + int character) +{ + assert(self); + + return trio_index_last(self->content, character); +} + +#endif + +/* + * trio_string_length + */ +#if defined(TRIO_FUNC_STRING_LENGTH) + +TRIO_PUBLIC_STRING int +trio_string_length +TRIO_ARGS1((self), + trio_string_t *self) +{ + assert(self); + + if (self->length == 0) + { + self->length = trio_length(self->content); + } + return self->length; +} + +#endif + +/* + * trio_string_lower + */ +#if defined(TRIO_FUNC_STRING_LOWER) + +TRIO_PUBLIC_STRING int +trio_string_lower +TRIO_ARGS1((self), + trio_string_t *self) +{ + assert(self); + + return trio_lower(self->content); +} + +#endif + +/* + * trio_string_match + */ +#if defined(TRIO_FUNC_STRING_MATCH) + +TRIO_PUBLIC_STRING int +trio_string_match +TRIO_ARGS2((self, other), + trio_string_t *self, + trio_string_t *other) +{ + assert(self); + assert(other); + + return trio_match(self->content, other->content); +} + +#endif + +/* + * trio_xstring_match + */ +#if defined(TRIO_FUNC_XSTRING_MATCH) + +TRIO_PUBLIC_STRING int +trio_xstring_match +TRIO_ARGS2((self, other), + trio_string_t *self, + TRIO_CONST char *other) +{ + assert(self); + assert(other); + + return trio_match(self->content, other); +} + +#endif + +/* + * trio_string_match_case + */ +#if defined(TRIO_FUNC_STRING_MATCH_CASE) + +TRIO_PUBLIC_STRING int +trio_string_match_case +TRIO_ARGS2((self, other), + trio_string_t *self, + trio_string_t *other) +{ + assert(self); + assert(other); + + return trio_match_case(self->content, other->content); +} + +#endif + +/* + * trio_xstring_match_case + */ +#if defined(TRIO_FUNC_XSTRING_MATCH_CASE) + +TRIO_PUBLIC_STRING int +trio_xstring_match_case +TRIO_ARGS2((self, other), + trio_string_t *self, + TRIO_CONST char *other) +{ + assert(self); + assert(other); + + return trio_match_case(self->content, other); +} + +#endif + +/* + * trio_string_substring + */ +#if defined(TRIO_FUNC_STRING_SUBSTRING) + +TRIO_PUBLIC_STRING char * +trio_string_substring +TRIO_ARGS2((self, other), + trio_string_t *self, + trio_string_t *other) +{ + assert(self); + assert(other); + + return trio_substring(self->content, other->content); +} + +#endif + +/* + * trio_xstring_substring + */ +#if defined(TRIO_FUNC_XSTRING_SUBSTRING) + +TRIO_PUBLIC_STRING char * +trio_xstring_substring +TRIO_ARGS2((self, other), + trio_string_t *self, + TRIO_CONST char *other) +{ + assert(self); + assert(other); + + return trio_substring(self->content, other); +} + +#endif + +/* + * trio_string_upper + */ +#if defined(TRIO_FUNC_STRING_UPPER) + +TRIO_PUBLIC_STRING int +trio_string_upper +TRIO_ARGS1((self), + trio_string_t *self) +{ + assert(self); + + return trio_upper(self->content); +} + +#endif + +/** @} End of DynamicStrings */ diff --git a/src/trio-snprintf/triostr.h b/src/trio-snprintf/triostr.h deleted file mode 120000 index ba4efead..00000000 --- a/src/trio-snprintf/triostr.h +++ /dev/null @@ -1 +0,0 @@ -../trio/triostr.h \ No newline at end of file diff --git a/src/trio-snprintf/triostr.h b/src/trio-snprintf/triostr.h new file mode 100644 index 00000000..27fb7f93 --- /dev/null +++ b/src/trio-snprintf/triostr.h @@ -0,0 +1,699 @@ +/* BEEBS trio benchmark + + Copyright (C) 2014 Embecosm Limited and University of Bristol + + This file is part of the Bristol/Embecosm Embedded Benchmark Suite. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* The original source of this file was from: + * http://daniel.haxx.se/projects/trio/ + * and is covered by the following copyright and licence: + * + * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND + * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. + * + ************************************************************************/ + +#ifndef TRIO_TRIOSTR_H +#define TRIO_TRIOSTR_H + +/* + * Documentation is located in triostr.c + */ + +#include +#include +#include +#include "triodef.h" +#include "triop.h" + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + TRIO_HASH_NONE = 0, + TRIO_HASH_PLAIN, + TRIO_HASH_TWOSIGNED +}; + +#if !defined(TRIO_PUBLIC_STRING) +# if !defined(TRIO_PUBLIC) +# define TRIO_PUBLIC +# endif +# define TRIO_PUBLIC_STRING TRIO_PUBLIC +#endif + +/************************************************************************* + * Dependencies + */ + +#if defined(TRIO_EMBED_STRING) + +/* + * The application that triostr is embedded in must define which functions + * it uses. + * + * The following resolves internal dependencies. + */ + +# if defined(TRIO_FUNC_XSTRING_SET) +# if !defined(TRIO_FUNC_DUPLICATE) +# define TRIO_FUNC_DUPLICATE +# endif +# endif + +# if defined(TRIO_FUNC_DUPLICATE) \ + || defined(TRIO_FUNC_DUPLICATE_MAX) \ + || defined(TRIO_FUNC_STRING_DUPLICATE) \ + || defined(TRIO_FUNC_XSTRING_DUPLICATE) +# if !defined(TRIO_FUNC_CREATE) +# define TRIO_FUNC_CREATE +# endif +# if !defined(TRIO_FUNC_COPY_MAX) +# define TRIO_FUNC_COPY_MAX +# endif +# endif + +# if defined(TRIO_FUNC_STRING_CREATE) +# if !defined(TRIO_FUNC_STRING_DESTROY) +# define TRIO_FUNC_STRING_DESTROY +# endif +# endif + +# if defined(TRIO_FUNC_STRING_DESTROY) \ + || defined(TRIO_FUNC_XSTRING_SET) +# if !defined(TRIO_FUNC_DESTROY) +# define TRIO_FUNC_DESTROY +# endif +# endif + +# if defined(TRIO_FUNC_EQUAL_LOCALE) \ + || defined(TRIO_FUNC_STRING_EQUAL) \ + || defined(TRIO_FUNC_XSTRING_EQUAL) +# if !defined(TRIO_FUNC_EQUAL) +# define TRIO_FUNC_EQUAL +# endif +# endif + +# if defined(TRIO_FUNC_EQUAL_CASE) \ + || defined(TRIO_FUNC_STRING_EQUAL_CASE) \ + || defined(TRIO_FUNC_XSTRING_EQUAL_CASE) +# if !defined(TRIO_FUNC_EQUAL_CASE) +# define TRIO_FUNC_EQUAL_CASE +# endif +# endif + +# if defined(TRIO_FUNC_SUBSTRING_MAX) \ + || defined(TRIO_FUNC_STRING_EQUAL_MAX) \ + || defined(TRIO_FUNC_XSTRING_EQUAL_MAX) +# if !defined(TRIO_FUNC_EQUAL_MAX) +# define TRIO_FUNC_EQUAL_MAX +# endif +# endif + +# if defined(TRIO_FUNC_TO_DOUBLE) \ + || defined(TRIO_FUNC_TO_FLOAT) +# if !defined(TRIO_FUNC_TO_LONG_DOUBLE) +# define TRIO_FUNC_TO_LONG_DOUBLE +# endif +# endif + +# if defined(TRIO_FUNC_STRING_TERMINATE) +# if !defined(TRIO_FUNC_XSTRING_APPEND_CHAR) +# define TRIO_FUNC_XSTRING_APPEND_CHAR +# endif +# endif + +# if defined(TRIO_FUNC_XSTRING_APPEND_CHAR) +# if !defined(TRIO_FUNC_STRING_SIZE) +# define TRIO_FUNC_STRING_SIZE +# endif +# endif + +#else + +/* + * When triostr is not embedded all functions are defined. + */ + +# define TRIO_FUNC_APPEND +# define TRIO_FUNC_APPEND_MAX +# define TRIO_FUNC_CONTAINS +# define TRIO_FUNC_COPY +# define TRIO_FUNC_COPY_MAX +# define TRIO_FUNC_CREATE +# define TRIO_FUNC_DESTROY +# define TRIO_FUNC_DUPLICATE +# define TRIO_FUNC_DUPLICATE_MAX +# define TRIO_FUNC_EQUAL +# define TRIO_FUNC_EQUAL_CASE +# define TRIO_FUNC_EQUAL_CASE_MAX +# define TRIO_FUNC_EQUAL_LOCALE +# define TRIO_FUNC_EQUAL_MAX +# define TRIO_FUNC_ERROR +# if !defined(TRIO_PLATFORM_WINCE) +# define TRIO_FUNC_FORMAT_DATE_MAX +# endif +# define TRIO_FUNC_HASH +# define TRIO_FUNC_INDEX +# define TRIO_FUNC_INDEX_LAST +# define TRIO_FUNC_LENGTH +# define TRIO_FUNC_LENGTH_MAX +# define TRIO_FUNC_LOWER +# define TRIO_FUNC_MATCH +# define TRIO_FUNC_MATCH_CASE +# define TRIO_FUNC_SPAN_FUNCTION +# define TRIO_FUNC_SUBSTRING +# define TRIO_FUNC_SUBSTRING_MAX +# define TRIO_FUNC_TO_DOUBLE +# define TRIO_FUNC_TO_FLOAT +# define TRIO_FUNC_TO_LONG +# define TRIO_FUNC_TO_LONG_DOUBLE +# define TRIO_FUNC_TO_LOWER +# define TRIO_FUNC_TO_UNSIGNED_LONG +# define TRIO_FUNC_TO_UPPER +# define TRIO_FUNC_TOKENIZE +# define TRIO_FUNC_UPPER + +# define TRIO_FUNC_STRING_APPEND +# define TRIO_FUNC_STRING_CONTAINS +# define TRIO_FUNC_STRING_COPY +# define TRIO_FUNC_STRING_CREATE +# define TRIO_FUNC_STRING_DESTROY +# define TRIO_FUNC_STRING_DUPLICATE +# define TRIO_FUNC_STRING_EQUAL +# define TRIO_FUNC_STRING_EQUAL_CASE +# define TRIO_FUNC_STRING_EQUAL_CASE_MAX +# define TRIO_FUNC_STRING_EQUAL_MAX +# define TRIO_FUNC_STRING_EXTRACT +# if !defined(TRIO_PLATFORM_WINCE) +# define TRIO_FUNC_STRING_FORMAT_DATE_MAX +# endif +# define TRIO_FUNC_STRING_GET +# define TRIO_FUNC_STRING_INDEX +# define TRIO_FUNC_STRING_INDEX_LAST +# define TRIO_FUNC_STRING_LENGTH +# define TRIO_FUNC_STRING_LOWER +# define TRIO_FUNC_STRING_MATCH +# define TRIO_FUNC_STRING_MATCH_CASE +# define TRIO_FUNC_STRING_SIZE +# define TRIO_FUNC_STRING_SUBSTRING +# define TRIO_FUNC_STRING_TERMINATE +# define TRIO_FUNC_STRING_UPPER + +# define TRIO_FUNC_XSTRING_APPEND +# define TRIO_FUNC_XSTRING_APPEND_CHAR +# define TRIO_FUNC_XSTRING_APPEND_MAX +# define TRIO_FUNC_XSTRING_CONTAINS +# define TRIO_FUNC_XSTRING_COPY +# define TRIO_FUNC_XSTRING_DUPLICATE +# define TRIO_FUNC_XSTRING_EQUAL +# define TRIO_FUNC_XSTRING_EQUAL_CASE +# define TRIO_FUNC_XSTRING_EQUAL_CASE_MAX +# define TRIO_FUNC_XSTRING_EQUAL_MAX +# define TRIO_FUNC_XSTRING_MATCH +# define TRIO_FUNC_XSTRING_MATCH_CASE +# define TRIO_FUNC_XSTRING_SET +# define TRIO_FUNC_XSTRING_SUBSTRING + +#endif + + +/************************************************************************* + * String functions + */ + +#if defined(TRIO_FUNC_APPEND) +TRIO_PUBLIC_STRING int +trio_append +TRIO_PROTO((char *target, TRIO_CONST char *source)); +#endif + +#if defined(TRIO_FUNC_APPEND_MAX) +TRIO_PUBLIC_STRING int +trio_append_max +TRIO_PROTO((char *target, size_t max, TRIO_CONST char *source)); +#endif + +#if defined(TRIO_FUNC_CONTAINS) +TRIO_PUBLIC_STRING int +trio_contains +TRIO_PROTO((TRIO_CONST char *string, TRIO_CONST char *substring)); +#endif + +#if defined(TRIO_FUNC_COPY) +TRIO_PUBLIC_STRING int +trio_copy +TRIO_PROTO((char *target, TRIO_CONST char *source)); +#endif + +#if defined(TRIO_FUNC_COPY_MAX) +TRIO_PUBLIC_STRING int +trio_copy_max +TRIO_PROTO((char *target, size_t max, TRIO_CONST char *source)); +#endif + +#if defined(TRIO_FUNC_CREATE) +TRIO_PUBLIC_STRING char * +trio_create +TRIO_PROTO((size_t size)); +#endif + +#if defined(TRIO_FUNC_DESTROY) +TRIO_PUBLIC_STRING void +trio_destroy +TRIO_PROTO((char *string)); +#endif + +#if defined(TRIO_FUNC_DUPLICATE) +TRIO_PUBLIC_STRING char * +trio_duplicate +TRIO_PROTO((TRIO_CONST char *source)); +#endif + +#if defined(TRIO_FUNC_DUPLICATE_MAX) +TRIO_PUBLIC_STRING char * +trio_duplicate_max +TRIO_PROTO((TRIO_CONST char *source, size_t max)); +#endif + +#if defined(TRIO_FUNC_EQUAL) +TRIO_PUBLIC_STRING int +trio_equal +TRIO_PROTO((TRIO_CONST char *first, TRIO_CONST char *second)); +#endif + +#if defined(TRIO_FUNC_EQUAL_CASE) +TRIO_PUBLIC_STRING int +trio_equal_case +TRIO_PROTO((TRIO_CONST char *first, TRIO_CONST char *second)); +#endif + +#if defined(TRIO_FUNC_EQUAL_CASE_MAX) +TRIO_PUBLIC_STRING int +trio_equal_case_max +TRIO_PROTO((TRIO_CONST char *first, size_t max, TRIO_CONST char *second)); +#endif + +#if defined(TRIO_FUNC_EQUAL_LOCALE) +TRIO_PUBLIC_STRING int +trio_equal_locale +TRIO_PROTO((TRIO_CONST char *first, TRIO_CONST char *second)); +#endif + +#if defined(TRIO_FUNC_EQUAL_MAX) +TRIO_PUBLIC_STRING int +trio_equal_max +TRIO_PROTO((TRIO_CONST char *first, size_t max, TRIO_CONST char *second)); +#endif + +#if defined(TRIO_FUNC_ERROR) +TRIO_PUBLIC_STRING TRIO_CONST char * +trio_error +TRIO_PROTO((int)); +#endif + +#if defined(TRIO_FUNC_FORMAT_DATE_MAX) +TRIO_PUBLIC_STRING size_t +trio_format_date_max +TRIO_PROTO((char *target, size_t max, TRIO_CONST char *format, TRIO_CONST struct tm *datetime)); +#endif + +#if defined(TRIO_FUNC_HASH) +TRIO_PUBLIC_STRING unsigned long +trio_hash +TRIO_PROTO((TRIO_CONST char *string, int type)); +#endif + +#if defined(TRIO_FUNC_INDEX) +TRIO_PUBLIC_STRING char * +trio_index +TRIO_PROTO((TRIO_CONST char *string, int character)); +#endif + +#if defined(TRIO_FUNC_INDEX_LAST) +TRIO_PUBLIC_STRING char * +trio_index_last +TRIO_PROTO((TRIO_CONST char *string, int character)); +#endif + +#if defined(TRIO_FUNC_LENGTH) +TRIO_PUBLIC_STRING size_t +trio_length +TRIO_PROTO((TRIO_CONST char *string)); +#endif + +#if defined(TRIO_FUNC_LENGTH_MAX) +TRIO_PUBLIC_STRING size_t +trio_length_max +TRIO_PROTO((TRIO_CONST char *string, size_t max)); +#endif + +#if defined(TRIO_FUNC_LOWER) +TRIO_PUBLIC_STRING int +trio_lower +TRIO_PROTO((char *target)); +#endif + +#if defined(TRIO_FUNC_MATCH) +TRIO_PUBLIC_STRING int +trio_match +TRIO_PROTO((TRIO_CONST char *string, TRIO_CONST char *pattern)); +#endif + +#if defined(TRIO_FUNC_MATCH_CASE) +TRIO_PUBLIC_STRING int +trio_match_case +TRIO_PROTO((TRIO_CONST char *string, TRIO_CONST char *pattern)); +#endif + +#if defined(TRIO_FUNC_SPAN_FUNCTION) +TRIO_PUBLIC_STRING size_t +trio_span_function +TRIO_PROTO((char *target, TRIO_CONST char *source, int (*Function) TRIO_PROTO((int)))); +#endif + +#if defined(TRIO_FUNC_SUBSTRING) +TRIO_PUBLIC_STRING char * +trio_substring +TRIO_PROTO((TRIO_CONST char *string, TRIO_CONST char *substring)); +#endif + +#if defined(TRIO_FUNC_SUBSTRING_MAX) +TRIO_PUBLIC_STRING char * +trio_substring_max +TRIO_PROTO((TRIO_CONST char *string, size_t max, TRIO_CONST char *substring)); +#endif + +#if defined(TRIO_FUNC_TO_DOUBLE) +TRIO_PUBLIC_STRING double +trio_to_double +TRIO_PROTO((TRIO_CONST char *source, char **endp)); +#endif + +#if defined(TRIO_FUNC_TO_FLOAT) +TRIO_PUBLIC_STRING float +trio_to_float +TRIO_PROTO((TRIO_CONST char *source, char **endp)); +#endif + +#if defined(TRIO_FUNC_TO_LONG) +TRIO_PUBLIC_STRING long +trio_to_long +TRIO_PROTO((TRIO_CONST char *source, char **endp, int base)); +#endif + +#if defined(TRIO_FUNC_TO_LOWER) +TRIO_PUBLIC_STRING int +trio_to_lower +TRIO_PROTO((int source)); +#endif + +#if defined(TRIO_FUNC_TO_LONG_DOUBLE) +TRIO_PUBLIC_STRING trio_long_double_t +trio_to_long_double +TRIO_PROTO((TRIO_CONST char *source, char **endp)); +#endif + +#if defined(TRIO_FUNC_TO_UNSIGNED_LONG) +TRIO_PUBLIC_STRING unsigned long +trio_to_unsigned_long +TRIO_PROTO((TRIO_CONST char *source, char **endp, int base)); +#endif + +#if defined(TRIO_FUNC_TO_UPPER) +TRIO_PUBLIC_STRING int +trio_to_upper +TRIO_PROTO((int source)); +#endif + +#if defined(TRIO_FUNC_TOKENIZE) +TRIO_PUBLIC_STRING char * +trio_tokenize +TRIO_PROTO((char *string, TRIO_CONST char *delimiters)); +#endif + +#if defined(TRIO_FUNC_UPPER) +TRIO_PUBLIC_STRING int +trio_upper +TRIO_PROTO((char *target)); +#endif + +/************************************************************************* + * Dynamic string functions + */ + +/* + * Opaque type for dynamic strings + */ + +typedef struct _trio_string_t trio_string_t; + +#if defined(TRIO_FUNC_STRING_APPEND) +TRIO_PUBLIC_STRING int +trio_string_append +TRIO_PROTO((trio_string_t *self, trio_string_t *other)); +#endif + +#if defined(TRIO_FUNC_STRING_CONTAINS) +TRIO_PUBLIC_STRING int +trio_string_contains +TRIO_PROTO((trio_string_t *self, trio_string_t *other)); +#endif + +#if defined(TRIO_FUNC_STRING_COPY) +TRIO_PUBLIC_STRING int +trio_string_copy +TRIO_PROTO((trio_string_t *self, trio_string_t *other)); +#endif + +#if defined(TRIO_FUNC_STRING_CREATE) +TRIO_PUBLIC_STRING trio_string_t * +trio_string_create +TRIO_PROTO((int initial_size)); +#endif + +#if defined(TRIO_FUNC_STRING_DESTROY) +TRIO_PUBLIC_STRING void +trio_string_destroy +TRIO_PROTO((trio_string_t *self)); +#endif + +#if defined(TRIO_FUNC_STRING_DUPLICATE) +TRIO_PUBLIC_STRING trio_string_t * +trio_string_duplicate +TRIO_PROTO((trio_string_t *other)); +#endif + +#if defined(TRIO_FUNC_STRING_EQUAL) +TRIO_PUBLIC_STRING int +trio_string_equal +TRIO_PROTO((trio_string_t *self, trio_string_t *other)); +#endif + +#if defined(TRIO_FUNC_STRING_EQUAL_MAX) +TRIO_PUBLIC_STRING int +trio_string_equal_max +TRIO_PROTO((trio_string_t *self, size_t max, trio_string_t *second)); +#endif + +#if defined(TRIO_FUNC_STRING_EQUAL_CASE) +TRIO_PUBLIC_STRING int +trio_string_equal_case +TRIO_PROTO((trio_string_t *self, trio_string_t *other)); +#endif + +#if defined(TRIO_FUNC_STRING_EQUAL_CASE_MAX) +TRIO_PUBLIC_STRING int +trio_string_equal_case_max +TRIO_PROTO((trio_string_t *self, size_t max, trio_string_t *other)); +#endif + +#if defined(TRIO_FUNC_STRING_EXTRACT) +TRIO_PUBLIC_STRING char * +trio_string_extract +TRIO_PROTO((trio_string_t *self)); +#endif + +#if defined(TRIO_FUNC_STRING_FORMAT_DATE_MAX) +TRIO_PUBLIC_STRING size_t +trio_string_format_date_max +TRIO_PROTO((trio_string_t *self, size_t max, TRIO_CONST char *format, TRIO_CONST struct tm *datetime)); +#endif + +#if defined(TRIO_FUNC_STRING_GET) +TRIO_PUBLIC_STRING char * +trio_string_get +TRIO_PROTO((trio_string_t *self, int offset)); +#endif + +#if defined(TRIO_FUNC_STRING_INDEX) +TRIO_PUBLIC_STRING char * +trio_string_index +TRIO_PROTO((trio_string_t *self, int character)); +#endif + +#if defined(TRIO_FUNC_STRING_INDEX_LAST) +TRIO_PUBLIC_STRING char * +trio_string_index_last +TRIO_PROTO((trio_string_t *self, int character)); +#endif + +#if defined(TRIO_FUNC_STRING_LENGTH) +TRIO_PUBLIC_STRING int +trio_string_length +TRIO_PROTO((trio_string_t *self)); +#endif + +#if defined(TRIO_FUNC_STRING_LOWER) +TRIO_PUBLIC_STRING int +trio_string_lower +TRIO_PROTO((trio_string_t *self)); +#endif + +#if defined(TRIO_FUNC_STRING_MATCH) +TRIO_PUBLIC_STRING int +trio_string_match +TRIO_PROTO((trio_string_t *self, trio_string_t *other)); +#endif + +#if defined(TRIO_FUNC_STRING_MATCH_CASE) +TRIO_PUBLIC_STRING int +trio_string_match_case +TRIO_PROTO((trio_string_t *self, trio_string_t *other)); +#endif + +#if defined(TRIO_FUNC_STRING_SIZE) +TRIO_PUBLIC_STRING int +trio_string_size +TRIO_PROTO((trio_string_t *self)); +#endif + +#if defined(TRIO_FUNC_STRING_SUBSTRING) +TRIO_PUBLIC_STRING char * +trio_string_substring +TRIO_PROTO((trio_string_t *self, trio_string_t *other)); +#endif + +#if defined(TRIO_FUNC_STRING_TERMINATE) +TRIO_PUBLIC_STRING void +trio_string_terminate +TRIO_PROTO((trio_string_t *self)); +#endif + +#if defined(TRIO_FUNC_STRING_UPPER) +TRIO_PUBLIC_STRING int +trio_string_upper +TRIO_PROTO((trio_string_t *self)); +#endif + +#if defined(TRIO_FUNC_XSTRING_APPEND) +TRIO_PUBLIC_STRING int +trio_xstring_append +TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other)); +#endif + +#if defined(TRIO_FUNC_XSTRING_APPEND_CHAR) +TRIO_PUBLIC_STRING int +trio_xstring_append_char +TRIO_PROTO((trio_string_t *self, char character)); +#endif + +#if defined(TRIO_FUNC_XSTRING_APPEND_MAX) +TRIO_PUBLIC_STRING int +trio_xstring_append_max +TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other, size_t max)); +#endif + +#if defined(TRIO_FUNC_XSTRING_CONTAINS) +TRIO_PUBLIC_STRING int +trio_xstring_contains +TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other)); +#endif + +#if defined(TRIO_FUNC_XSTRING_COPY) +TRIO_PUBLIC_STRING int +trio_xstring_copy +TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other)); +#endif + +#if defined(TRIO_FUNC_XSTRING_DUPLICATE) +TRIO_PUBLIC_STRING trio_string_t * +trio_xstring_duplicate +TRIO_PROTO((TRIO_CONST char *other)); +#endif + +#if defined(TRIO_FUNC_XSTRING_EQUAL) +TRIO_PUBLIC_STRING int +trio_xstring_equal +TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other)); +#endif + +#if defined(TRIO_FUNC_XSTRING_EQUAL_MAX) +TRIO_PUBLIC_STRING int +trio_xstring_equal_max +TRIO_PROTO((trio_string_t *self, size_t max, TRIO_CONST char *other)); +#endif + +#if defined(TRIO_FUNC_XSTRING_EQUAL_CASE) +TRIO_PUBLIC_STRING int +trio_xstring_equal_case +TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other)); +#endif + +#if defined(TRIO_FUNC_XSTRING_EQUAL_CASE_MAX) +TRIO_PUBLIC_STRING int +trio_xstring_equal_case_max +TRIO_PROTO((trio_string_t *self, size_t max, TRIO_CONST char *other)); +#endif + +#if defined(TRIO_FUNC_XSTRING_MATCH) +TRIO_PUBLIC_STRING int +trio_xstring_match +TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other)); +#endif + +#if defined(TRIO_FUNC_XSTRING_MATCH_CASE) +TRIO_PUBLIC_STRING int +trio_xstring_match_case +TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other)); +#endif + +#if defined(TRIO_FUNC_XSTRING_SET) +TRIO_PUBLIC_STRING void +trio_xstring_set +TRIO_PROTO((trio_string_t *self, char *buffer)); +#endif + +#if defined(TRIO_FUNC_XSTRING_SUBSTRING) +TRIO_PUBLIC_STRING char * +trio_xstring_substring +TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other)); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* TRIO_TRIOSTR_H */ diff --git a/src/trio-sscanf/Makefile.am b/src/trio-sscanf/Makefile.am index 7b4c3160..d2e2d5b2 100644 --- a/src/trio-sscanf/Makefile.am +++ b/src/trio-sscanf/Makefile.am @@ -36,7 +36,8 @@ libtrio_sscanf_la_SOURCES = trio.c trio.h trio_test.c triostr.c triostr.h \ trio_sscanf_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libtrio-sscanf.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) libtrio_sscanf_la_CPPFLAGS = -DTRIO_SSCANF -DTRIO_EXTENSION=0 \ -DTRIO_DEPRECATED=0 -DTRIO_MICROSOFT=0 \ -DTRIO_ERRORS=0 -DTRIO_FEATURE_FLOAT=0 \ diff --git a/src/trio-sscanf/Makefile.in b/src/trio-sscanf/Makefile.in index 68fb2fc9..5c0c9e89 100644 --- a/src/trio-sscanf/Makefile.in +++ b/src/trio-sscanf/Makefile.in @@ -176,6 +176,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_TRIO_SSCANF_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_TRIO_SSCANF_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_TRIO_SSCANF_TRUE@ libtrio-sscanf.la \ +@ENABLED_BENCHMARK_TRIO_SSCANF_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_TRIO_SSCANF_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_TRIO_SSCANF_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_TRIO_SSCANF_TRUE@ $(am__DEPENDENCIES_1) @@ -401,7 +402,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_TRIO_SSCANF_TRUE@trio_sscanf_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_TRIO_SSCANF_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_TRIO_SSCANF_TRUE@ libtrio-sscanf.la \ -@ENABLED_BENCHMARK_TRIO_SSCANF_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_TRIO_SSCANF_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_TRIO_SSCANF_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) @ENABLED_BENCHMARK_TRIO_SSCANF_TRUE@libtrio_sscanf_la_CPPFLAGS = -DTRIO_SSCANF -DTRIO_EXTENSION=0 \ @ENABLED_BENCHMARK_TRIO_SSCANF_TRUE@ -DTRIO_DEPRECATED=0 -DTRIO_MICROSOFT=0 \ diff --git a/src/trio-sscanf/trio.c b/src/trio-sscanf/trio.c deleted file mode 120000 index c8308b41..00000000 --- a/src/trio-sscanf/trio.c +++ /dev/null @@ -1 +0,0 @@ -../trio/trio.c \ No newline at end of file diff --git a/src/trio-sscanf/trio.c b/src/trio-sscanf/trio.c new file mode 100644 index 00000000..b8837707 --- /dev/null +++ b/src/trio-sscanf/trio.c @@ -0,0 +1,7758 @@ +/* BEEBS trio benchmark + + Copyright (C) 2014 Embecosm Limited and University of Bristol + + This file is part of the Bristol/Embecosm Embedded Benchmark Suite. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* The original source of this file was from: + * http://daniel.haxx.se/projects/trio/ + * and is covered by the following copyright and licence: + * + * Copyright (C) 1998, 2009 Bjorn Reese and Daniel Stenberg. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND + * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. + * + ************************************************************************* + * + * A note to trio contributors: + * + * Avoid heap allocation at all costs to ensure that the trio functions + * are async-safe. The exceptions are the printf/fprintf functions, which + * uses fputc, and the asprintf functions and the modifier, which + * by design are required to allocate form the heap. + * + ************************************************************************/ + +/* + * TODO: + * - Scan is probably too permissive about its modifiers. + * - C escapes in %#[] ? + * - Multibyte characters (done for format parsing, except scan groups) + * - Complex numbers? (C99 _Complex) + * - Boolean values? (C99 _Bool) + * - C99 NaN(n-char-sequence) missing. The n-char-sequence can be used + * to print the mantissa, e.g. NaN(0xc000000000000000) + * - Should we support the GNU %a alloc modifier? GNU has an ugly hack + * for %a, because C99 used %a for other purposes. If specified as + * %as or %a[ it is interpreted as the alloc modifier, otherwise as + * the C99 hex-float. This means that you cannot scan %as as a hex-float + * immediately followed by an 's'. + * - Scanning of collating symbols. + */ + +/************************************************************************* + * Trio include files + */ +#include "triodef.h" +#include "trio.h" +#include "triop.h" + +#if defined(TRIO_EMBED_NAN) +# define TRIO_PUBLIC_NAN static +# if TRIO_FEATURE_FLOAT +# define TRIO_FUNC_NAN +# define TRIO_FUNC_NINF +# define TRIO_FUNC_PINF +# define TRIO_FUNC_FPCLASSIFY_AND_SIGNBIT +# define TRIO_FUNC_ISINF +# endif +#endif + +#if defined(TRIO_EMBED_STRING) +# define TRIO_PUBLIC_STRING static +# define TRIO_FUNC_LENGTH +# define TRIO_FUNC_LENGTH_MAX +# define TRIO_FUNC_TO_LONG +# if TRIO_FEATURE_LOCALE +# define TRIO_FUNC_COPY_MAX +# endif +# if TRIO_FEATURE_DYNAMICSTRING +# define TRIO_FUNC_XSTRING_DUPLICATE +# endif +# if TRIO_EXTENSION && TRIO_FEATURE_SCANF +# define TRIO_FUNC_EQUAL_LOCALE +# endif +# if TRIO_FEATURE_ERRNO +# define TRIO_FUNC_ERROR +# endif +# if TRIO_FEATURE_FLOAT && TRIO_FEATURE_SCANF +# define TRIO_FUNC_TO_DOUBLE +# endif +# if TRIO_FEATURE_DYNAMICSTRING +# define TRIO_FUNC_STRING_EXTRACT +# endif +# if TRIO_FEATURE_DYNAMICSTRING +# define TRIO_FUNC_STRING_TERMINATE +# endif +# if TRIO_FEATURE_USER_DEFINED +# define TRIO_FUNC_DUPLICATE +# endif +# if TRIO_FEATURE_DYNAMICSTRING +# define TRIO_FUNC_STRING_DESTROY +# endif +# if TRIO_FEATURE_USER_DEFINED +# define TRIO_FUNC_DESTROY +# endif +# if TRIO_FEATURE_USER_DEFINED || (TRIO_FEATURE_FLOAT && TRIO_FEATURE_SCANF) +# define TRIO_FUNC_EQUAL +# endif +# if TRIO_FEATURE_USER_DEFINED || TRIO_FEATURE_SCANF +# define TRIO_FUNC_EQUAL_CASE +# endif +# if (TRIO_EXTENSION && TRIO_FEATURE_SCANF) +# define TRIO_FUNC_EQUAL_MAX +# endif +# if TRIO_FEATURE_SCANF +# define TRIO_FUNC_TO_UPPER +# endif +# if TRIO_FEATURE_DYNAMICSTRING +# define TRIO_FUNC_XSTRING_APPEND_CHAR +# endif +#endif +#include "triostr.h" + +/************************************************************************** + * + * Definitions + * + *************************************************************************/ + +#include +#if TRIO_FEATURE_FLOAT +# include +# include +#endif + +#if defined(__STDC_ISO_10646__) || defined(MB_LEN_MAX) || defined(USE_MULTIBYTE) || TRIO_FEATURE_WIDECHAR +# if !defined(TRIO_PLATFORM_WINCE) +# define TRIO_COMPILER_SUPPORTS_MULTIBYTE +# if !defined(MB_LEN_MAX) +# define MB_LEN_MAX 6 +# endif +# endif +#endif + +#if (TRIO_COMPILER_VISUALC - 0 >= 1100) || defined(TRIO_COMPILER_BORLAND) +# define TRIO_COMPILER_SUPPORTS_VISUALC_INT +#endif + +#if TRIO_FEATURE_FLOAT +# if defined(PREDEF_STANDARD_C99) \ + || defined(PREDEF_STANDARD_UNIX03) +# if !defined(HAVE_FLOORL) && !defined(TRIO_NO_FLOORL) +# define HAVE_FLOORL +# endif +# if !defined(HAVE_CEILL) && !defined(TRIO_NO_CEILL) +# define HAVE_CEILL +# endif +# if !defined(HAVE_POWL) && !defined(TRIO_NO_POWL) +# define HAVE_POWL +# endif +# if !defined(HAVE_FMODL) && !defined(TRIO_NO_FMODL) +# define HAVE_FMODL +# endif +# if !defined(HAVE_LOG10L) && !defined(TRIO_NO_LOG10L) +# define HAVE_LOG10L +# endif +# endif +# if defined(TRIO_COMPILER_VISUALC) +# if defined(floorl) +# define HAVE_FLOORL +# endif +# if defined(ceill) +# define HAVE_CEILL +# endif +# if defined(powl) +# define HAVE_POWL +# endif +# if defined(fmodl) +# define HAVE_FMODL +# endif +# if defined(log10l) +# define HAVE_LOG10L +# endif +# endif +#endif + +/************************************************************************* + * Generic definitions + */ + +#if !(defined(DEBUG) || defined(NDEBUG)) +# define NDEBUG +#endif + +#include +#include +#if defined(PREDEF_STANDARD_C99) && !defined(isascii) +# define isascii(x) ((x) & 0x7F) +#endif +#if defined(TRIO_COMPILER_ANCIENT) +# include +#else +# include +#endif +#include +#if defined(TRIO_PLATFORM_WINCE) +extern int errno; +#else +# include +#endif + +#ifndef NULL +# define NULL 0 +#endif +#define NIL ((char)0) +#ifndef FALSE +# define FALSE (1 == 0) +# define TRUE (! FALSE) +#endif +#define BOOLEAN_T int + +/* mincore() can be used for debugging purposes */ +#define VALID(x) (NULL != (x)) + +#if TRIO_FEATURE_ERRORCODE + /* + * Encode the error code and the position. This is decoded + * with TRIO_ERROR_CODE and TRIO_ERROR_POSITION. + */ +# define TRIO_ERROR_RETURN(x,y) (- ((x) + ((y) << 8))) +#else +# define TRIO_ERROR_RETURN(x,y) (-1) +#endif + +typedef unsigned long trio_flags_t; + + +/************************************************************************* + * Platform specific definitions + */ +#if defined(TRIO_PLATFORM_UNIX) +# include +# include +# include +# if !defined(TRIO_FEATURE_LOCALE) +# define USE_LOCALE +# endif +#endif /* TRIO_PLATFORM_UNIX */ +#if defined(TRIO_PLATFORM_VMS) +# include +#endif +#if defined(TRIO_PLATFORM_WIN32) +# if defined(TRIO_PLATFORM_WINCE) +int read(int handle, char *buffer, unsigned int length); +int write(int handle, const char *buffer, unsigned int length); +# else +# include +# define read _read +# define write _write +# endif +#endif /* TRIO_PLATFORM_WIN32 */ + +#if TRIO_FEATURE_WIDECHAR +# if defined(PREDEF_STANDARD_C94) +# include +# include +typedef wchar_t trio_wchar_t; +typedef wint_t trio_wint_t; +# else +typedef char trio_wchar_t; +typedef int trio_wint_t; +# define WCONST(x) L ## x +# define WEOF EOF +# define iswalnum(x) isalnum(x) +# define iswalpha(x) isalpha(x) +# define iswcntrl(x) iscntrl(x) +# define iswdigit(x) isdigit(x) +# define iswgraph(x) isgraph(x) +# define iswlower(x) islower(x) +# define iswprint(x) isprint(x) +# define iswpunct(x) ispunct(x) +# define iswspace(x) isspace(x) +# define iswupper(x) isupper(x) +# define iswxdigit(x) isxdigit(x) +# endif +#endif + + +/************************************************************************* + * Compiler dependent definitions + */ + +/* Support for long long */ +#ifndef __cplusplus +# if !defined(USE_LONGLONG) +# if defined(TRIO_COMPILER_GCC) && !defined(__STRICT_ANSI__) +# define USE_LONGLONG +# else +# if defined(TRIO_COMPILER_SUNPRO) +# define USE_LONGLONG +# else +# if defined(TRIO_COMPILER_MSVC) && (_MSC_VER >= 1400) +# define USE_LONGLONG +# else +# if defined(_LONG_LONG) || defined(_LONGLONG) +# define USE_LONGLONG +# endif +# endif +# endif +# endif +# endif +#endif + +/* The extra long numbers */ +#if defined(USE_LONGLONG) +typedef signed long long int trio_longlong_t; +typedef unsigned long long int trio_ulonglong_t; +#else +# if defined(TRIO_COMPILER_SUPPORTS_VISUALC_INT) +typedef signed __int64 trio_longlong_t; +typedef unsigned __int64 trio_ulonglong_t; +# else +typedef TRIO_SIGNED long int trio_longlong_t; +typedef unsigned long int trio_ulonglong_t; +# endif +#endif + +/* Maximal and fixed integer types */ +#if defined(PREDEF_STANDARD_C99) +# include +typedef intmax_t trio_intmax_t; +typedef uintmax_t trio_uintmax_t; +typedef int8_t trio_int8_t; +typedef int16_t trio_int16_t; +typedef int32_t trio_int32_t; +typedef int64_t trio_int64_t; +#else +# if defined(PREDEF_STANDARD_UNIX98) +# include +typedef intmax_t trio_intmax_t; +typedef uintmax_t trio_uintmax_t; +typedef int8_t trio_int8_t; +typedef int16_t trio_int16_t; +typedef int32_t trio_int32_t; +typedef int64_t trio_int64_t; +# else +# if defined(TRIO_COMPILER_SUPPORTS_VISUALC_INT) +typedef trio_longlong_t trio_intmax_t; +typedef trio_ulonglong_t trio_uintmax_t; +typedef __int8 trio_int8_t; +typedef __int16 trio_int16_t; +typedef __int32 trio_int32_t; +typedef __int64 trio_int64_t; +# else +typedef trio_longlong_t trio_intmax_t; +typedef trio_ulonglong_t trio_uintmax_t; +# if defined(TRIO_INT8_T) +typedef TRIO_INT8_T trio_int8_t; +# else +typedef TRIO_SIGNED char trio_int8_t; +# endif +# if defined(TRIO_INT16_T) +typedef TRIO_INT16_T trio_int16_t; +# else +typedef TRIO_SIGNED short trio_int16_t; +# endif +# if defined(TRIO_INT32_T) +typedef TRIO_INT32_T trio_int32_t; +# else +typedef TRIO_SIGNED int trio_int32_t; +# endif +# if defined(TRIO_INT64_T) +typedef TRIO_INT64_T trio_int64_t; +# else +typedef trio_longlong_t trio_int64_t; +# endif +# endif +# endif +#endif + +#if defined(HAVE_FLOORL) +# define trio_floor(x) floorl((x)) +#else +# define trio_floor(x) floor((double)(x)) +#endif + +#if defined(HAVE_CEILL) +# define trio_ceil(x) ceill((x)) +#else +# define trio_ceil(x) ceil((double)(x)) +#endif + +#if defined(HAVE_FMODL) +# define trio_fmod(x,y) fmodl((x),(y)) +#else +# define trio_fmod(x,y) fmod((double)(x),(double)(y)) +#endif + +#if defined(HAVE_POWL) +# define trio_pow(x,y) powl((x),(y)) +#else +# define trio_pow(x,y) pow((double)(x),(double)(y)) +#endif + +#if defined(HAVE_LOG10L) +# define trio_log10(x) log10l((x)) +#else +# define trio_log10(x) log10((double)(x)) +#endif + +#if TRIO_FEATURE_FLOAT +# define TRIO_FABS(x) (((x) < 0.0) ? -(x) : (x)) +#endif + +/************************************************************************* + * Internal Definitions + */ + +#if TRIO_FEATURE_FLOAT + +# if !defined(DECIMAL_DIG) +# define DECIMAL_DIG DBL_DIG +# endif + +/* Long double sizes */ +# ifdef LDBL_DIG +# define MAX_MANTISSA_DIGITS LDBL_DIG +# define MAX_EXPONENT_DIGITS 4 +# define MAX_DOUBLE_DIGITS LDBL_MAX_10_EXP +# else +# define MAX_MANTISSA_DIGITS DECIMAL_DIG +# define MAX_EXPONENT_DIGITS 3 +# define MAX_DOUBLE_DIGITS DBL_MAX_10_EXP +# endif + +# if defined(TRIO_COMPILER_ANCIENT) || !defined(LDBL_DIG) +# undef LDBL_DIG +# undef LDBL_MANT_DIG +# undef LDBL_EPSILON +# define LDBL_DIG DBL_DIG +# define LDBL_MANT_DIG DBL_MANT_DIG +# define LDBL_EPSILON DBL_EPSILON +# endif + +#endif /* TRIO_FEATURE_FLOAT */ + +/* The maximal number of digits is for base 2 */ +#define MAX_CHARS_IN(x) (sizeof(x) * CHAR_BIT) +/* The width of a pointer. The number of bits in a hex digit is 4 */ +#define POINTER_WIDTH ((sizeof("0x") - 1) + sizeof(trio_pointer_t) * CHAR_BIT / 4) + +#if TRIO_FEATURE_FLOAT +/* Infinite and Not-A-Number for floating-point */ +# define INFINITE_LOWER "inf" +# define INFINITE_UPPER "INF" +# define LONG_INFINITE_LOWER "infinite" +# define LONG_INFINITE_UPPER "INFINITE" +# define NAN_LOWER "nan" +# define NAN_UPPER "NAN" +#endif + +/* Various constants */ +enum { + TYPE_PRINT = 1, +#if TRIO_FEATURE_SCANF + TYPE_SCAN = 2, +#endif + + /* Flags. FLAGS_LAST must be less than ULONG_MAX */ + FLAGS_NEW = 0, + FLAGS_STICKY = 1, + FLAGS_SPACE = 2 * FLAGS_STICKY, + FLAGS_SHOWSIGN = 2 * FLAGS_SPACE, + FLAGS_LEFTADJUST = 2 * FLAGS_SHOWSIGN, + FLAGS_ALTERNATIVE = 2 * FLAGS_LEFTADJUST, + FLAGS_SHORT = 2 * FLAGS_ALTERNATIVE, + FLAGS_SHORTSHORT = 2 * FLAGS_SHORT, + FLAGS_LONG = 2 * FLAGS_SHORTSHORT, + FLAGS_QUAD = 2 * FLAGS_LONG, + FLAGS_LONGDOUBLE = 2 * FLAGS_QUAD, + FLAGS_SIZE_T = 2 * FLAGS_LONGDOUBLE, + FLAGS_PTRDIFF_T = 2 * FLAGS_SIZE_T, + FLAGS_INTMAX_T = 2 * FLAGS_PTRDIFF_T, + FLAGS_NILPADDING = 2 * FLAGS_INTMAX_T, + FLAGS_UNSIGNED = 2 * FLAGS_NILPADDING, + FLAGS_UPPER = 2UL * FLAGS_UNSIGNED, + FLAGS_WIDTH = 2 * FLAGS_UPPER, + FLAGS_WIDTH_PARAMETER = 2 * FLAGS_WIDTH, + FLAGS_PRECISION = 2 * FLAGS_WIDTH_PARAMETER, + FLAGS_PRECISION_PARAMETER = 2 * FLAGS_PRECISION, + FLAGS_BASE = 2 * FLAGS_PRECISION_PARAMETER, + FLAGS_BASE_PARAMETER = 2 * FLAGS_BASE, + FLAGS_FLOAT_E = 2 * FLAGS_BASE_PARAMETER, + FLAGS_FLOAT_G = 2 * FLAGS_FLOAT_E, + FLAGS_QUOTE = 2 * FLAGS_FLOAT_G, + FLAGS_WIDECHAR = 2 * FLAGS_QUOTE, + FLAGS_IGNORE = 2 * FLAGS_WIDECHAR, + FLAGS_IGNORE_PARAMETER = 2 * FLAGS_IGNORE, + FLAGS_VARSIZE_PARAMETER = 2 * FLAGS_IGNORE_PARAMETER, + FLAGS_FIXED_SIZE = 2 * FLAGS_VARSIZE_PARAMETER, + FLAGS_LAST = FLAGS_FIXED_SIZE, + /* Reused flags */ + FLAGS_EXCLUDE = FLAGS_SHORT, + FLAGS_USER_DEFINED = FLAGS_IGNORE, + FLAGS_USER_DEFINED_PARAMETER = FLAGS_IGNORE_PARAMETER, + FLAGS_ROUNDING = FLAGS_INTMAX_T, + /* Compounded flags */ + FLAGS_ALL_VARSIZES = FLAGS_LONG | FLAGS_QUAD | FLAGS_INTMAX_T | FLAGS_PTRDIFF_T | FLAGS_SIZE_T, + FLAGS_ALL_SIZES = FLAGS_ALL_VARSIZES | FLAGS_SHORTSHORT | FLAGS_SHORT, + + NO_POSITION = -1, + NO_WIDTH = 0, + NO_PRECISION = -1, + NO_SIZE = -1, + + /* Do not change these */ + NO_BASE = -1, + MIN_BASE = 2, + MAX_BASE = 36, + BASE_BINARY = 2, + BASE_OCTAL = 8, + BASE_DECIMAL = 10, + BASE_HEX = 16, + + /* Maximal number of allowed parameters */ + MAX_PARAMETERS = 64, + /* Maximal number of characters in class */ + MAX_CHARACTER_CLASS = UCHAR_MAX + 1, + +#if TRIO_FEATURE_USER_DEFINED + /* Maximal string lengths for user-defined specifiers */ + MAX_USER_NAME = 64, + MAX_USER_DATA = 256, +#endif + + /* Maximal length of locale separator strings */ + MAX_LOCALE_SEPARATOR_LENGTH = MB_LEN_MAX, + /* Maximal number of integers in grouping */ + MAX_LOCALE_GROUPS = 64 +}; + +#define NO_GROUPING ((int)CHAR_MAX) + +/* Fundamental formatting parameter types */ +#define FORMAT_SENTINEL -1 /* marks end of parameters array */ +#define FORMAT_UNKNOWN 0 +#define FORMAT_INT 1 +#define FORMAT_DOUBLE 2 +#define FORMAT_CHAR 3 +#define FORMAT_STRING 4 +#define FORMAT_POINTER 5 +#define FORMAT_COUNT 6 +#define FORMAT_PARAMETER 7 +#define FORMAT_GROUP 8 +#define FORMAT_ERRNO 9 +#define FORMAT_USER_DEFINED 10 + +/* Character constants */ +#define CHAR_IDENTIFIER '%' +#define CHAR_ALT_IDENTIFIER '$' +#define CHAR_BACKSLASH '\\' +#define CHAR_QUOTE '\"' +#define CHAR_ADJUST ' ' + +#if TRIO_EXTENSION +/* Character class expressions */ +# define CLASS_ALNUM "[:alnum:]" +# define CLASS_ALPHA "[:alpha:]" +# define CLASS_BLANK "[:blank:]" +# define CLASS_CNTRL "[:cntrl:]" +# define CLASS_DIGIT "[:digit:]" +# define CLASS_GRAPH "[:graph:]" +# define CLASS_LOWER "[:lower:]" +# define CLASS_PRINT "[:print:]" +# define CLASS_PUNCT "[:punct:]" +# define CLASS_SPACE "[:space:]" +# define CLASS_UPPER "[:upper:]" +# define CLASS_XDIGIT "[:xdigit:]" +#endif + +/* + * SPECIFIERS: + * + * + * a Hex-float + * A Hex-float + * c Character + * C Widechar character (wint_t) + * d Decimal + * e Float + * E Float + * F Float + * F Float + * g Float + * G Float + * i Integer + * m Error message + * n Count + * o Octal + * p Pointer + * s String + * S Widechar string (wchar_t *) + * u Unsigned + * x Hex + * X Hex + * [] Group + * <> User-defined + * + * Reserved: + * + * D Binary Coded Decimal %D(length,precision) (OS/390) + */ +#define SPECIFIER_CHAR 'c' +#define SPECIFIER_STRING 's' +#define SPECIFIER_DECIMAL 'd' +#define SPECIFIER_INTEGER 'i' +#define SPECIFIER_UNSIGNED 'u' +#define SPECIFIER_OCTAL 'o' +#define SPECIFIER_HEX 'x' +#define SPECIFIER_HEX_UPPER 'X' +#if TRIO_FEATURE_FLOAT +# define SPECIFIER_FLOAT_E 'e' +# define SPECIFIER_FLOAT_E_UPPER 'E' +# define SPECIFIER_FLOAT_F 'f' +# define SPECIFIER_FLOAT_F_UPPER 'F' +# define SPECIFIER_FLOAT_G 'g' +# define SPECIFIER_FLOAT_G_UPPER 'G' +#endif +#define SPECIFIER_POINTER 'p' +#if TRIO_FEATURE_SCANF +# define SPECIFIER_GROUP '[' +# define SPECIFIER_UNGROUP ']' +#endif +#define SPECIFIER_COUNT 'n' +#if TRIO_UNIX98 +# define SPECIFIER_CHAR_UPPER 'C' +# define SPECIFIER_STRING_UPPER 'S' +#endif +#define SPECIFIER_HEXFLOAT 'a' +#define SPECIFIER_HEXFLOAT_UPPER 'A' +#define SPECIFIER_ERRNO 'm' +#if TRIO_FEATURE_BINARY +# define SPECIFIER_BINARY 'b' +# define SPECIFIER_BINARY_UPPER 'B' +#endif +#if TRIO_FEATURE_USER_DEFINED +# define SPECIFIER_USER_DEFINED_BEGIN '<' +# define SPECIFIER_USER_DEFINED_END '>' +# define SPECIFIER_USER_DEFINED_SEPARATOR ':' +# define SPECIFIER_USER_DEFINED_EXTRA '|' +#endif + +/* + * QUALIFIERS: + * + * + * Numbers = d,i,o,u,x,X + * Float = a,A,e,E,f,F,g,G + * String = s + * Char = c + * + * + * 9$ Position + * Use the 9th parameter. 9 can be any number between 1 and + * the maximal argument + * + * 9 Width + * Set width to 9. 9 can be any number, but must not be postfixed + * by '$' + * + * h Short + * Numbers: + * (unsigned) short int + * + * hh Short short + * Numbers: + * (unsigned) char + * + * l Long + * Numbers: + * (unsigned) long int + * String: + * as the S specifier + * Char: + * as the C specifier + * + * ll Long Long + * Numbers: + * (unsigned) long long int + * + * L Long Double + * Float + * long double + * + * # Alternative + * Float: + * Decimal-point is always present + * String: + * non-printable characters are handled as \number + * + * Spacing + * + * + Sign + * + * - Alignment + * + * . Precision + * + * * Parameter + * print: use parameter + * scan: no parameter (ignore) + * + * q Quad + * + * Z size_t + * + * w Widechar + * + * ' Thousands/quote + * Numbers: + * Integer part grouped in thousands + * Binary numbers: + * Number grouped in nibbles (4 bits) + * String: + * Quoted string + * + * j intmax_t + * t prtdiff_t + * z size_t + * + * ! Sticky + * @ Parameter (for both print and scan) + * + * I n-bit Integer + * Numbers: + * The following options exists + * I8 = 8-bit integer + * I16 = 16-bit integer + * I32 = 32-bit integer + * I64 = 64-bit integer + */ +#define QUALIFIER_POSITION '$' +#define QUALIFIER_SHORT 'h' +#define QUALIFIER_LONG 'l' +#define QUALIFIER_LONG_UPPER 'L' +#define QUALIFIER_ALTERNATIVE '#' +#define QUALIFIER_SPACE ' ' +#define QUALIFIER_PLUS '+' +#define QUALIFIER_MINUS '-' +#define QUALIFIER_DOT '.' +#define QUALIFIER_STAR '*' +#define QUALIFIER_CIRCUMFLEX '^' /* For scanlists */ +#define QUALIFIER_SIZE_T 'z' +#define QUALIFIER_PTRDIFF_T 't' +#define QUALIFIER_INTMAX_T 'j' +#define QUALIFIER_QUAD 'q' +#define QUALIFIER_SIZE_T_UPPER 'Z' +#if TRIO_MISC +# define QUALIFIER_WIDECHAR 'w' +#endif +#define QUALIFIER_FIXED_SIZE 'I' +#define QUALIFIER_QUOTE '\'' +#define QUALIFIER_STICKY '!' +#define QUALIFIER_VARSIZE '&' /* This should remain undocumented */ +#define QUALIFIER_ROUNDING_UPPER 'R' +#if TRIO_EXTENSION +# define QUALIFIER_PARAM '@' /* Experimental */ +# define QUALIFIER_COLON ':' /* For scanlists */ +# define QUALIFIER_EQUAL '=' /* For scanlists */ +#endif + + +/************************************************************************* + * + * Internal Structures + * + *************************************************************************/ + +/* Parameters */ +typedef struct { + /* An indication of which entry in the data union is used */ + int type; + /* The flags */ + trio_flags_t flags; + /* The width qualifier */ + int width; + /* The precision qualifier */ + int precision; + /* The base qualifier */ + int base; + /* Base from specifier */ + int baseSpecifier; + /* The size for the variable size qualifier */ + int varsize; + /* Offset of the first character of the specifier */ + int beginOffset; + /* Offset of the first character after the specifier */ + int endOffset; + /* Position in the argument list that this parameter refers to */ + int position; + /* The data from the argument list */ + union { + char *string; +#if TRIO_FEATURE_WIDECHAR + trio_wchar_t *wstring; +#endif + trio_pointer_t pointer; + union { + trio_intmax_t as_signed; + trio_uintmax_t as_unsigned; + } number; +#if TRIO_FEATURE_FLOAT + double doubleNumber; + double *doublePointer; + trio_long_double_t longdoubleNumber; + trio_long_double_t *longdoublePointer; +#endif + int errorNumber; + } data; +#if TRIO_FEATURE_USER_DEFINED + /* For the user-defined specifier */ + union { + char namespace[MAX_USER_NAME]; + int handler; /* if flags & FLAGS_USER_DEFINED_PARAMETER */ + } user_defined; + char user_data[MAX_USER_DATA]; +#endif +} trio_parameter_t; + +/* Container for customized functions */ +typedef struct { + union { + trio_outstream_t out; + trio_instream_t in; + } stream; + trio_pointer_t closure; +} trio_custom_t; + +/* General trio "class" */ +typedef struct _trio_class_t { + /* + * The function to write characters to a stream. + */ + void (*OutStream) TRIO_PROTO((struct _trio_class_t *, int)); + /* + * The function to read characters from a stream. + */ + void (*InStream) TRIO_PROTO((struct _trio_class_t *, int *)); + /* + * The function to undo read characters from a stream. + */ + void (*UndoStream) TRIO_PROTO((struct _trio_class_t *)); + /* + * The current location in the stream. + */ + trio_pointer_t location; + /* + * The character currently being processed. + */ + int current; + /* + * The number of characters that would have been written/read + * if there had been sufficient space. + */ + int processed; + union { + /* + * The number of characters that are actually written. Processed and + * committed will only differ for the *nprintf functions. + */ + int committed; + /* + * The number of look-ahead characters read. + */ + int cached; + } actually; + /* + * The upper limit of characters that may be written/read. + */ + int max; + /* + * The last output error that was detected. + */ + int error; +} trio_class_t; + +/* References (for user-defined callbacks) */ +typedef struct _trio_reference_t { + trio_class_t *data; + trio_parameter_t *parameter; +} trio_reference_t; + +#if TRIO_FEATURE_USER_DEFINED +/* Registered entries (for user-defined callbacks) */ +typedef struct _trio_userdef_t { + struct _trio_userdef_t *next; + trio_callback_t callback; + char *name; +} trio_userdef_t; +#endif + +/************************************************************************* + * + * Internal Variables + * + *************************************************************************/ + +#if TRIO_FEATURE_FLOAT +/* + * Need this to workaround a parser bug in HP C/iX compiler that fails + * to resolves macro definitions that includes type 'long double', + * e.g: va_arg(arg_ptr, long double) + */ +# if defined(TRIO_PLATFORM_MPEIX) +static TRIO_CONST trio_long_double_t ___dummy_long_double = 0; +# endif +#endif + +static TRIO_CONST char internalNullString[] = "(nil)"; + +#if defined(USE_LOCALE) +static struct lconv *internalLocaleValues = NULL; +#endif + +/* + * UNIX98 says "in a locale where the radix character is not defined, + * the radix character defaults to a period (.)" + */ +#if TRIO_FEATURE_FLOAT || TRIO_FEATURE_LOCALE || defined(USE_LOCALE) +static int internalDecimalPointLength = 1; +static char internalDecimalPoint = '.'; +static char internalDecimalPointString[MAX_LOCALE_SEPARATOR_LENGTH + 1] = "."; +#endif +#if TRIO_FEATURE_QUOTE || TRIO_FEATURE_LOCALE || TRIO_EXTENSION +static int internalThousandSeparatorLength = 1; +static char internalThousandSeparator[MAX_LOCALE_SEPARATOR_LENGTH + 1] = ","; +static char internalGrouping[MAX_LOCALE_GROUPS] = { (char)NO_GROUPING }; +#endif + +static TRIO_CONST char internalDigitsLower[] = "0123456789abcdefghijklmnopqrstuvwxyz"; +static TRIO_CONST char internalDigitsUpper[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; +#if TRIO_FEATURE_SCANF +static BOOLEAN_T internalDigitsUnconverted = TRUE; +static int internalDigitArray[128]; +# if TRIO_EXTENSION +static BOOLEAN_T internalCollationUnconverted = TRUE; +static char internalCollationArray[MAX_CHARACTER_CLASS][MAX_CHARACTER_CLASS]; +# endif +#endif + +#if TRIO_FEATURE_USER_DEFINED +static TRIO_VOLATILE trio_callback_t internalEnterCriticalRegion = NULL; +static TRIO_VOLATILE trio_callback_t internalLeaveCriticalRegion = NULL; +static trio_userdef_t *internalUserDef = NULL; +#endif + + +/************************************************************************* + * + * Internal Functions + * + ************************************************************************/ + +#if defined(TRIO_EMBED_STRING) +# include "triostr.c" +#endif + +/************************************************************************* + * TrioInitializeParameter + * + * Description: + * Initialize a trio_parameter_t struct. + */ +TRIO_PRIVATE void +TrioInitializeParameter +TRIO_ARGS1((parameter), + trio_parameter_t *parameter) +{ + parameter->type = FORMAT_UNKNOWN; + parameter->flags = 0; + parameter->width = 0; + parameter->precision = 0; + parameter->base = 0; + parameter->baseSpecifier = 0; + parameter->varsize = 0; + parameter->beginOffset = 0; + parameter->endOffset = 0; + parameter->position = 0; + parameter->data.pointer = 0; +#if TRIO_FEATURE_USER_DEFINED + parameter->user_defined.handler = 0; + parameter->user_data[0] = 0; +#endif +} + +/************************************************************************* + * TrioCopyParameter + * + * Description: + * Copies one trio_parameter_t struct to another. + */ +TRIO_PRIVATE void +TrioCopyParameter +TRIO_ARGS2((target, source), + trio_parameter_t *target, + TRIO_CONST trio_parameter_t *source) +{ +#if TRIO_FEATURE_USER_DEFINED + size_t i; +#endif + + target->type = source->type; + target->flags = source->flags; + target->width = source->width; + target->precision = source->precision; + target->base = source->base; + target->baseSpecifier = source->baseSpecifier; + target->varsize = source->varsize; + target->beginOffset = source->beginOffset; + target->endOffset = source->endOffset; + target->position = source->position; + target->data = source->data; + +#if TRIO_FEATURE_USER_DEFINED + target->user_defined = source->user_defined; + + for (i = 0U; i < sizeof(target->user_data); ++i) + { + if ((target->user_data[i] = source->user_data[i]) == NIL) + break; + } +#endif +} + +/************************************************************************* + * TrioIsQualifier + * + * Description: + * Remember to add all new qualifiers to this function. + * QUALIFIER_POSITION must not be added. + */ +TRIO_PRIVATE BOOLEAN_T +TrioIsQualifier +TRIO_ARGS1((character), + TRIO_CONST char character) +{ + /* QUALIFIER_POSITION is not included */ + switch (character) + { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + case QUALIFIER_PLUS: + case QUALIFIER_MINUS: + case QUALIFIER_SPACE: + case QUALIFIER_DOT: + case QUALIFIER_STAR: + case QUALIFIER_ALTERNATIVE: + case QUALIFIER_SHORT: + case QUALIFIER_LONG: + case QUALIFIER_CIRCUMFLEX: + case QUALIFIER_LONG_UPPER: + case QUALIFIER_SIZE_T: + case QUALIFIER_PTRDIFF_T: + case QUALIFIER_INTMAX_T: + case QUALIFIER_QUAD: + case QUALIFIER_SIZE_T_UPPER: +#if defined(QUALIFIER_WIDECHAR) + case QUALIFIER_WIDECHAR: +#endif + case QUALIFIER_QUOTE: + case QUALIFIER_STICKY: + case QUALIFIER_VARSIZE: +#if defined(QUALIFIER_PARAM) + case QUALIFIER_PARAM: +#endif + case QUALIFIER_FIXED_SIZE: + case QUALIFIER_ROUNDING_UPPER: + return TRUE; + default: + return FALSE; + } +} + +/************************************************************************* + * TrioSetLocale + */ +#if defined(USE_LOCALE) +TRIO_PRIVATE void +TrioSetLocale(TRIO_NOARGS) +{ + internalLocaleValues = (struct lconv *)localeconv(); + if (internalLocaleValues) + { + if ((internalLocaleValues->decimal_point) && + (internalLocaleValues->decimal_point[0] != NIL)) + { + internalDecimalPointLength = trio_length(internalLocaleValues->decimal_point); + if (internalDecimalPointLength == 1) + { + internalDecimalPoint = internalLocaleValues->decimal_point[0]; + } + else + { + internalDecimalPoint = NIL; + trio_copy_max(internalDecimalPointString, + sizeof(internalDecimalPointString), + internalLocaleValues->decimal_point); + } + } +# if TRIO_EXTENSION + if ((internalLocaleValues->thousands_sep) && + (internalLocaleValues->thousands_sep[0] != NIL)) + { + trio_copy_max(internalThousandSeparator, + sizeof(internalThousandSeparator), + internalLocaleValues->thousands_sep); + internalThousandSeparatorLength = trio_length(internalThousandSeparator); + } +# endif +# if TRIO_EXTENSION + if ((internalLocaleValues->grouping) && + (internalLocaleValues->grouping[0] != NIL)) + { + trio_copy_max(internalGrouping, + sizeof(internalGrouping), + internalLocaleValues->grouping); + } +# endif + } +} +#endif /* defined(USE_LOCALE) */ + +#if TRIO_FEATURE_FLOAT && TRIO_FEATURE_QUOTE +TRIO_PRIVATE int +TrioCalcThousandSeparatorLength +TRIO_ARGS1((digits), + int digits) +{ + int count = 0; + int step = NO_GROUPING; + char *groupingPointer = internalGrouping; + + while (digits > 0) + { + if (*groupingPointer == CHAR_MAX) + { + /* Disable grouping */ + break; /* while */ + } + else if (*groupingPointer == 0) + { + /* Repeat last group */ + if (step == NO_GROUPING) + { + /* Error in locale */ + break; /* while */ + } + } + else + { + step = *groupingPointer++; + } + if (digits > step) + count += internalThousandSeparatorLength; + digits -= step; + } + return count; +} +#endif /* TRIO_FEATURE_FLOAT && TRIO_FEATURE_QUOTE */ + +#if TRIO_FEATURE_QUOTE +TRIO_PRIVATE BOOLEAN_T +TrioFollowedBySeparator +TRIO_ARGS1((position), + int position) +{ + int step = 0; + char *groupingPointer = internalGrouping; + + position--; + if (position == 0) + return FALSE; + while (position > 0) + { + if (*groupingPointer == CHAR_MAX) + { + /* Disable grouping */ + break; /* while */ + } + else if (*groupingPointer != 0) + { + step = *groupingPointer++; + } + if (step == 0) + break; + position -= step; + } + return (position == 0); +} +#endif /* TRIO_FEATURE_QUOTE */ + +/************************************************************************* + * TrioGetPosition + * + * Get the %n$ position. + */ +TRIO_PRIVATE int +TrioGetPosition +TRIO_ARGS2((format, offsetPointer), + TRIO_CONST char *format, + int *offsetPointer) +{ +#if TRIO_FEATURE_POSITIONAL + char *tmpformat; + int number = 0; + int offset = *offsetPointer; + + number = (int)trio_to_long(&format[offset], &tmpformat, BASE_DECIMAL); + offset = (int)(tmpformat - format); + if ((number != 0) && (QUALIFIER_POSITION == format[offset++])) + { + *offsetPointer = offset; + /* + * number is decreased by 1, because n$ starts from 1, whereas + * the array it is indexing starts from 0. + */ + return number - 1; + } +#endif + return NO_POSITION; +} + +/************************************************************************* + * TrioFindNamespace + * + * Find registered user-defined specifier. + * The prev argument is used for optimization only. + */ +#if TRIO_FEATURE_USER_DEFINED +TRIO_PRIVATE trio_userdef_t * +TrioFindNamespace +TRIO_ARGS2((name, prev), + TRIO_CONST char *name, + trio_userdef_t **prev) +{ + trio_userdef_t *def; + + if (internalEnterCriticalRegion) + (void)internalEnterCriticalRegion(NULL); + + for (def = internalUserDef; def; def = def->next) + { + /* Case-sensitive string comparison */ + if (trio_equal_case(def->name, name)) + break; + + if (prev) + *prev = def; + } + + if (internalLeaveCriticalRegion) + (void)internalLeaveCriticalRegion(NULL); + + return def; +} +#endif + +/************************************************************************* + * TrioPower + * + * Description: + * Calculate pow(base, exponent), where number and exponent are integers. + */ +#if TRIO_FEATURE_FLOAT +TRIO_PRIVATE trio_long_double_t +TrioPower +TRIO_ARGS2((number, exponent), + int number, + int exponent) +{ + trio_long_double_t result; + + if (number == 10) + { + switch (exponent) + { + /* Speed up calculation of common cases */ + case 0: + result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E-1); + break; + case 1: + result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+0); + break; + case 2: + result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+1); + break; + case 3: + result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+2); + break; + case 4: + result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+3); + break; + case 5: + result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+4); + break; + case 6: + result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+5); + break; + case 7: + result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+6); + break; + case 8: + result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+7); + break; + case 9: + result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+8); + break; + default: + result = trio_pow((trio_long_double_t)number, + (trio_long_double_t)exponent); + break; + } + } + else + { + return trio_pow((trio_long_double_t)number, + (trio_long_double_t)exponent); + } + return result; +} +#endif /* TRIO_FEATURE_FLOAT */ + +/************************************************************************* + * TrioLogarithm + */ +#if TRIO_FEATURE_FLOAT +TRIO_PRIVATE trio_long_double_t +TrioLogarithm +TRIO_ARGS2((number, base), + trio_long_double_t number, + int base) +{ + trio_long_double_t result; + + if (number <= 0.0) + { + /* xlC crashes on log(0) */ + result = (number == 0.0) ? trio_ninf() : trio_nan(); + } + else + { + if (base == 10) + { + result = trio_log10(number); + } + else + { + result = trio_log10(number) / trio_log10((double)base); + } + } + return result; +} +#endif /* TRIO_FEATURE_FLOAT */ + +/************************************************************************* + * TrioLogarithmBase + */ +#if TRIO_FEATURE_FLOAT +TRIO_PRIVATE double +TrioLogarithmBase +TRIO_ARGS1((base), + int base) +{ + switch (base) + { + case BASE_BINARY : return 1.0; + case BASE_OCTAL : return 3.0; + case BASE_DECIMAL: return 3.321928094887362345; + case BASE_HEX : return 4.0; + default : return TrioLogarithm((double)base, 2); + } +} +#endif /* TRIO_FEATURE_FLOAT */ + +/************************************************************************* + * TrioParseQualifiers + * + * Description: + * Parse the qualifiers of a potential conversion specifier + */ +TRIO_PRIVATE int +TrioParseQualifiers +TRIO_ARGS4((type, format, offset, parameter), + int type, + TRIO_CONST char *format, + int offset, + trio_parameter_t *parameter) +{ + char ch; + int dots = 0; /* Count number of dots in modifier part */ + char *tmpformat; + + parameter->beginOffset = offset - 1; + parameter->flags = FLAGS_NEW; + parameter->position = TrioGetPosition(format, &offset); + + /* Default values */ + parameter->width = NO_WIDTH; + parameter->precision = NO_PRECISION; + parameter->base = NO_BASE; + parameter->varsize = NO_SIZE; + + while (TrioIsQualifier(format[offset])) + { + ch = format[offset++]; + + switch (ch) + { + case QUALIFIER_SPACE: + parameter->flags |= FLAGS_SPACE; + break; + + case QUALIFIER_PLUS: + parameter->flags |= FLAGS_SHOWSIGN; + break; + + case QUALIFIER_MINUS: + parameter->flags |= FLAGS_LEFTADJUST; + parameter->flags &= ~FLAGS_NILPADDING; + break; + + case QUALIFIER_ALTERNATIVE: + parameter->flags |= FLAGS_ALTERNATIVE; + break; + + case QUALIFIER_DOT: + if (dots == 0) /* Precision */ + { + dots++; + + /* Skip if no precision */ + if (QUALIFIER_DOT == format[offset]) + break; + + /* After the first dot we have the precision */ + parameter->flags |= FLAGS_PRECISION; + if ((QUALIFIER_STAR == format[offset]) +#if defined(QUALIFIER_PARAM) + || (QUALIFIER_PARAM == format[offset]) +#endif + ) + { + offset++; + parameter->flags |= FLAGS_PRECISION_PARAMETER; + parameter->precision = TrioGetPosition(format, &offset); + } + else + { + parameter->precision = trio_to_long(&format[offset], + &tmpformat, + BASE_DECIMAL); + offset = (int)(tmpformat - format); + } + } + else if (dots == 1) /* Base */ + { + dots++; + + /* After the second dot we have the base */ + parameter->flags |= FLAGS_BASE; + if ((QUALIFIER_STAR == format[offset]) +#if defined(QUALIFIER_PARAM) + || (QUALIFIER_PARAM == format[offset]) +#endif + ) + { + offset++; + parameter->flags |= FLAGS_BASE_PARAMETER; + parameter->base = TrioGetPosition(format, &offset); + } + else + { + parameter->base = trio_to_long(&format[offset], + &tmpformat, + BASE_DECIMAL); + if (parameter->base > MAX_BASE) + return TRIO_ERROR_RETURN(TRIO_EINVAL, offset); + offset = (int)(tmpformat - format); + } + } + else + { + return TRIO_ERROR_RETURN(TRIO_EINVAL, offset); + } + break; /* QUALIFIER_DOT */ + +#if defined(QUALIFIER_PARAM) + case QUALIFIER_PARAM: + parameter->type = TYPE_PRINT; + /* FALLTHROUGH */ +#endif + case QUALIFIER_STAR: + /* This has different meanings for print and scan */ + if (TYPE_PRINT == type) + { + /* Read with from parameter */ + int width = TrioGetPosition(format, &offset); + parameter->flags |= (FLAGS_WIDTH | FLAGS_WIDTH_PARAMETER); + if (NO_POSITION != width) + parameter->width = width; + /* else keep parameter->width = NO_WIDTH which != NO_POSITION */ + } +#if TRIO_FEATURE_SCANF + else + { + /* Scan, but do not store result */ + parameter->flags |= FLAGS_IGNORE; + } +#endif + break; /* QUALIFIER_STAR */ + + case '0': + if (! (parameter->flags & FLAGS_LEFTADJUST)) + parameter->flags |= FLAGS_NILPADDING; + /* FALLTHROUGH */ + case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + parameter->flags |= FLAGS_WIDTH; + /* + * &format[offset - 1] is used to "rewind" the read + * character from format + */ + parameter->width = trio_to_long(&format[offset - 1], + &tmpformat, + BASE_DECIMAL); + offset = (int)(tmpformat - format); + break; + + case QUALIFIER_SHORT: + if (parameter->flags & FLAGS_SHORTSHORT) + return TRIO_ERROR_RETURN(TRIO_EINVAL, offset); + else if (parameter->flags & FLAGS_SHORT) + parameter->flags |= FLAGS_SHORTSHORT; + else + parameter->flags |= FLAGS_SHORT; + break; + + case QUALIFIER_LONG: + if (parameter->flags & FLAGS_QUAD) + return TRIO_ERROR_RETURN(TRIO_EINVAL, offset); + else if (parameter->flags & FLAGS_LONG) + parameter->flags |= FLAGS_QUAD; + else + parameter->flags |= FLAGS_LONG; + break; + +#if TRIO_FEATURE_LONGDOUBLE + case QUALIFIER_LONG_UPPER: + parameter->flags |= FLAGS_LONGDOUBLE; + break; +#endif + +#if TRIO_FEATURE_SIZE_T + case QUALIFIER_SIZE_T: + parameter->flags |= FLAGS_SIZE_T; + /* Modify flags for later truncation of number */ + if (sizeof(size_t) == sizeof(trio_ulonglong_t)) + parameter->flags |= FLAGS_QUAD; + else if (sizeof(size_t) == sizeof(long)) + parameter->flags |= FLAGS_LONG; + break; +#endif + +#if TRIO_FEATURE_PTRDIFF_T + case QUALIFIER_PTRDIFF_T: + parameter->flags |= FLAGS_PTRDIFF_T; + if (sizeof(ptrdiff_t) == sizeof(trio_ulonglong_t)) + parameter->flags |= FLAGS_QUAD; + else if (sizeof(ptrdiff_t) == sizeof(long)) + parameter->flags |= FLAGS_LONG; + break; +#endif + +#if TRIO_FEATURE_INTMAX_T + case QUALIFIER_INTMAX_T: + parameter->flags |= FLAGS_INTMAX_T; + if (sizeof(trio_intmax_t) == sizeof(trio_ulonglong_t)) + parameter->flags |= FLAGS_QUAD; + else if (sizeof(trio_intmax_t) == sizeof(long)) + parameter->flags |= FLAGS_LONG; + break; +#endif + +#if TRIO_FEATURE_QUAD + case QUALIFIER_QUAD: + parameter->flags |= FLAGS_QUAD; + break; +#endif + +#if TRIO_FEATURE_FIXED_SIZE + case QUALIFIER_FIXED_SIZE: + if (parameter->flags & FLAGS_FIXED_SIZE) + return TRIO_ERROR_RETURN(TRIO_EINVAL, offset); + + if (parameter->flags & (FLAGS_ALL_SIZES | + FLAGS_LONGDOUBLE | + FLAGS_WIDECHAR | + FLAGS_VARSIZE_PARAMETER)) + return TRIO_ERROR_RETURN(TRIO_EINVAL, offset); + + if ((format[offset] == '6') && + (format[offset + 1] == '4')) + { + parameter->varsize = sizeof(trio_int64_t); + offset += 2; + } + else if ((format[offset] == '3') && + (format[offset + 1] == '2')) + { + parameter->varsize = sizeof(trio_int32_t); + offset += 2; + } + else if ((format[offset] == '1') && + (format[offset + 1] == '6')) + { + parameter->varsize = sizeof(trio_int16_t); + offset += 2; + } + else if (format[offset] == '8') + { + parameter->varsize = sizeof(trio_int8_t); + offset++; + } + else + return TRIO_ERROR_RETURN(TRIO_EINVAL, offset); + + parameter->flags |= FLAGS_FIXED_SIZE; + break; +#endif /* TRIO_FEATURE_FIXED_SIZE */ + +#if defined(QUALIFIER_WIDECHAR) + case QUALIFIER_WIDECHAR: + parameter->flags |= FLAGS_WIDECHAR; + break; +#endif + +#if TRIO_FEATURE_SIZE_T_UPPER + case QUALIFIER_SIZE_T_UPPER: + break; +#endif + +#if TRIO_FEATURE_QUOTE + case QUALIFIER_QUOTE: + parameter->flags |= FLAGS_QUOTE; + break; +#endif + +#if TRIO_FEATURE_STICKY + case QUALIFIER_STICKY: + parameter->flags |= FLAGS_STICKY; + break; +#endif + +#if TRIO_FEATURE_VARSIZE + case QUALIFIER_VARSIZE: + parameter->flags |= FLAGS_VARSIZE_PARAMETER; + break; +#endif + +#if TRIO_FEATURE_ROUNDING + case QUALIFIER_ROUNDING_UPPER: + parameter->flags |= FLAGS_ROUNDING; + break; +#endif + + default: + /* Bail out completely to make the error more obvious */ + return TRIO_ERROR_RETURN(TRIO_EINVAL, offset); + } + } /* while qualifier */ + + parameter->endOffset = offset; + + return 0; +} + +/************************************************************************* + * TrioParseSpecifier + * + * Description: + * Parse the specifier part of a potential conversion specifier + */ +TRIO_PRIVATE int +TrioParseSpecifier +TRIO_ARGS4((type, format, offset, parameter), + int type, + TRIO_CONST char *format, + int offset, + trio_parameter_t *parameter) +{ + parameter->baseSpecifier = NO_BASE; + + switch (format[offset++]) + { +#if defined(SPECIFIER_CHAR_UPPER) + case SPECIFIER_CHAR_UPPER: + parameter->flags |= FLAGS_WIDECHAR; + /* FALLTHROUGH */ +#endif + case SPECIFIER_CHAR: + if (parameter->flags & FLAGS_LONG) + parameter->flags |= FLAGS_WIDECHAR; + else if (parameter->flags & FLAGS_SHORT) + parameter->flags &= ~FLAGS_WIDECHAR; + parameter->type = FORMAT_CHAR; + break; + +#if defined(SPECIFIER_STRING_UPPER) + case SPECIFIER_STRING_UPPER: + parameter->flags |= FLAGS_WIDECHAR; + /* FALLTHROUGH */ +#endif + case SPECIFIER_STRING: + if (parameter->flags & FLAGS_LONG) + parameter->flags |= FLAGS_WIDECHAR; + else if (parameter->flags & FLAGS_SHORT) + parameter->flags &= ~FLAGS_WIDECHAR; + parameter->type = FORMAT_STRING; + break; + +#if defined(SPECIFIER_GROUP) + case SPECIFIER_GROUP: + if (TYPE_SCAN == type) + { + int depth = 1; + parameter->type = FORMAT_GROUP; + if (format[offset] == QUALIFIER_CIRCUMFLEX) + offset++; + if (format[offset] == SPECIFIER_UNGROUP) + offset++; + if (format[offset] == QUALIFIER_MINUS) + offset++; + /* Skip nested brackets */ + while (format[offset] != NIL) + { + if (format[offset] == SPECIFIER_GROUP) + { + depth++; + } + else if (format[offset] == SPECIFIER_UNGROUP) + { + if (--depth <= 0) + { + offset++; + break; + } + } + offset++; + } + } + break; +#endif /* defined(SPECIFIER_GROUP) */ + + case SPECIFIER_INTEGER: + parameter->type = FORMAT_INT; + break; + + case SPECIFIER_UNSIGNED: + parameter->flags |= FLAGS_UNSIGNED; + parameter->type = FORMAT_INT; + break; + + case SPECIFIER_DECIMAL: + parameter->baseSpecifier = BASE_DECIMAL; + parameter->type = FORMAT_INT; + break; + + case SPECIFIER_OCTAL: + parameter->flags |= FLAGS_UNSIGNED; + parameter->baseSpecifier = BASE_OCTAL; + parameter->type = FORMAT_INT; + break; + +#if TRIO_FEATURE_BINARY + case SPECIFIER_BINARY_UPPER: + parameter->flags |= FLAGS_UPPER; + /* FALLTHROUGH */ + case SPECIFIER_BINARY: + parameter->flags |= FLAGS_NILPADDING; + parameter->baseSpecifier = BASE_BINARY; + parameter->type = FORMAT_INT; + break; +#endif + + case SPECIFIER_HEX_UPPER: + parameter->flags |= FLAGS_UPPER; + /* FALLTHROUGH */ + case SPECIFIER_HEX: + parameter->flags |= FLAGS_UNSIGNED; + parameter->baseSpecifier = BASE_HEX; + parameter->type = FORMAT_INT; + break; + +#if defined(SPECIFIER_FLOAT_E) +# if defined(SPECIFIER_FLOAT_E_UPPER) + case SPECIFIER_FLOAT_E_UPPER: + parameter->flags |= FLAGS_UPPER; + /* FALLTHROUGH */ +# endif + case SPECIFIER_FLOAT_E: + parameter->flags |= FLAGS_FLOAT_E; + parameter->type = FORMAT_DOUBLE; + break; +#endif + +#if defined(SPECIFIER_FLOAT_G) +# if defined(SPECIFIER_FLOAT_G_UPPER) + case SPECIFIER_FLOAT_G_UPPER: + parameter->flags |= FLAGS_UPPER; + /* FALLTHROUGH */ +# endif + case SPECIFIER_FLOAT_G: + parameter->flags |= FLAGS_FLOAT_G; + parameter->type = FORMAT_DOUBLE; + break; +#endif + +#if defined(SPECIFIER_FLOAT_F) +# if defined(SPECIFIER_FLOAT_F_UPPER) + case SPECIFIER_FLOAT_F_UPPER: + parameter->flags |= FLAGS_UPPER; + /* FALLTHROUGH */ +# endif + case SPECIFIER_FLOAT_F: + parameter->type = FORMAT_DOUBLE; + break; +#endif + +#if defined(TRIO_COMPILER_VISUALC) +# pragma warning( push ) +# pragma warning( disable : 4127 ) /* Conditional expression is constant */ +#endif + case SPECIFIER_POINTER: + if (sizeof(trio_pointer_t) == sizeof(trio_ulonglong_t)) + parameter->flags |= FLAGS_QUAD; + else if (sizeof(trio_pointer_t) == sizeof(long)) + parameter->flags |= FLAGS_LONG; + parameter->type = FORMAT_POINTER; + break; +#if defined(TRIO_COMPILER_VISUALC) +# pragma warning( pop ) +#endif + + case SPECIFIER_COUNT: + parameter->type = FORMAT_COUNT; + break; + +#if TRIO_FEATURE_HEXFLOAT + case SPECIFIER_HEXFLOAT_UPPER: + parameter->flags |= FLAGS_UPPER; + /* FALLTHROUGH */ + case SPECIFIER_HEXFLOAT: + parameter->baseSpecifier = BASE_HEX; + parameter->type = FORMAT_DOUBLE; + break; +#endif + +#if TRIO_FEATURE_ERRNO + case SPECIFIER_ERRNO: + parameter->type = FORMAT_ERRNO; + break; +#endif + +#if TRIO_FEATURE_USER_DEFINED + case SPECIFIER_USER_DEFINED_BEGIN: + { + unsigned int max; + int without_namespace = TRUE; + char* tmpformat = (char *)&format[offset]; + int ch; + + parameter->type = FORMAT_USER_DEFINED; + parameter->user_defined.namespace[0] = NIL; + + while ((ch = format[offset]) != NIL) + { + offset++; + if ((ch == SPECIFIER_USER_DEFINED_END) || (ch == SPECIFIER_USER_DEFINED_EXTRA)) + { + if (without_namespace) + /* No namespace, handler will be passed as an argument */ + parameter->flags |= FLAGS_USER_DEFINED_PARAMETER; + + /* Copy the user data */ + max = (unsigned int)(&format[offset] - tmpformat); + if (max > MAX_USER_DATA) + max = MAX_USER_DATA; + trio_copy_max(parameter->user_data, max, tmpformat); + + /* Skip extra data (which is only there to keep the compiler happy) */ + while ((ch != NIL) && (ch != SPECIFIER_USER_DEFINED_END)) + ch = format[offset++]; + + break; /* while */ + } + + if (ch == SPECIFIER_USER_DEFINED_SEPARATOR) + { + without_namespace = FALSE; + /* Copy the namespace for later looking-up */ + max = (int)(&format[offset] - tmpformat); + if (max > MAX_USER_NAME) + max = MAX_USER_NAME; + trio_copy_max(parameter->user_defined.namespace, max, tmpformat); + tmpformat = (char *)&format[offset]; + } + } + + if (ch != SPECIFIER_USER_DEFINED_END) + return TRIO_ERROR_RETURN(TRIO_EINVAL, offset); + } + break; +#endif /* TRIO_FEATURE_USER_DEFINED */ + + default: + /* Bail out completely to make the error more obvious */ + return TRIO_ERROR_RETURN(TRIO_EINVAL, offset); + } + + parameter->endOffset = offset; + + return 0; +} + +/************************************************************************* + * TrioParse + * + * Description: + * Parse the format string + */ +TRIO_PRIVATE int +TrioParse +TRIO_ARGS5((type, format, parameters, arglist, argarray), + int type, + TRIO_CONST char *format, + trio_parameter_t *parameters, + va_list arglist, + trio_pointer_t *argarray) +{ + /* Count the number of times a parameter is referenced */ + unsigned short usedEntries[MAX_PARAMETERS]; + /* Parameter counters */ + int parameterPosition; + int maxParam = -1; + /* Utility variables */ + int offset; /* Offset into formatting string */ + BOOLEAN_T positional; /* Does the specifier have a positional? */ +#if TRIO_FEATURE_STICKY + BOOLEAN_T gotSticky = FALSE; /* Are there any sticky modifiers at all? */ +#endif + /* + * indices specifies the order in which the parameters must be + * read from the va_args (this is necessary to handle positionals) + */ + int indices[MAX_PARAMETERS]; + int pos = 0; + /* Various variables */ + int save_errno; + int i = -1; + int num; + trio_parameter_t workParameter; + int status; + + /* + * The 'parameters' array is not initialized, but we need to + * know which entries we have used. + */ + memset(usedEntries, 0, sizeof(usedEntries)); + + save_errno = errno; + offset = 0; + parameterPosition = 0; + + while (format[offset]) + { + TrioInitializeParameter(&workParameter); + + switch(format[offset++]) { + + case CHAR_IDENTIFIER: + { + if (CHAR_IDENTIFIER == format[offset]) + { + /* skip double "%" */ + offset++; + continue; /* while */ + } + + status = TrioParseQualifiers(type, format, offset, &workParameter); + if (status < 0) + return status; /* Return qualifier syntax error */ + + status = TrioParseSpecifier(type, format, workParameter.endOffset, &workParameter); + if (status < 0) + return status; /* Return specifier syntax error */ + } + break; + +#if TRIO_EXTENSION + case CHAR_ALT_IDENTIFIER: + { + status = TrioParseQualifiers(type, format, offset, &workParameter); + if (status < 0) + continue; /* False alert, not a user defined specifier */ + + status = TrioParseSpecifier(type, format, workParameter.endOffset, &workParameter); + if ((status < 0) || (FORMAT_USER_DEFINED != workParameter.type)) + continue; /* False alert, not a user defined specifier */ + } + break; +#endif + + default: + continue; /* while */ + } + + /* now handle the parsed conversion specification */ + positional = (NO_POSITION != workParameter.position); + + /* + * Parameters only need the type and value. The value is + * read later. + */ + if (workParameter.flags & FLAGS_WIDTH_PARAMETER) + { + if (workParameter.width == NO_WIDTH) + { + workParameter.width = parameterPosition++; + } + else + { + if (! positional) + workParameter.position = workParameter.width + 1; + } + + usedEntries[workParameter.width] += 1; + if (workParameter.width > maxParam) + maxParam = workParameter.width; + parameters[pos].type = FORMAT_PARAMETER; + parameters[pos].flags = 0; + indices[workParameter.width] = pos; + workParameter.width = pos++; + } + if (workParameter.flags & FLAGS_PRECISION_PARAMETER) + { + if (workParameter.precision == NO_PRECISION) + { + workParameter.precision = parameterPosition++; + } + else + { + if (! positional) + workParameter.position = workParameter.precision + 1; + } + + usedEntries[workParameter.precision] += 1; + if (workParameter.precision > maxParam) + maxParam = workParameter.precision; + parameters[pos].type = FORMAT_PARAMETER; + parameters[pos].flags = 0; + indices[workParameter.precision] = pos; + workParameter.precision = pos++; + } + if (workParameter.flags & FLAGS_BASE_PARAMETER) + { + if (workParameter.base == NO_BASE) + { + workParameter.base = parameterPosition++; + } + else + { + if (! positional) + workParameter.position = workParameter.base + 1; + } + + usedEntries[workParameter.base] += 1; + if (workParameter.base > maxParam) + maxParam = workParameter.base; + parameters[pos].type = FORMAT_PARAMETER; + parameters[pos].flags = 0; + indices[workParameter.base] = pos; + workParameter.base = pos++; + } +#if TRIO_FEATURE_VARSIZE + if (workParameter.flags & FLAGS_VARSIZE_PARAMETER) + { + workParameter.varsize = parameterPosition++; + + usedEntries[workParameter.varsize] += 1; + if (workParameter.varsize > maxParam) + maxParam = workParameter.varsize; + parameters[pos].type = FORMAT_PARAMETER; + parameters[pos].flags = 0; + indices[workParameter.varsize] = pos; + workParameter.varsize = pos++; + } +#endif +#if TRIO_FEATURE_USER_DEFINED + if (workParameter.flags & FLAGS_USER_DEFINED_PARAMETER) + { + workParameter.user_defined.handler = parameterPosition++; + + usedEntries[workParameter.user_defined.handler] += 1; + if (workParameter.user_defined.handler > maxParam) + maxParam = workParameter.user_defined.handler; + parameters[pos].type = FORMAT_PARAMETER; + parameters[pos].flags = FLAGS_USER_DEFINED; + indices[workParameter.user_defined.handler] = pos; + workParameter.user_defined.handler = pos++; + } +#endif + + if (NO_POSITION == workParameter.position) + { + workParameter.position = parameterPosition++; + } + + if (workParameter.position > maxParam) + maxParam = workParameter.position; + + if (workParameter.position >= MAX_PARAMETERS) + { + /* Bail out completely to make the error more obvious */ + return TRIO_ERROR_RETURN(TRIO_ETOOMANY, offset); + } + + indices[workParameter.position] = pos; + + /* Count the number of times this entry has been used */ + usedEntries[workParameter.position] += 1; + + /* Find last sticky parameters */ +#if TRIO_FEATURE_STICKY + if (workParameter.flags & FLAGS_STICKY) + { + gotSticky = TRUE; + } + else if (gotSticky) + { + for (i = pos - 1; i >= 0; i--) + { + if (parameters[i].type == FORMAT_PARAMETER) + continue; + if ((parameters[i].flags & FLAGS_STICKY) && + (parameters[i].type == workParameter.type)) + { + /* Do not overwrite current qualifiers */ + workParameter.flags |= (parameters[i].flags & (unsigned long)~FLAGS_STICKY); + if (workParameter.width == NO_WIDTH) + workParameter.width = parameters[i].width; + if (workParameter.precision == NO_PRECISION) + workParameter.precision = parameters[i].precision; + if (workParameter.base == NO_BASE) + workParameter.base = parameters[i].base; + break; + } + } + } +#endif + + if (workParameter.base == NO_BASE) + workParameter.base = BASE_DECIMAL; + + offset = workParameter.endOffset; + + TrioCopyParameter(¶meters[pos++], &workParameter); + } /* while format characters left */ + + parameters[pos].type = FORMAT_SENTINEL; /* end parameter array with sentinel */ + parameters[pos].beginOffset = offset; + + for (num = 0; num <= maxParam; num++) + { + if (usedEntries[num] != 1) + { + if (usedEntries[num] == 0) /* gap detected */ + return TRIO_ERROR_RETURN(TRIO_EGAP, num); + else /* double references detected */ + return TRIO_ERROR_RETURN(TRIO_EDBLREF, num); + } + + i = indices[num]; + + /* + * FORMAT_PARAMETERS are only present if they must be read, + * so it makes no sense to check the ignore flag (besides, + * the flags variable is not set for that particular type) + */ + if ((parameters[i].type != FORMAT_PARAMETER) && + (parameters[i].flags & FLAGS_IGNORE)) + continue; /* for all arguments */ + + /* + * The stack arguments are read according to ANSI C89 + * default argument promotions: + * + * char = int + * short = int + * unsigned char = unsigned int + * unsigned short = unsigned int + * float = double + * + * In addition to the ANSI C89 these types are read (the + * default argument promotions of C99 has not been + * considered yet) + * + * long long + * long double + * size_t + * ptrdiff_t + * intmax_t + */ + switch (parameters[i].type) + { + case FORMAT_GROUP: + case FORMAT_STRING: +#if TRIO_FEATURE_WIDECHAR + if (parameters[i].flags & FLAGS_WIDECHAR) + { + parameters[i].data.wstring = (argarray == NULL) + ? va_arg(arglist, trio_wchar_t *) + : (trio_wchar_t *)(argarray[num]); + } + else +#endif + { + parameters[i].data.string = (argarray == NULL) + ? va_arg(arglist, char *) + : (char *)(argarray[num]); + } + break; + +#if TRIO_FEATURE_USER_DEFINED + case FORMAT_USER_DEFINED: +#endif + case FORMAT_POINTER: + case FORMAT_COUNT: + case FORMAT_UNKNOWN: + parameters[i].data.pointer = (argarray == NULL) + ? va_arg(arglist, trio_pointer_t ) + : argarray[num]; + break; + + case FORMAT_CHAR: + case FORMAT_INT: +#if TRIO_FEATURE_SCANF + if (TYPE_SCAN == type) + { + if (argarray == NULL) + parameters[i].data.pointer = + (trio_pointer_t)va_arg(arglist, trio_pointer_t); + else + { + if (parameters[i].type == FORMAT_CHAR) + parameters[i].data.pointer = + (trio_pointer_t)((char *)argarray[num]); + else if (parameters[i].flags & FLAGS_SHORT) + parameters[i].data.pointer = + (trio_pointer_t)((short *)argarray[num]); + else + parameters[i].data.pointer = + (trio_pointer_t)((int *)argarray[num]); + } + } + else +#endif /* TRIO_FEATURE_SCANF */ + { +#if TRIO_FEATURE_VARSIZE || TRIO_FEATURE_FIXED_SIZE + if (parameters[i].flags + & (FLAGS_VARSIZE_PARAMETER | FLAGS_FIXED_SIZE)) + { + int varsize; + if (parameters[i].flags & FLAGS_VARSIZE_PARAMETER) + { + /* + * Variable sizes are mapped onto the fixed sizes, in + * accordance with integer promotion. + * + * Please note that this may not be portable, as we + * only guess the size, not the layout of the numbers. + * For example, if int is little-endian, and long is + * big-endian, then this will fail. + */ + varsize = (int)parameters[parameters[i].varsize].data.number.as_unsigned; + } + else + { + /* Used for the I modifiers */ + varsize = parameters[i].varsize; + } + parameters[i].flags &= ~FLAGS_ALL_VARSIZES; + + if (varsize <= (int)sizeof(int)) + ; + else if (varsize <= (int)sizeof(long)) + parameters[i].flags |= FLAGS_LONG; +#if TRIO_FEATURE_INTMAX_T + else if (varsize <= (int)sizeof(trio_longlong_t)) + parameters[i].flags |= FLAGS_QUAD; + else + parameters[i].flags |= FLAGS_INTMAX_T; +#else + else + parameters[i].flags |= FLAGS_QUAD; +#endif + } +#endif /* TRIO_FEATURE_VARSIZE */ +#if TRIO_FEATURE_SIZE_T || TRIO_FEATURE_SIZE_T_UPPER + if (parameters[i].flags & FLAGS_SIZE_T) + parameters[i].data.number.as_unsigned = (argarray == NULL) + ? (trio_uintmax_t)va_arg(arglist, size_t) + : (trio_uintmax_t)(*((size_t *)argarray[num])); + else +#endif +#if TRIO_FEATURE_PTRDIFF_T + if (parameters[i].flags & FLAGS_PTRDIFF_T) + parameters[i].data.number.as_unsigned = (argarray == NULL) + ? (trio_uintmax_t)va_arg(arglist, ptrdiff_t) + : (trio_uintmax_t)(*((ptrdiff_t *)argarray[num])); + else +#endif +#if TRIO_FEATURE_INTMAX_T + if (parameters[i].flags & FLAGS_INTMAX_T) + parameters[i].data.number.as_unsigned = (argarray == NULL) + ? (trio_uintmax_t)va_arg(arglist, trio_intmax_t) + : (trio_uintmax_t)(*((trio_intmax_t *)argarray[num])); + else +#endif + if (parameters[i].flags & FLAGS_QUAD) + parameters[i].data.number.as_unsigned = (argarray == NULL) + ? (trio_uintmax_t)va_arg(arglist, trio_ulonglong_t) + : (trio_uintmax_t)(*((trio_ulonglong_t *)argarray[num])); + else if (parameters[i].flags & FLAGS_LONG) + parameters[i].data.number.as_unsigned = (argarray == NULL) + ? (trio_uintmax_t)va_arg(arglist, long) + : (trio_uintmax_t)(*((long *)argarray[num])); + else + { + if (argarray == NULL) + parameters[i].data.number.as_unsigned = (trio_uintmax_t)va_arg(arglist, int); + else + { + if (parameters[i].type == FORMAT_CHAR) + parameters[i].data.number.as_unsigned = (trio_uintmax_t)(*((char *)argarray[num])); + else if (parameters[i].flags & FLAGS_SHORT) + parameters[i].data.number.as_unsigned = (trio_uintmax_t)(*((short *)argarray[num])); + else + parameters[i].data.number.as_unsigned = (trio_uintmax_t)(*((int *)argarray[num])); + } + } + } + break; + + case FORMAT_PARAMETER: + /* + * The parameter for the user-defined specifier is a pointer, + * whereas the rest (width, precision, base) uses an integer. + */ + if (parameters[i].flags & FLAGS_USER_DEFINED) + parameters[i].data.pointer = (argarray == NULL) + ? va_arg(arglist, trio_pointer_t ) + : argarray[num]; + else + parameters[i].data.number.as_unsigned = (argarray == NULL) + ? (trio_uintmax_t)va_arg(arglist, int) + : (trio_uintmax_t)(*((int *)argarray[num])); + break; + +#if TRIO_FEATURE_FLOAT + case FORMAT_DOUBLE: +# if TRIO_FEATURE_SCANF + if (TYPE_SCAN == type) + { + if (parameters[i].flags & FLAGS_LONGDOUBLE) + parameters[i].data.longdoublePointer = (argarray == NULL) + ? va_arg(arglist, trio_long_double_t *) + : (trio_long_double_t *)argarray[num]; + else + { + if (parameters[i].flags & FLAGS_LONG) + parameters[i].data.doublePointer = (argarray == NULL) + ? va_arg(arglist, double *) + : (double *)argarray[num]; + else + parameters[i].data.doublePointer = (argarray == NULL) + ? (double *)va_arg(arglist, float *) + : (double *)((float *)argarray[num]); + } + } + else +# endif /* TRIO_FEATURE_SCANF */ + { + if (parameters[i].flags & FLAGS_LONGDOUBLE) + parameters[i].data.longdoubleNumber = (argarray == NULL) + ? va_arg(arglist, trio_long_double_t) + : (trio_long_double_t)(*((trio_long_double_t *)argarray[num])); + else + { + if (argarray == NULL) + parameters[i].data.longdoubleNumber = + (trio_long_double_t)va_arg(arglist, double); + else + { + if (parameters[i].flags & FLAGS_SHORT) + parameters[i].data.longdoubleNumber = + (trio_long_double_t)(*((float *)argarray[num])); + else + parameters[i].data.longdoubleNumber = + (trio_long_double_t)(*((double *)argarray[num])); + } + } + } + break; +#endif /* TRIO_FEATURE_FLOAT */ + +#if TRIO_FEATURE_ERRNO + case FORMAT_ERRNO: + parameters[i].data.errorNumber = save_errno; + break; +#endif + + default: + break; + } + } /* for all specifiers */ + return num; +} + + +/************************************************************************* + * + * FORMATTING + * + ************************************************************************/ + + +/************************************************************************* + * TrioWriteNumber + * + * Description: + * Output a number. + * The complexity of this function is a result of the complexity + * of the dependencies of the flags. + */ +TRIO_PRIVATE void +TrioWriteNumber +TRIO_ARGS6((self, number, flags, width, precision, base), + trio_class_t *self, + trio_uintmax_t number, + trio_flags_t flags, + int width, + int precision, + int base) +{ + BOOLEAN_T isNegative; + BOOLEAN_T isNumberZero; + BOOLEAN_T isPrecisionZero; + BOOLEAN_T ignoreNumber; + char buffer[MAX_CHARS_IN(trio_uintmax_t) * (1 + MAX_LOCALE_SEPARATOR_LENGTH) + 1]; + char *bufferend; + char *pointer; + TRIO_CONST char *digits; + int i; +#if TRIO_FEATURE_QUOTE + int length; + char *p; +#endif + int count; + int digitOffset; + + assert(VALID(self)); + assert(VALID(self->OutStream)); + assert(((base >= MIN_BASE) && (base <= MAX_BASE)) || (base == NO_BASE)); + + digits = (flags & FLAGS_UPPER) ? internalDigitsUpper : internalDigitsLower; + if (base == NO_BASE) + base = BASE_DECIMAL; + + isNumberZero = (number == 0); + isPrecisionZero = (precision == 0); + ignoreNumber = (isNumberZero + && isPrecisionZero + && !((flags & FLAGS_ALTERNATIVE) && (base == BASE_OCTAL))); + + if (flags & FLAGS_UNSIGNED) + { + isNegative = FALSE; + flags &= ~FLAGS_SHOWSIGN; + } + else + { + isNegative = ((trio_intmax_t)number < 0); + if (isNegative) + number = -((trio_intmax_t)number); + } + + if (flags & FLAGS_QUAD) + number &= (trio_ulonglong_t)-1; + else if (flags & FLAGS_LONG) + number &= (unsigned long)-1; + else + number &= (unsigned int)-1; + + /* Build number */ + pointer = bufferend = &buffer[sizeof(buffer) - 1]; + *pointer-- = NIL; + for (i = 1; i < (int)sizeof(buffer); i++) + { + digitOffset = number % base; + *pointer-- = digits[digitOffset]; + number /= base; + if (number == 0) + break; + +#if TRIO_FEATURE_QUOTE + if ((flags & FLAGS_QUOTE) && TrioFollowedBySeparator(i + 1)) + { + /* + * We are building the number from the least significant + * to the most significant digit, so we have to copy the + * thousand separator backwards + */ + length = internalThousandSeparatorLength; + if (((int)(pointer - buffer) - length) > 0) + { + p = &internalThousandSeparator[length - 1]; + while (length-- > 0) + *pointer-- = *p--; + } + } +#endif + } + + if (! ignoreNumber) + { + /* Adjust width */ + width -= (bufferend - pointer) - 1; + } + + /* Adjust precision */ + if (NO_PRECISION != precision) + { + precision -= (bufferend - pointer) - 1; + if (precision < 0) + precision = 0; + flags |= FLAGS_NILPADDING; + } + + /* Calculate padding */ + count = (! ((flags & FLAGS_LEFTADJUST) || (precision == NO_PRECISION))) + ? precision + : 0; + + /* Adjust width further */ + if (isNegative || (flags & FLAGS_SHOWSIGN) || (flags & FLAGS_SPACE)) + width--; + if ((flags & FLAGS_ALTERNATIVE) && !isNumberZero) + { + switch (base) + { + case BASE_BINARY: + case BASE_HEX: + width -= 2; + break; + case BASE_OCTAL: + if (!(flags & FLAGS_NILPADDING) || (count == 0)) + width--; + break; + default: + break; + } + } + + /* Output prefixes spaces if needed */ + if (! ((flags & FLAGS_LEFTADJUST) || + ((flags & FLAGS_NILPADDING) && (precision == NO_PRECISION)))) + { + while (width-- > count) + self->OutStream(self, CHAR_ADJUST); + } + + /* width has been adjusted for signs and alternatives */ + if (isNegative) + self->OutStream(self, '-'); + else if (flags & FLAGS_SHOWSIGN) + self->OutStream(self, '+'); + else if (flags & FLAGS_SPACE) + self->OutStream(self, ' '); + + /* Prefix is not written when the value is zero */ + if ((flags & FLAGS_ALTERNATIVE) && !isNumberZero) + { + switch (base) + { + case BASE_BINARY: + self->OutStream(self, '0'); + self->OutStream(self, (flags & FLAGS_UPPER) ? 'B' : 'b'); + break; + + case BASE_OCTAL: + if (!(flags & FLAGS_NILPADDING) || (count == 0)) + self->OutStream(self, '0'); + break; + + case BASE_HEX: + self->OutStream(self, '0'); + self->OutStream(self, (flags & FLAGS_UPPER) ? 'X' : 'x'); + break; + + default: + break; + } /* switch base */ + } + + /* Output prefixed zero padding if needed */ + if (flags & FLAGS_NILPADDING) + { + if (precision == NO_PRECISION) + precision = width; + while (precision-- > 0) + { + self->OutStream(self, '0'); + width--; + } + } + + if (! ignoreNumber) + { + /* Output the number itself */ + while (*(++pointer)) + { + self->OutStream(self, *pointer); + } + } + + /* Output trailing spaces if needed */ + if (flags & FLAGS_LEFTADJUST) + { + while (width-- > 0) + self->OutStream(self, CHAR_ADJUST); + } +} + +/************************************************************************* + * TrioWriteStringCharacter + * + * Description: + * Output a single character of a string + */ +TRIO_PRIVATE void +TrioWriteStringCharacter +TRIO_ARGS3((self, ch, flags), + trio_class_t *self, + int ch, + trio_flags_t flags) +{ + if (flags & FLAGS_ALTERNATIVE) + { + if (! isprint(ch)) + { + /* + * Non-printable characters are converted to C escapes or + * \number, if no C escape exists. + */ + self->OutStream(self, CHAR_BACKSLASH); + switch (ch) + { + case '\007': self->OutStream(self, 'a'); break; + case '\b': self->OutStream(self, 'b'); break; + case '\f': self->OutStream(self, 'f'); break; + case '\n': self->OutStream(self, 'n'); break; + case '\r': self->OutStream(self, 'r'); break; + case '\t': self->OutStream(self, 't'); break; + case '\v': self->OutStream(self, 'v'); break; + case '\\': self->OutStream(self, '\\'); break; + default: + self->OutStream(self, 'x'); + TrioWriteNumber(self, (trio_uintmax_t)ch, + FLAGS_UNSIGNED | FLAGS_NILPADDING, + 2, 2, BASE_HEX); + break; + } + } + else if (ch == CHAR_BACKSLASH) + { + self->OutStream(self, CHAR_BACKSLASH); + self->OutStream(self, CHAR_BACKSLASH); + } + else + { + self->OutStream(self, ch); + } + } + else + { + self->OutStream(self, ch); + } +} + +/************************************************************************* + * TrioWriteString + * + * Description: + * Output a string + */ +TRIO_PRIVATE void +TrioWriteString +TRIO_ARGS5((self, string, flags, width, precision), + trio_class_t *self, + TRIO_CONST char *string, + trio_flags_t flags, + int width, + int precision) +{ + int length; + int ch; + + assert(VALID(self)); + assert(VALID(self->OutStream)); + + if (string == NULL) + { + string = internalNullString; + length = sizeof(internalNullString) - 1; +#if TRIO_FEATURE_QUOTE + /* Disable quoting for the null pointer */ + flags &= (~FLAGS_QUOTE); +#endif + width = 0; + } + else + { + if (precision == 0) + { + length = trio_length(string); + } + else + { + length = trio_length_max(string, precision); + } + } + if ((NO_PRECISION != precision) && + (precision < length)) + { + length = precision; + } + width -= length; + +#if TRIO_FEATURE_QUOTE + if (flags & FLAGS_QUOTE) + self->OutStream(self, CHAR_QUOTE); +#endif + + if (! (flags & FLAGS_LEFTADJUST)) + { + while (width-- > 0) + self->OutStream(self, CHAR_ADJUST); + } + + while (length-- > 0) + { + /* The ctype parameters must be an unsigned char (or EOF) */ + ch = (int)((unsigned char)(*string++)); + TrioWriteStringCharacter(self, ch, flags); + } + + if (flags & FLAGS_LEFTADJUST) + { + while (width-- > 0) + self->OutStream(self, CHAR_ADJUST); + } +#if TRIO_FEATURE_QUOTE + if (flags & FLAGS_QUOTE) + self->OutStream(self, CHAR_QUOTE); +#endif +} + +/************************************************************************* + * TrioWriteWideStringCharacter + * + * Description: + * Output a wide string as a multi-byte sequence + */ +#if TRIO_FEATURE_WIDECHAR +TRIO_PRIVATE int +TrioWriteWideStringCharacter +TRIO_ARGS4((self, wch, flags, width), + trio_class_t *self, + trio_wchar_t wch, + trio_flags_t flags, + int width) +{ + int size; + int i; + int ch; + char *string; + char buffer[MB_LEN_MAX + 1]; + + if (width == NO_WIDTH) + width = sizeof(buffer); + + size = wctomb(buffer, wch); + if ((size <= 0) || (size > width) || (buffer[0] == NIL)) + return 0; + + string = buffer; + i = size; + while ((width >= i) && (width-- > 0) && (i-- > 0)) + { + /* The ctype parameters must be an unsigned char (or EOF) */ + ch = (int)((unsigned char)(*string++)); + TrioWriteStringCharacter(self, ch, flags); + } + return size; +} +#endif /* TRIO_FEATURE_WIDECHAR */ + +/************************************************************************* + * TrioWriteWideString + * + * Description: + * Output a wide character string as a multi-byte string + */ +#if TRIO_FEATURE_WIDECHAR +TRIO_PRIVATE void +TrioWriteWideString +TRIO_ARGS5((self, wstring, flags, width, precision), + trio_class_t *self, + TRIO_CONST trio_wchar_t *wstring, + trio_flags_t flags, + int width, + int precision) +{ + int length; + int size; + + assert(VALID(self)); + assert(VALID(self->OutStream)); + +#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE) + /* Required by TrioWriteWideStringCharacter */ + (void)mblen(NULL, 0); +#endif + + if (wstring == NULL) + { + TrioWriteString(self, NULL, flags, width, precision); + return; + } + + if (NO_PRECISION == precision) + { + length = INT_MAX; + } + else + { + length = precision; + width -= length; + } + +#if TRIO_FEATURE_QUOTE + if (flags & FLAGS_QUOTE) + self->OutStream(self, CHAR_QUOTE); +#endif + + if (! (flags & FLAGS_LEFTADJUST)) + { + while (width-- > 0) + self->OutStream(self, CHAR_ADJUST); + } + + while (length > 0) + { + size = TrioWriteWideStringCharacter(self, *wstring++, flags, length); + if (size == 0) + break; /* while */ + length -= size; + } + + if (flags & FLAGS_LEFTADJUST) + { + while (width-- > 0) + self->OutStream(self, CHAR_ADJUST); + } +#if TRIO_FEATURE_QUOTE + if (flags & FLAGS_QUOTE) + self->OutStream(self, CHAR_QUOTE); +#endif +} +#endif /* TRIO_FEATURE_WIDECHAR */ + +/************************************************************************* + * TrioWriteDouble + * + * http://wwwold.dkuug.dk/JTC1/SC22/WG14/www/docs/dr_211.htm + * + * "5.2.4.2.2 paragraph #4 + * + * The accuracy [...] is implementation defined, as is the accuracy + * of the conversion between floating-point internal representations + * and string representations performed by the libray routine in + * " + */ +/* FIXME: handle all instances of constant long-double number (L) + * and *l() math functions. + */ +#if TRIO_FEATURE_FLOAT +TRIO_PRIVATE void +TrioWriteDouble +TRIO_ARGS6((self, number, flags, width, precision, base), + trio_class_t *self, + trio_long_double_t number, + trio_flags_t flags, + int width, + int precision, + int base) +{ + trio_long_double_t integerNumber; + trio_long_double_t fractionNumber; + trio_long_double_t workNumber; + int integerDigits; + int fractionDigits; + int exponentDigits; + int workDigits; + int baseDigits; + int integerThreshold; + int fractionThreshold; + int expectedWidth; + int exponent = 0; + unsigned int uExponent = 0; + int exponentBase; + trio_long_double_t dblBase; + trio_long_double_t dblFractionBase; + trio_long_double_t integerAdjust; + trio_long_double_t fractionAdjust; + trio_long_double_t workFractionNumber; + trio_long_double_t workFractionAdjust; + int fractionDigitsInspect; + BOOLEAN_T isNegative; + BOOLEAN_T isExponentNegative = FALSE; + BOOLEAN_T requireTwoDigitExponent; + BOOLEAN_T isHex; + TRIO_CONST char *digits; +# if TRIO_FEATURE_QUOTE + char *groupingPointer; +# endif + int i; + int offset; + BOOLEAN_T hasOnlyZeroes; + int leadingFractionZeroes = -1; + register int trailingZeroes; + BOOLEAN_T keepTrailingZeroes; + BOOLEAN_T keepDecimalPoint; + trio_long_double_t epsilon; + BOOLEAN_T adjustNumber = FALSE; + + assert(VALID(self)); + assert(VALID(self->OutStream)); + assert(((base >= MIN_BASE) && (base <= MAX_BASE)) || (base == NO_BASE)); + + /* Determine sign and look for special quantities */ + switch (trio_fpclassify_and_signbit(number, &isNegative)) + { + case TRIO_FP_NAN: + TrioWriteString(self, + (flags & FLAGS_UPPER) + ? NAN_UPPER + : NAN_LOWER, + flags, width, precision); + return; + + case TRIO_FP_INFINITE: + if (isNegative) + { + /* Negative infinity */ + TrioWriteString(self, + (flags & FLAGS_UPPER) + ? "-" INFINITE_UPPER + : "-" INFINITE_LOWER, + flags, width, precision); + return; + } + else + { + /* Positive infinity */ + TrioWriteString(self, + (flags & FLAGS_UPPER) + ? INFINITE_UPPER + : INFINITE_LOWER, + flags, width, precision); + return; + } + + default: + /* Finitude */ + break; + } + + /* Normal numbers */ + if (flags & FLAGS_LONGDOUBLE) + { + baseDigits = (base == 10) + ? LDBL_DIG + : (int)trio_floor(LDBL_MANT_DIG / TrioLogarithmBase(base)); + epsilon = LDBL_EPSILON; + } + else if (flags & FLAGS_SHORT) + { + baseDigits = (base == BASE_DECIMAL) + ? FLT_DIG + : (int)trio_floor(FLT_MANT_DIG / TrioLogarithmBase(base)); + epsilon = FLT_EPSILON; + } + else + { + baseDigits = (base == BASE_DECIMAL) + ? DBL_DIG + : (int)trio_floor(DBL_MANT_DIG / TrioLogarithmBase(base)); + epsilon = DBL_EPSILON; + } + + digits = (flags & FLAGS_UPPER) ? internalDigitsUpper : internalDigitsLower; + isHex = (base == BASE_HEX); + if (base == NO_BASE) + base = BASE_DECIMAL; + dblBase = (trio_long_double_t)base; + keepTrailingZeroes = !( (flags & FLAGS_ROUNDING) || + ( (flags & FLAGS_FLOAT_G) && + !(flags & FLAGS_ALTERNATIVE) ) ); + +# if TRIO_FEATURE_ROUNDING + if (flags & FLAGS_ROUNDING) + { + precision = baseDigits; + } +# endif + + if (precision == NO_PRECISION) + { + if (isHex) + { + keepTrailingZeroes = FALSE; + precision = FLT_MANT_DIG; + } + else + { + precision = FLT_DIG; + } + } + + if (isNegative) + { + number = -number; + } + + if (isHex) + { + flags |= FLAGS_FLOAT_E; + } + + reprocess: + + if (flags & FLAGS_FLOAT_G) + { + if (precision == 0) + precision = 1; + + if ( (number < TRIO_SUFFIX_LONG(1.0E-4)) || + (number >= TrioPower(base, (trio_long_double_t)precision)) ) + { + /* Use scientific notation */ + flags |= FLAGS_FLOAT_E; + } + else if (number < 1.0) + { + /* + * Use normal notation. If the integer part of the number is + * zero, then adjust the precision to include leading fractional + * zeros. + */ + workNumber = TrioLogarithm(number, base); + workNumber = TRIO_FABS(workNumber); + if (workNumber - trio_floor(workNumber) < epsilon) + workNumber--; + leadingFractionZeroes = (int)trio_floor(workNumber); + } + } + + if (flags & FLAGS_FLOAT_E) + { + /* Scale the number */ + workNumber = TrioLogarithm(number, base); + if (trio_isinf(workNumber) == -1) + { + exponent = 0; + /* Undo setting */ + if (flags & FLAGS_FLOAT_G) + flags &= ~FLAGS_FLOAT_E; + } + else + { + exponent = (int)trio_floor(workNumber); + workNumber = number; + /* + * The expression A * 10^-B is equivalent to A / 10^B but the former + * usually gives better accuracy. + */ + workNumber *= TrioPower(dblBase, (trio_long_double_t)-exponent); + if (trio_isinf(workNumber)) { + /* + * Scaling is done it two steps to avoid problems with subnormal + * numbers. + */ + workNumber /= TrioPower(dblBase, (trio_long_double_t)(exponent / 2)); + workNumber /= TrioPower(dblBase, (trio_long_double_t)(exponent - (exponent / 2))); + } + number = workNumber; + isExponentNegative = (exponent < 0); + uExponent = (isExponentNegative) ? -exponent : exponent; + if (isHex) + uExponent *= 4; /* log16(2) */ +#if TRIO_FEATURE_QUOTE + /* No thousand separators */ + flags &= ~FLAGS_QUOTE; +#endif + } + } + + integerNumber = trio_floor(number); + fractionNumber = number - integerNumber; + + /* + * Truncated number. + * + * Precision is number of significant digits for FLOAT_G and number of + * fractional digits for others. + */ + integerDigits = 1; + if (integerNumber > epsilon) + { + integerDigits += (int)TrioLogarithm(integerNumber, base); + } + + fractionDigits = precision; + if (flags & FLAGS_FLOAT_G) + { + if (leadingFractionZeroes > 0) + { + fractionDigits += leadingFractionZeroes; + } + if ((integerNumber > epsilon) || (number <= epsilon)) + { + fractionDigits -= integerDigits; + } + } + + dblFractionBase = TrioPower(base, fractionDigits); + + if (integerNumber < 1.0) + { + workNumber = number * dblFractionBase + TRIO_SUFFIX_LONG(0.5); + if (trio_floor(number * dblFractionBase) != trio_floor(workNumber)) + { + adjustNumber = TRUE; + /* Remove a leading fraction zero if fraction is rounded up */ + if ((int)TrioLogarithm(number * dblFractionBase, base) != (int)TrioLogarithm(workNumber, base)) + { + --leadingFractionZeroes; + } + } + workNumber /= dblFractionBase; + } + else + { + workNumber = number + TRIO_SUFFIX_LONG(0.5) / dblFractionBase; + adjustNumber = (trio_floor(number) != trio_floor(workNumber)); + } + if (adjustNumber) + { + if ((flags & FLAGS_FLOAT_G) && !(flags & FLAGS_FLOAT_E)) + { + /* The adjustment may require a change to scientific notation */ + if ( (workNumber < TRIO_SUFFIX_LONG(1.0E-4)) || + (workNumber >= TrioPower(base, (trio_long_double_t)precision)) ) + { + /* Use scientific notation */ + flags |= FLAGS_FLOAT_E; + goto reprocess; + } + } + + if (flags & FLAGS_FLOAT_E) + { + workDigits = 1 + TrioLogarithm(trio_floor(workNumber), base); + if (integerDigits == workDigits) + { + /* Adjust if the same number of digits are used */ + number += TRIO_SUFFIX_LONG(0.5) / dblFractionBase; + integerNumber = trio_floor(number); + fractionNumber = number - integerNumber; + } + else + { + /* Adjust if number was rounded up one digit (ie. 0.99 to 1.00) */ + exponent++; + isExponentNegative = (exponent < 0); + uExponent = (isExponentNegative) ? -exponent : exponent; + if (isHex) + uExponent *= 4; /* log16(2) */ + workNumber = (number + TRIO_SUFFIX_LONG(0.5) / dblFractionBase) / dblBase; + integerNumber = trio_floor(workNumber); + fractionNumber = workNumber - integerNumber; + } + } + else + { + if (workNumber > 1.0) + { + /* Adjust if number was rounded up one digit (ie. 99 to 100) */ + integerNumber = trio_floor(workNumber); + fractionNumber = 0.0; + integerDigits = (integerNumber > epsilon) + ? 1 + (int)TrioLogarithm(integerNumber, base) + : 1; + if (flags & FLAGS_FLOAT_G) + { + if (flags & FLAGS_ALTERNATIVE) + { + if ((integerNumber > epsilon) || (number <= epsilon)) + { + fractionDigits -= integerDigits; + } + } + else + { + fractionDigits = 0; + } + } + } + else + { + integerNumber = trio_floor(workNumber); + fractionNumber = workNumber - integerNumber; + if (flags & FLAGS_FLOAT_G) + { + if (flags & FLAGS_ALTERNATIVE) + { + fractionDigits = precision; + if (leadingFractionZeroes > 0) + { + fractionDigits += leadingFractionZeroes; + } + if ((integerNumber > epsilon) || (number <= epsilon)) + { + fractionDigits -= integerDigits; + } + } + } + } + } + } + + /* Estimate accuracy */ + integerAdjust = fractionAdjust = TRIO_SUFFIX_LONG(0.5); +# if TRIO_FEATURE_ROUNDING + if (flags & FLAGS_ROUNDING) + { + if (integerDigits > baseDigits) + { + integerThreshold = baseDigits; + fractionDigits = 0; + dblFractionBase = 1.0; + fractionThreshold = 0; + precision = 0; /* Disable decimal-point */ + integerAdjust = TrioPower(base, integerDigits - integerThreshold - 1); + fractionAdjust = 0.0; + } + else + { + integerThreshold = integerDigits; + fractionThreshold = fractionDigits - integerThreshold; + fractionAdjust = 1.0; + } + } + else +# endif + { + integerThreshold = INT_MAX; + fractionThreshold = INT_MAX; + } + + /* + * Calculate expected width. + * sign + integer part + thousands separators + decimal point + * + fraction + exponent + */ + fractionAdjust /= dblFractionBase; + hasOnlyZeroes = (trio_floor((fractionNumber + fractionAdjust) * + dblFractionBase) < epsilon); + keepDecimalPoint = ( (flags & FLAGS_ALTERNATIVE) || + !((precision == 0) || + (!keepTrailingZeroes && hasOnlyZeroes)) ); + + expectedWidth = integerDigits + fractionDigits; + + if (!keepTrailingZeroes) + { + trailingZeroes = 0; + workFractionNumber = fractionNumber; + workFractionAdjust = fractionAdjust; + fractionDigitsInspect = fractionDigits; + + if (integerDigits > integerThreshold) + { + fractionDigitsInspect = 0; + } + else if (fractionThreshold <= fractionDigits) + { + fractionDigitsInspect = fractionThreshold + 1; + } + + trailingZeroes = fractionDigits - fractionDigitsInspect; + for (i = 0; i < fractionDigitsInspect; i++) + { + workFractionNumber *= dblBase; + workFractionAdjust *= dblBase; + workNumber = trio_floor(workFractionNumber + workFractionAdjust); + workFractionNumber -= workNumber; + offset = (int)trio_fmod(workNumber, dblBase); + if (offset == 0) + { + trailingZeroes++; + } + else + { + trailingZeroes = 0; + } + } + expectedWidth -= trailingZeroes; + } + + if (keepDecimalPoint) + { + expectedWidth += internalDecimalPointLength; + } + +#if TRIO_FEATURE_QUOTE + if (flags & FLAGS_QUOTE) + { + expectedWidth += TrioCalcThousandSeparatorLength(integerDigits); + } +#endif + + if (isNegative || (flags & FLAGS_SHOWSIGN) || (flags & FLAGS_SPACE)) + { + expectedWidth += sizeof("-") - 1; + } + + exponentDigits = 0; + if (flags & FLAGS_FLOAT_E) + { + exponentDigits = (uExponent == 0) + ? 1 + : (int)trio_ceil(TrioLogarithm((double)(uExponent + 1), + (isHex) ? 10 : base)); + } + requireTwoDigitExponent = ((base == BASE_DECIMAL) && (exponentDigits == 1)); + if (exponentDigits > 0) + { + expectedWidth += exponentDigits; + expectedWidth += (requireTwoDigitExponent + ? sizeof("E+0") - 1 + : sizeof("E+") - 1); + } + + if (isHex) + { + expectedWidth += sizeof("0X") - 1; + } + + /* Output prefixing */ + if (flags & FLAGS_NILPADDING) + { + /* Leading zeros must be after sign */ + if (isNegative) + self->OutStream(self, '-'); + else if (flags & FLAGS_SHOWSIGN) + self->OutStream(self, '+'); + else if (flags & FLAGS_SPACE) + self->OutStream(self, ' '); + if (isHex) + { + self->OutStream(self, '0'); + self->OutStream(self, (flags & FLAGS_UPPER) ? 'X' : 'x'); + } + if (!(flags & FLAGS_LEFTADJUST)) + { + for (i = expectedWidth; i < width; i++) + { + self->OutStream(self, '0'); + } + } + } + else + { + /* Leading spaces must be before sign */ + if (!(flags & FLAGS_LEFTADJUST)) + { + for (i = expectedWidth; i < width; i++) + { + self->OutStream(self, CHAR_ADJUST); + } + } + if (isNegative) + self->OutStream(self, '-'); + else if (flags & FLAGS_SHOWSIGN) + self->OutStream(self, '+'); + else if (flags & FLAGS_SPACE) + self->OutStream(self, ' '); + if (isHex) + { + self->OutStream(self, '0'); + self->OutStream(self, (flags & FLAGS_UPPER) ? 'X' : 'x'); + } + } + + /* Output the integer part and thousand separators */ + for (i = 0; i < integerDigits; i++) + { + workNumber = trio_floor(((integerNumber + integerAdjust) + / TrioPower(base, integerDigits - i - 1))); + if (i > integerThreshold) + { + /* Beyond accuracy */ + self->OutStream(self, digits[0]); + } + else + { + self->OutStream(self, digits[(int)trio_fmod(workNumber, dblBase)]); + } + +#if TRIO_FEATURE_QUOTE + if (((flags & (FLAGS_FLOAT_E | FLAGS_QUOTE)) == FLAGS_QUOTE) + && TrioFollowedBySeparator(integerDigits - i)) + { + for (groupingPointer = internalThousandSeparator; + *groupingPointer != NIL; + groupingPointer++) + { + self->OutStream(self, *groupingPointer); + } + } +#endif + } + + /* Insert decimal point and build the fraction part */ + trailingZeroes = 0; + + if (keepDecimalPoint) + { + if (internalDecimalPoint) + { + self->OutStream(self, internalDecimalPoint); + } + else + { + for (i = 0; i < internalDecimalPointLength; i++) + { + self->OutStream(self, internalDecimalPointString[i]); + } + } + } + + for (i = 0; i < fractionDigits; i++) + { + if ((integerDigits > integerThreshold) || (i > fractionThreshold)) + { + /* Beyond accuracy */ + trailingZeroes++; + } + else + { + fractionNumber *= dblBase; + fractionAdjust *= dblBase; + workNumber = trio_floor(fractionNumber + fractionAdjust); + if (workNumber > fractionNumber) + { + /* fractionNumber should never become negative */ + fractionNumber = 0.0; + fractionAdjust = 0.0; + } + else + { + fractionNumber -= workNumber; + } + offset = (int)trio_fmod(workNumber, dblBase); + if (offset == 0) + { + trailingZeroes++; + } + else + { + while (trailingZeroes > 0) + { + /* Not trailing zeroes after all */ + self->OutStream(self, digits[0]); + trailingZeroes--; + } + self->OutStream(self, digits[offset]); + } + } + } + + if (keepTrailingZeroes) + { + while (trailingZeroes > 0) + { + self->OutStream(self, digits[0]); + trailingZeroes--; + } + } + + /* Output exponent */ + if (exponentDigits > 0) + { + self->OutStream(self, + isHex + ? ((flags & FLAGS_UPPER) ? 'P' : 'p') + : ((flags & FLAGS_UPPER) ? 'E' : 'e')); + self->OutStream(self, (isExponentNegative) ? '-' : '+'); + + /* The exponent must contain at least two digits */ + if (requireTwoDigitExponent) + self->OutStream(self, '0'); + + if (isHex) + base = 10; + exponentBase = (int)TrioPower(base, exponentDigits - 1); + for (i = 0; i < exponentDigits; i++) + { + self->OutStream(self, digits[(uExponent / exponentBase) % base]); + exponentBase /= base; + } + } + /* Output trailing spaces */ + if (flags & FLAGS_LEFTADJUST) + { + for (i = expectedWidth; i < width; i++) + { + self->OutStream(self, CHAR_ADJUST); + } + } +} +#endif /* TRIO_FEATURE_FLOAT */ + +/************************************************************************* + * TrioFormatProcess + * + * Description: + * This is the main engine for formatting output + */ +TRIO_PRIVATE int +TrioFormatProcess +TRIO_ARGS3((data, format, parameters), + trio_class_t *data, + TRIO_CONST char *format, + trio_parameter_t *parameters) +{ + int i; +#if TRIO_FEATURE_ERRNO + TRIO_CONST char *string; +#endif + trio_pointer_t pointer; + trio_flags_t flags; + int width; + int precision; + int base; + int offset; + + offset = 0; + i = 0; + + for (;;) + { + /* Skip the parameter entries */ + while (parameters[i].type == FORMAT_PARAMETER) + i++; + + /* Copy non conversion-specifier part of format string */ + while (offset < parameters[i].beginOffset) + { + if (CHAR_IDENTIFIER == format[offset] && CHAR_IDENTIFIER == format[offset + 1]) + { + data->OutStream(data, CHAR_IDENTIFIER); + offset += 2; + } + else + { + data->OutStream(data, format[offset++]); + } + } + + /* Abort if we reached end of format string */ + if (parameters[i].type == FORMAT_SENTINEL) + break; + + /* Ouput parameter */ + flags = parameters[i].flags; + + /* Find width */ + width = parameters[i].width; + if (flags & FLAGS_WIDTH_PARAMETER) + { + /* Get width from parameter list */ + width = (int)parameters[width].data.number.as_signed; + if (width < 0) + { + /* + * A negative width is the same as the - flag and + * a positive width. + */ + flags |= FLAGS_LEFTADJUST; + flags &= ~FLAGS_NILPADDING; + width = -width; + } + } + + /* Find precision */ + if (flags & FLAGS_PRECISION) + { + precision = parameters[i].precision; + if (flags & FLAGS_PRECISION_PARAMETER) + { + /* Get precision from parameter list */ + precision = (int)parameters[precision].data.number.as_signed; + if (precision < 0) + { + /* + * A negative precision is the same as no + * precision + */ + precision = NO_PRECISION; + } + } + } + else + { + precision = NO_PRECISION; + } + + /* Find base */ + if (NO_BASE != parameters[i].baseSpecifier) + { + /* Base from specifier has priority */ + base = parameters[i].baseSpecifier; + } + else if (flags & FLAGS_BASE_PARAMETER) + { + /* Get base from parameter list */ + base = parameters[i].base; + base = (int)parameters[base].data.number.as_signed; + } + else + { + /* Use base from format string */ + base = parameters[i].base; + } + + switch (parameters[i].type) + { + case FORMAT_CHAR: +#if TRIO_FEATURE_QUOTE + if (flags & FLAGS_QUOTE) + data->OutStream(data, CHAR_QUOTE); +#endif + if (! (flags & FLAGS_LEFTADJUST)) + { + while (--width > 0) + data->OutStream(data, CHAR_ADJUST); + } +#if TRIO_FEATURE_WIDECHAR + if (flags & FLAGS_WIDECHAR) + { + TrioWriteWideStringCharacter(data, + (trio_wchar_t)parameters[i].data.number.as_signed, + flags, + NO_WIDTH); + } + else +#endif + { + TrioWriteStringCharacter(data, + (int)parameters[i].data.number.as_signed, + flags); + } + + if (flags & FLAGS_LEFTADJUST) + { + while(--width > 0) + data->OutStream(data, CHAR_ADJUST); + } +#if TRIO_FEATURE_QUOTE + if (flags & FLAGS_QUOTE) + data->OutStream(data, CHAR_QUOTE); +#endif + + break; /* FORMAT_CHAR */ + + case FORMAT_INT: + TrioWriteNumber(data, + parameters[i].data.number.as_unsigned, + flags, + width, + precision, + base); + + break; /* FORMAT_INT */ + +#if TRIO_FEATURE_FLOAT + case FORMAT_DOUBLE: + TrioWriteDouble(data, + parameters[i].data.longdoubleNumber, + flags, + width, + precision, + base); + break; /* FORMAT_DOUBLE */ +#endif + + case FORMAT_STRING: +#if TRIO_FEATURE_WIDECHAR + if (flags & FLAGS_WIDECHAR) + { + TrioWriteWideString(data, + parameters[i].data.wstring, + flags, + width, + precision); + } + else +#endif + { + TrioWriteString(data, + parameters[i].data.string, + flags, + width, + precision); + } + break; /* FORMAT_STRING */ + + case FORMAT_POINTER: + { + trio_reference_t reference; + + reference.data = data; + reference.parameter = ¶meters[i]; + trio_print_pointer(&reference, parameters[i].data.pointer); + } + break; /* FORMAT_POINTER */ + + case FORMAT_COUNT: + pointer = parameters[i].data.pointer; + if (NULL != pointer) + { + /* + * C99 paragraph 7.19.6.1.8 says "the number of + * characters written to the output stream so far by + * this call", which is data->actually.committed + */ +#if TRIO_FEATURE_SIZE_T || TRIO_FEATURE_SIZE_T_UPPER + if (flags & FLAGS_SIZE_T) + *(size_t *)pointer = (size_t)data->actually.committed; + else +#endif +#if TRIO_FEATURE_PTRDIFF_T + if (flags & FLAGS_PTRDIFF_T) + *(ptrdiff_t *)pointer = (ptrdiff_t)data->actually.committed; + else +#endif +#if TRIO_FEATURE_INTMAX_T + if (flags & FLAGS_INTMAX_T) + *(trio_intmax_t *)pointer = (trio_intmax_t)data->actually.committed; + else +#endif + if (flags & FLAGS_QUAD) + { + *(trio_ulonglong_t *)pointer = (trio_ulonglong_t)data->actually.committed; + } + else if (flags & FLAGS_LONG) + { + *(long int *)pointer = (long int)data->actually.committed; + } + else if (flags & FLAGS_SHORT) + { + *(short int *)pointer = (short int)data->actually.committed; + } + else + { + *(int *)pointer = (int)data->actually.committed; + } + } + break; /* FORMAT_COUNT */ + + case FORMAT_PARAMETER: + break; /* FORMAT_PARAMETER */ + +#if TRIO_FEATURE_ERRNO + case FORMAT_ERRNO: + string = trio_error(parameters[i].data.errorNumber); + if (string) + { + TrioWriteString(data, + string, + flags, + width, + precision); + } + else + { + data->OutStream(data, '#'); + TrioWriteNumber(data, + (trio_uintmax_t)parameters[i].data.errorNumber, + flags, + width, + precision, + BASE_DECIMAL); + } + break; /* FORMAT_ERRNO */ +#endif /* TRIO_FEATURE_ERRNO */ + +#if TRIO_FEATURE_USER_DEFINED + case FORMAT_USER_DEFINED: + { + trio_reference_t reference; + trio_userdef_t *def = NULL; + + if (parameters[i].flags & FLAGS_USER_DEFINED_PARAMETER) + { + /* Use handle */ + if ((i > 0) || + (parameters[i - 1].type == FORMAT_PARAMETER)) + def = (trio_userdef_t *)parameters[i - 1].data.pointer; + } + else + { + /* Look up namespace */ + def = TrioFindNamespace(parameters[i].user_defined.namespace, NULL); + } + if (def) + { + reference.data = data; + reference.parameter = ¶meters[i]; + def->callback(&reference); + } + } + break; +#endif /* TRIO_FEATURE_USER_DEFINED */ + + default: + break; + } /* switch parameter type */ + + /* Prepare for next */ + offset = parameters[i].endOffset; + i++; + } + + return data->processed; +} + +/************************************************************************* + * TrioFormatRef + */ +#if TRIO_EXTENSION +TRIO_PRIVATE int +TrioFormatRef +TRIO_ARGS4((reference, format, arglist, argarray), + trio_reference_t *reference, + TRIO_CONST char *format, + va_list arglist, + trio_pointer_t *argarray) +{ + int status; + trio_parameter_t parameters[MAX_PARAMETERS]; + + status = TrioParse(TYPE_PRINT, format, parameters, arglist, argarray); + if (status < 0) + return status; + + status = TrioFormatProcess(reference->data, format, parameters); + if (reference->data->error != 0) + { + status = reference->data->error; + } + return status; +} +#endif /* TRIO_EXTENSION */ + +/************************************************************************* + * TrioFormat + */ +TRIO_PRIVATE int +TrioFormat +TRIO_ARGS6((destination, destinationSize, OutStream, format, arglist, argarray), + trio_pointer_t destination, + size_t destinationSize, + void (*OutStream) TRIO_PROTO((trio_class_t *, int)), + TRIO_CONST char *format, + va_list arglist, + trio_pointer_t *argarray) +{ + int status; + trio_class_t data; + trio_parameter_t parameters[MAX_PARAMETERS]; + + assert(VALID(OutStream)); + assert(VALID(format)); + + memset(&data, 0, sizeof(data)); + data.OutStream = OutStream; + data.location = destination; + data.max = destinationSize; + data.error = 0; + +#if defined(USE_LOCALE) + if (NULL == internalLocaleValues) + { + TrioSetLocale(); + } +#endif + + status = TrioParse(TYPE_PRINT, format, parameters, arglist, argarray); + if (status < 0) + return status; + + status = TrioFormatProcess(&data, format, parameters); + if (data.error != 0) + { + status = data.error; + } + return status; +} + +/************************************************************************* + * TrioOutStreamFile + */ +#if TRIO_FEATURE_FILE || TRIO_FEATURE_STDIO +TRIO_PRIVATE void +TrioOutStreamFile +TRIO_ARGS2((self, output), + trio_class_t *self, + int output) +{ + FILE *file; + + assert(VALID(self)); + assert(VALID(self->location)); + + file = (FILE *)self->location; + self->processed++; + if (fputc(output, file) == EOF) + { + self->error = TRIO_ERROR_RETURN(TRIO_EOF, 0); + } + else + { + self->actually.committed++; + } +} +#endif /* TRIO_FEATURE_FILE || TRIO_FEATURE_STDIO */ + +/************************************************************************* + * TrioOutStreamFileDescriptor + */ +#if TRIO_FEATURE_FD +TRIO_PRIVATE void +TrioOutStreamFileDescriptor +TRIO_ARGS2((self, output), + trio_class_t *self, + int output) +{ + int fd; + char ch; + + assert(VALID(self)); + + fd = *((int *)self->location); + ch = (char)output; + self->processed++; + if (write(fd, &ch, sizeof(char)) == -1) + { + self->error = TRIO_ERROR_RETURN(TRIO_ERRNO, 0); + } + else + { + self->actually.committed++; + } +} +#endif /* TRIO_FEATURE_FD */ + +/************************************************************************* + * TrioOutStreamCustom + */ +#if TRIO_FEATURE_CLOSURE +TRIO_PRIVATE void +TrioOutStreamCustom +TRIO_ARGS2((self, output), + trio_class_t *self, + int output) +{ + int status; + trio_custom_t *data; + + assert(VALID(self)); + assert(VALID(self->location)); + + data = (trio_custom_t *)self->location; + if (data->stream.out) + { + status = (data->stream.out)(data->closure, output); + if (status >= 0) + { + self->actually.committed++; + } + else + { + if (self->error == 0) + { + self->error = TRIO_ERROR_RETURN(TRIO_ECUSTOM, -status); + } + } + } + self->processed++; +} +#endif /* TRIO_FEATURE_CLOSURE */ + +/************************************************************************* + * TrioOutStreamString + */ +TRIO_PRIVATE void +TrioOutStreamString +TRIO_ARGS2((self, output), + trio_class_t *self, + int output) +{ + char **buffer; + + assert(VALID(self)); + assert(VALID(self->location)); + + buffer = (char **)self->location; + **buffer = (char)output; + (*buffer)++; + self->processed++; + self->actually.committed++; +} + +/************************************************************************* + * TrioOutStreamStringMax + */ +TRIO_PRIVATE void +TrioOutStreamStringMax +TRIO_ARGS2((self, output), + trio_class_t *self, + int output) +{ + char **buffer; + + assert(VALID(self)); + assert(VALID(self->location)); + + buffer = (char **)self->location; + + if (self->processed < self->max) + { + **buffer = (char)output; + (*buffer)++; + self->actually.committed++; + } + self->processed++; +} + +/************************************************************************* + * TrioOutStreamStringDynamic + */ +#if TRIO_FEATURE_DYNAMICSTRING +TRIO_PRIVATE void +TrioOutStreamStringDynamic +TRIO_ARGS2((self, output), + trio_class_t *self, + int output) +{ + assert(VALID(self)); + assert(VALID(self->location)); + + if (self->error == 0) + { + trio_xstring_append_char((trio_string_t *)self->location, + (char)output); + self->actually.committed++; + } + /* The processed variable must always be increased */ + self->processed++; +} +#endif /* TRIO_FEATURE_DYNAMICSTRING */ + +/************************************************************************* + * + * Formatted printing functions + * + ************************************************************************/ + +#if defined(TRIO_DOCUMENTATION) +# include "doc/doc_printf.h" +#endif +/** @addtogroup Printf + @{ +*/ + +/************************************************************************* + * printf + */ + +/** + Print to standard output stream. + + @param format Formatting string. + @param ... Arguments. + @return Number of printed characters. + */ +#if TRIO_FEATURE_STDIO +TRIO_PUBLIC int +trio_printf +TRIO_VARGS2((format, va_alist), + TRIO_CONST char *format, + TRIO_VA_DECL) +{ + int status; + va_list args; + + assert(VALID(format)); + + TRIO_VA_START(args, format); + status = TrioFormat(stdout, 0, TrioOutStreamFile, format, args, NULL); + TRIO_VA_END(args); + return status; +} +#endif /* TRIO_FEATURE_STDIO */ + +/** + Print to standard output stream. + + @param format Formatting string. + @param args Arguments. + @return Number of printed characters. + */ +#if TRIO_FEATURE_STDIO +TRIO_PUBLIC int +trio_vprintf +TRIO_ARGS2((format, args), + TRIO_CONST char *format, + va_list args) +{ + assert(VALID(format)); + + return TrioFormat(stdout, 0, TrioOutStreamFile, format, args, NULL); +} +#endif /* TRIO_FEATURE_STDIO */ + +/** + Print to standard output stream. + + @param format Formatting string. + @param args Arguments. + @return Number of printed characters. + */ +#if TRIO_FEATURE_STDIO +TRIO_PUBLIC int +trio_printfv +TRIO_ARGS2((format, args), + TRIO_CONST char *format, + trio_pointer_t * args) +{ + static va_list unused; + + assert(VALID(format)); + + return TrioFormat(stdout, 0, TrioOutStreamFile, format, unused, args); +} +#endif /* TRIO_FEATURE_STDIO */ + +/************************************************************************* + * fprintf + */ + +/** + Print to file. + + @param file File pointer. + @param format Formatting string. + @param ... Arguments. + @return Number of printed characters. + */ +#if TRIO_FEATURE_FILE +TRIO_PUBLIC int +trio_fprintf +TRIO_VARGS3((file, format, va_alist), + FILE *file, + TRIO_CONST char *format, + TRIO_VA_DECL) +{ + int status; + va_list args; + + assert(VALID(file)); + assert(VALID(format)); + + TRIO_VA_START(args, format); + status = TrioFormat(file, 0, TrioOutStreamFile, format, args, NULL); + TRIO_VA_END(args); + return status; +} +#endif /* TRIO_FEATURE_FILE */ + +/** + Print to file. + + @param file File pointer. + @param format Formatting string. + @param args Arguments. + @return Number of printed characters. + */ +#if TRIO_FEATURE_FILE +TRIO_PUBLIC int +trio_vfprintf +TRIO_ARGS3((file, format, args), + FILE *file, + TRIO_CONST char *format, + va_list args) +{ + assert(VALID(file)); + assert(VALID(format)); + + return TrioFormat(file, 0, TrioOutStreamFile, format, args, NULL); +} +#endif /* TRIO_FEATURE_FILE */ + +/** + Print to file. + + @param file File pointer. + @param format Formatting string. + @param args Arguments. + @return Number of printed characters. + */ +#if TRIO_FEATURE_FILE +TRIO_PUBLIC int +trio_fprintfv +TRIO_ARGS3((file, format, args), + FILE *file, + TRIO_CONST char *format, + trio_pointer_t * args) +{ + static va_list unused; + + assert(VALID(file)); + assert(VALID(format)); + + return TrioFormat(file, 0, TrioOutStreamFile, format, unused, args); +} +#endif /* TRIO_FEATURE_FILE */ + +/************************************************************************* + * dprintf + */ + +/** + Print to file descriptor. + + @param fd File descriptor. + @param format Formatting string. + @param ... Arguments. + @return Number of printed characters. + */ +#if TRIO_FEATURE_FD +TRIO_PUBLIC int +trio_dprintf +TRIO_VARGS3((fd, format, va_alist), + int fd, + TRIO_CONST char *format, + TRIO_VA_DECL) +{ + int status; + va_list args; + + assert(VALID(format)); + + TRIO_VA_START(args, format); + status = TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, args, NULL); + TRIO_VA_END(args); + return status; +} +#endif /* TRIO_FEATURE_FD */ + +/** + Print to file descriptor. + + @param fd File descriptor. + @param format Formatting string. + @param args Arguments. + @return Number of printed characters. + */ +#if TRIO_FEATURE_FD +TRIO_PUBLIC int +trio_vdprintf +TRIO_ARGS3((fd, format, args), + int fd, + TRIO_CONST char *format, + va_list args) +{ + assert(VALID(format)); + + return TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, args, NULL); +} +#endif /* TRIO_FEATURE_FD */ + +/** + Print to file descriptor. + + @param fd File descriptor. + @param format Formatting string. + @param args Arguments. + @return Number of printed characters. + */ +#if TRIO_FEATURE_FD +TRIO_PUBLIC int +trio_dprintfv +TRIO_ARGS3((fd, format, args), + int fd, + TRIO_CONST char *format, + trio_pointer_t *args) +{ + static va_list unused; + + assert(VALID(format)); + + return TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, unused, args); +} +#endif /* TRIO_FEATURE_FD */ + +/************************************************************************* + * cprintf + */ +#if TRIO_FEATURE_CLOSURE +TRIO_PUBLIC int +trio_cprintf +TRIO_VARGS4((stream, closure, format, va_alist), + trio_outstream_t stream, + trio_pointer_t closure, + TRIO_CONST char *format, + TRIO_VA_DECL) +{ + int status; + va_list args; + trio_custom_t data; + + assert(VALID(stream)); + assert(VALID(format)); + + TRIO_VA_START(args, format); + data.stream.out = stream; + data.closure = closure; + status = TrioFormat(&data, 0, TrioOutStreamCustom, format, args, NULL); + TRIO_VA_END(args); + return status; +} +#endif /* TRIO_FEATURE_CLOSURE */ + +#if TRIO_FEATURE_CLOSURE +TRIO_PUBLIC int +trio_vcprintf +TRIO_ARGS4((stream, closure, format, args), + trio_outstream_t stream, + trio_pointer_t closure, + TRIO_CONST char *format, + va_list args) +{ + trio_custom_t data; + + assert(VALID(stream)); + assert(VALID(format)); + + data.stream.out = stream; + data.closure = closure; + return TrioFormat(&data, 0, TrioOutStreamCustom, format, args, NULL); +} +#endif /* TRIO_FEATURE_CLOSURE */ + +#if TRIO_FEATURE_CLOSURE +TRIO_PUBLIC int +trio_cprintfv +TRIO_ARGS4((stream, closure, format, args), + trio_outstream_t stream, + trio_pointer_t closure, + TRIO_CONST char *format, + void **args) +{ + static va_list unused; + trio_custom_t data; + + assert(VALID(stream)); + assert(VALID(format)); + + data.stream.out = stream; + data.closure = closure; + return TrioFormat(&data, 0, TrioOutStreamCustom, format, unused, args); +} +#endif /* TRIO_FEATURE_CLOSURE */ + +/************************************************************************* + * sprintf + */ + +/** + Print to string. + + @param buffer Output string. + @param format Formatting string. + @param ... Arguments. + @return Number of printed characters. + */ +TRIO_PUBLIC int +trio_sprintf +TRIO_VARGS3((buffer, format, va_alist), + char *buffer, + TRIO_CONST char *format, + TRIO_VA_DECL) +{ + int status; + va_list args; + + assert(VALID(buffer)); + assert(VALID(format)); + + TRIO_VA_START(args, format); + status = TrioFormat(&buffer, 0, TrioOutStreamString, format, args, NULL); + *buffer = NIL; /* Terminate with NIL character */ + TRIO_VA_END(args); + return status; +} + +/** + Print to string. + + @param buffer Output string. + @param format Formatting string. + @param args Arguments. + @return Number of printed characters. + */ +TRIO_PUBLIC int +trio_vsprintf +TRIO_ARGS3((buffer, format, args), + char *buffer, + TRIO_CONST char *format, + va_list args) +{ + int status; + + assert(VALID(buffer)); + assert(VALID(format)); + + status = TrioFormat(&buffer, 0, TrioOutStreamString, format, args, NULL); + *buffer = NIL; + return status; +} + +/** + Print to string. + + @param buffer Output string. + @param format Formatting string. + @param args Arguments. + @return Number of printed characters. + */ +TRIO_PUBLIC int +trio_sprintfv +TRIO_ARGS3((buffer, format, args), + char *buffer, + TRIO_CONST char *format, + trio_pointer_t *args) +{ + static va_list unused; + int status; + + assert(VALID(buffer)); + assert(VALID(format)); + + status = TrioFormat(&buffer, 0, TrioOutStreamString, format, unused, args); + *buffer = NIL; + return status; +} + +/************************************************************************* + * snprintf + */ + +/** + Print at most @p max characters to string. + + @param buffer Output string. + @param max Maximum number of characters to print. + @param format Formatting string. + @param ... Arguments. + @return Number of printed characters. + */ +TRIO_PUBLIC int +trio_snprintf +TRIO_VARGS4((buffer, max, format, va_alist), + char *buffer, + size_t max, + TRIO_CONST char *format, + TRIO_VA_DECL) +{ + int status; + va_list args; + + assert(VALID(buffer) || (max == 0)); + assert(VALID(format)); + + TRIO_VA_START(args, format); + status = TrioFormat(&buffer, max > 0 ? max - 1 : 0, + TrioOutStreamStringMax, format, args, NULL); + if (max > 0) + *buffer = NIL; + TRIO_VA_END(args); + return status; +} + +/** + Print at most @p max characters to string. + + @param buffer Output string. + @param max Maximum number of characters to print. + @param format Formatting string. + @param args Arguments. + @return Number of printed characters. + */ +TRIO_PUBLIC int +trio_vsnprintf +TRIO_ARGS4((buffer, max, format, args), + char *buffer, + size_t max, + TRIO_CONST char *format, + va_list args) +{ + int status; + + assert(VALID(buffer) || (max == 0)); + assert(VALID(format)); + + status = TrioFormat(&buffer, max > 0 ? max - 1 : 0, + TrioOutStreamStringMax, format, args, NULL); + if (max > 0) + *buffer = NIL; + return status; +} + +/** + Print at most @p max characters to string. + + @param buffer Output string. + @param max Maximum number of characters to print. + @param format Formatting string. + @param args Arguments. + @return Number of printed characters. + */ +TRIO_PUBLIC int +trio_snprintfv +TRIO_ARGS4((buffer, max, format, args), + char *buffer, + size_t max, + TRIO_CONST char *format, + trio_pointer_t *args) +{ + static va_list unused; + int status; + + assert(VALID(buffer) || (max == 0)); + assert(VALID(format)); + + status = TrioFormat(&buffer, max > 0 ? max - 1 : 0, + TrioOutStreamStringMax, format, unused, args); + if (max > 0) + *buffer = NIL; + return status; +} + +/************************************************************************* + * snprintfcat + * Appends the new string to the buffer string overwriting the '\0' + * character at the end of buffer. + */ +#if TRIO_EXTENSION +TRIO_PUBLIC int +trio_snprintfcat +TRIO_VARGS4((buffer, max, format, va_alist), + char *buffer, + size_t max, + TRIO_CONST char *format, + TRIO_VA_DECL) +{ + int status; + va_list args; + size_t buf_len; + + TRIO_VA_START(args, format); + + assert(VALID(buffer)); + assert(VALID(format)); + + buf_len = trio_length(buffer); + buffer = &buffer[buf_len]; + + status = TrioFormat(&buffer, max - 1 - buf_len, + TrioOutStreamStringMax, format, args, NULL); + TRIO_VA_END(args); + *buffer = NIL; + return status; +} +#endif + +#if TRIO_EXTENSION +TRIO_PUBLIC int +trio_vsnprintfcat +TRIO_ARGS4((buffer, max, format, args), + char *buffer, + size_t max, + TRIO_CONST char *format, + va_list args) +{ + int status; + size_t buf_len; + + assert(VALID(buffer)); + assert(VALID(format)); + + buf_len = trio_length(buffer); + buffer = &buffer[buf_len]; + status = TrioFormat(&buffer, max - 1 - buf_len, + TrioOutStreamStringMax, format, args, NULL); + *buffer = NIL; + return status; +} +#endif + +/************************************************************************* + * trio_aprintf + */ + +#if TRIO_DEPRECATED && TRIO_FEATURE_DYNAMICSTRING +TRIO_PUBLIC char * +trio_aprintf +TRIO_VARGS2((format, va_alist), + TRIO_CONST char *format, + TRIO_VA_DECL) +{ + va_list args; + trio_string_t *info; + char *result = NULL; + + assert(VALID(format)); + + info = trio_xstring_duplicate(""); + if (info) + { + TRIO_VA_START(args, format); + (void)TrioFormat(info, 0, TrioOutStreamStringDynamic, + format, args, NULL); + TRIO_VA_END(args); + + trio_string_terminate(info); + result = trio_string_extract(info); + trio_string_destroy(info); + } + return result; +} +#endif /* TRIO_DEPRECATED && TRIO_FEATURE_DYNAMICSTRING */ + +#if TRIO_DEPRECATED && TRIO_FEATURE_DYNAMICSTRING +TRIO_PUBLIC char * +trio_vaprintf +TRIO_ARGS2((format, args), + TRIO_CONST char *format, + va_list args) +{ + trio_string_t *info; + char *result = NULL; + + assert(VALID(format)); + + info = trio_xstring_duplicate(""); + if (info) + { + (void)TrioFormat(info, 0, TrioOutStreamStringDynamic, + format, args, NULL); + trio_string_terminate(info); + result = trio_string_extract(info); + trio_string_destroy(info); + } + return result; +} +#endif /* TRIO_DEPRECATED && TRIO_FEATURE_DYNAMICSTRING */ + +/** + Allocate and print to string. + The memory allocated and returned by @p result must be freed by the + calling application. + + @param result Output string. + @param format Formatting string. + @param ... Arguments. + @return Number of printed characters. + */ +#if TRIO_FEATURE_DYNAMICSTRING +TRIO_PUBLIC int +trio_asprintf +TRIO_VARGS3((result, format, va_alist), + char **result, + TRIO_CONST char *format, + TRIO_VA_DECL) +{ + va_list args; + int status; + trio_string_t *info; + + assert(VALID(format)); + + *result = NULL; + + info = trio_xstring_duplicate(""); + if (info == NULL) + { + status = TRIO_ERROR_RETURN(TRIO_ENOMEM, 0); + } + else + { + TRIO_VA_START(args, format); + status = TrioFormat(info, 0, TrioOutStreamStringDynamic, + format, args, NULL); + TRIO_VA_END(args); + if (status >= 0) + { + trio_string_terminate(info); + *result = trio_string_extract(info); + } + trio_string_destroy(info); + } + return status; +} +#endif /* TRIO_FEATURE_DYNAMICSTRING */ + +/** + Allocate and print to string. + The memory allocated and returned by @p result must be freed by the + calling application. + + @param result Output string. + @param format Formatting string. + @param args Arguments. + @return Number of printed characters. + */ +#if TRIO_FEATURE_DYNAMICSTRING +TRIO_PUBLIC int +trio_vasprintf +TRIO_ARGS3((result, format, args), + char **result, + TRIO_CONST char *format, + va_list args) +{ + int status; + trio_string_t *info; + + assert(VALID(format)); + + *result = NULL; + + info = trio_xstring_duplicate(""); + if (info == NULL) + { + status = TRIO_ERROR_RETURN(TRIO_ENOMEM, 0); + } + else + { + status = TrioFormat(info, 0, TrioOutStreamStringDynamic, + format, args, NULL); + if (status >= 0) + { + trio_string_terminate(info); + *result = trio_string_extract(info); + } + trio_string_destroy(info); + } + return status; +} +#endif /* TRIO_FEATURE_DYNAMICSTRING */ + +/** + Allocate and print to string. + The memory allocated and returned by @p result must be freed by the + calling application. + + @param result Output string. + @param format Formatting string. + @param args Arguments. + @return Number of printed characters. + */ +#if TRIO_FEATURE_DYNAMICSTRING +TRIO_PUBLIC int +trio_asprintfv +TRIO_ARGS3((result, format, args), + char **result, + TRIO_CONST char *format, + trio_pointer_t * args) +{ + static va_list unused; + int status; + trio_string_t *info; + + assert(VALID(format)); + + *result = NULL; + + info = trio_xstring_duplicate(""); + if (info == NULL) + { + status = TRIO_ERROR_RETURN(TRIO_ENOMEM, 0); + } + else + { + status = TrioFormat(info, 0, TrioOutStreamStringDynamic, + format, unused, args); + if (status >= 0) + { + trio_string_terminate(info); + *result = trio_string_extract(info); + } + trio_string_destroy(info); + } + return status; +} +#endif /* TRIO_FEATURE_DYNAMICSTRING */ + +/** @} End of Printf documentation module */ + +/************************************************************************* + * + * CALLBACK + * + ************************************************************************/ + +#if defined(TRIO_DOCUMENTATION) +# include "doc/doc_register.h" +#endif +/** + @addtogroup UserDefined + @{ +*/ + +#if TRIO_FEATURE_USER_DEFINED + +/************************************************************************* + * trio_register + */ + +/** + Register new user-defined specifier. + + @param callback + @param name + @return Handle. + */ +TRIO_PUBLIC trio_pointer_t +trio_register +TRIO_ARGS2((callback, name), + trio_callback_t callback, + TRIO_CONST char *name) +{ + trio_userdef_t *def; + trio_userdef_t *prev = NULL; + + if (callback == NULL) + return NULL; + + if (name) + { + /* Handle built-in namespaces */ + if (name[0] == ':') + { + if (trio_equal(name, ":enter")) + { + internalEnterCriticalRegion = callback; + } + else if (trio_equal(name, ":leave")) + { + internalLeaveCriticalRegion = callback; + } + return NULL; + } + + /* Bail out if namespace is too long */ + if (trio_length(name) >= MAX_USER_NAME) + return NULL; + + /* Bail out if namespace already is registered */ + def = TrioFindNamespace(name, &prev); + if (def) + return NULL; + } + + def = (trio_userdef_t *)TRIO_MALLOC(sizeof(trio_userdef_t)); + if (def) + { + if (internalEnterCriticalRegion) + (void)internalEnterCriticalRegion(NULL); + + if (name) + { + /* Link into internal list */ + if (prev == NULL) + internalUserDef = def; + else + prev->next = def; + } + /* Initialize */ + def->callback = callback; + def->name = (name == NULL) + ? NULL + : trio_duplicate(name); + def->next = NULL; + + if (internalLeaveCriticalRegion) + (void)internalLeaveCriticalRegion(NULL); + } + return (trio_pointer_t)def; +} + +/** + Unregister an existing user-defined specifier. + + @param handle + */ +void +trio_unregister +TRIO_ARGS1((handle), + trio_pointer_t handle) +{ + trio_userdef_t *self = (trio_userdef_t *)handle; + trio_userdef_t *def; + trio_userdef_t *prev = NULL; + + assert(VALID(self)); + + if (self->name) + { + def = TrioFindNamespace(self->name, &prev); + if (def) + { + if (internalEnterCriticalRegion) + (void)internalEnterCriticalRegion(NULL); + + if (prev == NULL) + internalUserDef = internalUserDef->next; + else + prev->next = def->next; + + if (internalLeaveCriticalRegion) + (void)internalLeaveCriticalRegion(NULL); + } + trio_destroy(self->name); + } + TRIO_FREE(self); +} + +/************************************************************************* + * trio_get_format [public] + */ +TRIO_CONST char * +trio_get_format +TRIO_ARGS1((ref), + trio_pointer_t ref) +{ +#if TRIO_FEATURE_USER_DEFINED + assert(((trio_reference_t *)ref)->parameter->type == FORMAT_USER_DEFINED); +#endif + + return (((trio_reference_t *)ref)->parameter->user_data); +} + +/************************************************************************* + * trio_get_argument [public] + */ +TRIO_CONST trio_pointer_t +trio_get_argument +TRIO_ARGS1((ref), + trio_pointer_t ref) +{ +#if TRIO_FEATURE_USER_DEFINED + assert(((trio_reference_t *)ref)->parameter->type == FORMAT_USER_DEFINED); +#endif + + return ((trio_reference_t *)ref)->parameter->data.pointer; +} + +/************************************************************************* + * trio_get_width / trio_set_width [public] + */ +int +trio_get_width +TRIO_ARGS1((ref), + trio_pointer_t ref) +{ + return ((trio_reference_t *)ref)->parameter->width; +} + +void +trio_set_width +TRIO_ARGS2((ref, width), + trio_pointer_t ref, + int width) +{ + ((trio_reference_t *)ref)->parameter->width = width; +} + +/************************************************************************* + * trio_get_precision / trio_set_precision [public] + */ +int +trio_get_precision +TRIO_ARGS1((ref), + trio_pointer_t ref) +{ + return (((trio_reference_t *)ref)->parameter->precision); +} + +void +trio_set_precision +TRIO_ARGS2((ref, precision), + trio_pointer_t ref, + int precision) +{ + ((trio_reference_t *)ref)->parameter->precision = precision; +} + +/************************************************************************* + * trio_get_base / trio_set_base [public] + */ +int +trio_get_base +TRIO_ARGS1((ref), + trio_pointer_t ref) +{ + return (((trio_reference_t *)ref)->parameter->base); +} + +void +trio_set_base +TRIO_ARGS2((ref, base), + trio_pointer_t ref, + int base) +{ + ((trio_reference_t *)ref)->parameter->base = base; +} + +/************************************************************************* + * trio_get_long / trio_set_long [public] + */ +int +trio_get_long +TRIO_ARGS1((ref), + trio_pointer_t ref) +{ + return (((trio_reference_t *)ref)->parameter->flags & FLAGS_LONG) + ? TRUE + : FALSE; +} + +void +trio_set_long +TRIO_ARGS2((ref, is_long), + trio_pointer_t ref, + int is_long) +{ + if (is_long) + ((trio_reference_t *)ref)->parameter->flags |= FLAGS_LONG; + else + ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_LONG; +} + +/************************************************************************* + * trio_get_longlong / trio_set_longlong [public] + */ +int +trio_get_longlong +TRIO_ARGS1((ref), + trio_pointer_t ref) +{ + return (((trio_reference_t *)ref)->parameter->flags & FLAGS_QUAD) + ? TRUE + : FALSE; +} + +void +trio_set_longlong +TRIO_ARGS2((ref, is_longlong), + trio_pointer_t ref, + int is_longlong) +{ + if (is_longlong) + ((trio_reference_t *)ref)->parameter->flags |= FLAGS_QUAD; + else + ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_QUAD; +} + +/************************************************************************* + * trio_get_longdouble / trio_set_longdouble [public] + */ +# if TRIO_FEATURE_FLOAT +int +trio_get_longdouble +TRIO_ARGS1((ref), + trio_pointer_t ref) +{ + return (((trio_reference_t *)ref)->parameter->flags & FLAGS_LONGDOUBLE) + ? TRUE + : FALSE; +} + +void +trio_set_longdouble +TRIO_ARGS2((ref, is_longdouble), + trio_pointer_t ref, + int is_longdouble) +{ + if (is_longdouble) + ((trio_reference_t *)ref)->parameter->flags |= FLAGS_LONGDOUBLE; + else + ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_LONGDOUBLE; +} +# endif /* TRIO_FEATURE_FLOAT */ + +/************************************************************************* + * trio_get_short / trio_set_short [public] + */ +int +trio_get_short +TRIO_ARGS1((ref), + trio_pointer_t ref) +{ + return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SHORT) + ? TRUE + : FALSE; +} + +void +trio_set_short +TRIO_ARGS2((ref, is_short), + trio_pointer_t ref, + int is_short) +{ + if (is_short) + ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SHORT; + else + ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SHORT; +} + +/************************************************************************* + * trio_get_shortshort / trio_set_shortshort [public] + */ +int +trio_get_shortshort +TRIO_ARGS1((ref), + trio_pointer_t ref) +{ + return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SHORTSHORT) + ? TRUE + : FALSE; +} + +void +trio_set_shortshort +TRIO_ARGS2((ref, is_shortshort), + trio_pointer_t ref, + int is_shortshort) +{ + if (is_shortshort) + ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SHORTSHORT; + else + ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SHORTSHORT; +} + +/************************************************************************* + * trio_get_alternative / trio_set_alternative [public] + */ +int +trio_get_alternative +TRIO_ARGS1((ref), + trio_pointer_t ref) +{ + return (((trio_reference_t *)ref)->parameter->flags & FLAGS_ALTERNATIVE) + ? TRUE + : FALSE; +} + +void +trio_set_alternative +TRIO_ARGS2((ref, is_alternative), + trio_pointer_t ref, + int is_alternative) +{ + if (is_alternative) + ((trio_reference_t *)ref)->parameter->flags |= FLAGS_ALTERNATIVE; + else + ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_ALTERNATIVE; +} + +/************************************************************************* + * trio_get_alignment / trio_set_alignment [public] + */ +int +trio_get_alignment +TRIO_ARGS1((ref), + trio_pointer_t ref) +{ + return (((trio_reference_t *)ref)->parameter->flags & FLAGS_LEFTADJUST) + ? TRUE + : FALSE; +} + +void +trio_set_alignment +TRIO_ARGS2((ref, is_leftaligned), + trio_pointer_t ref, + int is_leftaligned) +{ + if (is_leftaligned) + ((trio_reference_t *)ref)->parameter->flags |= FLAGS_LEFTADJUST; + else + ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_LEFTADJUST; +} + +/************************************************************************* + * trio_get_spacing /trio_set_spacing [public] + */ +int +trio_get_spacing +TRIO_ARGS1((ref), + trio_pointer_t ref) +{ + return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SPACE) + ? TRUE + : FALSE; +} + +void +trio_set_spacing +TRIO_ARGS2((ref, is_space), + trio_pointer_t ref, + int is_space) +{ + if (is_space) + ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SPACE; + else + ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SPACE; +} + +/************************************************************************* + * trio_get_sign / trio_set_sign [public] + */ +int +trio_get_sign +TRIO_ARGS1((ref), + trio_pointer_t ref) +{ + return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SHOWSIGN) + ? TRUE + : FALSE; +} + +void +trio_set_sign +TRIO_ARGS2((ref, is_sign), + trio_pointer_t ref, + int is_sign) +{ + if (is_sign) + ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SHOWSIGN; + else + ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SHOWSIGN; +} + +/************************************************************************* + * trio_get_padding / trio_set_padding [public] + */ +int +trio_get_padding +TRIO_ARGS1((ref), + trio_pointer_t ref) +{ + return (((trio_reference_t *)ref)->parameter->flags & FLAGS_NILPADDING) + ? TRUE + : FALSE; +} + +void +trio_set_padding +TRIO_ARGS2((ref, is_padding), + trio_pointer_t ref, + int is_padding) +{ + if (is_padding) + ((trio_reference_t *)ref)->parameter->flags |= FLAGS_NILPADDING; + else + ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_NILPADDING; +} + +/************************************************************************* + * trio_get_quote / trio_set_quote [public] + */ +# if TRIO_FEATURE_QUOTE +int +trio_get_quote +TRIO_ARGS1((ref), + trio_pointer_t ref) +{ + return (((trio_reference_t *)ref)->parameter->flags & FLAGS_QUOTE) + ? TRUE + : FALSE; +} + +void +trio_set_quote +TRIO_ARGS2((ref, is_quote), + trio_pointer_t ref, + int is_quote) +{ + if (is_quote) + ((trio_reference_t *)ref)->parameter->flags |= FLAGS_QUOTE; + else + ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_QUOTE; +} +#endif /* TRIO_FEATURE_QUOTE */ + +/************************************************************************* + * trio_get_upper / trio_set_upper [public] + */ +int +trio_get_upper +TRIO_ARGS1((ref), + trio_pointer_t ref) +{ + return (((trio_reference_t *)ref)->parameter->flags & FLAGS_UPPER) + ? TRUE + : FALSE; +} + +void +trio_set_upper +TRIO_ARGS2((ref, is_upper), + trio_pointer_t ref, + int is_upper) +{ + if (is_upper) + ((trio_reference_t *)ref)->parameter->flags |= FLAGS_UPPER; + else + ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_UPPER; +} + +/************************************************************************* + * trio_get_largest / trio_set_largest [public] + */ +#if TRIO_FEATURE_INTMAX_T +int +trio_get_largest +TRIO_ARGS1((ref), + trio_pointer_t ref) +{ + return (((trio_reference_t *)ref)->parameter->flags & FLAGS_INTMAX_T) + ? TRUE + : FALSE; +} + +void +trio_set_largest +TRIO_ARGS2((ref, is_largest), + trio_pointer_t ref, + int is_largest) +{ + if (is_largest) + ((trio_reference_t *)ref)->parameter->flags |= FLAGS_INTMAX_T; + else + ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_INTMAX_T; +} +#endif /* TRIO_FEATURE_INTMAX_T */ + +/************************************************************************* + * trio_get_ptrdiff / trio_set_ptrdiff [public] + */ +#if TRIO_FEATURE_PTRDIFF_T +int +trio_get_ptrdiff +TRIO_ARGS1((ref), + trio_pointer_t ref) +{ + return (((trio_reference_t *)ref)->parameter->flags & FLAGS_PTRDIFF_T) + ? TRUE + : FALSE; +} + +void +trio_set_ptrdiff +TRIO_ARGS2((ref, is_ptrdiff), + trio_pointer_t ref, + int is_ptrdiff) +{ + if (is_ptrdiff) + ((trio_reference_t *)ref)->parameter->flags |= FLAGS_PTRDIFF_T; + else + ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_PTRDIFF_T; +} +#endif /* TRIO_FEATURE_PTRDIFF_T */ + +/************************************************************************* + * trio_get_size / trio_set_size [public] + */ +#if TRIO_FEATURE_SIZE_T +int +trio_get_size +TRIO_ARGS1((ref), + trio_pointer_t ref) +{ + return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SIZE_T) + ? TRUE + : FALSE; +} + +void +trio_set_size +TRIO_ARGS2((ref, is_size), + trio_pointer_t ref, + int is_size) +{ + if (is_size) + ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SIZE_T; + else + ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SIZE_T; +} +#endif /* TRIO_FEATURE_SIZE_T */ + +/************************************************************************* + * trio_print_int [public] + */ +void +trio_print_int +TRIO_ARGS2((ref, number), + trio_pointer_t ref, + int number) +{ + trio_reference_t *self = (trio_reference_t *)ref; + + TrioWriteNumber(self->data, + (trio_uintmax_t)number, + self->parameter->flags, + self->parameter->width, + self->parameter->precision, + self->parameter->base); +} + +/************************************************************************* + * trio_print_uint [public] + */ +void +trio_print_uint +TRIO_ARGS2((ref, number), + trio_pointer_t ref, + unsigned int number) +{ + trio_reference_t *self = (trio_reference_t *)ref; + + TrioWriteNumber(self->data, + (trio_uintmax_t)number, + self->parameter->flags | FLAGS_UNSIGNED, + self->parameter->width, + self->parameter->precision, + self->parameter->base); +} + +/************************************************************************* + * trio_print_double [public] + */ +#if TRIO_FEATURE_FLOAT +void +trio_print_double +TRIO_ARGS2((ref, number), + trio_pointer_t ref, + double number) +{ + trio_reference_t *self = (trio_reference_t *)ref; + + TrioWriteDouble(self->data, + number, + self->parameter->flags, + self->parameter->width, + self->parameter->precision, + self->parameter->base); +} +#endif /* TRIO_FEATURE_FLOAT */ + +/************************************************************************* + * trio_print_string [public] + */ +void +trio_print_string +TRIO_ARGS2((ref, string), + trio_pointer_t ref, + TRIO_CONST char *string) +{ + trio_reference_t *self = (trio_reference_t *)ref; + + TrioWriteString(self->data, + string, + self->parameter->flags, + self->parameter->width, + self->parameter->precision); +} + +/************************************************************************* + * trio_print_ref [public] + */ +int +trio_print_ref +TRIO_VARGS3((ref, format, va_alist), + trio_pointer_t ref, + TRIO_CONST char *format, + TRIO_VA_DECL) +{ + int status; + va_list arglist; + + assert(VALID(format)); + + TRIO_VA_START(arglist, format); + status = TrioFormatRef((trio_reference_t *)ref, format, arglist, NULL); + TRIO_VA_END(arglist); + return status; +} + +/************************************************************************* + * trio_vprint_ref [public] + */ +int +trio_vprint_ref +TRIO_ARGS3((ref, format, arglist), + trio_pointer_t ref, + TRIO_CONST char *format, + va_list arglist) +{ + assert(VALID(format)); + + return TrioFormatRef((trio_reference_t *)ref, format, arglist, NULL); +} + +/************************************************************************* + * trio_printv_ref [public] + */ +int +trio_printv_ref +TRIO_ARGS3((ref, format, argarray), + trio_pointer_t ref, + TRIO_CONST char *format, + trio_pointer_t *argarray) +{ + static va_list unused; + + assert(VALID(format)); + + return TrioFormatRef((trio_reference_t *)ref, format, unused, argarray); +} + +#endif + +/************************************************************************* + * trio_print_pointer [public] + */ +void +trio_print_pointer +TRIO_ARGS2((ref, pointer), + trio_pointer_t ref, + trio_pointer_t pointer) +{ + trio_reference_t *self = (trio_reference_t *)ref; + trio_flags_t flags; + trio_uintmax_t number; + + if (NULL == pointer) + { + TRIO_CONST char *string = internalNullString; + while (*string) + self->data->OutStream(self->data, *string++); + } + else + { + /* + * The subtraction of the null pointer is a workaround + * to avoid a compiler warning. The performance overhead + * is negligible (and likely to be removed by an + * optimizing compiler). The (char *) casting is done + * to please ANSI C++. + */ + number = (trio_uintmax_t)((char *)pointer - (char *)0); + /* Shrink to size of pointer */ + number &= (trio_uintmax_t)-1; + flags = self->parameter->flags; + flags |= (FLAGS_UNSIGNED | FLAGS_ALTERNATIVE | + FLAGS_NILPADDING); + TrioWriteNumber(self->data, + number, + flags, + POINTER_WIDTH, + NO_PRECISION, + BASE_HEX); + } +} + +/** @} End of UserDefined documentation module */ + +/************************************************************************* + * + * LOCALES + * + ************************************************************************/ + +/************************************************************************* + * trio_locale_set_decimal_point + * + * Decimal point can only be one character. The input argument is a + * string to enable multibyte characters. At most MB_LEN_MAX characters + * will be used. + */ +#if TRIO_FEATURE_LOCALE +TRIO_PUBLIC void +trio_locale_set_decimal_point +TRIO_ARGS1((decimalPoint), + char *decimalPoint) +{ +#if defined(USE_LOCALE) + if (NULL == internalLocaleValues) + { + TrioSetLocale(); + } +#endif + internalDecimalPointLength = trio_length(decimalPoint); + if (internalDecimalPointLength == 1) + { + internalDecimalPoint = *decimalPoint; + } + else + { + internalDecimalPoint = NIL; + trio_copy_max(internalDecimalPointString, + sizeof(internalDecimalPointString), + decimalPoint); + } +} +#endif + +/************************************************************************* + * trio_locale_set_thousand_separator + * + * See trio_locale_set_decimal_point + */ +#if TRIO_FEATURE_LOCALE || TRIO_EXTENSION +TRIO_PUBLIC void +trio_locale_set_thousand_separator +TRIO_ARGS1((thousandSeparator), + char *thousandSeparator) +{ +# if defined(USE_LOCALE) + if (NULL == internalLocaleValues) + { + TrioSetLocale(); + } +# endif + trio_copy_max(internalThousandSeparator, + sizeof(internalThousandSeparator), + thousandSeparator); + internalThousandSeparatorLength = trio_length(internalThousandSeparator); +} +#endif + +/************************************************************************* + * trio_locale_set_grouping + * + * Array of bytes. Reversed order. + * + * CHAR_MAX : No further grouping + * 0 : Repeat last group for the remaining digits (not necessary + * as C strings are zero-terminated) + * n : Set current group to n + * + * Same order as the grouping attribute in LC_NUMERIC. + */ +#if TRIO_FEATURE_LOCALE || TRIO_EXTENSION +TRIO_PUBLIC void +trio_locale_set_grouping +TRIO_ARGS1((grouping), + char *grouping) +{ +# if defined(USE_LOCALE) + if (NULL == internalLocaleValues) + { + TrioSetLocale(); + } +# endif + trio_copy_max(internalGrouping, + sizeof(internalGrouping), + grouping); +} +#endif + + +/************************************************************************* + * + * SCANNING + * + ************************************************************************/ + +#if TRIO_FEATURE_SCANF + +/************************************************************************* + * TrioSkipWhitespaces + */ +TRIO_PRIVATE int +TrioSkipWhitespaces +TRIO_ARGS1((self), + trio_class_t *self) +{ + int ch; + + ch = self->current; + while (isspace(ch)) + { + self->InStream(self, &ch); + } + return ch; +} + +/************************************************************************* + * TrioGetCollation + */ +#if TRIO_EXTENSION +TRIO_PRIVATE void +TrioGetCollation(TRIO_NOARGS) +{ + int i; + int j; + int k; + char first[2]; + char second[2]; + + /* This is computationally expensive */ + first[1] = NIL; + second[1] = NIL; + for (i = 0; i < MAX_CHARACTER_CLASS; i++) + { + k = 0; + first[0] = (char)i; + for (j = 0; j < MAX_CHARACTER_CLASS; j++) + { + second[0] = (char)j; + if (trio_equal_locale(first, second)) + internalCollationArray[i][k++] = (char)j; + } + internalCollationArray[i][k] = NIL; + } +} +#endif + +/************************************************************************* + * TrioGetCharacterClass + * + * FIXME: + * multibyte + */ +TRIO_PRIVATE int +TrioGetCharacterClass +TRIO_ARGS4((format, offsetPointer, flagsPointer, characterclass), + TRIO_CONST char *format, + int *offsetPointer, + trio_flags_t *flagsPointer, + int *characterclass) +{ + int offset = *offsetPointer; + int i; + char ch; + char range_begin; + char range_end; + + *flagsPointer &= ~FLAGS_EXCLUDE; + + if (format[offset] == QUALIFIER_CIRCUMFLEX) + { + *flagsPointer |= FLAGS_EXCLUDE; + offset++; + } + /* + * If the ungroup character is at the beginning of the scanlist, + * it will be part of the class, and a second ungroup character + * must follow to end the group. + */ + if (format[offset] == SPECIFIER_UNGROUP) + { + characterclass[(int)SPECIFIER_UNGROUP]++; + offset++; + } + /* + * Minus is used to specify ranges. To include minus in the class, + * it must be at the beginning of the list + */ + if (format[offset] == QUALIFIER_MINUS) + { + characterclass[(int)QUALIFIER_MINUS]++; + offset++; + } + /* Collect characters */ + for (ch = format[offset]; + (ch != SPECIFIER_UNGROUP) && (ch != NIL); + ch = format[++offset]) + { + switch (ch) + { + case QUALIFIER_MINUS: /* Scanlist ranges */ + + /* + * Both C99 and UNIX98 describes ranges as implementation- + * defined. + * + * We support the following behaviour (although this may + * change as we become wiser) + * - only increasing ranges, ie. [a-b] but not [b-a] + * - transitive ranges, ie. [a-b-c] == [a-c] + * - trailing minus, ie. [a-] is interpreted as an 'a' + * and a '-' + * - duplicates (although we can easily convert these + * into errors) + */ + range_begin = format[offset - 1]; + range_end = format[++offset]; + if (range_end == SPECIFIER_UNGROUP) + { + /* Trailing minus is included */ + characterclass[(int)ch]++; + ch = range_end; + break; /* for */ + } + if (range_end == NIL) + return TRIO_ERROR_RETURN(TRIO_EINVAL, offset); + if (range_begin > range_end) + return TRIO_ERROR_RETURN(TRIO_ERANGE, offset); + + for (i = (int)range_begin; i <= (int)range_end; i++) + characterclass[i]++; + + ch = range_end; + break; + +#if TRIO_EXTENSION + + case SPECIFIER_GROUP: + + switch (format[offset + 1]) + { + case QUALIFIER_DOT: /* Collating symbol */ + /* + * FIXME: This will be easier to implement when multibyte + * characters have been implemented. Until now, we ignore + * this feature. + */ + for (i = offset + 2; ; i++) + { + if (format[i] == NIL) + /* Error in syntax */ + return -1; + else if (format[i] == QUALIFIER_DOT) + break; /* for */ + } + if (format[++i] != SPECIFIER_UNGROUP) + return -1; + + offset = i; + break; + + case QUALIFIER_EQUAL: /* Equivalence class expressions */ + { + unsigned int j; + unsigned int k; + + if (internalCollationUnconverted) + { + /* Lazy evaluation of collation array */ + TrioGetCollation(); + internalCollationUnconverted = FALSE; + } + for (i = offset + 2; ; i++) + { + if (format[i] == NIL) + /* Error in syntax */ + return -1; + else if (format[i] == QUALIFIER_EQUAL) + break; /* for */ + else + { + /* Mark any equivalent character */ + k = (unsigned int)format[i]; + for (j = 0; internalCollationArray[k][j] != NIL; j++) + characterclass[(int)internalCollationArray[k][j]]++; + } + } + if (format[++i] != SPECIFIER_UNGROUP) + return -1; + + offset = i; + } + break; + + case QUALIFIER_COLON: /* Character class expressions */ + + if (trio_equal_max(CLASS_ALNUM, sizeof(CLASS_ALNUM) - 1, + &format[offset])) + { + for (i = 0; i < MAX_CHARACTER_CLASS; i++) + if (isalnum(i)) + characterclass[i]++; + offset += sizeof(CLASS_ALNUM) - 1; + } + else if (trio_equal_max(CLASS_ALPHA, sizeof(CLASS_ALPHA) - 1, + &format[offset])) + { + for (i = 0; i < MAX_CHARACTER_CLASS; i++) + if (isalpha(i)) + characterclass[i]++; + offset += sizeof(CLASS_ALPHA) - 1; + } + else if (trio_equal_max(CLASS_CNTRL, sizeof(CLASS_CNTRL) - 1, + &format[offset])) + { + for (i = 0; i < MAX_CHARACTER_CLASS; i++) + if (iscntrl(i)) + characterclass[i]++; + offset += sizeof(CLASS_CNTRL) - 1; + } + else if (trio_equal_max(CLASS_DIGIT, sizeof(CLASS_DIGIT) - 1, + &format[offset])) + { + for (i = 0; i < MAX_CHARACTER_CLASS; i++) + if (isdigit(i)) + characterclass[i]++; + offset += sizeof(CLASS_DIGIT) - 1; + } + else if (trio_equal_max(CLASS_GRAPH, sizeof(CLASS_GRAPH) - 1, + &format[offset])) + { + for (i = 0; i < MAX_CHARACTER_CLASS; i++) + if (isgraph(i)) + characterclass[i]++; + offset += sizeof(CLASS_GRAPH) - 1; + } + else if (trio_equal_max(CLASS_LOWER, sizeof(CLASS_LOWER) - 1, + &format[offset])) + { + for (i = 0; i < MAX_CHARACTER_CLASS; i++) + if (islower(i)) + characterclass[i]++; + offset += sizeof(CLASS_LOWER) - 1; + } + else if (trio_equal_max(CLASS_PRINT, sizeof(CLASS_PRINT) - 1, + &format[offset])) + { + for (i = 0; i < MAX_CHARACTER_CLASS; i++) + if (isprint(i)) + characterclass[i]++; + offset += sizeof(CLASS_PRINT) - 1; + } + else if (trio_equal_max(CLASS_PUNCT, sizeof(CLASS_PUNCT) - 1, + &format[offset])) + { + for (i = 0; i < MAX_CHARACTER_CLASS; i++) + if (ispunct(i)) + characterclass[i]++; + offset += sizeof(CLASS_PUNCT) - 1; + } + else if (trio_equal_max(CLASS_SPACE, sizeof(CLASS_SPACE) - 1, + &format[offset])) + { + for (i = 0; i < MAX_CHARACTER_CLASS; i++) + if (isspace(i)) + characterclass[i]++; + offset += sizeof(CLASS_SPACE) - 1; + } + else if (trio_equal_max(CLASS_UPPER, sizeof(CLASS_UPPER) - 1, + &format[offset])) + { + for (i = 0; i < MAX_CHARACTER_CLASS; i++) + if (isupper(i)) + characterclass[i]++; + offset += sizeof(CLASS_UPPER) - 1; + } + else if (trio_equal_max(CLASS_XDIGIT, sizeof(CLASS_XDIGIT) - 1, + &format[offset])) + { + for (i = 0; i < MAX_CHARACTER_CLASS; i++) + if (isxdigit(i)) + characterclass[i]++; + offset += sizeof(CLASS_XDIGIT) - 1; + } + else + { + characterclass[(int)ch]++; + } + break; + + default: + characterclass[(int)ch]++; + break; + } + break; + +#endif /* TRIO_EXTENSION */ + + default: + characterclass[(int)ch]++; + break; + } + } + return 0; +} + +/************************************************************************* + * TrioReadNumber + * + * We implement our own number conversion in preference of strtol and + * strtoul, because we must handle 'long long' and thousand separators. + */ +TRIO_PRIVATE BOOLEAN_T +TrioReadNumber +TRIO_ARGS5((self, target, flags, width, base), + trio_class_t *self, + trio_uintmax_t *target, + trio_flags_t flags, + int width, + int base) +{ + trio_uintmax_t number = 0; + int digit; + int count; + BOOLEAN_T isNegative = FALSE; + BOOLEAN_T gotNumber = FALSE; + int j; + + assert(VALID(self)); + assert(VALID(self->InStream)); + assert((base >= MIN_BASE && base <= MAX_BASE) || (base == NO_BASE)); + + if (internalDigitsUnconverted) + { + /* Lazy evaluation of digits array */ + memset(internalDigitArray, -1, sizeof(internalDigitArray)); + for (j = 0; j < (int)sizeof(internalDigitsLower) - 1; j++) + { + internalDigitArray[(int)internalDigitsLower[j]] = j; + internalDigitArray[(int)internalDigitsUpper[j]] = j; + } + internalDigitsUnconverted = FALSE; + } + + TrioSkipWhitespaces(self); + + /* Leading sign */ + if (self->current == '+') + { + self->InStream(self, NULL); + } + else if (self->current == '-') + { + self->InStream(self, NULL); + isNegative = TRUE; + } + + count = self->processed; + + if (flags & FLAGS_ALTERNATIVE) + { + switch (base) + { + case NO_BASE: + case BASE_OCTAL: + case BASE_HEX: + case BASE_BINARY: + if (self->current == '0') + { + self->InStream(self, NULL); + if (self->current) + { + if ((base == BASE_HEX) && + (trio_to_upper(self->current) == 'X')) + { + self->InStream(self, NULL); + } + else if ((base == BASE_BINARY) && + (trio_to_upper(self->current) == 'B')) + { + self->InStream(self, NULL); + } + } + } + else + return FALSE; + break; + default: + break; + } + } + + while (((width == NO_WIDTH) || (self->processed - count < width)) && + (! ((self->current == EOF) || isspace(self->current)))) + { + if (isascii(self->current)) + { + digit = internalDigitArray[self->current]; + /* Abort if digit is not allowed in the specified base */ + if ((digit == -1) || (digit >= base)) + break; + } +#if TRIO_FEATURE_QUOTE + else if (flags & FLAGS_QUOTE) + { + /* Compare with thousands separator */ + for (j = 0; internalThousandSeparator[j] && self->current; j++) + { + if (internalThousandSeparator[j] != self->current) + break; + + self->InStream(self, NULL); + } + if (internalThousandSeparator[j]) + break; /* Mismatch */ + else + continue; /* Match */ + } +#endif + else + break; + + number *= base; + number += digit; + gotNumber = TRUE; /* we need at least one digit */ + + self->InStream(self, NULL); + } + + /* Was anything read at all? */ + if (!gotNumber) + return FALSE; + + if (target) + *target = (isNegative) ? (trio_uintmax_t)(-((trio_intmax_t)number)) : number; + return TRUE; +} + +/************************************************************************* + * TrioReadChar + */ +TRIO_PRIVATE int +TrioReadChar +TRIO_ARGS4((self, target, flags, width), + trio_class_t *self, + char *target, + trio_flags_t flags, + int width) +{ + int i; + char ch; + trio_uintmax_t number; + + assert(VALID(self)); + assert(VALID(self->InStream)); + + for (i = 0; + (self->current != EOF) && (i < width); + i++) + { + ch = (char)self->current; + self->InStream(self, NULL); + if ((flags & FLAGS_ALTERNATIVE) && (ch == CHAR_BACKSLASH)) + { + switch (self->current) + { + case '\\': ch = '\\'; break; + case 'a': ch = '\007'; break; + case 'b': ch = '\b'; break; + case 'f': ch = '\f'; break; + case 'n': ch = '\n'; break; + case 'r': ch = '\r'; break; + case 't': ch = '\t'; break; + case 'v': ch = '\v'; break; + default: + if (isdigit(self->current)) + { + /* Read octal number */ + if (!TrioReadNumber(self, &number, 0, 3, BASE_OCTAL)) + return 0; + ch = (char)number; + } + else if (trio_to_upper(self->current) == 'X') + { + /* Read hexadecimal number */ + self->InStream(self, NULL); + if (!TrioReadNumber(self, &number, 0, 2, BASE_HEX)) + return 0; + ch = (char)number; + } + else + { + ch = (char)self->current; + } + break; + } + } + + if (target) + target[i] = ch; + } + return i + 1; +} + +/************************************************************************* + * TrioReadString + */ +TRIO_PRIVATE BOOLEAN_T +TrioReadString +TRIO_ARGS4((self, target, flags, width), + trio_class_t *self, + char *target, + trio_flags_t flags, + int width) +{ + int i; + + assert(VALID(self)); + assert(VALID(self->InStream)); + + TrioSkipWhitespaces(self); + + /* + * Continue until end of string is reached, a whitespace is encountered, + * or width is exceeded + */ + for (i = 0; + ((width == NO_WIDTH) || (i < width)) && + (! ((self->current == EOF) || isspace(self->current))); + i++) + { + if (TrioReadChar(self, (target ? &target[i] : 0), flags, 1) == 0) + break; /* for */ + } + if (target) + target[i] = NIL; + return TRUE; +} + +/************************************************************************* + * TrioReadWideChar + */ +#if TRIO_FEATURE_WIDECHAR +TRIO_PRIVATE int +TrioReadWideChar +TRIO_ARGS4((self, target, flags, width), + trio_class_t *self, + trio_wchar_t *target, + trio_flags_t flags, + int width) +{ + int i; + int j; + int size; + int amount = 0; + trio_wchar_t wch; + char buffer[MB_LEN_MAX + 1]; + + assert(VALID(self)); + assert(VALID(self->InStream)); + + for (i = 0; + (self->current != EOF) && (i < width); + i++) + { + if (isascii(self->current)) + { + if (TrioReadChar(self, buffer, flags, 1) == 0) + return 0; + buffer[1] = NIL; + } + else + { + /* + * Collect a multibyte character, by enlarging buffer until + * it contains a fully legal multibyte character, or the + * buffer is full. + */ + j = 0; + do + { + buffer[j++] = (char)self->current; + buffer[j] = NIL; + self->InStream(self, NULL); + } + while ((j < (int)sizeof(buffer)) && (mblen(buffer, (size_t)j) != j)); + } + if (target) + { + size = mbtowc(&wch, buffer, sizeof(buffer)); + if (size > 0) + target[i] = wch; + } + amount += size; + self->InStream(self, NULL); + } + return amount; +} +#endif /* TRIO_FEATURE_WIDECHAR */ + +/************************************************************************* + * TrioReadWideString + */ +#if TRIO_FEATURE_WIDECHAR +TRIO_PRIVATE BOOLEAN_T +TrioReadWideString +TRIO_ARGS4((self, target, flags, width), + trio_class_t *self, + trio_wchar_t *target, + trio_flags_t flags, + int width) +{ + int i; + int size; + + assert(VALID(self)); + assert(VALID(self->InStream)); + + TrioSkipWhitespaces(self); + +#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE) + /* Required by TrioReadWideChar */ + (void)mblen(NULL, 0); +#endif + + /* + * Continue until end of string is reached, a whitespace is encountered, + * or width is exceeded + */ + for (i = 0; + ((width == NO_WIDTH) || (i < width)) && + (! ((self->current == EOF) || isspace(self->current))); + ) + { + size = TrioReadWideChar(self, &target[i], flags, 1); + if (size == 0) + break; /* for */ + + i += size; + } + if (target) + target[i] = WCONST('\0'); + return TRUE; +} +#endif /* TRIO_FEATURE_WIDECHAR */ + +/************************************************************************* + * TrioReadGroup + * + * Reads non-empty character groups. + * + * FIXME: characterclass does not work with multibyte characters + */ +TRIO_PRIVATE BOOLEAN_T +TrioReadGroup +TRIO_ARGS5((self, target, characterclass, flags, width), + trio_class_t *self, + char *target, + int *characterclass, + trio_flags_t flags, + int width) +{ + int ch; + int i; + + assert(VALID(self)); + assert(VALID(self->InStream)); + + ch = self->current; + for (i = 0; + ((width == NO_WIDTH) || (i < width)) && + (! ((ch == EOF) || + (((flags & FLAGS_EXCLUDE) != 0) ^ (characterclass[ch] == 0)))); + i++) + { + if (target) + target[i] = (char)ch; + self->InStream(self, &ch); + } + + if (i == 0) + return FALSE; + + /* Terminate the string if input saved */ + if (target) + target[i] = NIL; + return TRUE; +} + +/************************************************************************* + * TrioReadDouble + * + * FIXME: + * add long double + * handle base + */ +#if TRIO_FEATURE_FLOAT +TRIO_PRIVATE BOOLEAN_T +TrioReadDouble +TRIO_ARGS4((self, target, flags, width), + trio_class_t *self, + trio_pointer_t target, + trio_flags_t flags, + int width) +{ + int ch; + char doubleString[512]; + int offset = 0; + int start; +# if TRIO_FEATURE_QUOTE + int j; +# endif + BOOLEAN_T isHex = FALSE; + trio_long_double_t infinity; + + doubleString[0] = 0; + + if ((width == NO_WIDTH) || (width > (int)sizeof(doubleString) - 1)) + width = sizeof(doubleString) - 1; + + TrioSkipWhitespaces(self); + + /* + * Read entire double number from stream. trio_to_double requires + * a string as input, but InStream can be anything, so we have to + * collect all characters. + */ + ch = self->current; + if ((ch == '+') || (ch == '-')) + { + doubleString[offset++] = (char)ch; + self->InStream(self, &ch); + width--; + } + + start = offset; + switch (ch) + { + case 'n': + case 'N': + /* Not-a-number */ + if (offset != 0) + break; + /* FALLTHROUGH */ + case 'i': + case 'I': + /* Infinity */ + while (isalpha(ch) && (offset - start < width)) + { + doubleString[offset++] = (char)ch; + self->InStream(self, &ch); + } + doubleString[offset] = NIL; + + /* Case insensitive string comparison */ + if (trio_equal(&doubleString[start], INFINITE_UPPER) || + trio_equal(&doubleString[start], LONG_INFINITE_UPPER)) + { + infinity = ((start == 1) && (doubleString[0] == '-')) + ? trio_ninf() + : trio_pinf(); + if (flags & FLAGS_LONGDOUBLE) + { + *((trio_long_double_t *)target) = infinity; + } + else if (flags & FLAGS_LONG) + { + *((double *)target) = infinity; + } + else + { + *((float *)target) = infinity; + } + return TRUE; + } + if (trio_equal(doubleString, NAN_UPPER)) + { + /* NaN must not have a preceeding + nor - */ + if (flags & FLAGS_LONGDOUBLE) + { + *((trio_long_double_t *)target) = trio_nan(); + } + else if (flags & FLAGS_LONG) + { + *((double *)target) = trio_nan(); + } + else + { + *((float *)target) = trio_nan(); + } + return TRUE; + } + return FALSE; + + case '0': + doubleString[offset++] = (char)ch; + self->InStream(self, &ch); + if (trio_to_upper(ch) == 'X') + { + isHex = TRUE; + doubleString[offset++] = (char)ch; + self->InStream(self, &ch); + } + break; + + default: + break; + } + + while ((ch != EOF) && (offset - start < width)) + { + /* Integer part */ + if (isHex ? isxdigit(ch) : isdigit(ch)) + { + doubleString[offset++] = (char)ch; + self->InStream(self, &ch); + } +# if TRIO_FEATURE_QUOTE + else if (flags & FLAGS_QUOTE) + { + /* Compare with thousands separator */ + for (j = 0; internalThousandSeparator[j] && self->current; j++) + { + if (internalThousandSeparator[j] != self->current) + break; + + self->InStream(self, &ch); + } + if (internalThousandSeparator[j]) + break; /* Mismatch */ + else + continue; /* Match */ + } +# endif + else + break; /* while */ + } + if (ch == '.') + { + /* Decimal part */ + doubleString[offset++] = (char)ch; + self->InStream(self, &ch); + while ((isHex ? isxdigit(ch) : isdigit(ch)) && + (offset - start < width)) + { + doubleString[offset++] = (char)ch; + self->InStream(self, &ch); + } + } + if (isHex ? (trio_to_upper(ch) == 'P') : (trio_to_upper(ch) == 'E')) + { + /* Exponent */ + doubleString[offset++] = (char)ch; + self->InStream(self, &ch); + if ((ch == '+') || (ch == '-')) + { + doubleString[offset++] = (char)ch; + self->InStream(self, &ch); + } + while (isdigit(ch) && (offset - start < width)) + { + doubleString[offset++] = (char)ch; + self->InStream(self, &ch); + } + } + + if ((offset == start) || (*doubleString == NIL)) + return FALSE; + + doubleString[offset] = 0; + + if (flags & FLAGS_LONGDOUBLE) + { + *((trio_long_double_t *)target) = trio_to_long_double(doubleString, NULL); + } + else if (flags & FLAGS_LONG) + { + *((double *)target) = trio_to_double(doubleString, NULL); + } + else + { + *((float *)target) = trio_to_float(doubleString, NULL); + } + return TRUE; +} +#endif /* TRIO_FEATURE_FLOAT */ + +/************************************************************************* + * TrioReadPointer + */ +TRIO_PRIVATE BOOLEAN_T +TrioReadPointer +TRIO_ARGS3((self, target, flags), + trio_class_t *self, + trio_pointer_t *target, + trio_flags_t flags) +{ + trio_uintmax_t number; + char buffer[sizeof(internalNullString)]; + + flags |= (FLAGS_UNSIGNED | FLAGS_ALTERNATIVE | FLAGS_NILPADDING); + + if (TrioReadNumber(self, + &number, + flags, + POINTER_WIDTH, + BASE_HEX)) + { + if (target) + { +#if defined(TRIO_COMPILER_GCC) || defined(TRIO_COMPILER_MIPSPRO) + /* + * The strange assignment of number is a workaround for a compiler + * warning + */ + *target = &((char *)0)[number]; +#else + *target = (trio_pointer_t)number; +#endif + } + return TRUE; + } + else if (TrioReadString(self, + (flags & FLAGS_IGNORE) + ? NULL + : buffer, + 0, + sizeof(internalNullString) - 1)) + { + if (trio_equal_case(buffer, internalNullString)) + { + if (target) + *target = NULL; + return TRUE; + } + } + return FALSE; +} + +/************************************************************************* + * TrioScanProcess + */ +TRIO_PRIVATE int +TrioScanProcess +TRIO_ARGS3((data, format, parameters), + trio_class_t *data, + TRIO_CONST char *format, + trio_parameter_t *parameters) +{ + int status; + int assignment; + int ch; + int offset; /* Offset of format string */ + int i; /* Offset of current parameter */ + trio_flags_t flags; + int width; + int base; + trio_pointer_t pointer; + + /* Return on empty format string */ + if (format[0] == NIL) + return 0; + + status = 0; + assignment = 0; + i = 0; + offset = 0; + data->InStream(data, &ch); + + for (;;) + { + /* Skip the parameter entries */ + while (parameters[i].type == FORMAT_PARAMETER) + { + assert(i <= MAX_PARAMETERS); + i++; + } + + /* Compare non conversion-specifier part of format string */ + while (offset < parameters[i].beginOffset) + { + if ((CHAR_IDENTIFIER == format[offset]) && + (CHAR_IDENTIFIER == format[offset + 1])) + { + /* Two % in format matches one % in input stream */ + if (CHAR_IDENTIFIER == ch) + { + data->InStream(data, &ch); + offset += 2; + continue; /* while format chars left */ + } + else + { + status = TRIO_ERROR_RETURN(TRIO_EINVAL, offset); + goto end; + } + } + else /* Not an % identifier */ + { + if (isspace((int)format[offset])) + { + /* Whitespaces may match any amount of whitespaces */ + ch = TrioSkipWhitespaces(data); + } + else if (ch == format[offset]) + { + data->InStream(data, &ch); + } + else + { + status = assignment; + goto end; + } + + offset++; + } + } + + if (parameters[i].type == FORMAT_SENTINEL) + break; + + if ((EOF == ch) && (parameters[i].type != FORMAT_COUNT)) + { + status = (assignment > 0) ? assignment : EOF; + goto end; + } + + flags = parameters[i].flags; + + /* Find width */ + width = parameters[i].width; + if (flags & FLAGS_WIDTH_PARAMETER) + { + /* Get width from parameter list */ + width = (int)parameters[width].data.number.as_signed; + } + + /* Find base */ + if (NO_BASE != parameters[i].baseSpecifier) + { + /* Base from specifier has priority */ + base = parameters[i].baseSpecifier; + } + else if (flags & FLAGS_BASE_PARAMETER) + { + /* Get base from parameter list */ + base = parameters[i].base; + base = (int)parameters[base].data.number.as_signed; + } + else + { + /* Use base from format string */ + base = parameters[i].base; + } + + switch (parameters[i].type) + { + case FORMAT_INT: + { + trio_uintmax_t number; + + if (0 == base) + base = BASE_DECIMAL; + + if (!TrioReadNumber(data, + &number, + flags, + width, + base)) + { + status = assignment; + goto end; + } + + if (!(flags & FLAGS_IGNORE)) + { + assignment++; + + pointer = parameters[i].data.pointer; +#if TRIO_FEATURE_SIZE_T || TRIO_FEATURE_SIZE_T_UPPER + if (flags & FLAGS_SIZE_T) + *(size_t *)pointer = (size_t)number; + else +#endif +#if TRIO_FEATURE_PTRDIFF_T + if (flags & FLAGS_PTRDIFF_T) + *(ptrdiff_t *)pointer = (ptrdiff_t)number; + else +#endif +#if TRIO_FEATURE_INTMAX_T + if (flags & FLAGS_INTMAX_T) + *(trio_intmax_t *)pointer = (trio_intmax_t)number; + else +#endif + if (flags & FLAGS_QUAD) + *(trio_ulonglong_t *)pointer = (trio_ulonglong_t)number; + else if (flags & FLAGS_LONG) + *(long int *)pointer = (long int)number; + else if (flags & FLAGS_SHORT) + *(short int *)pointer = (short int)number; + else + *(int *)pointer = (int)number; + } + } + break; /* FORMAT_INT */ + + case FORMAT_STRING: +#if TRIO_FEATURE_WIDECHAR + if (flags & FLAGS_WIDECHAR) + { + if (!TrioReadWideString(data, + (flags & FLAGS_IGNORE) + ? NULL + : parameters[i].data.wstring, + flags, + width)) + { + status = assignment; + goto end; + } + } + else +#endif + { + if (!TrioReadString(data, + (flags & FLAGS_IGNORE) + ? NULL + : parameters[i].data.string, + flags, + width)) + { + status = assignment; + goto end; + } + } + if (!(flags & FLAGS_IGNORE)) + assignment++; + break; /* FORMAT_STRING */ + +#if TRIO_FEATURE_FLOAT + case FORMAT_DOUBLE: + { + if (flags & FLAGS_IGNORE) + { + pointer = NULL; + } + else + { + pointer = (flags & FLAGS_LONGDOUBLE) + ? (trio_pointer_t)parameters[i].data.longdoublePointer + : (trio_pointer_t)parameters[i].data.doublePointer; + } + if (!TrioReadDouble(data, pointer, flags, width)) + { + status = assignment; + goto end; + } + if (!(flags & FLAGS_IGNORE)) + { + assignment++; + } + break; /* FORMAT_DOUBLE */ + } +#endif + + case FORMAT_GROUP: + { + int characterclass[MAX_CHARACTER_CLASS + 1]; + + /* Skip over modifiers */ + while (format[offset] != SPECIFIER_GROUP) + { + offset++; + } + /* Skip over group specifier */ + offset++; + + memset(characterclass, 0, sizeof(characterclass)); + status = TrioGetCharacterClass(format, + &offset, + &flags, + characterclass); + if (status < 0) + goto end; + + if (!TrioReadGroup(data, + (flags & FLAGS_IGNORE) + ? NULL + : parameters[i].data.string, + characterclass, + flags, + parameters[i].width)) + { + status = assignment; + goto end; + } + if (!(flags & FLAGS_IGNORE)) + assignment++; + } + break; /* FORMAT_GROUP */ + + case FORMAT_COUNT: + pointer = parameters[i].data.pointer; + if (NULL != pointer) + { + int count = data->processed; + if (ch != EOF) + count--; /* a character is read, but is not consumed yet */ +#if TRIO_FEATURE_SIZE_T || TRIO_FEATURE_SIZE_T_UPPER + if (flags & FLAGS_SIZE_T) + *(size_t *)pointer = (size_t)count; + else +#endif +#if TRIO_FEATURE_PTRDIFF_T + if (flags & FLAGS_PTRDIFF_T) + *(ptrdiff_t *)pointer = (ptrdiff_t)count; + else +#endif +#if TRIO_FEATURE_INTMAX_T + if (flags & FLAGS_INTMAX_T) + *(trio_intmax_t *)pointer = (trio_intmax_t)count; + else +#endif + if (flags & FLAGS_QUAD) + { + *(trio_ulonglong_t *)pointer = (trio_ulonglong_t)count; + } + else if (flags & FLAGS_LONG) + { + *(long int *)pointer = (long int)count; + } + else if (flags & FLAGS_SHORT) + { + *(short int *)pointer = (short int)count; + } + else + { + *(int *)pointer = (int)count; + } + } + break; /* FORMAT_COUNT */ + + case FORMAT_CHAR: +#if TRIO_FEATURE_WIDECHAR + if (flags & FLAGS_WIDECHAR) + { + if (TrioReadWideChar(data, + (flags & FLAGS_IGNORE) + ? NULL + : parameters[i].data.wstring, + flags, + (width == NO_WIDTH) ? 1 : width) == 0) + { + status = assignment; + goto end; + } + } + else +#endif + { + if (TrioReadChar(data, + (flags & FLAGS_IGNORE) + ? NULL + : parameters[i].data.string, + flags, + (width == NO_WIDTH) ? 1 : width) == 0) + { + status = assignment; + goto end; + } + } + if (!(flags & FLAGS_IGNORE)) + assignment++; + break; /* FORMAT_CHAR */ + + case FORMAT_POINTER: + if (!TrioReadPointer(data, + (flags & FLAGS_IGNORE) + ? NULL + : (trio_pointer_t *)parameters[i].data.pointer, + flags)) + { + status = assignment; + goto end; + } + if (!(flags & FLAGS_IGNORE)) + assignment++; + break; /* FORMAT_POINTER */ + + case FORMAT_PARAMETER: + break; /* FORMAT_PARAMETER */ + + default: + status = TRIO_ERROR_RETURN(TRIO_EINVAL, offset); + goto end; + } + + ch = data->current; + offset = parameters[i].endOffset; + i++; + } + + status = assignment; + end: + if (data->UndoStream) + data->UndoStream(data); + return status; +} + +/************************************************************************* + * TrioScan + */ +TRIO_PRIVATE int +TrioScan +TRIO_ARGS7((source, sourceSize, InStream, UndoStream, format, arglist, argarray), + trio_pointer_t source, + size_t sourceSize, + void (*InStream) TRIO_PROTO((trio_class_t *, int *)), + void (*UndoStream) TRIO_PROTO((trio_class_t *)), + TRIO_CONST char *format, + va_list arglist, + trio_pointer_t *argarray) +{ + int status; + trio_parameter_t parameters[MAX_PARAMETERS]; + trio_class_t data; + + assert(VALID(InStream)); + assert(VALID(format)); + + memset(&data, 0, sizeof(data)); + data.InStream = InStream; + data.UndoStream = UndoStream; + data.location = (trio_pointer_t)source; + data.max = sourceSize; + data.error = 0; + +#if defined(USE_LOCALE) + if (NULL == internalLocaleValues) + { + TrioSetLocale(); + } +#endif + + status = TrioParse(TYPE_SCAN, format, parameters, arglist, argarray); + if (status < 0) + return status; + + status = TrioScanProcess(&data, format, parameters); + if (data.error != 0) + { + status = data.error; + } + return status; +} + +/************************************************************************* + * TrioInStreamFile + */ +#if TRIO_FEATURE_FILE || TRIO_FEATURE_STDIO +TRIO_PRIVATE void +TrioInStreamFile +TRIO_ARGS2((self, intPointer), + trio_class_t *self, + int *intPointer) +{ + FILE *file = (FILE *)self->location; + + assert(VALID(self)); + assert(VALID(file)); + + self->actually.cached = 0; + + /* The initial value of self->current is zero */ + if (self->current == EOF) + { + self->error = (ferror(file)) + ? TRIO_ERROR_RETURN(TRIO_ERRNO, 0) + : TRIO_ERROR_RETURN(TRIO_EOF, 0); + } + else + { + self->processed++; + self->actually.cached++; + } + + self->current = fgetc(file); + + if (VALID(intPointer)) + { + *intPointer = self->current; + } +} +#endif /* TRIO_FEATURE_FILE || TRIO_FEATURE_STDIO */ + +/************************************************************************* + * TrioUndoStreamFile + */ +#if TRIO_FEATURE_FILE || TRIO_FEATURE_STDIO +TRIO_PRIVATE void +TrioUndoStreamFile +TRIO_ARGS1((self), + trio_class_t *self) +{ + FILE *file = (FILE *)self->location; + + assert(VALID(self)); + assert(VALID(file)); + + if (self->actually.cached > 0) + { + assert(self->actually.cached == 1); + + self->current = ungetc(self->current, file); + self->actually.cached = 0; + } +} +#endif /* TRIO_FEATURE_FILE || TRIO_FEATURE_STDIO */ + +/************************************************************************* + * TrioInStreamFileDescriptor + */ +#if TRIO_FEATURE_FD +TRIO_PRIVATE void +TrioInStreamFileDescriptor +TRIO_ARGS2((self, intPointer), + trio_class_t *self, + int *intPointer) +{ + int fd = *((int *)self->location); + int size; + unsigned char input; + + assert(VALID(self)); + + self->actually.cached = 0; + + size = read(fd, &input, sizeof(char)); + if (size == -1) + { + self->error = TRIO_ERROR_RETURN(TRIO_ERRNO, 0); + self->current = EOF; + } + else + { + self->current = (size == 0) ? EOF : input; + } + if (self->current != EOF) + { + self->actually.cached++; + self->processed++; + } + + if (VALID(intPointer)) + { + *intPointer = self->current; + } +} +#endif /* TRIO_FEATURE_FD */ + +/************************************************************************* + * TrioInStreamCustom + */ +#if TRIO_FEATURE_CLOSURE +TRIO_PRIVATE void +TrioInStreamCustom +TRIO_ARGS2((self, intPointer), + trio_class_t *self, + int *intPointer) +{ + trio_custom_t *data; + + assert(VALID(self)); + assert(VALID(self->location)); + + self->actually.cached = 0; + + data = (trio_custom_t *)self->location; + + self->current = (data->stream.in == NULL) + ? NIL + : (data->stream.in)(data->closure); + + if (self->current == NIL) + { + self->current = EOF; + } + else + { + self->processed++; + self->actually.cached++; + } + + if (VALID(intPointer)) + { + *intPointer = self->current; + } +} +#endif /* TRIO_FEATURE_CLOSURE */ + +/************************************************************************* + * TrioInStreamString + */ +TRIO_PRIVATE void +TrioInStreamString +TRIO_ARGS2((self, intPointer), + trio_class_t *self, + int *intPointer) +{ + unsigned char **buffer; + + assert(VALID(self)); + assert(VALID(self->location)); + + self->actually.cached = 0; + + buffer = (unsigned char **)self->location; + self->current = (*buffer)[0]; + if (self->current == NIL) + { + self->current = EOF; + } + else + { + (*buffer)++; + self->processed++; + self->actually.cached++; + } + + if (VALID(intPointer)) + { + *intPointer = self->current; + } +} + +/************************************************************************* + * + * Formatted scanning functions + * + ************************************************************************/ + +#if defined(TRIO_DOCUMENTATION) +# include "doc/doc_scanf.h" +#endif +/** @addtogroup Scanf + @{ +*/ + +/************************************************************************* + * scanf + */ + +/** + Scan characters from standard input stream. + + @param format Formatting string. + @param ... Arguments. + @return Number of scanned characters. + */ +#if TRIO_FEATURE_STDIO +TRIO_PUBLIC int +trio_scanf +TRIO_VARGS2((format, va_alist), + TRIO_CONST char *format, + TRIO_VA_DECL) +{ + int status; + va_list args; + + assert(VALID(format)); + + TRIO_VA_START(args, format); + status = TrioScan((trio_pointer_t)stdin, 0, + TrioInStreamFile, + TrioUndoStreamFile, + format, args, NULL); + TRIO_VA_END(args); + return status; +} +#endif /* TRIO_FEATURE_STDIO */ + +/** + Scan characters from standard input stream. + + @param format Formatting string. + @param args Arguments. + @return Number of scanned characters. + */ +#if TRIO_FEATURE_STDIO +TRIO_PUBLIC int +trio_vscanf +TRIO_ARGS2((format, args), + TRIO_CONST char *format, + va_list args) +{ + assert(VALID(format)); + + return TrioScan((trio_pointer_t)stdin, 0, + TrioInStreamFile, + TrioUndoStreamFile, + format, args, NULL); +} +#endif /* TRIO_FEATURE_STDIO */ + +/** + Scan characters from standard input stream. + + @param format Formatting string. + @param args Arguments. + @return Number of scanned characters. + */ +#if TRIO_FEATURE_STDIO +TRIO_PUBLIC int +trio_scanfv +TRIO_ARGS2((format, args), + TRIO_CONST char *format, + trio_pointer_t *args) +{ + static va_list unused; + + assert(VALID(format)); + + return TrioScan((trio_pointer_t)stdin, 0, + TrioInStreamFile, + TrioUndoStreamFile, + format, unused, args); +} +#endif /* TRIO_FEATURE_STDIO */ + +/************************************************************************* + * fscanf + */ + +/** + Scan characters from file. + + @param file File pointer. + @param format Formatting string. + @param ... Arguments. + @return Number of scanned characters. + */ +#if TRIO_FEATURE_FILE +TRIO_PUBLIC int +trio_fscanf +TRIO_VARGS3((file, format, va_alist), + FILE *file, + TRIO_CONST char *format, + TRIO_VA_DECL) +{ + int status; + va_list args; + + assert(VALID(file)); + assert(VALID(format)); + + TRIO_VA_START(args, format); + status = TrioScan((trio_pointer_t)file, 0, + TrioInStreamFile, + TrioUndoStreamFile, + format, args, NULL); + TRIO_VA_END(args); + return status; +} +#endif /* TRIO_FEATURE_FILE */ + +/** + Scan characters from file. + + @param file File pointer. + @param format Formatting string. + @param args Arguments. + @return Number of scanned characters. + */ +#if TRIO_FEATURE_FILE +TRIO_PUBLIC int +trio_vfscanf +TRIO_ARGS3((file, format, args), + FILE *file, + TRIO_CONST char *format, + va_list args) +{ + assert(VALID(file)); + assert(VALID(format)); + + return TrioScan((trio_pointer_t)file, 0, + TrioInStreamFile, + TrioUndoStreamFile, + format, args, NULL); +} +#endif /* TRIO_FEATURE_FILE */ + +/** + Scan characters from file. + + @param file File pointer. + @param format Formatting string. + @param args Arguments. + @return Number of scanned characters. + */ +#if TRIO_FEATURE_FILE +TRIO_PUBLIC int +trio_fscanfv +TRIO_ARGS3((file, format, args), + FILE *file, + TRIO_CONST char *format, + trio_pointer_t *args) +{ + static va_list unused; + + assert(VALID(file)); + assert(VALID(format)); + + return TrioScan((trio_pointer_t)file, 0, + TrioInStreamFile, + TrioUndoStreamFile, + format, unused, args); +} +#endif /* TRIO_FEATURE_FILE */ + +/************************************************************************* + * dscanf + */ + +/** + Scan characters from file descriptor. + + @param fd File descriptor. + @param format Formatting string. + @param ... Arguments. + @return Number of scanned characters. + */ +#if TRIO_FEATURE_FD +TRIO_PUBLIC int +trio_dscanf +TRIO_VARGS3((fd, format, va_alist), + int fd, + TRIO_CONST char *format, + TRIO_VA_DECL) +{ + int status; + va_list args; + + assert(VALID(format)); + + TRIO_VA_START(args, format); + status = TrioScan((trio_pointer_t)&fd, 0, + TrioInStreamFileDescriptor, + NULL, + format, args, NULL); + TRIO_VA_END(args); + return status; +} +#endif /* TRIO_FEATURE_FD */ + +/** + Scan characters from file descriptor. + + @param fd File descriptor. + @param format Formatting string. + @param args Arguments. + @return Number of scanned characters. + */ +#if TRIO_FEATURE_FD +TRIO_PUBLIC int +trio_vdscanf +TRIO_ARGS3((fd, format, args), + int fd, + TRIO_CONST char *format, + va_list args) +{ + assert(VALID(format)); + + return TrioScan((trio_pointer_t)&fd, 0, + TrioInStreamFileDescriptor, + NULL, + format, args, NULL); +} +#endif /* TRIO_FEATURE_FD */ + +/** + Scan characters from file descriptor. + + @param fd File descriptor. + @param format Formatting string. + @param args Arguments. + @return Number of scanned characters. + */ +#if TRIO_FEATURE_FD +TRIO_PUBLIC int +trio_dscanfv +TRIO_ARGS3((fd, format, args), + int fd, + TRIO_CONST char *format, + trio_pointer_t *args) +{ + static va_list unused; + + assert(VALID(format)); + + return TrioScan((trio_pointer_t)&fd, 0, + TrioInStreamFileDescriptor, + NULL, + format, unused, args); +} +#endif /* TRIO_FEATURE_FD */ + +/************************************************************************* + * cscanf + */ +#if TRIO_FEATURE_CLOSURE +TRIO_PUBLIC int +trio_cscanf +TRIO_VARGS4((stream, closure, format, va_alist), + trio_instream_t stream, + trio_pointer_t closure, + TRIO_CONST char *format, + TRIO_VA_DECL) +{ + int status; + va_list args; + trio_custom_t data; + + assert(VALID(stream)); + assert(VALID(format)); + + TRIO_VA_START(args, format); + data.stream.in = stream; + data.closure = closure; + status = TrioScan(&data, 0, TrioInStreamCustom, NULL, format, args, NULL); + TRIO_VA_END(args); + return status; +} +#endif /* TRIO_FEATURE_CLOSURE */ + +#if TRIO_FEATURE_CLOSURE +TRIO_PUBLIC int +trio_vcscanf +TRIO_ARGS4((stream, closure, format, args), + trio_instream_t stream, + trio_pointer_t closure, + TRIO_CONST char *format, + va_list args) +{ + trio_custom_t data; + + assert(VALID(stream)); + assert(VALID(format)); + + data.stream.in = stream; + data.closure = closure; + return TrioScan(&data, 0, TrioInStreamCustom, NULL, format, args, NULL); +} +#endif /* TRIO_FEATURE_CLOSURE */ + +#if TRIO_FEATURE_CLOSURE +TRIO_PUBLIC int +trio_cscanfv +TRIO_ARGS4((stream, closure, format, args), + trio_instream_t stream, + trio_pointer_t closure, + TRIO_CONST char *format, + trio_pointer_t *args) +{ + static va_list unused; + trio_custom_t data; + + assert(VALID(stream)); + assert(VALID(format)); + + data.stream.in = stream; + data.closure = closure; + return TrioScan(&data, 0, TrioInStreamCustom, NULL, format, unused, args); +} +#endif /* TRIO_FEATURE_CLOSURE */ + +/************************************************************************* + * sscanf + */ + +/** + Scan characters from string. + + @param buffer Input string. + @param format Formatting string. + @param ... Arguments. + @return Number of scanned characters. + */ +TRIO_PUBLIC int +trio_sscanf +TRIO_VARGS3((buffer, format, va_alist), + TRIO_CONST char *buffer, + TRIO_CONST char *format, + TRIO_VA_DECL) +{ + int status; + va_list args; + + assert(VALID(buffer)); + assert(VALID(format)); + + TRIO_VA_START(args, format); + status = TrioScan((trio_pointer_t)&buffer, 0, + TrioInStreamString, + NULL, + format, args, NULL); + TRIO_VA_END(args); + return status; +} + +/** + Scan characters from string. + + @param buffer Input string. + @param format Formatting string. + @param args Arguments. + @return Number of scanned characters. + */ +TRIO_PUBLIC int +trio_vsscanf +TRIO_ARGS3((buffer, format, args), + TRIO_CONST char *buffer, + TRIO_CONST char *format, + va_list args) +{ + assert(VALID(buffer)); + assert(VALID(format)); + + return TrioScan((trio_pointer_t)&buffer, 0, + TrioInStreamString, + NULL, + format, args, NULL); +} + +/** + Scan characters from string. + + @param buffer Input string. + @param format Formatting string. + @param args Arguments. + @return Number of scanned characters. + */ +TRIO_PUBLIC int +trio_sscanfv +TRIO_ARGS3((buffer, format, args), + TRIO_CONST char *buffer, + TRIO_CONST char *format, + trio_pointer_t *args) +{ + static va_list unused; + + assert(VALID(buffer)); + assert(VALID(format)); + + return TrioScan((trio_pointer_t)&buffer, 0, + TrioInStreamString, + NULL, + format, unused, args); +} + +#endif /* TRIO_FEATURE_SCANF */ + +/** @} End of Scanf documentation module */ + +/************************************************************************* + * trio_strerror + */ +TRIO_PUBLIC TRIO_CONST char * +trio_strerror +TRIO_ARGS1((errorcode), + int errorcode) +{ +#if TRIO_FEATURE_STRERR + /* Textual versions of the error codes */ + switch (TRIO_ERROR_CODE(errorcode)) + { + case TRIO_EOF: + return "End of file"; + case TRIO_EINVAL: + return "Invalid argument"; + case TRIO_ETOOMANY: + return "Too many arguments"; + case TRIO_EDBLREF: + return "Double reference"; + case TRIO_EGAP: + return "Reference gap"; + case TRIO_ENOMEM: + return "Out of memory"; + case TRIO_ERANGE: + return "Invalid range"; + case TRIO_ECUSTOM: + return "Custom error"; + default: + return "Unknown"; + } +#else + return "Unknown"; +#endif +} diff --git a/src/trio-sscanf/trio.h b/src/trio-sscanf/trio.h deleted file mode 120000 index 89bccb7f..00000000 --- a/src/trio-sscanf/trio.h +++ /dev/null @@ -1 +0,0 @@ -../trio/trio.h \ No newline at end of file diff --git a/src/trio-sscanf/trio.h b/src/trio-sscanf/trio.h new file mode 100644 index 00000000..1844ea60 --- /dev/null +++ b/src/trio-sscanf/trio.h @@ -0,0 +1,260 @@ +/* BEEBS trio benchmark + + Copyright (C) 2014 Embecosm Limited and University of Bristol + + This file is part of the Bristol/Embecosm Embedded Benchmark Suite. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* The original source of this file was from: + * http://daniel.haxx.se/projects/trio/ + * and is covered by the following copyright and licence: + * + * Copyright (C) 1998 Bjorn Reese and Daniel Stenberg. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND + * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. + * + ************************************************************************* + * + * http://ctrio.sourceforge.net/ + * + ************************************************************************/ + +#ifndef TRIO_TRIO_H +#define TRIO_TRIO_H + +#if !defined(WITHOUT_TRIO) + +/* + * Use autoconf defines if present. Packages using trio must define + * HAVE_CONFIG_H as a compiler option themselves. + */ +#if defined(HAVE_CONFIG_H) +# include +#endif + +#include "beebsc.h" +#include "triop.h" + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Error codes. + * + * Remember to add a textual description to trio_strerror. + */ +enum { + TRIO_EOF = 1, + TRIO_EINVAL = 2, + TRIO_ETOOMANY = 3, + TRIO_EDBLREF = 4, + TRIO_EGAP = 5, + TRIO_ENOMEM = 6, + TRIO_ERANGE = 7, + TRIO_ERRNO = 8, + TRIO_ECUSTOM = 9 +}; + +/* Error macros */ +#define TRIO_ERROR_CODE(x) ((-(x)) & 0x00FF) +#define TRIO_ERROR_POSITION(x) ((-(x)) >> 8) +#define TRIO_ERROR_NAME(x) trio_strerror(x) + +typedef int (*trio_outstream_t) TRIO_PROTO((trio_pointer_t, int)); +typedef int (*trio_instream_t) TRIO_PROTO((trio_pointer_t)); + +TRIO_CONST char *trio_strerror TRIO_PROTO((int)); + +/************************************************************************* + * Print Functions + */ + +int trio_printf TRIO_PROTO((TRIO_CONST char *format, ...)); +int trio_vprintf TRIO_PROTO((TRIO_CONST char *format, va_list args)); +int trio_printfv TRIO_PROTO((TRIO_CONST char *format, void **args)); + +int trio_fprintf TRIO_PROTO((FILE *file, TRIO_CONST char *format, ...)); +int trio_vfprintf TRIO_PROTO((FILE *file, TRIO_CONST char *format, va_list args)); +int trio_fprintfv TRIO_PROTO((FILE *file, TRIO_CONST char *format, void **args)); + +int trio_dprintf TRIO_PROTO((int fd, TRIO_CONST char *format, ...)); +int trio_vdprintf TRIO_PROTO((int fd, TRIO_CONST char *format, va_list args)); +int trio_dprintfv TRIO_PROTO((int fd, TRIO_CONST char *format, void **args)); + +int trio_cprintf TRIO_PROTO((trio_outstream_t stream, trio_pointer_t closure, + TRIO_CONST char *format, ...)); +int trio_vcprintf TRIO_PROTO((trio_outstream_t stream, trio_pointer_t closure, + TRIO_CONST char *format, va_list args)); +int trio_cprintfv TRIO_PROTO((trio_outstream_t stream, trio_pointer_t closure, + TRIO_CONST char *format, void **args)); + +int trio_sprintf TRIO_PROTO((char *buffer, TRIO_CONST char *format, ...)); +int trio_vsprintf TRIO_PROTO((char *buffer, TRIO_CONST char *format, va_list args)); +int trio_sprintfv TRIO_PROTO((char *buffer, TRIO_CONST char *format, void **args)); + +int trio_snprintf TRIO_PROTO((char *buffer, size_t max, TRIO_CONST char *format, ...)); +int trio_vsnprintf TRIO_PROTO((char *buffer, size_t bufferSize, TRIO_CONST char *format, + va_list args)); +int trio_snprintfv TRIO_PROTO((char *buffer, size_t bufferSize, TRIO_CONST char *format, + void **args)); + +int trio_snprintfcat TRIO_PROTO((char *buffer, size_t max, TRIO_CONST char *format, ...)); +int trio_vsnprintfcat TRIO_PROTO((char *buffer, size_t bufferSize, TRIO_CONST char *format, + va_list args)); + +#if defined(TRIO_DEPRECATED) +char *trio_aprintf TRIO_PROTO((TRIO_CONST char *format, ...)); +char *trio_vaprintf TRIO_PROTO((TRIO_CONST char *format, va_list args)); +#endif + +int trio_asprintf TRIO_PROTO((char **ret, TRIO_CONST char *format, ...)); +int trio_vasprintf TRIO_PROTO((char **ret, TRIO_CONST char *format, va_list args)); +int trio_asprintfv TRIO_PROTO((char **result, TRIO_CONST char *format, trio_pointer_t * args)); + +/************************************************************************* + * Scan Functions + */ +int trio_scanf TRIO_PROTO((TRIO_CONST char *format, ...)); +int trio_vscanf TRIO_PROTO((TRIO_CONST char *format, va_list args)); +int trio_scanfv TRIO_PROTO((TRIO_CONST char *format, void **args)); + +int trio_fscanf TRIO_PROTO((FILE *file, TRIO_CONST char *format, ...)); +int trio_vfscanf TRIO_PROTO((FILE *file, TRIO_CONST char *format, va_list args)); +int trio_fscanfv TRIO_PROTO((FILE *file, TRIO_CONST char *format, void **args)); + +int trio_dscanf TRIO_PROTO((int fd, TRIO_CONST char *format, ...)); +int trio_vdscanf TRIO_PROTO((int fd, TRIO_CONST char *format, va_list args)); +int trio_dscanfv TRIO_PROTO((int fd, TRIO_CONST char *format, void **args)); + +int trio_cscanf TRIO_PROTO((trio_instream_t stream, trio_pointer_t closure, + TRIO_CONST char *format, ...)); +int trio_vcscanf TRIO_PROTO((trio_instream_t stream, trio_pointer_t closure, + TRIO_CONST char *format, va_list args)); +int trio_cscanfv TRIO_PROTO((trio_instream_t stream, trio_pointer_t closure, + TRIO_CONST char *format, void **args)); + +int trio_sscanf TRIO_PROTO((TRIO_CONST char *buffer, TRIO_CONST char *format, ...)); +int trio_vsscanf TRIO_PROTO((TRIO_CONST char *buffer, TRIO_CONST char *format, va_list args)); +int trio_sscanfv TRIO_PROTO((TRIO_CONST char *buffer, TRIO_CONST char *format, void **args)); + +/************************************************************************* + * Locale Functions + */ +void trio_locale_set_decimal_point TRIO_PROTO((char *decimalPoint)); +void trio_locale_set_thousand_separator TRIO_PROTO((char *thousandSeparator)); +void trio_locale_set_grouping TRIO_PROTO((char *grouping)); + +/************************************************************************* + * Renaming + */ +#ifdef TRIO_REPLACE_STDIO +/* Replace the functions */ +#ifndef HAVE_PRINTF +# undef printf +# define printf trio_printf +#endif +#ifndef HAVE_VPRINTF +# undef vprintf +# define vprintf trio_vprintf +#endif +#ifndef HAVE_FPRINTF +# undef fprintf +# define fprintf trio_fprintf +#endif +#ifndef HAVE_VFPRINTF +# undef vfprintf +# define vfprintf trio_vfprintf +#endif +#ifndef HAVE_SPRINTF +# undef sprintf +# define sprintf trio_sprintf +#endif +#ifndef HAVE_VSPRINTF +# undef vsprintf +# define vsprintf trio_vsprintf +#endif +#ifndef HAVE_SNPRINTF +# undef snprintf +# define snprintf trio_snprintf +#endif +#ifndef HAVE_VSNPRINTF +# undef vsnprintf +# define vsnprintf trio_vsnprintf +#endif +#ifndef HAVE_SCANF +# undef scanf +# define scanf trio_scanf +#endif +#ifndef HAVE_VSCANF +# undef vscanf +# define vscanf trio_vscanf +#endif +#ifndef HAVE_FSCANF +# undef fscanf +# define fscanf trio_fscanf +#endif +#ifndef HAVE_VFSCANF +# undef vfscanf +# define vfscanf trio_vfscanf +#endif +#ifndef HAVE_SSCANF +# undef sscanf +# define sscanf trio_sscanf +#endif +#ifndef HAVE_VSSCANF +# undef vsscanf +# define vsscanf trio_vsscanf +#endif +/* These aren't stdio functions, but we make them look similar */ +#undef dprintf +#define dprintf trio_dprintf +#undef vdprintf +#define vdprintf trio_vdprintf +#undef aprintf +#define aprintf trio_aprintf +#undef vaprintf +#define vaprintf trio_vaprintf +#undef asprintf +#define asprintf trio_asprintf +#undef vasprintf +#define vasprintf trio_vasprintf +#undef dscanf +#define dscanf trio_dscanf +#undef vdscanf +#define vdscanf trio_vdscanf +#endif + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* WITHOUT_TRIO */ + +void init_heap (void); +void *malloc_beebs (size_t size); +void *realloc_beebs (void *ptr, size_t size); +void free_beebs (void *ptr); + +#endif /* TRIO_TRIO_H */ diff --git a/src/trio-sscanf/trio_test.c b/src/trio-sscanf/trio_test.c deleted file mode 120000 index 9260d6fd..00000000 --- a/src/trio-sscanf/trio_test.c +++ /dev/null @@ -1 +0,0 @@ -../trio/trio_test.c \ No newline at end of file diff --git a/src/trio-sscanf/trio_test.c b/src/trio-sscanf/trio_test.c new file mode 100644 index 00000000..3b514a7d --- /dev/null +++ b/src/trio-sscanf/trio_test.c @@ -0,0 +1,75 @@ +/* BEEBS template benchmark + + Copyright (C) 2014 Embecosm Limited and University of Bristol + + Contributor James Pallister + + This file is part of the Bristol/Embecosm Embedded Benchmark Suite. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include +#include "support.h" +#include "trio.h" + +/* This scale factor will be changed to equalise the runtime of the + benchmarks. */ +#define LOCAL_SCALE_FACTOR 466 + +/* Global variables, so calls in BENCHMARK are not optimised away. */ +int int_dest[7]; +char char_dest [20]; + + +void +initialise_benchmark (void) +{ +} + + +int +benchmark (void) +{ + int i; + + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + { + volatile int i1, i2; + trio_sscanf("123", "%d", &i1); + int_dest[0] = i1; + trio_sscanf("123 456", "%d %d", &i1, &i2); + int_dest[1] = i1; + int_dest[2] = i2; + trio_sscanf("000000123", "%d", &i1); + int_dest[3] = i1; + trio_sscanf("cdefg", "%x", &i1); + int_dest[4] = i1; + trio_sscanf("FF", "%x",&i1); + int_dest[5] = i1; + trio_sscanf("abcdefg", "%[^f]%xg", &char_dest, &i1); + int_dest[6] = i1; + } + + return 0; +} + +int verify_benchmark(int unused) { + static const int int_exp[7] = { + 123, 123, 456, 123, 0xcdef, 0xff, 0xf + }; + static const char char_exp [20] = "abcde"; + + return (0 == memcmp (int_exp, int_dest, 7 * sizeof (int_exp[0]))) + && (0 == strcmp (char_exp, char_dest)); +} diff --git a/src/trio-sscanf/triodef.h b/src/trio-sscanf/triodef.h deleted file mode 120000 index 085f7c57..00000000 --- a/src/trio-sscanf/triodef.h +++ /dev/null @@ -1 +0,0 @@ -../trio/triodef.h \ No newline at end of file diff --git a/src/trio-sscanf/triodef.h b/src/trio-sscanf/triodef.h new file mode 100644 index 00000000..037c1da7 --- /dev/null +++ b/src/trio-sscanf/triodef.h @@ -0,0 +1,354 @@ +/* BEEBS trio benchmark + + Copyright (C) 2014 Embecosm Limited and University of Bristol + + This file is part of the Bristol/Embecosm Embedded Benchmark Suite. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* The original source of this file was from: + * http://daniel.haxx.se/projects/trio/ + * and is covered by the following copyright and licence: + * + * Copyright (C) 2001 Bjorn Reese + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND + * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. + * + ************************************************************************/ + +#ifndef TRIO_TRIODEF_H +#define TRIO_TRIODEF_H + +/************************************************************************* + * Compiler support detection + */ + +#if defined(__GNUC__) +# define TRIO_COMPILER_GCC +#endif + +#if defined(__SUNPRO_CC) +# define TRIO_COMPILER_SUNPRO __SUNPRO_CC +#else +# if defined(__SUNPRO_C) +# define TRIO_COMPILER_SUNPRO __SUNPRO_C +# endif +#endif + +#if defined(__xlC__) || defined(__IBMC__) || defined(__IBMCPP__) +# define TRIO_COMPILER_XLC +#else +# if defined(_AIX) && !defined(__GNUC__) +# define TRIO_COMPILER_XLC /* Workaround for old xlc */ +# endif +#endif + +#if defined(__DECC) || defined(__DECCXX) +# define TRIO_COMPILER_DECC +#else +# if defined(__osf__) && defined(__LANGUAGE_C__) && !defined(__GNUC__) +# define TRIO_COMPILER_DECC /* Workaround for old DEC C compilers */ +# endif +#endif + +#if defined(__HP_aCC) || defined(__HP_cc) +# define TRIO_COMPILER_HP +#endif + +#if defined(sgi) || defined(__sgi) +# define TRIO_COMPILER_MIPSPRO +#endif + +#if defined(_MSC_VER) +# define TRIO_COMPILER_MSVC +#endif + +#if defined(__BORLANDC__) +# define TRIO_COMPILER_BCB +#endif + +/************************************************************************* + * Platform support detection + */ + +#if defined(VMS) || defined(__VMS) +# define TRIO_PLATFORM_VMS +#endif + +#if defined(unix) || defined(__unix) || defined(__unix__) +# define TRIO_PLATFORM_UNIX +#endif + +#if defined(TRIO_COMPILER_XLC) || defined(_AIX) +# define TRIO_PLATFORM_UNIX +#endif + +#if defined(TRIO_COMPILER_DECC) || defined(__osf___) +# if !defined(TRIO_PLATFORM_VMS) +# define TRIO_PLATFORM_UNIX +# endif +#endif + +#if defined(__NetBSD__) +# define TRIO_PLATFORM_UNIX +#endif + +#if defined(__Lynx__) +# define TRIO_PLATFORM_UNIX +# define TRIO_PLATFORM_LYNX +#endif + +#if defined(__APPLE__) && defined(__MACH__) +# define TRIO_PLATFORM_UNIX +#endif + +#if defined(__QNX__) +# define TRIO_PLATFORM_UNIX +# define TRIO_PLATFORM_QNX +#endif + +#if defined(__CYGWIN__) +# define TRIO_PLATFORM_UNIX +#endif + +#if defined(AMIGA) && defined(TRIO_COMPILER_GCC) +# define TRIO_PLATFORM_UNIX +#endif + +#if defined(TRIO_COMPILER_MSVC) || defined(WIN32) || defined(_WIN32) +# define TRIO_PLATFORM_WIN32 +#endif + +#if defined(_WIN32_WCE) +# define TRIO_PLATFORM_WINCE +#endif + +#if defined(mpeix) || defined(__mpexl) +# define TRIO_PLATFORM_MPEIX +#endif + +#if defined(_AIX) +# define TRIO_PLATFORM_AIX +#endif + +#if defined(__hpux) +# define TRIO_PLATFORM_HPUX +#endif + +#if defined(sun) || defined(__sun__) +# if defined(__SVR4) || defined(__svr4__) +# define TRIO_PLATFORM_SOLARIS +# else +# define TRIO_PLATFORM_SUNOS +# endif +#endif + +/************************************************************************* + * Standards support detection + */ + +#if defined(__STDC__) \ + || defined(_MSC_EXTENSIONS) \ + || defined(TRIO_COMPILER_BCB) +# define PREDEF_STANDARD_C89 +#endif +#if defined(__STDC_VERSION__) +# define PREDEF_STANDARD_C90 +#endif +#if (__STDC_VERSION__ - 0 >= 199409L) +# define PREDEF_STANDARD_C94 +#endif +#if (__STDC_VERSION__ - 0 >= 199901L) +# define PREDEF_STANDARD_C99 +#endif +#if defined(TRIO_COMPILER_SUNPRO) && (TRIO_COMPILER_SUNPRO >= 0x420) +# if !defined(PREDEF_STANDARD_C94) +# define PREDEF_STANDARD_C94 +# endif +#endif + +#if defined(__cplusplus) +# define PREDEF_STANDARD_CXX +#endif +#if __cplusplus - 0 >= 199711L +# define PREDEF_STANDARD_CXX89 +#endif + +#if defined(TRIO_PLATFORM_UNIX) +# include +#endif + +#if defined(_POSIX_VERSION) +# define PREDEF_STANDARD_POSIX _POSIX_VERSION +# if (_POSIX_VERSION >= 199506L) +# define PREDEF_STANDARD_POSIX_1996 +# endif +#endif + +#if (_XOPEN_VERSION - 0 >= 3) || defined(_XOPEN_XPG3) +# define PREDEF_STANDARD_XPG3 +#endif +#if (_XOPEN_VERSION - 0 >= 4) || defined(_XOPEN_XPG4) +# define PREDEF_STANDARD_XPG4 +#endif +#if (_XOPEN_VERSION - 0 > 4) \ + || (defined(_XOPEN_UNIX) && (_XOPEN_VERSION - 0 == 4)) +# define PREDEF_STANDARD_UNIX95 +#endif +#if (_XOPEN_VERSION - 0 >= 500) +# define PREDEF_STANDARD_UNIX98 +#endif +#if (_XOPEN_VERSION - 0 >= 600) +# define PREDEF_STANDARD_UNIX03 +#endif + +/************************************************************************* + * Generic defines + */ + +#if !defined(TRIO_PUBLIC) +# define TRIO_PUBLIC +#endif +#if !defined(TRIO_PRIVATE) +# define TRIO_PRIVATE static +#endif + +#if !(defined(PREDEF_STANDARD_C89) || defined(PREDEF_STANDARD_CXX)) +# define TRIO_COMPILER_ANCIENT +#endif + +#if defined(TRIO_COMPILER_ANCIENT) +# define TRIO_CONST +# define TRIO_VOLATILE +# define TRIO_SIGNED +typedef double trio_long_double_t; +typedef char * trio_pointer_t; +# define TRIO_SUFFIX_LONG(x) x +# define TRIO_PROTO(x) () +# define TRIO_NOARGS +# define TRIO_ARGS1(list,a1) list a1; +# define TRIO_ARGS2(list,a1,a2) list a1; a2; +# define TRIO_ARGS3(list,a1,a2,a3) list a1; a2; a3; +# define TRIO_ARGS4(list,a1,a2,a3,a4) list a1; a2; a3; a4; +# define TRIO_ARGS5(list,a1,a2,a3,a4,a5) list a1; a2; a3; a4; a5; +# define TRIO_ARGS6(list,a1,a2,a3,a4,a5,a6) list a1; a2; a3; a4; a5; a6; +# define TRIO_ARGS7(list,a1,a2,a3,a4,a5,a6,a7) list a1; a2; a3; a4; a5; a6; a7; +# define TRIO_VARGS2(list,a1,a2) list a1; a2 +# define TRIO_VARGS3(list,a1,a2,a3) list a1; a2; a3 +# define TRIO_VARGS4(list,a1,a2,a3,a4) list a1; a2; a3; a4 +# define TRIO_VARGS5(list,a1,a2,a3,a4,a5) list a1; a2; a3; a4; a5 +# define TRIO_VA_DECL va_dcl +# define TRIO_VA_START(x,y) va_start(x) +# define TRIO_VA_END(x) va_end(x) +#else /* ANSI C */ +# define TRIO_CONST const +# define TRIO_VOLATILE volatile +# define TRIO_SIGNED signed +typedef long double trio_long_double_t; +typedef void * trio_pointer_t; +# define TRIO_SUFFIX_LONG(x) x ## L +# define TRIO_PROTO(x) x +# define TRIO_NOARGS void +# define TRIO_ARGS1(list,a1) (a1) +# define TRIO_ARGS2(list,a1,a2) (a1,a2) +# define TRIO_ARGS3(list,a1,a2,a3) (a1,a2,a3) +# define TRIO_ARGS4(list,a1,a2,a3,a4) (a1,a2,a3,a4) +# define TRIO_ARGS5(list,a1,a2,a3,a4,a5) (a1,a2,a3,a4,a5) +# define TRIO_ARGS6(list,a1,a2,a3,a4,a5,a6) (a1,a2,a3,a4,a5,a6) +# define TRIO_ARGS7(list,a1,a2,a3,a4,a5,a6,a7) (a1,a2,a3,a4,a5,a6,a7) +# define TRIO_VARGS2 TRIO_ARGS2 +# define TRIO_VARGS3 TRIO_ARGS3 +# define TRIO_VARGS4 TRIO_ARGS4 +# define TRIO_VARGS5 TRIO_ARGS5 +# define TRIO_VA_DECL ... +# define TRIO_VA_START(x,y) va_start(x,y) +# define TRIO_VA_END(x) va_end(x) +#endif + +#if defined(PREDEF_STANDARD_C99) || defined(PREDEF_STANDARD_CXX) +# define TRIO_INLINE inline +#else +# if defined(TRIO_COMPILER_GCC) +# define TRIO_INLINE __inline__ +# endif +# if defined(TRIO_COMPILER_MSVC) +# define TRIO_INLINE _inline +# endif +# if defined(TRIO_COMPILER_BCB) +# define TRIO_INLINE __inline +# endif +#endif +#if !defined(TRIO_INLINE) +# define TRIO_INLINE +#endif + +/************************************************************************* + * Workarounds + */ + +#if defined(TRIO_PLATFORM_VMS) +/* + * Computations done with constants at compile time can trigger these + * even when compiling with IEEE enabled. + */ +# pragma message disable (UNDERFLOW, FLOATOVERFL) + +# if (__CRTL_VER < 80210001) +/* + * Although the compiler supports C99 language constructs, the C + * run-time library does not contain all C99 functions. + */ +# if defined(PREDEF_STANDARD_C99) +# undef PREDEF_STANDARD_C99 +# endif +# endif +#endif + +/* + * Not all preprocessors supports the LL token. + */ +#if defined(TRIO_COMPILER_MSVC) || defined(TRIO_COMPILER_BCB) +#else +# define TRIO_COMPILER_SUPPORTS_LL +#endif + +#if defined(__CYGWIN__) +/* + * Cygwin defines the macros for hosted C99, but does not support certain + * long double math functions. + */ +# include +# define TRIO_CYGWIN_VERSION_API CYGWIN_VERSION_API_MAJOR * 1000 + \ + CYGWIN_VERSION_API_MINOR +/* + * Please change the version number below when the Cygwin API supports + * long double math functions (powl, fmodl, etc.) + */ +# if TRIO_CYGWIN_VERSION_API < 99999999 +# define TRIO_NO_FLOORL 1 +# define TRIO_NO_CEILL 1 +# define TRIO_NO_POWL 1 +# define TRIO_NO_FMODL 1 +# define TRIO_NO_LOG10L 1 +# endif +#endif + +#endif /* TRIO_TRIODEF_H */ diff --git a/src/trio-sscanf/triop.h b/src/trio-sscanf/triop.h deleted file mode 120000 index 58444347..00000000 --- a/src/trio-sscanf/triop.h +++ /dev/null @@ -1 +0,0 @@ -../trio/triop.h \ No newline at end of file diff --git a/src/trio-sscanf/triop.h b/src/trio-sscanf/triop.h new file mode 100644 index 00000000..60aaacef --- /dev/null +++ b/src/trio-sscanf/triop.h @@ -0,0 +1,491 @@ +/* BEEBS trio benchmark + + Copyright (C) 2014 Embecosm Limited and University of Bristol + + This file is part of the Bristol/Embecosm Embedded Benchmark Suite. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* The original source of this file was from: + * http://daniel.haxx.se/projects/trio/ + * and is covered by the following copyright and licence: + * + * Copyright (C) 2000 Bjorn Reese and Daniel Stenberg. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND + * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. + * + ************************************************************************ + * + * Private functions, types, etc. used for callback functions. + * + * The ref pointer is an opaque type and should remain as such. + * Private data must only be accessible through the getter and + * setter functions. + * + ************************************************************************/ + +#ifndef TRIO_TRIOP_H +#define TRIO_TRIOP_H + +#include "triodef.h" + +#include +#if defined(TRIO_COMPILER_ANCIENT) +# include +#else +# include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/************************************************************************* + * Supported standards + */ + +/* + * TRIO_C99 (=0 or =1) + * + * Define this to 0 to disable C99 format specifier extensions, or + * define to 1 to enable them. The format specifiers that are + * disabled by this switch are labelled with [C99] in the format + * specifier documentation. + */ +#if !defined(TRIO_C99) +# define TRIO_C99 1 +#endif + +/* + * TRIO_BSD (=0 or =1) + * + * Define this to 0 to disable BSD format specifier extensions, or + * define to 1 to enable them. The format specifiers that are + * disabled by this switch are labelled with [BSD] in the format + * specifier documentation. + */ +#if !defined(TRIO_BSD) +# define TRIO_BSD 1 +#endif + +/* + * TRIO_GNU (=0 or =1) + * + * Define this to 0 to disable GNU format specifier extensions, or + * define to 1 to enable them. The format specifiers that are + * disabled by this switch are labelled with [GNU] in the format + * specifier documentation. + */ +#if !defined(TRIO_GNU) +# define TRIO_GNU 1 +#endif + +/* + * TRIO_MISC (=0 or =1) + * + * Define this to 0 to disable miscellaneous format specifier + * extensions, or define to 1 to enable them. The format specifiers + * that are disabled by this switch are labelled with [MISC] in the + * format specifier documentation. + */ +#if !defined(TRIO_MISC) +# define TRIO_MISC 1 +#endif + +/* + * TRIO_UNIX98 (=0 or =1) + * + * Define this to 0 to disable UNIX98 format specifier extensions, + * or define to 1 to enable them. The format specifiers that are + * disabled by this switch are labelled with [UNIX98] in the format + * specifier documentation. + */ +#if !defined(TRIO_UNIX98) +# define TRIO_UNIX98 1 +#endif + +/* + * TRIO_MICROSOFT (=0 or =1) + * + * Define this to 0 to disable Microsoft Visual C format specifier + * extensions, or define to 1 to enable them. The format specifiers + * that are disabled by this switch are labelled with [MSVC] in the + * format specifier documentation. + */ +#if !defined(TRIO_MICROSOFT) +# define TRIO_MICROSOFT 1 +#endif + +/* + * TRIO_EXTENSION (=0 or =1) + * + * Define this to 0 to disable Trio-specific extensions, or define + * to 1 to enable them. This has two effects: it controls whether + * or not the Trio user-defined formating mechanism + * (trio_register() etc) is supported, and it enables or disables + * Trio's own format specifier extensions. The format specifiers + * that are disabled by this switch are labelled with [TRIO] in + * the format specifier documentation. + */ +#if !defined(TRIO_EXTENSION) +# define TRIO_EXTENSION 1 +#endif + +/* + * TRIO_DEPRECATED (=0 or =1) + * + * Define this to 0 to disable deprecated functionality, or define + * to 1 to enable them. + */ +#if !defined(TRIO_DEPRECATED) +# define TRIO_DEPRECATED 1 +#endif + +/************************************************************************* + * Features + */ + +#if defined(TRIO_SNPRINTF_ONLY) +# define TRIO_FEATURE_SCANF 0 +# define TRIO_FEATURE_FILE 0 +# define TRIO_FEATURE_STDIO 0 +# define TRIO_FEATURE_FD 0 +# define TRIO_FEATURE_DYNAMICSTRING 0 +# define TRIO_FEATURE_CLOSURE 0 +# define TRIO_FEATURE_STRERR 0 +# define TRIO_FEATURE_LOCALE 0 +# define TRIO_EMBED_NAN 1 +# define TRIO_EMBED_STRING 1 +#endif + +/* + * TRIO_FEATURE_SCANF (=0 or =1) + * + * Define this to 0 to disable all the scanf() variants, or define to 1 + * to enable them. + */ +#if !defined(TRIO_FEATURE_SCANF) +# define TRIO_FEATURE_SCANF 1 +#endif + +/* + * TRIO_FEATURE_FILE (=0 or =1) + * + * Define this to 0 to disable compilation of the trio_fprintf() and + * trio_fscanf() family of functions, or define to 1 to enable them. + * + * This may be useful on an embedded platform with no filesystem. + * Note that trio_printf() uses fwrite to write to stdout, so if you + * do not have an implementation of fwrite() at all then you must also + * define TRIO_FEATURE_STDIO to 0. + */ +#if !defined(TRIO_FEATURE_FILE) +# define TRIO_FEATURE_FILE 1 +#endif + +/* + * TRIO_FEATURE_STDIO (=0 or =1) + * + * Define this to 0 to disable compilation of the trio_printf() and + * trio_scanf() family of functions, or define to 1 to enable them. + * + * This may be useful on an embedded platform with no standard I/O. + */ +#if !defined(TRIO_FEATURE_STDIO) +# define TRIO_FEATURE_STDIO 1 +#endif + +/* + * TRIO_FEATURE_FD (=0 or =1) + * + * Define this to 0 to disable compilation of the trio_dprintf() and + * trio_dscanf() family of functions, or define to 1 to enable them. + * + * This may be useful on an embedded platform with no filesystem, or on + * a platform that supports file I/O using FILE* but not using raw file + * descriptors. + */ +#if !defined(TRIO_FEATURE_FD) +# define TRIO_FEATURE_FD 1 +#endif + +/* + * TRIO_FEATURE_DYNAMICSTRING (=0 or =1) + * + * Define this to 0 to disable compilation of the trio_aprintf() + * family of functions, or define to 1 to enable them. + * + * If you define both this and TRIO_MINIMAL to 0, then Trio will never + * call malloc or free. + */ +#if !defined(TRIO_FEATURE_DYNAMICSTRING) +# define TRIO_FEATURE_DYNAMICSTRING 1 +#endif + +/* + * TRIO_FEATURE_CLOSURE (=0 or =1) + * + * Define this to 0 to disable compilation of the trio_cprintf() and + * trio_cscanf() family of functions, or define to 1 to enable them. + * + * These functions are rarely needed. This saves a (small) amount of code. + */ +#if !defined(TRIO_FEATURE_CLOSURE) +# define TRIO_FEATURE_CLOSURE 1 +#endif + +/* + * TRIO_FEATURE_ERRORCODE (=0 or =1) + * + * Define this to 0 to return -1 from the print and scan function on + * error, or define to 1 to return a negative number with debugging + * information as part of the return code. + * + * If enabled, the return code will be a negative number, which encodes + * an error code and an error location. These can be decoded with the + * TRIO_ERROR_CODE and TRIO_ERROR_POSITION macros. + */ +#if defined(TRIO_ERRORS) +# define TRIO_FEATURE_ERRORCODE TRIO_ERRORS +#endif +#if !defined(TRIO_FEATURE_ERRORCODE) +# define TRIO_FEATURE_ERRORCODE 1 +#endif + +/* + * TRIO_FEATURE_STRERR (=0 or =1) + * + * Define this to 0 if you do not use trio_strerror(), or define to 1 if + * you do use it. + * + * This saves a (small) amount of code. + */ +#if !defined(TRIO_FEATURE_STRERR) +# define TRIO_FEATURE_STRERR 1 +#endif + +/* + * TRIO_FEATURE_FLOAT (=0 or =1) + * + * Define this to 0 to disable all floating-point support, or define + * to 1 to enable it. + * + * This is useful in restricted embedded platforms that do not support + * floating-point. Obviously you cannot use floating-point format + * specifiers if you define this. + * + * Do not compile trionan.c if you disable this. + */ +#if !defined(TRIO_FEATURE_FLOAT) +# define TRIO_FEATURE_FLOAT 1 +#endif + +/* + * TRIO_FEATURE_LOCALE (=0 or =1) + * + * Define this to 0 to disable customized locale support, or define + * to 1 to enable it. + * + * This saves a (small) amount of code. + */ +#if !defined(TRIO_FEATURE_LOCALE) +# define TRIO_FEATURE_LOCALE 1 +#endif + +/* + * TRIO_MINIMAL + * + * Define this to disable building the public trionan.h and triostr.h. + * If you define this, then you must not compile trionan.c and triostr.c + * separately. + */ +#if defined(TRIO_MINIMAL) +# if !defined(TRIO_EMBED_NAN) +# define TRIO_EMBED_NAN +# endif +# if !defined(TRIO_EMBED_STRING) +# define TRIO_EMBED_STRING +# endif +#endif + +/* Does not work yet. Do not enable */ +#ifndef TRIO_FEATURE_WIDECHAR +# define TRIO_FEATURE_WIDECHAR 0 +#endif + +/************************************************************************* + * Mapping standards to internal features + */ + +#if !defined(TRIO_FEATURE_HEXFLOAT) +# define TRIO_FEATURE_HEXFLOAT (TRIO_C99 && TRIO_FEATURE_FLOAT) +#endif + +#if !defined(TRIO_FEATURE_LONGDOUBLE) +# define TRIO_FEATURE_LONGDOUBLE TRIO_FEATURE_FLOAT +#endif + +#if !defined(TRIO_FEATURE_ERRNO) +# define TRIO_FEATURE_ERRNO TRIO_GNU +#endif + +#if !defined(TRIO_FEATURE_QUAD) +# define TRIO_FEATURE_QUAD (TRIO_BSD || TRIO_GNU) +#endif + +#if !defined(TRIO_FEATURE_SIZE_T) +# define TRIO_FEATURE_SIZE_T TRIO_C99 +#endif + +#if !defined(TRIO_FEATURE_SIZE_T_UPPER) +# define TRIO_FEATURE_SIZE_T_UPPER TRIO_GNU +#endif + +#if !defined(TRIO_FEATURE_PTRDIFF_T) +# define TRIO_FEATURE_PTRDIFF_T TRIO_C99 +#endif + +#if !defined(TRIO_FEATURE_INTMAX_T) +# define TRIO_FEATURE_INTMAX_T TRIO_C99 +#endif + +#if !defined(TRIO_FEATURE_FIXED_SIZE) +# define TRIO_FEATURE_FIXED_SIZE TRIO_MICROSOFT +#endif + +#if !defined(TRIO_FEATURE_POSITIONAL) +# define TRIO_FEATURE_POSITIONAL TRIO_UNIX98 +#endif + +#if !defined(TRIO_FEATURE_USER_DEFINED) +# define TRIO_FEATURE_USER_DEFINED TRIO_EXTENSION +#endif + +#if !defined(TRIO_FEATURE_BINARY) +# define TRIO_FEATURE_BINARY TRIO_EXTENSION +#endif + +#if !defined(TRIO_FEATURE_QUOTE) +# define TRIO_FEATURE_QUOTE TRIO_EXTENSION +#endif + +#if !defined(TRIO_FEATURE_STICKY) +# define TRIO_FEATURE_STICKY TRIO_EXTENSION +#endif + +#if !defined(TRIO_FEATURE_VARSIZE) +# define TRIO_FEATURE_VARSIZE TRIO_EXTENSION +#endif + +#if !defined(TRIO_FEATURE_ROUNDING) +# define TRIO_FEATURE_ROUNDING TRIO_EXTENSION +#endif + +/************************************************************************* + * Memory handling + */ +#ifndef TRIO_MALLOC +# define TRIO_MALLOC(n) malloc_beebs(n) +#endif +#ifndef TRIO_REALLOC +# define TRIO_REALLOC(x,n) realloc_beebs((x),(n)) +#endif +#ifndef TRIO_FREE +# define TRIO_FREE(x) free_beebs(x) +#endif + + +/************************************************************************* + * User-defined specifiers + */ + +typedef int (*trio_callback_t) TRIO_PROTO((trio_pointer_t)); + +trio_pointer_t trio_register TRIO_PROTO((trio_callback_t callback, const char *name)); +void trio_unregister TRIO_PROTO((trio_pointer_t handle)); + +TRIO_CONST char *trio_get_format TRIO_PROTO((trio_pointer_t ref)); +TRIO_CONST trio_pointer_t trio_get_argument TRIO_PROTO((trio_pointer_t ref)); + +/* Modifiers */ +int trio_get_width TRIO_PROTO((trio_pointer_t ref)); +void trio_set_width TRIO_PROTO((trio_pointer_t ref, int width)); +int trio_get_precision TRIO_PROTO((trio_pointer_t ref)); +void trio_set_precision TRIO_PROTO((trio_pointer_t ref, int precision)); +int trio_get_base TRIO_PROTO((trio_pointer_t ref)); +void trio_set_base TRIO_PROTO((trio_pointer_t ref, int base)); +int trio_get_padding TRIO_PROTO((trio_pointer_t ref)); +void trio_set_padding TRIO_PROTO((trio_pointer_t ref, int is_padding)); +int trio_get_short TRIO_PROTO((trio_pointer_t ref)); /* h */ +void trio_set_shortshort TRIO_PROTO((trio_pointer_t ref, int is_shortshort)); +int trio_get_shortshort TRIO_PROTO((trio_pointer_t ref)); /* hh */ +void trio_set_short TRIO_PROTO((trio_pointer_t ref, int is_short)); +int trio_get_long TRIO_PROTO((trio_pointer_t ref)); /* l */ +void trio_set_long TRIO_PROTO((trio_pointer_t ref, int is_long)); +int trio_get_longlong TRIO_PROTO((trio_pointer_t ref)); /* ll */ +void trio_set_longlong TRIO_PROTO((trio_pointer_t ref, int is_longlong)); +int trio_get_longdouble TRIO_PROTO((trio_pointer_t ref)); /* L */ +void trio_set_longdouble TRIO_PROTO((trio_pointer_t ref, int is_longdouble)); +int trio_get_alternative TRIO_PROTO((trio_pointer_t ref)); /* # */ +void trio_set_alternative TRIO_PROTO((trio_pointer_t ref, int is_alternative)); +int trio_get_alignment TRIO_PROTO((trio_pointer_t ref)); /* - */ +void trio_set_alignment TRIO_PROTO((trio_pointer_t ref, int is_leftaligned)); +int trio_get_spacing TRIO_PROTO((trio_pointer_t ref)); /* (space) */ +void trio_set_spacing TRIO_PROTO((trio_pointer_t ref, int is_space)); +int trio_get_sign TRIO_PROTO((trio_pointer_t ref)); /* + */ +void trio_set_sign TRIO_PROTO((trio_pointer_t ref, int is_showsign)); +#if TRIO_FEATURE_QUOTE +int trio_get_quote TRIO_PROTO((trio_pointer_t ref)); /* ' */ +void trio_set_quote TRIO_PROTO((trio_pointer_t ref, int is_quote)); +#endif +int trio_get_upper TRIO_PROTO((trio_pointer_t ref)); +void trio_set_upper TRIO_PROTO((trio_pointer_t ref, int is_upper)); +#if TRIO_FEATURE_INTMAX_T +int trio_get_largest TRIO_PROTO((trio_pointer_t ref)); /* j */ +void trio_set_largest TRIO_PROTO((trio_pointer_t ref, int is_largest)); +#endif +#if TRIO_FEATURE_PTRDIFF_T +int trio_get_ptrdiff TRIO_PROTO((trio_pointer_t ref)); /* t */ +void trio_set_ptrdiff TRIO_PROTO((trio_pointer_t ref, int is_ptrdiff)); +#endif +#if TRIO_FEATURE_SIZE_T +int trio_get_size TRIO_PROTO((trio_pointer_t ref)); /* z / Z */ +void trio_set_size TRIO_PROTO((trio_pointer_t ref, int is_size)); +#endif + +/* Printing */ +int trio_print_ref TRIO_PROTO((trio_pointer_t ref, const char *format, ...)); +int trio_vprint_ref TRIO_PROTO((trio_pointer_t ref, const char *format, va_list args)); +int trio_printv_ref TRIO_PROTO((trio_pointer_t ref, const char *format, trio_pointer_t *args)); + +void trio_print_int TRIO_PROTO((trio_pointer_t ref, int number)); +void trio_print_uint TRIO_PROTO((trio_pointer_t ref, unsigned int number)); +/* void trio_print_long TRIO_PROTO((trio_pointer_t ref, long number)); */ +/* void trio_print_ulong TRIO_PROTO((trio_pointer_t ref, unsigned long number)); */ +void trio_print_double TRIO_PROTO((trio_pointer_t ref, double number)); +void trio_print_string TRIO_PROTO((trio_pointer_t ref, TRIO_CONST char *string)); +void trio_print_pointer TRIO_PROTO((trio_pointer_t ref, trio_pointer_t pointer)); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* TRIO_TRIOP_H */ diff --git a/src/trio-sscanf/triostr.c b/src/trio-sscanf/triostr.c deleted file mode 120000 index 56efe157..00000000 --- a/src/trio-sscanf/triostr.c +++ /dev/null @@ -1 +0,0 @@ -../trio/triostr.c \ No newline at end of file diff --git a/src/trio-sscanf/triostr.c b/src/trio-sscanf/triostr.c new file mode 100644 index 00000000..c42822d9 --- /dev/null +++ b/src/trio-sscanf/triostr.c @@ -0,0 +1,2404 @@ +/* BEEBS trio benchmark + + Copyright (C) 2014 Embecosm Limited and University of Bristol + + This file is part of the Bristol/Embecosm Embedded Benchmark Suite. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* The original source of this file was from: + * http://daniel.haxx.se/projects/trio/ + * and is covered by the following copyright and licence: + * + * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND + * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. + * + ************************************************************************/ + +/************************************************************************* + * Include files + */ + +#if defined(HAVE_CONFIG_H) +# include +#endif +#include +#include +#include +#include +#include "triodef.h" +#include "triostr.h" +#if defined(TRIO_FUNC_TO_LONG_DOUBLE) +# define USE_MATH +#endif +#if defined(USE_MATH) +# include +#endif + +/************************************************************************* + * Definitions + */ + +#if !defined(TRIO_PUBLIC_STRING) +# define TRIO_PUBLIC_STRING TRIO_PUBLIC +#endif +#if !defined(TRIO_PRIVATE_STRING) +# define TRIO_PRIVATE_STRING TRIO_PRIVATE +#endif + +#if !defined(NULL) +# define NULL 0 +#endif +#if !defined(NIL) +# define NIL ((char)0) +#endif +#if !defined(FALSE) +# define FALSE (1 == 0) +# define TRUE (! FALSE) +#endif +#if !defined(BOOLEAN_T) +# define BOOLEAN_T int +#endif + +#if defined(USE_MATH) +# if defined(PREDEF_STANDARD_C99) +# if defined(TRIO_COMPILER_DECC) +# if (TRIO_COMPILER_DECC - 0 > 80000000) +/* + * The OSF/1 runtime that comes with the DECC compiler does not support + * hexfloats conversion. + */ +# define USE_STRTOD +# define USE_STRTOF +# endif +# else +# define USE_STRTOD +# define USE_STRTOF +# endif +# else +# if defined(TRIO_COMPILER_VISUALC) +# define USE_STRTOD +# endif +#endif +#endif + +#if defined(TRIO_PLATFORM_UNIX) +# if defined(PREDEF_STANDARD_UNIX95) +# define USE_STRCASECMP +# define USE_STRNCASECMP +# endif +# if defined(TRIO_PLATFORM_SUNOS) +# define USE_SYS_ERRLIST +# else +# define USE_STRERROR +# endif +# if defined(TRIO_PLATFORM_QNX) +# define strcasecmp(x,y) stricmp(x,y) +# define strncasecmp(x,y,n) strnicmp(x,y,n) +# endif +#endif + +#if defined(TRIO_PLATFORM_WIN32) +# define USE_STRCASECMP +# if defined(TRIO_PLATFORM_WINCE) +# define strcasecmp(x,y) _stricmp(x,y) +# else +# define strcasecmp(x,y) strcmpi(x,y) +# endif +#endif + +#if !defined(HAVE_CONFIG_H) +# if !(defined(TRIO_PLATFORM_SUNOS)) +# define HAVE_TOLOWER +# define HAVE_TOUPPER +# endif +#endif + +#if defined(USE_MATH) && !defined(TRIO_NO_POWL) +# if !defined(HAVE_POWL) +# if defined(PREDEF_STANDARD_C99) \ + || defined(PREDEF_STANDARD_UNIX03) +# define HAVE_POWL +# else +# if defined(TRIO_COMPILER_VISUALC) +# if defined(powl) +# define HAVE_POWL +# endif +# endif +# endif +# endif +#endif + +#if defined(HAVE_POWL) +# define trio_powl(x,y) powl((x),(y)) +#else +# define trio_powl(x,y) pow((double)(x),(double)(y)) +#endif + +#if defined(TRIO_FUNC_TO_UPPER) \ + || (defined(TRIO_FUNC_EQUAL) && !defined(USE_STRCASECMP)) \ + || (defined(TRIO_FUNC_EQUAL_MAX) && !defined(USE_STRNCASECMP)) \ + || defined(TRIO_FUNC_MATCH) \ + || defined(TRIO_FUNC_TO_LONG_DOUBLE) \ + || defined(TRIO_FUNC_UPPER) +# define TRIO_FUNC_INTERNAL_TO_UPPER +#endif + +/************************************************************************* + * Structures + */ + +struct _trio_string_t +{ + char *content; + size_t length; + size_t allocated; +}; + +/************************************************************************* + * Constants + */ + +#if !defined(TRIO_EMBED_STRING) +static TRIO_CONST char rcsid[] = "@(#)$Id: triostr.c,v 1.36 2010/01/26 13:02:02 breese Exp $"; +#endif + +/************************************************************************* + * Static String Functions + */ + +#if defined(TRIO_DOCUMENTATION) +# include "doc/doc_static.h" +#endif +/** @addtogroup StaticStrings + @{ +*/ + +/* + * internal_duplicate_max + */ +#if defined(TRIO_FUNC_DUPLICATE) \ + || defined(TRIO_FUNC_DUPLICATE_MAX) \ + || defined(TRIO_FUNC_STRING_DUPLICATE) \ + || defined(TRIO_FUNC_XSTRING_DUPLICATE) + +TRIO_PRIVATE_STRING char * +internal_duplicate_max +TRIO_ARGS2((source, size), + TRIO_CONST char *source, + size_t size) +{ + char *target; + + assert(source); + + /* Make room for string plus a terminating zero */ + size++; + target = trio_create(size); + if (target) + { + trio_copy_max(target, size, source); + } + return target; +} + +#endif + +/* + * internal_string_alloc + */ +#if defined(TRIO_FUNC_STRING_CREATE) \ + || defined(TRIO_FUNC_STRING_DUPLICATE) \ + || defined(TRIO_FUNC_XSTRING_DUPLICATE) + +TRIO_PRIVATE_STRING trio_string_t * +internal_string_alloc(TRIO_NOARGS) +{ + trio_string_t *self; + + self = (trio_string_t *)TRIO_MALLOC(sizeof(trio_string_t)); + if (self) + { + self->content = NULL; + self->length = 0; + self->allocated = 0; + } + return self; +} + +#endif + +/* + * internal_string_grow + * + * The size of the string will be increased by 'delta' characters. If + * 'delta' is zero, the size will be doubled. + */ +#if defined(TRIO_FUNC_STRING_CREATE) \ + || defined(TRIO_FUNC_STRING_APPEND) \ + || defined(TRIO_FUNC_XSTRING_APPEND) \ + || defined(TRIO_FUNC_XSTRING_APPEND_CHAR) + +TRIO_PRIVATE_STRING BOOLEAN_T +internal_string_grow +TRIO_ARGS2((self, delta), + trio_string_t *self, + size_t delta) +{ + BOOLEAN_T status = FALSE; + char *new_content; + size_t new_size; + + new_size = (delta == 0) + ? ( (self->allocated == 0) ? 1 : self->allocated * 2 ) + : self->allocated + delta; + + new_content = (char *)TRIO_REALLOC(self->content, new_size); + if (new_content) + { + self->content = new_content; + self->allocated = new_size; + status = TRUE; + } + return status; +} + +#endif + +/* + * internal_string_grow_to + * + * The size of the string will be increased to 'length' plus one characters. + * If 'length' is less than the original size, the original size will be + * used (that is, the size of the string is never decreased). + */ +#if defined(TRIO_FUNC_STRING_APPEND) \ + || defined(TRIO_FUNC_XSTRING_APPEND) \ + || defined(TRIO_FUNC_XSTRING_APPEND_MAX) + +TRIO_PRIVATE_STRING BOOLEAN_T +internal_string_grow_to +TRIO_ARGS2((self, length), + trio_string_t *self, + size_t length) +{ + length++; /* Room for terminating zero */ + return (self->allocated < length) + ? internal_string_grow(self, length - self->allocated) + : TRUE; +} + +#endif + +#if defined(TRIO_FUNC_INTERNAL_TO_UPPER) + +TRIO_PRIVATE_STRING TRIO_INLINE int +internal_to_upper +TRIO_ARGS1((source), + int source) +{ +# if defined(HAVE_TOUPPER) + + return toupper(source); + +# else + + /* Does not handle locales or non-contiguous alphabetic characters */ + return ((source >= (int)'a') && (source <= (int)'z')) + ? source - 'a' + 'A' + : source; + +# endif +} + +#endif + + +/** + Create new string. + + @param size Size of new string. + @return Pointer to string, or NULL if allocation failed. +*/ +#if defined(TRIO_FUNC_CREATE) + +TRIO_PUBLIC_STRING char * +trio_create +TRIO_ARGS1((size), + size_t size) +{ + return (char *)TRIO_MALLOC(size); +} + +#endif + +/** + Destroy string. + + @param string String to be freed. +*/ +#if defined(TRIO_FUNC_DESTROY) + +TRIO_PUBLIC_STRING void +trio_destroy +TRIO_ARGS1((string), + char *string) +{ + if (string) + { + TRIO_FREE(string); + } +} + +#endif + +/** + Count the number of characters in a string. + + @param string String to measure. + @return Number of characters in @p string. +*/ +#if defined(TRIO_FUNC_LENGTH) + +TRIO_PUBLIC_STRING size_t +trio_length +TRIO_ARGS1((string), + TRIO_CONST char *string) +{ + return strlen(string); +} + +#endif + +/** + Count at most @p max characters in a string. + + @param string String to measure. + @param max Maximum number of characters to count. + @return The maximum value of @p max and number of characters in @p string. +*/ +#if defined(TRIO_FUNC_LENGTH_MAX) + +TRIO_PUBLIC_STRING size_t +trio_length_max +TRIO_ARGS2((string, max), + TRIO_CONST char *string, + size_t max) +{ + size_t i; + + for (i = 0; i < max; ++i) + { + if (string[i] == 0) + break; + } + return i; +} + +#endif + +/** + Append @p source at the end of @p target. + + @param target Target string. + @param source Source string. + @return Boolean value indicating success or failure. + + @pre @p target must point to a memory chunk with sufficient room to + contain the @p target string and @p source string. + @pre No boundary checking is performed, so insufficient memory will + result in a buffer overrun. + @post @p target will be zero terminated. +*/ +#if defined(TRIO_FUNC_APPEND) + +TRIO_PUBLIC_STRING int +trio_append +TRIO_ARGS2((target, source), + char *target, + TRIO_CONST char *source) +{ + assert(target); + assert(source); + + return (strcat(target, source) != NULL); +} + +#endif + +/** + Append at most @p max characters from @p source to @p target. + + @param target Target string. + @param max Maximum number of characters to append. + @param source Source string. + @return Boolean value indicating success or failure. + + @pre @p target must point to a memory chuck with sufficient room to + contain the @p target string and the @p source string (at most @p max + characters). + @pre No boundary checking is performed, so insufficient memory will + result in a buffer overrun. + @post @p target will be zero terminated. +*/ +#if defined(TRIO_FUNC_APPEND_MAX) + +TRIO_PUBLIC_STRING int +trio_append_max +TRIO_ARGS3((target, max, source), + char *target, + size_t max, + TRIO_CONST char *source) +{ + size_t length; + + assert(target); + assert(source); + + length = trio_length(target); + + if (max > length) + { + strncat(target, source, max - length - 1); + } + return TRUE; +} + +#endif + +/** + Determine if a string contains a substring. + + @param string String to be searched. + @param substring String to be found. + @return Boolean value indicating success or failure. +*/ +#if defined(TRIO_FUNC_CONTAINS) + +TRIO_PUBLIC_STRING int +trio_contains +TRIO_ARGS2((string, substring), + TRIO_CONST char *string, + TRIO_CONST char *substring) +{ + assert(string); + assert(substring); + + return (0 != strstr(string, substring)); +} + +#endif + +/** + Copy @p source to @p target. + + @param target Target string. + @param source Source string. + @return Boolean value indicating success or failure. + + @pre @p target must point to a memory chunk with sufficient room to + contain the @p source string. + @pre No boundary checking is performed, so insufficient memory will + result in a buffer overrun. + @post @p target will be zero terminated. +*/ +#if defined(TRIO_FUNC_COPY) + +TRIO_PUBLIC_STRING int +trio_copy +TRIO_ARGS2((target, source), + char *target, + TRIO_CONST char *source) +{ + assert(target); + assert(source); + + (void)strcpy(target, source); + return TRUE; +} + +#endif + +/** + Copy at most @p max - 1 characters from @p source to @p target. + + @param target Target string. + @param max Maximum number of characters to append (one of which is + a NUL terminator). In other words @p source must point to at least + @p max - 1 bytes, but @p target must point to at least @p max + bytes. + @param source Source string. + @return Boolean value indicating success or failure. + + @pre @p target must point to a memory chunk with sufficient room to + contain the @p source string and a NUL terminator (at most @p max + bytes total). + @pre No boundary checking is performed, so insufficient memory will + result in a buffer overrun. + @post @p target will be zero terminated. +*/ +#if defined(TRIO_FUNC_COPY_MAX) + +TRIO_PUBLIC_STRING int +trio_copy_max +TRIO_ARGS3((target, max, source), + char *target, + size_t max, + TRIO_CONST char *source) +{ + assert(target); + assert(source); + assert(max > 0); /* Includes != 0 */ + + (void)strncpy(target, source, max - 1); + target[max - 1] = (char)0; + return TRUE; +} + +#endif + +/** + Duplicate @p source. + + @param source Source string. + @return A copy of the @p source string. + + @post @p target will be zero terminated. +*/ +#if defined(TRIO_FUNC_DUPLICATE) + +TRIO_PUBLIC_STRING char * +trio_duplicate +TRIO_ARGS1((source), + TRIO_CONST char *source) +{ + return internal_duplicate_max(source, trio_length(source)); +} + +#endif + +/** + Duplicate at most @p max characters of @p source. + + @param source Source string. + @param max Maximum number of characters to duplicate. + @return A copy of the @p source string. + + @post @p target will be zero terminated. +*/ +#if defined(TRIO_FUNC_DUPLICATE_MAX) + +TRIO_PUBLIC_STRING char * +trio_duplicate_max +TRIO_ARGS2((source, max), + TRIO_CONST char *source, + size_t max) +{ + size_t length; + + assert(source); + assert(max > 0); + + length = trio_length(source); + if (length > max) + { + length = max; + } + return internal_duplicate_max(source, length); +} + +#endif + +/** + Compare if two strings are equal. + + @param first First string. + @param second Second string. + @return Boolean indicating whether the two strings are equal or not. + + Case-insensitive comparison. +*/ +#if defined(TRIO_FUNC_EQUAL) + +TRIO_PUBLIC_STRING int +trio_equal +TRIO_ARGS2((first, second), + TRIO_CONST char *first, + TRIO_CONST char *second) +{ + assert(first); + assert(second); + + if ((first != NULL) && (second != NULL)) + { +# if defined(USE_STRCASECMP) + return (0 == strcasecmp(first, second)); +# else + while ((*first != NIL) && (*second != NIL)) + { + if (internal_to_upper(*first) != internal_to_upper(*second)) + { + break; + } + first++; + second++; + } + return ((*first == NIL) && (*second == NIL)); +# endif + } + return FALSE; +} + +#endif + +/** + Compare if two strings are equal. + + @param first First string. + @param second Second string. + @return Boolean indicating whether the two strings are equal or not. + + Case-sensitive comparison. +*/ +#if defined(TRIO_FUNC_EQUAL_CASE) + +TRIO_PUBLIC_STRING int +trio_equal_case +TRIO_ARGS2((first, second), + TRIO_CONST char *first, + TRIO_CONST char *second) +{ + assert(first); + assert(second); + + if ((first != NULL) && (second != NULL)) + { + return (0 == strcmp(first, second)); + } + return FALSE; +} + +#endif + +/** + Compare if two strings up until the first @p max characters are equal. + + @param first First string. + @param max Maximum number of characters to compare. + @param second Second string. + @return Boolean indicating whether the two strings are equal or not. + + Case-sensitive comparison. +*/ +#if defined(TRIO_FUNC_EQUAL_CASE_MAX) + +TRIO_PUBLIC_STRING int +trio_equal_case_max +TRIO_ARGS3((first, max, second), + TRIO_CONST char *first, + size_t max, + TRIO_CONST char *second) +{ + assert(first); + assert(second); + + if ((first != NULL) && (second != NULL)) + { + return (0 == strncmp(first, second, max)); + } + return FALSE; +} + +#endif + +/** + Compare if two strings are equal. + + @param first First string. + @param second Second string. + @return Boolean indicating whether the two strings are equal or not. + + Collating characters are considered equal. +*/ +#if defined(TRIO_FUNC_EQUAL_LOCALE) + +TRIO_PUBLIC_STRING int +trio_equal_locale +TRIO_ARGS2((first, second), + TRIO_CONST char *first, + TRIO_CONST char *second) +{ + assert(first); + assert(second); + +# if defined(LC_COLLATE) + return (strcoll(first, second) == 0); +# else + return trio_equal(first, second); +# endif +} + +#endif + +/** + Compare if two strings up until the first @p max characters are equal. + + @param first First string. + @param max Maximum number of characters to compare. + @param second Second string. + @return Boolean indicating whether the two strings are equal or not. + + Case-insensitive comparison. +*/ +#if defined(TRIO_FUNC_EQUAL_MAX) + +TRIO_PUBLIC_STRING int +trio_equal_max +TRIO_ARGS3((first, max, second), + TRIO_CONST char *first, + size_t max, + TRIO_CONST char *second) +{ + assert(first); + assert(second); + + if ((first != NULL) && (second != NULL)) + { +# if defined(USE_STRNCASECMP) + return (0 == strncasecmp(first, second, max)); +# else + /* Not adequately tested yet */ + size_t cnt = 0; + while ((*first != NIL) && (*second != NIL) && (cnt <= max)) + { + if (internal_to_upper(*first) != internal_to_upper(*second)) + { + break; + } + first++; + second++; + cnt++; + } + return ((cnt == max) || ((*first == NIL) && (*second == NIL))); +# endif + } + return FALSE; +} + +#endif + +/** + Provide a textual description of an error code (errno). + + @param error_number Error number. + @return Textual description of @p error_number. +*/ +#if defined(TRIO_FUNC_ERROR) + +TRIO_PUBLIC_STRING TRIO_CONST char * +trio_error +TRIO_ARGS1((error_number), + int error_number) +{ +# if defined(USE_STRERROR) + + return strerror(error_number); + +# else +# if defined(USE_SYS_ERRLIST) + + extern char *sys_errlist[]; + extern int sys_nerr; + + return ((error_number < 0) || (error_number >= sys_nerr)) + ? "unknown" + : sys_errlist[error_number]; + +# else + + return "unknown"; + +# endif +# endif +} + +#endif + +/** + Format the date/time according to @p format. + + @param target Target string. + @param max Maximum number of characters to format. + @param format Formatting string. + @param datetime Date/time structure. + @return Number of formatted characters. + + The formatting string accepts the same specifiers as the standard C + function strftime. +*/ +#if defined(TRIO_FUNC_FORMAT_DATE_MAX) + +TRIO_PUBLIC_STRING size_t +trio_format_date_max +TRIO_ARGS4((target, max, format, datetime), + char *target, + size_t max, + TRIO_CONST char *format, + TRIO_CONST struct tm *datetime) +{ + assert(target); + assert(format); + assert(datetime); + assert(max > 0); + + return strftime(target, max, format, datetime); +} + +#endif + +/** + Calculate a hash value for a string. + + @param string String to be calculated on. + @param type Hash function. + @return Calculated hash value. + + @p type can be one of the following + @li @c TRIO_HASH_PLAIN Plain hash function. +*/ +#if defined(TRIO_FUNC_HASH) + +TRIO_PUBLIC_STRING unsigned long +trio_hash +TRIO_ARGS2((string, type), + TRIO_CONST char *string, + int type) +{ + unsigned long value = 0L; + char ch; + + assert(string); + + switch (type) + { + case TRIO_HASH_PLAIN: + while ( (ch = *string++) != NIL ) + { + value *= 31; + value += (unsigned long)ch; + } + break; + default: + assert(FALSE); + break; + } + return value; +} + +#endif + +/** + Find first occurrence of a character in a string. + + @param string String to be searched. + @param character Character to be found. + @return A pointer to the found character, or NULL if character was not found. + */ +#if defined(TRIO_FUNC_INDEX) + +TRIO_PUBLIC_STRING char * +trio_index +TRIO_ARGS2((string, character), + TRIO_CONST char *string, + int character) +{ + assert(string); + + return strchr(string, character); +} + +#endif + +/** + Find last occurrence of a character in a string. + + @param string String to be searched. + @param character Character to be found. + @return A pointer to the found character, or NULL if character was not found. + */ +#if defined(TRIO_FUNC_INDEX_LAST) + +TRIO_PUBLIC_STRING char * +trio_index_last +TRIO_ARGS2((string, character), + TRIO_CONST char *string, + int character) +{ + assert(string); + + return strchr(string, character); +} + +#endif + +/** + Convert the alphabetic letters in the string to lower-case. + + @param target String to be converted. + @return Number of processed characters (converted or not). +*/ +#if defined(TRIO_FUNC_LOWER) + +TRIO_PUBLIC_STRING int +trio_lower +TRIO_ARGS1((target), + char *target) +{ + assert(target); + + return trio_span_function(target, target, trio_to_lower); +} + +#endif + +/** + Compare two strings using wildcards. + + @param string String to be searched. + @param pattern Pattern, including wildcards, to search for. + @return Boolean value indicating success or failure. + + Case-insensitive comparison. + + The following wildcards can be used + @li @c * Match any number of characters. + @li @c ? Match a single character. +*/ +#if defined(TRIO_FUNC_MATCH) + +TRIO_PUBLIC_STRING int +trio_match +TRIO_ARGS2((string, pattern), + TRIO_CONST char *string, + TRIO_CONST char *pattern) +{ + assert(string); + assert(pattern); + + for (; ('*' != *pattern); ++pattern, ++string) + { + if (NIL == *string) + { + return (NIL == *pattern); + } + if ((internal_to_upper((int)*string) != internal_to_upper((int)*pattern)) + && ('?' != *pattern)) + { + return FALSE; + } + } + /* two-line patch to prevent *too* much recursiveness: */ + while ('*' == pattern[1]) + pattern++; + + do + { + if ( trio_match(string, &pattern[1]) ) + { + return TRUE; + } + } + while (*string++); + + return FALSE; +} + +#endif + +/** + Compare two strings using wildcards. + + @param string String to be searched. + @param pattern Pattern, including wildcards, to search for. + @return Boolean value indicating success or failure. + + Case-sensitive comparison. + + The following wildcards can be used + @li @c * Match any number of characters. + @li @c ? Match a single character. +*/ +#if defined(TRIO_FUNC_MATCH_CASE) + +TRIO_PUBLIC_STRING int +trio_match_case +TRIO_ARGS2((string, pattern), + TRIO_CONST char *string, + TRIO_CONST char *pattern) +{ + assert(string); + assert(pattern); + + for (; ('*' != *pattern); ++pattern, ++string) + { + if (NIL == *string) + { + return (NIL == *pattern); + } + if ((*string != *pattern) + && ('?' != *pattern)) + { + return FALSE; + } + } + /* two-line patch to prevent *too* much recursiveness: */ + while ('*' == pattern[1]) + pattern++; + + do + { + if ( trio_match_case(string, &pattern[1]) ) + { + return TRUE; + } + } + while (*string++); + + return FALSE; +} + +#endif + +/** + Execute a function on each character in string. + + @param target Target string. + @param source Source string. + @param Function Function to be executed. + @return Number of processed characters. +*/ +#if defined(TRIO_FUNC_SPAN_FUNCTION) + +TRIO_PUBLIC_STRING size_t +trio_span_function +TRIO_ARGS3((target, source, Function), + char *target, + TRIO_CONST char *source, + int (*Function) TRIO_PROTO((int))) +{ + size_t count = 0; + + assert(target); + assert(source); + assert(Function); + + while (*source != NIL) + { + *target++ = Function(*source++); + count++; + } + return count; +} + +#endif + +/** + Search for a substring in a string. + + @param string String to be searched. + @param substring String to be found. + @return Pointer to first occurrence of @p substring in @p string, or NULL + if no match was found. +*/ +#if defined(TRIO_FUNC_SUBSTRING) + +TRIO_PUBLIC_STRING char * +trio_substring +TRIO_ARGS2((string, substring), + TRIO_CONST char *string, + TRIO_CONST char *substring) +{ + assert(string); + assert(substring); + + return strstr(string, substring); +} + +#endif + +/** + Search for a substring in the first @p max characters of a string. + + @param string String to be searched. + @param max Maximum characters to be searched. + @param substring String to be found. + @return Pointer to first occurrence of @p substring in @p string, or NULL + if no match was found. +*/ +#if defined(TRIO_FUNC_SUBSTRING_MAX) + +TRIO_PUBLIC_STRING char * +trio_substring_max +TRIO_ARGS3((string, max, substring), + TRIO_CONST char *string, + size_t max, + TRIO_CONST char *substring) +{ + size_t count; + size_t size; + char *result = NULL; + + assert(string); + assert(substring); + + size = trio_length(substring); + if (size <= max) + { + for (count = 0; count <= max - size; count++) + { + if (trio_equal_max(substring, size, &string[count])) + { + result = (char *)&string[count]; + break; + } + } + } + return result; +} + +#endif + +/** + Tokenize string. + + @param string String to be tokenized. + @param delimiters String containing list of delimiting characters. + @return Start of new token. + + @warning @p string will be destroyed. +*/ +#if defined(TRIO_FUNC_TOKENIZE) + +TRIO_PUBLIC_STRING char * +trio_tokenize +TRIO_ARGS2((string, delimiters), + char *string, + TRIO_CONST char *delimiters) +{ + assert(delimiters); + + return strtok(string, delimiters); +} + +#endif + +/** + Convert string to floating-point number. + + @param source String to be converted. + @param endp Pointer to end of the converted string. + @return A floating-point number. + + The following Extended Backus-Naur form is used + @verbatim + double ::= [ ] + ( | + | + ) + [ [ ] ] + number ::= 1*( ) + digit ::= ( '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' ) + exponential ::= ( 'e' | 'E' ) + sign ::= ( '-' | '+' ) + decimal_point ::= '.' + @endverbatim +*/ +#if defined(TRIO_FUNC_TO_LONG_DOUBLE) + +/* FIXME: Add EBNF for hex-floats */ +TRIO_PUBLIC_STRING trio_long_double_t +trio_to_long_double +TRIO_ARGS2((source, endp), + TRIO_CONST char *source, + char **endp) +{ +# if defined(USE_STRTOLD) + return strtold(source, endp); +# else + int isNegative = FALSE; + int isExponentNegative = FALSE; + trio_long_double_t integer = 0.0; + trio_long_double_t fraction = 0.0; + unsigned long exponent = 0; + trio_long_double_t base; + trio_long_double_t fracdiv = 1.0; + trio_long_double_t value = 0.0; + + /* First try hex-floats */ + if ((source[0] == '0') && ((source[1] == 'x') || (source[1] == 'X'))) + { + base = 16.0; + source += 2; + while (isxdigit((int)*source)) + { + integer *= base; + integer += (isdigit((int)*source) + ? (*source - '0') + : 10 + (internal_to_upper((int)*source) - 'A')); + source++; + } + if (*source == '.') + { + source++; + while (isxdigit((int)*source)) + { + fracdiv /= base; + fraction += fracdiv * (isdigit((int)*source) + ? (*source - '0') + : 10 + (internal_to_upper((int)*source) - 'A')); + source++; + } + if ((*source == 'p') || (*source == 'P')) + { + source++; + if ((*source == '+') || (*source == '-')) + { + isExponentNegative = (*source == '-'); + source++; + } + while (isdigit((int)*source)) + { + exponent *= 10; + exponent += (*source - '0'); + source++; + } + } + } + /* For later use with exponent */ + base = 2.0; + } + else /* Then try normal decimal floats */ + { + base = 10.0; + isNegative = (*source == '-'); + /* Skip sign */ + if ((*source == '+') || (*source == '-')) + source++; + + /* Integer part */ + while (isdigit((int)*source)) + { + integer *= base; + integer += (*source - '0'); + source++; + } + + if (*source == '.') + { + source++; /* skip decimal point */ + while (isdigit((int)*source)) + { + fracdiv /= base; + fraction += (*source - '0') * fracdiv; + source++; + } + } + if ((*source == 'e') + || (*source == 'E') +# if TRIO_MICROSOFT + || (*source == 'd') + || (*source == 'D') +# endif + ) + { + source++; /* Skip exponential indicator */ + isExponentNegative = (*source == '-'); + if ((*source == '+') || (*source == '-')) + source++; + while (isdigit((int)*source)) + { + exponent *= (int)base; + exponent += (*source - '0'); + source++; + } + } + } + + value = integer + fraction; + if (exponent != 0) + { + if (isExponentNegative) + value /= trio_powl(base, (trio_long_double_t)exponent); + else + value *= trio_powl(base, (trio_long_double_t)exponent); + } + if (isNegative) + value = -value; + + if (endp) + *endp = (char *)source; + return value; +# endif +} + +#endif + +/** + Convert string to floating-point number. + + @param source String to be converted. + @param endp Pointer to end of the converted string. + @return A floating-point number. + + See @ref trio_to_long_double. +*/ +#if defined(TRIO_FUNC_TO_DOUBLE) + +TRIO_PUBLIC_STRING double +trio_to_double +TRIO_ARGS2((source, endp), + TRIO_CONST char *source, + char **endp) +{ +#if defined(USE_STRTOD) + return strtod(source, endp); +#else + return (double)trio_to_long_double(source, endp); +#endif +} + +#endif + +/** + Convert string to floating-point number. + + @param source String to be converted. + @param endp Pointer to end of the converted string. + @return A floating-point number. + + See @ref trio_to_long_double. +*/ +#if defined(TRIO_FUNC_TO_FLOAT) + +TRIO_PUBLIC_STRING float +trio_to_float +TRIO_ARGS2((source, endp), + TRIO_CONST char *source, + char **endp) +{ +# if defined(USE_STRTOF) + return strtof(source, endp); +# else + return (float)trio_to_long_double(source, endp); +# endif +} + +#endif + +/** + Convert string to signed integer. + + @param string String to be converted. + @param endp Pointer to end of converted string. + @param base Radix number of number. +*/ +#if defined(TRIO_FUNC_TO_LONG) + +TRIO_PUBLIC_STRING long +trio_to_long +TRIO_ARGS3((string, endp, base), + TRIO_CONST char *string, + char **endp, + int base) +{ + assert(string); + assert((base >= 2) && (base <= 36)); + + return strtol(string, endp, base); +} + +#endif + +/** + Convert one alphabetic letter to lower-case. + + @param source The letter to be converted. + @return The converted letter. +*/ +#if defined(TRIO_FUNC_TO_LOWER) + +TRIO_PUBLIC_STRING int +trio_to_lower +TRIO_ARGS1((source), + int source) +{ +# if defined(HAVE_TOLOWER) + + return tolower(source); + +# else + + /* Does not handle locales or non-contiguous alphabetic characters */ + return ((source >= (int)'A') && (source <= (int)'Z')) + ? source - 'A' + 'a' + : source; + +# endif +} + +#endif + +/** + Convert string to unsigned integer. + + @param string String to be converted. + @param endp Pointer to end of converted string. + @param base Radix number of number. +*/ +#if defined(TRIO_FUNC_TO_UNSIGNED_LONG) + +TRIO_PUBLIC_STRING unsigned long +trio_to_unsigned_long +TRIO_ARGS3((string, endp, base), + TRIO_CONST char *string, + char **endp, + int base) +{ + assert(string); + assert((base >= 2) && (base <= 36)); + + return strtoul(string, endp, base); +} + +#endif + +/** + Convert one alphabetic letter to upper-case. + + @param source The letter to be converted. + @return The converted letter. +*/ +#if defined(TRIO_FUNC_TO_UPPER) + +TRIO_PUBLIC_STRING int +trio_to_upper +TRIO_ARGS1((source), + int source) +{ + return internal_to_upper(source); +} + +#endif + +/** + Convert the alphabetic letters in the string to upper-case. + + @param target The string to be converted. + @return The number of processed characters (converted or not). +*/ +#if defined(TRIO_FUNC_UPPER) + +TRIO_PUBLIC_STRING int +trio_upper +TRIO_ARGS1((target), + char *target) +{ + assert(target); + + return trio_span_function(target, target, internal_to_upper); +} + +#endif + +/** @} End of StaticStrings */ + + +/************************************************************************* + * Dynamic String Functions + */ + +#if defined(TRIO_DOCUMENTATION) +# include "doc/doc_dynamic.h" +#endif +/** @addtogroup DynamicStrings + @{ +*/ + +/** + Create a new dynamic string. + + @param initial_size Initial size of the buffer. + @return Newly allocated dynamic string, or NULL if memory allocation failed. +*/ +#if defined(TRIO_FUNC_STRING_CREATE) + +TRIO_PUBLIC_STRING trio_string_t * +trio_string_create +TRIO_ARGS1((initial_size), + int initial_size) +{ + trio_string_t *self; + + self = internal_string_alloc(); + if (self) + { + if (internal_string_grow(self, + (size_t)((initial_size > 0) ? initial_size : 1))) + { + self->content[0] = (char)0; + self->allocated = initial_size; + } + else + { + trio_string_destroy(self); + self = NULL; + } + } + return self; +} + +#endif + +/** + Deallocate the dynamic string and its contents. + + @param self Dynamic string +*/ +#if defined(TRIO_FUNC_STRING_DESTROY) + +TRIO_PUBLIC_STRING void +trio_string_destroy +TRIO_ARGS1((self), + trio_string_t *self) +{ + assert(self); + + if (self) + { + trio_destroy(self->content); + TRIO_FREE(self); + } +} + +#endif + +/** + Get a pointer to the content. + + @param self Dynamic string. + @param offset Offset into content. + @return Pointer to the content. + + @p Offset can be zero, positive, or negative. If @p offset is zero, + then the start of the content will be returned. If @p offset is positive, + then a pointer to @p offset number of characters from the beginning of the + content is returned. If @p offset is negative, then a pointer to @p offset + number of characters from the ending of the string, starting at the + terminating zero, is returned. +*/ +#if defined(TRIO_FUNC_STRING_GET) + +TRIO_PUBLIC_STRING char * +trio_string_get +TRIO_ARGS2((self, offset), + trio_string_t *self, + int offset) +{ + char *result = NULL; + + assert(self); + + if (self->content != NULL) + { + if (self->length == 0) + { + (void)trio_string_length(self); + } + if (offset >= 0) + { + if (offset > (int)self->length) + { + offset = self->length; + } + } + else + { + offset += self->length + 1; + if (offset < 0) + { + offset = 0; + } + } + result = &(self->content[offset]); + } + return result; +} + +#endif + +/** + Extract the content. + + @param self Dynamic String + @return Content of dynamic string. + + The content is removed from the dynamic string. This enables destruction + of the dynamic string without deallocation of the content. +*/ +#if defined(TRIO_FUNC_STRING_EXTRACT) + +TRIO_PUBLIC_STRING char * +trio_string_extract +TRIO_ARGS1((self), + trio_string_t *self) +{ + char *result; + + assert(self); + + result = self->content; + /* FIXME: Allocate new empty buffer? */ + self->content = NULL; + self->length = self->allocated = 0; + return result; +} + +#endif + +/** + Set the content of the dynamic string. + + @param self Dynamic String + @param buffer The new content. + + Sets the content of the dynamic string to a copy @p buffer. + An existing content will be deallocated first, if necessary. + + @remark + This function will make a copy of @p buffer. + You are responsible for deallocating @p buffer yourself. +*/ +#if defined(TRIO_FUNC_XSTRING_SET) + +TRIO_PUBLIC_STRING void +trio_xstring_set +TRIO_ARGS2((self, buffer), + trio_string_t *self, + char *buffer) +{ + assert(self); + + trio_destroy(self->content); + self->content = trio_duplicate(buffer); +} + +#endif + +/* + * trio_string_size + */ +#if defined(TRIO_FUNC_STRING_SIZE) + +TRIO_PUBLIC_STRING int +trio_string_size +TRIO_ARGS1((self), + trio_string_t *self) +{ + assert(self); + + return self->allocated; +} + +#endif + +/* + * trio_string_terminate + */ +#if defined(TRIO_FUNC_STRING_TERMINATE) + +TRIO_PUBLIC_STRING void +trio_string_terminate +TRIO_ARGS1((self), + trio_string_t *self) +{ + trio_xstring_append_char(self, 0); +} + +#endif + +/** + Append the second string to the first. + + @param self Dynamic string to be modified. + @param other Dynamic string to copy from. + @return Boolean value indicating success or failure. +*/ +#if defined(TRIO_FUNC_STRING_APPEND) + +TRIO_PUBLIC_STRING int +trio_string_append +TRIO_ARGS2((self, other), + trio_string_t *self, + trio_string_t *other) +{ + size_t length; + + assert(self); + assert(other); + + length = self->length + other->length; + if (!internal_string_grow_to(self, length)) + goto error; + trio_copy(&self->content[self->length], other->content); + self->length = length; + return TRUE; + + error: + return FALSE; +} + +#endif + + +/* + * trio_xstring_append + */ +#if defined(TRIO_FUNC_XSTRING_APPEND) + +TRIO_PUBLIC_STRING int +trio_xstring_append +TRIO_ARGS2((self, other), + trio_string_t *self, + TRIO_CONST char *other) +{ + size_t length; + + assert(self); + assert(other); + + length = self->length + trio_length(other); + if (!internal_string_grow_to(self, length)) + goto error; + trio_copy(&self->content[self->length], other); + self->length = length; + return TRUE; + + error: + return FALSE; +} + +#endif + +/* + * trio_xstring_append_char + */ +#if defined(TRIO_FUNC_XSTRING_APPEND_CHAR) + +TRIO_PUBLIC_STRING int +trio_xstring_append_char +TRIO_ARGS2((self, character), + trio_string_t *self, + char character) +{ + assert(self); + + if ((int)self->length >= trio_string_size(self)) + { + if (!internal_string_grow(self, 0)) + goto error; + } + self->content[self->length] = character; + self->length++; + return TRUE; + + error: + return FALSE; +} + +#endif + +/* + * trio_xstring_append_max + */ +#if defined(TRIO_FUNC_XSTRING_APPEND_MAX) + +TRIO_PUBLIC_STRING int +trio_xstring_append_max +TRIO_ARGS3((self, other, max), + trio_string_t *self, + TRIO_CONST char *other, + size_t max) +{ + size_t length; + + assert(self); + assert(other); + + length = self->length + trio_length_max(other, max); + if (!internal_string_grow_to(self, length)) + goto error; + + /* + * Pass max + 1 since trio_copy_max copies one character less than + * this from the source to make room for a terminating zero. + */ + trio_copy_max(&self->content[self->length], max + 1, other); + self->length = length; + return TRUE; + + error: + return FALSE; +} + +#endif + +/** + Search for the first occurrence of second parameter in the first. + + @param self Dynamic string to be modified. + @param other Dynamic string to copy from. + @return Boolean value indicating success or failure. +*/ +#if defined(TRIO_FUNC_STRING_CONTAINS) + +TRIO_PUBLIC_STRING int +trio_string_contains +TRIO_ARGS2((self, other), + trio_string_t *self, + trio_string_t *other) +{ + assert(self); + assert(other); + + return trio_contains(self->content, other->content); +} + +#endif + +/* + * trio_xstring_contains + */ +#if defined(TRIO_FUNC_XSTRING_CONTAINS) + +TRIO_PUBLIC_STRING int +trio_xstring_contains +TRIO_ARGS2((self, other), + trio_string_t *self, + TRIO_CONST char *other) +{ + assert(self); + assert(other); + + return trio_contains(self->content, other); +} + +#endif + +/* + * trio_string_copy + */ +#if defined(TRIO_FUNC_STRING_COPY) + +TRIO_PUBLIC_STRING int +trio_string_copy +TRIO_ARGS2((self, other), + trio_string_t *self, + trio_string_t *other) +{ + assert(self); + assert(other); + + self->length = 0; + return trio_string_append(self, other); +} + +#endif + + +/* + * trio_xstring_copy + */ +#if defined(TRIO_FUNC_XSTRING_COPY) + +TRIO_PUBLIC_STRING int +trio_xstring_copy +TRIO_ARGS2((self, other), + trio_string_t *self, + TRIO_CONST char *other) +{ + assert(self); + assert(other); + + self->length = 0; + return trio_xstring_append(self, other); +} + +#endif + +/* + * trio_string_duplicate + */ +#if defined(TRIO_FUNC_STRING_DUPLICATE) + +TRIO_PUBLIC_STRING trio_string_t * +trio_string_duplicate +TRIO_ARGS1((other), + trio_string_t *other) +{ + trio_string_t *self; + + assert(other); + + self = internal_string_alloc(); + if (self) + { + self->content = internal_duplicate_max(other->content, other->length); + if (self->content) + { + self->length = other->length; + self->allocated = self->length + 1; + } + else + { + self->length = self->allocated = 0; + } + } + return self; +} + +#endif + +/* + * trio_xstring_duplicate + */ +#if defined(TRIO_FUNC_XSTRING_DUPLICATE) + +TRIO_PUBLIC_STRING trio_string_t * +trio_xstring_duplicate +TRIO_ARGS1((other), + TRIO_CONST char *other) +{ + trio_string_t *self; + + assert(other); + + self = internal_string_alloc(); + if (self) + { + self->content = internal_duplicate_max(other, trio_length(other)); + if (self->content) + { + self->length = trio_length(self->content); + self->allocated = self->length + 1; + } + else + { + self->length = self->allocated = 0; + } + } + return self; +} + +#endif + +/* + * trio_string_equal + */ +#if defined(TRIO_FUNC_STRING_EQUAL) + +TRIO_PUBLIC_STRING int +trio_string_equal +TRIO_ARGS2((self, other), + trio_string_t *self, + trio_string_t *other) +{ + assert(self); + assert(other); + + return trio_equal(self->content, other->content); +} + +#endif + + +/* + * trio_xstring_equal + */ +#if defined(TRIO_FUNC_XSTRING_EQUAL) + +TRIO_PUBLIC_STRING int +trio_xstring_equal +TRIO_ARGS2((self, other), + trio_string_t *self, + TRIO_CONST char *other) +{ + assert(self); + assert(other); + + return trio_equal(self->content, other); +} + +#endif + +/* + * trio_string_equal_max + */ +#if defined(TRIO_FUNC_STRING_EQUAL_MAX) + +TRIO_PUBLIC_STRING int +trio_string_equal_max +TRIO_ARGS3((self, max, other), + trio_string_t *self, + size_t max, + trio_string_t *other) +{ + assert(self); + assert(other); + + return trio_equal_max(self->content, max, other->content); +} +#endif + +/* + * trio_xstring_equal_max + */ +#if defined(TRIO_FUNC_XSTRING_EQUAL_MAX) + +TRIO_PUBLIC_STRING int +trio_xstring_equal_max +TRIO_ARGS3((self, max, other), + trio_string_t *self, + size_t max, + TRIO_CONST char *other) +{ + assert(self); + assert(other); + + return trio_equal_max(self->content, max, other); +} + +#endif + +/* + * trio_string_equal_case + */ +#if defined(TRIO_FUNC_STRING_EQUAL_CASE) + +TRIO_PUBLIC_STRING int +trio_string_equal_case +TRIO_ARGS2((self, other), + trio_string_t *self, + trio_string_t *other) +{ + assert(self); + assert(other); + + return trio_equal_case(self->content, other->content); +} + +#endif + +/* + * trio_xstring_equal_case + */ +#if defined(TRIO_FUNC_XSTRING_EQUAL_CASE) + +TRIO_PUBLIC_STRING int +trio_xstring_equal_case +TRIO_ARGS2((self, other), + trio_string_t *self, + TRIO_CONST char *other) +{ + assert(self); + assert(other); + + return trio_equal_case(self->content, other); +} + +#endif + +/* + * trio_string_equal_case_max + */ +#if defined(TRIO_FUNC_STRING_EQUAL_CASE_MAX) + +TRIO_PUBLIC_STRING int +trio_string_equal_case_max +TRIO_ARGS3((self, max, other), + trio_string_t *self, + size_t max, + trio_string_t *other) +{ + assert(self); + assert(other); + + return trio_equal_case_max(self->content, max, other->content); +} + +#endif + +/* + * trio_xstring_equal_case_max + */ +#if defined(TRIO_FUNC_XSTRING_EQUAL_CASE_MAX) + +TRIO_PUBLIC_STRING int +trio_xstring_equal_case_max +TRIO_ARGS3((self, max, other), + trio_string_t *self, + size_t max, + TRIO_CONST char *other) +{ + assert(self); + assert(other); + + return trio_equal_case_max(self->content, max, other); +} + +#endif + +/* + * trio_string_format_data_max + */ +#if defined(TRIO_FUNC_STRING_FORMAT_DATE_MAX) + +TRIO_PUBLIC_STRING size_t +trio_string_format_date_max +TRIO_ARGS4((self, max, format, datetime), + trio_string_t *self, + size_t max, + TRIO_CONST char *format, + TRIO_CONST struct tm *datetime) +{ + assert(self); + + return trio_format_date_max(self->content, max, format, datetime); +} + +#endif + +/* + * trio_string_index + */ +#if defined(TRIO_FUNC_STRING_INDEX) + +TRIO_PUBLIC_STRING char * +trio_string_index +TRIO_ARGS2((self, character), + trio_string_t *self, + int character) +{ + assert(self); + + return trio_index(self->content, character); +} + +#endif + +/* + * trio_string_index_last + */ +#if defined(TRIO_FUNC_STRING_INDEX_LAST) + +TRIO_PUBLIC_STRING char * +trio_string_index_last +TRIO_ARGS2((self, character), + trio_string_t *self, + int character) +{ + assert(self); + + return trio_index_last(self->content, character); +} + +#endif + +/* + * trio_string_length + */ +#if defined(TRIO_FUNC_STRING_LENGTH) + +TRIO_PUBLIC_STRING int +trio_string_length +TRIO_ARGS1((self), + trio_string_t *self) +{ + assert(self); + + if (self->length == 0) + { + self->length = trio_length(self->content); + } + return self->length; +} + +#endif + +/* + * trio_string_lower + */ +#if defined(TRIO_FUNC_STRING_LOWER) + +TRIO_PUBLIC_STRING int +trio_string_lower +TRIO_ARGS1((self), + trio_string_t *self) +{ + assert(self); + + return trio_lower(self->content); +} + +#endif + +/* + * trio_string_match + */ +#if defined(TRIO_FUNC_STRING_MATCH) + +TRIO_PUBLIC_STRING int +trio_string_match +TRIO_ARGS2((self, other), + trio_string_t *self, + trio_string_t *other) +{ + assert(self); + assert(other); + + return trio_match(self->content, other->content); +} + +#endif + +/* + * trio_xstring_match + */ +#if defined(TRIO_FUNC_XSTRING_MATCH) + +TRIO_PUBLIC_STRING int +trio_xstring_match +TRIO_ARGS2((self, other), + trio_string_t *self, + TRIO_CONST char *other) +{ + assert(self); + assert(other); + + return trio_match(self->content, other); +} + +#endif + +/* + * trio_string_match_case + */ +#if defined(TRIO_FUNC_STRING_MATCH_CASE) + +TRIO_PUBLIC_STRING int +trio_string_match_case +TRIO_ARGS2((self, other), + trio_string_t *self, + trio_string_t *other) +{ + assert(self); + assert(other); + + return trio_match_case(self->content, other->content); +} + +#endif + +/* + * trio_xstring_match_case + */ +#if defined(TRIO_FUNC_XSTRING_MATCH_CASE) + +TRIO_PUBLIC_STRING int +trio_xstring_match_case +TRIO_ARGS2((self, other), + trio_string_t *self, + TRIO_CONST char *other) +{ + assert(self); + assert(other); + + return trio_match_case(self->content, other); +} + +#endif + +/* + * trio_string_substring + */ +#if defined(TRIO_FUNC_STRING_SUBSTRING) + +TRIO_PUBLIC_STRING char * +trio_string_substring +TRIO_ARGS2((self, other), + trio_string_t *self, + trio_string_t *other) +{ + assert(self); + assert(other); + + return trio_substring(self->content, other->content); +} + +#endif + +/* + * trio_xstring_substring + */ +#if defined(TRIO_FUNC_XSTRING_SUBSTRING) + +TRIO_PUBLIC_STRING char * +trio_xstring_substring +TRIO_ARGS2((self, other), + trio_string_t *self, + TRIO_CONST char *other) +{ + assert(self); + assert(other); + + return trio_substring(self->content, other); +} + +#endif + +/* + * trio_string_upper + */ +#if defined(TRIO_FUNC_STRING_UPPER) + +TRIO_PUBLIC_STRING int +trio_string_upper +TRIO_ARGS1((self), + trio_string_t *self) +{ + assert(self); + + return trio_upper(self->content); +} + +#endif + +/** @} End of DynamicStrings */ diff --git a/src/trio-sscanf/triostr.h b/src/trio-sscanf/triostr.h deleted file mode 120000 index ba4efead..00000000 --- a/src/trio-sscanf/triostr.h +++ /dev/null @@ -1 +0,0 @@ -../trio/triostr.h \ No newline at end of file diff --git a/src/trio-sscanf/triostr.h b/src/trio-sscanf/triostr.h new file mode 100644 index 00000000..27fb7f93 --- /dev/null +++ b/src/trio-sscanf/triostr.h @@ -0,0 +1,699 @@ +/* BEEBS trio benchmark + + Copyright (C) 2014 Embecosm Limited and University of Bristol + + This file is part of the Bristol/Embecosm Embedded Benchmark Suite. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* The original source of this file was from: + * http://daniel.haxx.se/projects/trio/ + * and is covered by the following copyright and licence: + * + * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND + * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. + * + ************************************************************************/ + +#ifndef TRIO_TRIOSTR_H +#define TRIO_TRIOSTR_H + +/* + * Documentation is located in triostr.c + */ + +#include +#include +#include +#include "triodef.h" +#include "triop.h" + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + TRIO_HASH_NONE = 0, + TRIO_HASH_PLAIN, + TRIO_HASH_TWOSIGNED +}; + +#if !defined(TRIO_PUBLIC_STRING) +# if !defined(TRIO_PUBLIC) +# define TRIO_PUBLIC +# endif +# define TRIO_PUBLIC_STRING TRIO_PUBLIC +#endif + +/************************************************************************* + * Dependencies + */ + +#if defined(TRIO_EMBED_STRING) + +/* + * The application that triostr is embedded in must define which functions + * it uses. + * + * The following resolves internal dependencies. + */ + +# if defined(TRIO_FUNC_XSTRING_SET) +# if !defined(TRIO_FUNC_DUPLICATE) +# define TRIO_FUNC_DUPLICATE +# endif +# endif + +# if defined(TRIO_FUNC_DUPLICATE) \ + || defined(TRIO_FUNC_DUPLICATE_MAX) \ + || defined(TRIO_FUNC_STRING_DUPLICATE) \ + || defined(TRIO_FUNC_XSTRING_DUPLICATE) +# if !defined(TRIO_FUNC_CREATE) +# define TRIO_FUNC_CREATE +# endif +# if !defined(TRIO_FUNC_COPY_MAX) +# define TRIO_FUNC_COPY_MAX +# endif +# endif + +# if defined(TRIO_FUNC_STRING_CREATE) +# if !defined(TRIO_FUNC_STRING_DESTROY) +# define TRIO_FUNC_STRING_DESTROY +# endif +# endif + +# if defined(TRIO_FUNC_STRING_DESTROY) \ + || defined(TRIO_FUNC_XSTRING_SET) +# if !defined(TRIO_FUNC_DESTROY) +# define TRIO_FUNC_DESTROY +# endif +# endif + +# if defined(TRIO_FUNC_EQUAL_LOCALE) \ + || defined(TRIO_FUNC_STRING_EQUAL) \ + || defined(TRIO_FUNC_XSTRING_EQUAL) +# if !defined(TRIO_FUNC_EQUAL) +# define TRIO_FUNC_EQUAL +# endif +# endif + +# if defined(TRIO_FUNC_EQUAL_CASE) \ + || defined(TRIO_FUNC_STRING_EQUAL_CASE) \ + || defined(TRIO_FUNC_XSTRING_EQUAL_CASE) +# if !defined(TRIO_FUNC_EQUAL_CASE) +# define TRIO_FUNC_EQUAL_CASE +# endif +# endif + +# if defined(TRIO_FUNC_SUBSTRING_MAX) \ + || defined(TRIO_FUNC_STRING_EQUAL_MAX) \ + || defined(TRIO_FUNC_XSTRING_EQUAL_MAX) +# if !defined(TRIO_FUNC_EQUAL_MAX) +# define TRIO_FUNC_EQUAL_MAX +# endif +# endif + +# if defined(TRIO_FUNC_TO_DOUBLE) \ + || defined(TRIO_FUNC_TO_FLOAT) +# if !defined(TRIO_FUNC_TO_LONG_DOUBLE) +# define TRIO_FUNC_TO_LONG_DOUBLE +# endif +# endif + +# if defined(TRIO_FUNC_STRING_TERMINATE) +# if !defined(TRIO_FUNC_XSTRING_APPEND_CHAR) +# define TRIO_FUNC_XSTRING_APPEND_CHAR +# endif +# endif + +# if defined(TRIO_FUNC_XSTRING_APPEND_CHAR) +# if !defined(TRIO_FUNC_STRING_SIZE) +# define TRIO_FUNC_STRING_SIZE +# endif +# endif + +#else + +/* + * When triostr is not embedded all functions are defined. + */ + +# define TRIO_FUNC_APPEND +# define TRIO_FUNC_APPEND_MAX +# define TRIO_FUNC_CONTAINS +# define TRIO_FUNC_COPY +# define TRIO_FUNC_COPY_MAX +# define TRIO_FUNC_CREATE +# define TRIO_FUNC_DESTROY +# define TRIO_FUNC_DUPLICATE +# define TRIO_FUNC_DUPLICATE_MAX +# define TRIO_FUNC_EQUAL +# define TRIO_FUNC_EQUAL_CASE +# define TRIO_FUNC_EQUAL_CASE_MAX +# define TRIO_FUNC_EQUAL_LOCALE +# define TRIO_FUNC_EQUAL_MAX +# define TRIO_FUNC_ERROR +# if !defined(TRIO_PLATFORM_WINCE) +# define TRIO_FUNC_FORMAT_DATE_MAX +# endif +# define TRIO_FUNC_HASH +# define TRIO_FUNC_INDEX +# define TRIO_FUNC_INDEX_LAST +# define TRIO_FUNC_LENGTH +# define TRIO_FUNC_LENGTH_MAX +# define TRIO_FUNC_LOWER +# define TRIO_FUNC_MATCH +# define TRIO_FUNC_MATCH_CASE +# define TRIO_FUNC_SPAN_FUNCTION +# define TRIO_FUNC_SUBSTRING +# define TRIO_FUNC_SUBSTRING_MAX +# define TRIO_FUNC_TO_DOUBLE +# define TRIO_FUNC_TO_FLOAT +# define TRIO_FUNC_TO_LONG +# define TRIO_FUNC_TO_LONG_DOUBLE +# define TRIO_FUNC_TO_LOWER +# define TRIO_FUNC_TO_UNSIGNED_LONG +# define TRIO_FUNC_TO_UPPER +# define TRIO_FUNC_TOKENIZE +# define TRIO_FUNC_UPPER + +# define TRIO_FUNC_STRING_APPEND +# define TRIO_FUNC_STRING_CONTAINS +# define TRIO_FUNC_STRING_COPY +# define TRIO_FUNC_STRING_CREATE +# define TRIO_FUNC_STRING_DESTROY +# define TRIO_FUNC_STRING_DUPLICATE +# define TRIO_FUNC_STRING_EQUAL +# define TRIO_FUNC_STRING_EQUAL_CASE +# define TRIO_FUNC_STRING_EQUAL_CASE_MAX +# define TRIO_FUNC_STRING_EQUAL_MAX +# define TRIO_FUNC_STRING_EXTRACT +# if !defined(TRIO_PLATFORM_WINCE) +# define TRIO_FUNC_STRING_FORMAT_DATE_MAX +# endif +# define TRIO_FUNC_STRING_GET +# define TRIO_FUNC_STRING_INDEX +# define TRIO_FUNC_STRING_INDEX_LAST +# define TRIO_FUNC_STRING_LENGTH +# define TRIO_FUNC_STRING_LOWER +# define TRIO_FUNC_STRING_MATCH +# define TRIO_FUNC_STRING_MATCH_CASE +# define TRIO_FUNC_STRING_SIZE +# define TRIO_FUNC_STRING_SUBSTRING +# define TRIO_FUNC_STRING_TERMINATE +# define TRIO_FUNC_STRING_UPPER + +# define TRIO_FUNC_XSTRING_APPEND +# define TRIO_FUNC_XSTRING_APPEND_CHAR +# define TRIO_FUNC_XSTRING_APPEND_MAX +# define TRIO_FUNC_XSTRING_CONTAINS +# define TRIO_FUNC_XSTRING_COPY +# define TRIO_FUNC_XSTRING_DUPLICATE +# define TRIO_FUNC_XSTRING_EQUAL +# define TRIO_FUNC_XSTRING_EQUAL_CASE +# define TRIO_FUNC_XSTRING_EQUAL_CASE_MAX +# define TRIO_FUNC_XSTRING_EQUAL_MAX +# define TRIO_FUNC_XSTRING_MATCH +# define TRIO_FUNC_XSTRING_MATCH_CASE +# define TRIO_FUNC_XSTRING_SET +# define TRIO_FUNC_XSTRING_SUBSTRING + +#endif + + +/************************************************************************* + * String functions + */ + +#if defined(TRIO_FUNC_APPEND) +TRIO_PUBLIC_STRING int +trio_append +TRIO_PROTO((char *target, TRIO_CONST char *source)); +#endif + +#if defined(TRIO_FUNC_APPEND_MAX) +TRIO_PUBLIC_STRING int +trio_append_max +TRIO_PROTO((char *target, size_t max, TRIO_CONST char *source)); +#endif + +#if defined(TRIO_FUNC_CONTAINS) +TRIO_PUBLIC_STRING int +trio_contains +TRIO_PROTO((TRIO_CONST char *string, TRIO_CONST char *substring)); +#endif + +#if defined(TRIO_FUNC_COPY) +TRIO_PUBLIC_STRING int +trio_copy +TRIO_PROTO((char *target, TRIO_CONST char *source)); +#endif + +#if defined(TRIO_FUNC_COPY_MAX) +TRIO_PUBLIC_STRING int +trio_copy_max +TRIO_PROTO((char *target, size_t max, TRIO_CONST char *source)); +#endif + +#if defined(TRIO_FUNC_CREATE) +TRIO_PUBLIC_STRING char * +trio_create +TRIO_PROTO((size_t size)); +#endif + +#if defined(TRIO_FUNC_DESTROY) +TRIO_PUBLIC_STRING void +trio_destroy +TRIO_PROTO((char *string)); +#endif + +#if defined(TRIO_FUNC_DUPLICATE) +TRIO_PUBLIC_STRING char * +trio_duplicate +TRIO_PROTO((TRIO_CONST char *source)); +#endif + +#if defined(TRIO_FUNC_DUPLICATE_MAX) +TRIO_PUBLIC_STRING char * +trio_duplicate_max +TRIO_PROTO((TRIO_CONST char *source, size_t max)); +#endif + +#if defined(TRIO_FUNC_EQUAL) +TRIO_PUBLIC_STRING int +trio_equal +TRIO_PROTO((TRIO_CONST char *first, TRIO_CONST char *second)); +#endif + +#if defined(TRIO_FUNC_EQUAL_CASE) +TRIO_PUBLIC_STRING int +trio_equal_case +TRIO_PROTO((TRIO_CONST char *first, TRIO_CONST char *second)); +#endif + +#if defined(TRIO_FUNC_EQUAL_CASE_MAX) +TRIO_PUBLIC_STRING int +trio_equal_case_max +TRIO_PROTO((TRIO_CONST char *first, size_t max, TRIO_CONST char *second)); +#endif + +#if defined(TRIO_FUNC_EQUAL_LOCALE) +TRIO_PUBLIC_STRING int +trio_equal_locale +TRIO_PROTO((TRIO_CONST char *first, TRIO_CONST char *second)); +#endif + +#if defined(TRIO_FUNC_EQUAL_MAX) +TRIO_PUBLIC_STRING int +trio_equal_max +TRIO_PROTO((TRIO_CONST char *first, size_t max, TRIO_CONST char *second)); +#endif + +#if defined(TRIO_FUNC_ERROR) +TRIO_PUBLIC_STRING TRIO_CONST char * +trio_error +TRIO_PROTO((int)); +#endif + +#if defined(TRIO_FUNC_FORMAT_DATE_MAX) +TRIO_PUBLIC_STRING size_t +trio_format_date_max +TRIO_PROTO((char *target, size_t max, TRIO_CONST char *format, TRIO_CONST struct tm *datetime)); +#endif + +#if defined(TRIO_FUNC_HASH) +TRIO_PUBLIC_STRING unsigned long +trio_hash +TRIO_PROTO((TRIO_CONST char *string, int type)); +#endif + +#if defined(TRIO_FUNC_INDEX) +TRIO_PUBLIC_STRING char * +trio_index +TRIO_PROTO((TRIO_CONST char *string, int character)); +#endif + +#if defined(TRIO_FUNC_INDEX_LAST) +TRIO_PUBLIC_STRING char * +trio_index_last +TRIO_PROTO((TRIO_CONST char *string, int character)); +#endif + +#if defined(TRIO_FUNC_LENGTH) +TRIO_PUBLIC_STRING size_t +trio_length +TRIO_PROTO((TRIO_CONST char *string)); +#endif + +#if defined(TRIO_FUNC_LENGTH_MAX) +TRIO_PUBLIC_STRING size_t +trio_length_max +TRIO_PROTO((TRIO_CONST char *string, size_t max)); +#endif + +#if defined(TRIO_FUNC_LOWER) +TRIO_PUBLIC_STRING int +trio_lower +TRIO_PROTO((char *target)); +#endif + +#if defined(TRIO_FUNC_MATCH) +TRIO_PUBLIC_STRING int +trio_match +TRIO_PROTO((TRIO_CONST char *string, TRIO_CONST char *pattern)); +#endif + +#if defined(TRIO_FUNC_MATCH_CASE) +TRIO_PUBLIC_STRING int +trio_match_case +TRIO_PROTO((TRIO_CONST char *string, TRIO_CONST char *pattern)); +#endif + +#if defined(TRIO_FUNC_SPAN_FUNCTION) +TRIO_PUBLIC_STRING size_t +trio_span_function +TRIO_PROTO((char *target, TRIO_CONST char *source, int (*Function) TRIO_PROTO((int)))); +#endif + +#if defined(TRIO_FUNC_SUBSTRING) +TRIO_PUBLIC_STRING char * +trio_substring +TRIO_PROTO((TRIO_CONST char *string, TRIO_CONST char *substring)); +#endif + +#if defined(TRIO_FUNC_SUBSTRING_MAX) +TRIO_PUBLIC_STRING char * +trio_substring_max +TRIO_PROTO((TRIO_CONST char *string, size_t max, TRIO_CONST char *substring)); +#endif + +#if defined(TRIO_FUNC_TO_DOUBLE) +TRIO_PUBLIC_STRING double +trio_to_double +TRIO_PROTO((TRIO_CONST char *source, char **endp)); +#endif + +#if defined(TRIO_FUNC_TO_FLOAT) +TRIO_PUBLIC_STRING float +trio_to_float +TRIO_PROTO((TRIO_CONST char *source, char **endp)); +#endif + +#if defined(TRIO_FUNC_TO_LONG) +TRIO_PUBLIC_STRING long +trio_to_long +TRIO_PROTO((TRIO_CONST char *source, char **endp, int base)); +#endif + +#if defined(TRIO_FUNC_TO_LOWER) +TRIO_PUBLIC_STRING int +trio_to_lower +TRIO_PROTO((int source)); +#endif + +#if defined(TRIO_FUNC_TO_LONG_DOUBLE) +TRIO_PUBLIC_STRING trio_long_double_t +trio_to_long_double +TRIO_PROTO((TRIO_CONST char *source, char **endp)); +#endif + +#if defined(TRIO_FUNC_TO_UNSIGNED_LONG) +TRIO_PUBLIC_STRING unsigned long +trio_to_unsigned_long +TRIO_PROTO((TRIO_CONST char *source, char **endp, int base)); +#endif + +#if defined(TRIO_FUNC_TO_UPPER) +TRIO_PUBLIC_STRING int +trio_to_upper +TRIO_PROTO((int source)); +#endif + +#if defined(TRIO_FUNC_TOKENIZE) +TRIO_PUBLIC_STRING char * +trio_tokenize +TRIO_PROTO((char *string, TRIO_CONST char *delimiters)); +#endif + +#if defined(TRIO_FUNC_UPPER) +TRIO_PUBLIC_STRING int +trio_upper +TRIO_PROTO((char *target)); +#endif + +/************************************************************************* + * Dynamic string functions + */ + +/* + * Opaque type for dynamic strings + */ + +typedef struct _trio_string_t trio_string_t; + +#if defined(TRIO_FUNC_STRING_APPEND) +TRIO_PUBLIC_STRING int +trio_string_append +TRIO_PROTO((trio_string_t *self, trio_string_t *other)); +#endif + +#if defined(TRIO_FUNC_STRING_CONTAINS) +TRIO_PUBLIC_STRING int +trio_string_contains +TRIO_PROTO((trio_string_t *self, trio_string_t *other)); +#endif + +#if defined(TRIO_FUNC_STRING_COPY) +TRIO_PUBLIC_STRING int +trio_string_copy +TRIO_PROTO((trio_string_t *self, trio_string_t *other)); +#endif + +#if defined(TRIO_FUNC_STRING_CREATE) +TRIO_PUBLIC_STRING trio_string_t * +trio_string_create +TRIO_PROTO((int initial_size)); +#endif + +#if defined(TRIO_FUNC_STRING_DESTROY) +TRIO_PUBLIC_STRING void +trio_string_destroy +TRIO_PROTO((trio_string_t *self)); +#endif + +#if defined(TRIO_FUNC_STRING_DUPLICATE) +TRIO_PUBLIC_STRING trio_string_t * +trio_string_duplicate +TRIO_PROTO((trio_string_t *other)); +#endif + +#if defined(TRIO_FUNC_STRING_EQUAL) +TRIO_PUBLIC_STRING int +trio_string_equal +TRIO_PROTO((trio_string_t *self, trio_string_t *other)); +#endif + +#if defined(TRIO_FUNC_STRING_EQUAL_MAX) +TRIO_PUBLIC_STRING int +trio_string_equal_max +TRIO_PROTO((trio_string_t *self, size_t max, trio_string_t *second)); +#endif + +#if defined(TRIO_FUNC_STRING_EQUAL_CASE) +TRIO_PUBLIC_STRING int +trio_string_equal_case +TRIO_PROTO((trio_string_t *self, trio_string_t *other)); +#endif + +#if defined(TRIO_FUNC_STRING_EQUAL_CASE_MAX) +TRIO_PUBLIC_STRING int +trio_string_equal_case_max +TRIO_PROTO((trio_string_t *self, size_t max, trio_string_t *other)); +#endif + +#if defined(TRIO_FUNC_STRING_EXTRACT) +TRIO_PUBLIC_STRING char * +trio_string_extract +TRIO_PROTO((trio_string_t *self)); +#endif + +#if defined(TRIO_FUNC_STRING_FORMAT_DATE_MAX) +TRIO_PUBLIC_STRING size_t +trio_string_format_date_max +TRIO_PROTO((trio_string_t *self, size_t max, TRIO_CONST char *format, TRIO_CONST struct tm *datetime)); +#endif + +#if defined(TRIO_FUNC_STRING_GET) +TRIO_PUBLIC_STRING char * +trio_string_get +TRIO_PROTO((trio_string_t *self, int offset)); +#endif + +#if defined(TRIO_FUNC_STRING_INDEX) +TRIO_PUBLIC_STRING char * +trio_string_index +TRIO_PROTO((trio_string_t *self, int character)); +#endif + +#if defined(TRIO_FUNC_STRING_INDEX_LAST) +TRIO_PUBLIC_STRING char * +trio_string_index_last +TRIO_PROTO((trio_string_t *self, int character)); +#endif + +#if defined(TRIO_FUNC_STRING_LENGTH) +TRIO_PUBLIC_STRING int +trio_string_length +TRIO_PROTO((trio_string_t *self)); +#endif + +#if defined(TRIO_FUNC_STRING_LOWER) +TRIO_PUBLIC_STRING int +trio_string_lower +TRIO_PROTO((trio_string_t *self)); +#endif + +#if defined(TRIO_FUNC_STRING_MATCH) +TRIO_PUBLIC_STRING int +trio_string_match +TRIO_PROTO((trio_string_t *self, trio_string_t *other)); +#endif + +#if defined(TRIO_FUNC_STRING_MATCH_CASE) +TRIO_PUBLIC_STRING int +trio_string_match_case +TRIO_PROTO((trio_string_t *self, trio_string_t *other)); +#endif + +#if defined(TRIO_FUNC_STRING_SIZE) +TRIO_PUBLIC_STRING int +trio_string_size +TRIO_PROTO((trio_string_t *self)); +#endif + +#if defined(TRIO_FUNC_STRING_SUBSTRING) +TRIO_PUBLIC_STRING char * +trio_string_substring +TRIO_PROTO((trio_string_t *self, trio_string_t *other)); +#endif + +#if defined(TRIO_FUNC_STRING_TERMINATE) +TRIO_PUBLIC_STRING void +trio_string_terminate +TRIO_PROTO((trio_string_t *self)); +#endif + +#if defined(TRIO_FUNC_STRING_UPPER) +TRIO_PUBLIC_STRING int +trio_string_upper +TRIO_PROTO((trio_string_t *self)); +#endif + +#if defined(TRIO_FUNC_XSTRING_APPEND) +TRIO_PUBLIC_STRING int +trio_xstring_append +TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other)); +#endif + +#if defined(TRIO_FUNC_XSTRING_APPEND_CHAR) +TRIO_PUBLIC_STRING int +trio_xstring_append_char +TRIO_PROTO((trio_string_t *self, char character)); +#endif + +#if defined(TRIO_FUNC_XSTRING_APPEND_MAX) +TRIO_PUBLIC_STRING int +trio_xstring_append_max +TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other, size_t max)); +#endif + +#if defined(TRIO_FUNC_XSTRING_CONTAINS) +TRIO_PUBLIC_STRING int +trio_xstring_contains +TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other)); +#endif + +#if defined(TRIO_FUNC_XSTRING_COPY) +TRIO_PUBLIC_STRING int +trio_xstring_copy +TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other)); +#endif + +#if defined(TRIO_FUNC_XSTRING_DUPLICATE) +TRIO_PUBLIC_STRING trio_string_t * +trio_xstring_duplicate +TRIO_PROTO((TRIO_CONST char *other)); +#endif + +#if defined(TRIO_FUNC_XSTRING_EQUAL) +TRIO_PUBLIC_STRING int +trio_xstring_equal +TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other)); +#endif + +#if defined(TRIO_FUNC_XSTRING_EQUAL_MAX) +TRIO_PUBLIC_STRING int +trio_xstring_equal_max +TRIO_PROTO((trio_string_t *self, size_t max, TRIO_CONST char *other)); +#endif + +#if defined(TRIO_FUNC_XSTRING_EQUAL_CASE) +TRIO_PUBLIC_STRING int +trio_xstring_equal_case +TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other)); +#endif + +#if defined(TRIO_FUNC_XSTRING_EQUAL_CASE_MAX) +TRIO_PUBLIC_STRING int +trio_xstring_equal_case_max +TRIO_PROTO((trio_string_t *self, size_t max, TRIO_CONST char *other)); +#endif + +#if defined(TRIO_FUNC_XSTRING_MATCH) +TRIO_PUBLIC_STRING int +trio_xstring_match +TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other)); +#endif + +#if defined(TRIO_FUNC_XSTRING_MATCH_CASE) +TRIO_PUBLIC_STRING int +trio_xstring_match_case +TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other)); +#endif + +#if defined(TRIO_FUNC_XSTRING_SET) +TRIO_PUBLIC_STRING void +trio_xstring_set +TRIO_PROTO((trio_string_t *self, char *buffer)); +#endif + +#if defined(TRIO_FUNC_XSTRING_SUBSTRING) +TRIO_PUBLIC_STRING char * +trio_xstring_substring +TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other)); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* TRIO_TRIOSTR_H */ diff --git a/src/trio/.gitignore b/src/trio/.gitignore deleted file mode 100644 index ae0d704f..00000000 --- a/src/trio/.gitignore +++ /dev/null @@ -1 +0,0 @@ -trio diff --git a/src/trio/Makefile.am b/src/trio/Makefile.am deleted file mode 100644 index a23afa46..00000000 --- a/src/trio/Makefile.am +++ /dev/null @@ -1,26 +0,0 @@ -# Makefile.am for distributing trio -# -# Copyright (C) 2013 Embecosm Limited and University of Bristol -# -# This file is part of the Bristol/Embecosm Embedded Benchmark Suite. -# -# Contributor: James Pallister -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# SPDX-License-Identifier: GPL-3.0-or-later - -# Not a benchmark per se, but the base software for other benchmarks. - -EXTRA_DIST = trio.c triodef.h trio.h triop.h triostr.c triostr.h trio_test.c diff --git a/src/trio/Makefile.in b/src/trio/Makefile.in deleted file mode 100644 index 7aa12281..00000000 --- a/src/trio/Makefile.in +++ /dev/null @@ -1,480 +0,0 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2014 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -# Makefile.am for distributing trio -# -# Copyright (C) 2013 Embecosm Limited and University of Bristol -# -# This file is part of the Bristol/Embecosm Embedded Benchmark Suite. -# -# Contributor: James Pallister -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# SPDX-License-Identifier: GPL-3.0-or-later - -# Not a benchmark per se, but the base software for other benchmarks. -VPATH = @srcdir@ -am__is_gnu_make = { \ - if test -z '$(MAKELEVEL)'; then \ - false; \ - elif test -n '$(MAKE_HOST)'; then \ - true; \ - elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ - true; \ - else \ - false; \ - fi; \ -} -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -target_triplet = @target@ -subdir = src/trio -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ - $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ - $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ - $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -SOURCES = -DIST_SOURCES = -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -am__DIST_COMMON = $(srcdir)/Makefile.in -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AR = @AR@ -ARCH = @ARCH@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -BENCHMARKS = @BENCHMARKS@ -BOARD = @BOARD@ -CC = @CC@ -CCAS = @CCAS@ -CCASDEPMODE = @CCASDEPMODE@ -CCASFLAGS = @CCASFLAGS@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CHIP = @CHIP@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEJAGNU = @DEJAGNU@ -DEPDIR = @DEPDIR@ -DLLTOOL = @DLLTOOL@ -DSYMUTIL = @DSYMUTIL@ -DUMMY_COMPILERRT = @DUMMY_COMPILERRT@ -DUMMY_CRT0 = @DUMMY_CRT0@ -DUMMY_LIBC = @DUMMY_LIBC@ -DUMMY_LIBGCC = @DUMMY_LIBGCC@ -DUMMY_LIBM = @DUMMY_LIBM@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LIBTOOL_DEPS = @LIBTOOL_DEPS@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MKDIR_P = @MKDIR_P@ -NM = @NM@ -NMEDIT = @NMEDIT@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -RANLIB = @RANLIB@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -VERSION = @VERSION@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target = @target@ -target_alias = @target_alias@ -target_cpu = @target_cpu@ -target_os = @target_os@ -target_vendor = @target_vendor@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -EXTRA_DIST = trio.c triodef.h trio.h triop.h triostr.c triostr.h trio_test.c -all: all-am - -.SUFFIXES: -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/trio/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu src/trio/Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs -tags TAGS: - -ctags CTAGS: - -cscope cscopelist: - - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile -installdirs: -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic clean-libtool mostlyclean-am - -distclean: distclean-am - -rm -f Makefile -distclean-am: clean-am distclean-generic - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-generic mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: - -.MAKE: install-am install-strip - -.PHONY: all all-am check check-am clean clean-generic clean-libtool \ - cscopelist-am ctags-am distclean distclean-generic \ - distclean-libtool distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags-am uninstall uninstall-am - -.PRECIOUS: Makefile - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/src/trio/trio.c b/src/trio/trio.c deleted file mode 100644 index c9dabdbd..00000000 --- a/src/trio/trio.c +++ /dev/null @@ -1,7839 +0,0 @@ -/* BEEBS trio benchmark - - Copyright (C) 2014 Embecosm Limited and University of Bristol - - This file is part of the Bristol/Embecosm Embedded Benchmark Suite. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* The original source of this file was from: - * http://daniel.haxx.se/projects/trio/ - * and is covered by the following copyright and licence: - * - * Copyright (C) 1998, 2009 Bjorn Reese and Daniel Stenberg. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND - * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. - * - ************************************************************************* - * - * A note to trio contributors: - * - * Avoid heap allocation at all costs to ensure that the trio functions - * are async-safe. The exceptions are the printf/fprintf functions, which - * uses fputc, and the asprintf functions and the modifier, which - * by design are required to allocate form the heap. - * - ************************************************************************/ - -/* - * TODO: - * - Scan is probably too permissive about its modifiers. - * - C escapes in %#[] ? - * - Multibyte characters (done for format parsing, except scan groups) - * - Complex numbers? (C99 _Complex) - * - Boolean values? (C99 _Bool) - * - C99 NaN(n-char-sequence) missing. The n-char-sequence can be used - * to print the mantissa, e.g. NaN(0xc000000000000000) - * - Should we support the GNU %a alloc modifier? GNU has an ugly hack - * for %a, because C99 used %a for other purposes. If specified as - * %as or %a[ it is interpreted as the alloc modifier, otherwise as - * the C99 hex-float. This means that you cannot scan %as as a hex-float - * immediately followed by an 's'. - * - Scanning of collating symbols. - */ - -/************************************************************************* - * Trio include files - */ -#include "triodef.h" -#include "trio.h" -#include "triop.h" - -#if defined(TRIO_EMBED_NAN) -# define TRIO_PUBLIC_NAN static -# if TRIO_FEATURE_FLOAT -# define TRIO_FUNC_NAN -# define TRIO_FUNC_NINF -# define TRIO_FUNC_PINF -# define TRIO_FUNC_FPCLASSIFY_AND_SIGNBIT -# define TRIO_FUNC_ISINF -# endif -#endif - -#if defined(TRIO_EMBED_STRING) -# define TRIO_PUBLIC_STRING static -# define TRIO_FUNC_LENGTH -# define TRIO_FUNC_LENGTH_MAX -# define TRIO_FUNC_TO_LONG -# if TRIO_FEATURE_LOCALE -# define TRIO_FUNC_COPY_MAX -# endif -# if TRIO_FEATURE_DYNAMICSTRING -# define TRIO_FUNC_XSTRING_DUPLICATE -# endif -# if TRIO_EXTENSION && TRIO_FEATURE_SCANF -# define TRIO_FUNC_EQUAL_LOCALE -# endif -# if TRIO_FEATURE_ERRNO -# define TRIO_FUNC_ERROR -# endif -# if TRIO_FEATURE_FLOAT && TRIO_FEATURE_SCANF -# define TRIO_FUNC_TO_DOUBLE -# endif -# if TRIO_FEATURE_DYNAMICSTRING -# define TRIO_FUNC_STRING_EXTRACT -# endif -# if TRIO_FEATURE_DYNAMICSTRING -# define TRIO_FUNC_STRING_TERMINATE -# endif -# if TRIO_FEATURE_USER_DEFINED -# define TRIO_FUNC_DUPLICATE -# endif -# if TRIO_FEATURE_DYNAMICSTRING -# define TRIO_FUNC_STRING_DESTROY -# endif -# if TRIO_FEATURE_USER_DEFINED -# define TRIO_FUNC_DESTROY -# endif -# if TRIO_FEATURE_USER_DEFINED || (TRIO_FEATURE_FLOAT && TRIO_FEATURE_SCANF) -# define TRIO_FUNC_EQUAL -# endif -# if TRIO_FEATURE_USER_DEFINED || TRIO_FEATURE_SCANF -# define TRIO_FUNC_EQUAL_CASE -# endif -# if (TRIO_EXTENSION && TRIO_FEATURE_SCANF) -# define TRIO_FUNC_EQUAL_MAX -# endif -# if TRIO_FEATURE_SCANF -# define TRIO_FUNC_TO_UPPER -# endif -# if TRIO_FEATURE_DYNAMICSTRING -# define TRIO_FUNC_XSTRING_APPEND_CHAR -# endif -#endif -#include "triostr.h" - -/************************************************************************** - * - * Definitions - * - *************************************************************************/ - -#include -#if TRIO_FEATURE_FLOAT -# include -# include -#endif - -#if defined(__STDC_ISO_10646__) || defined(MB_LEN_MAX) || defined(USE_MULTIBYTE) || TRIO_FEATURE_WIDECHAR -# if !defined(TRIO_PLATFORM_WINCE) -# define TRIO_COMPILER_SUPPORTS_MULTIBYTE -# if !defined(MB_LEN_MAX) -# define MB_LEN_MAX 6 -# endif -# endif -#endif - -#if (TRIO_COMPILER_VISUALC - 0 >= 1100) || defined(TRIO_COMPILER_BORLAND) -# define TRIO_COMPILER_SUPPORTS_VISUALC_INT -#endif - -#if TRIO_FEATURE_FLOAT -# if defined(PREDEF_STANDARD_C99) \ - || defined(PREDEF_STANDARD_UNIX03) -# if !defined(HAVE_FLOORL) && !defined(TRIO_NO_FLOORL) -# define HAVE_FLOORL -# endif -# if !defined(HAVE_CEILL) && !defined(TRIO_NO_CEILL) -# define HAVE_CEILL -# endif -# if !defined(HAVE_POWL) && !defined(TRIO_NO_POWL) -# define HAVE_POWL -# endif -# if !defined(HAVE_FMODL) && !defined(TRIO_NO_FMODL) -# define HAVE_FMODL -# endif -# if !defined(HAVE_LOG10L) && !defined(TRIO_NO_LOG10L) -# define HAVE_LOG10L -# endif -# endif -# if defined(TRIO_COMPILER_VISUALC) -# if defined(floorl) -# define HAVE_FLOORL -# endif -# if defined(ceill) -# define HAVE_CEILL -# endif -# if defined(powl) -# define HAVE_POWL -# endif -# if defined(fmodl) -# define HAVE_FMODL -# endif -# if defined(log10l) -# define HAVE_LOG10L -# endif -# endif -#endif - -/************************************************************************* - * Generic definitions - */ - -#if !(defined(DEBUG) || defined(NDEBUG)) -# define NDEBUG -#endif - -#include -#include -#if defined(PREDEF_STANDARD_C99) && !defined(isascii) -# define isascii(x) ((x) & 0x7F) -#endif -#if defined(TRIO_COMPILER_ANCIENT) -# include -#else -# include -#endif -#include -#if defined(TRIO_PLATFORM_WINCE) -extern int errno; -#else -# include -#endif - -#ifndef NULL -# define NULL 0 -#endif -#define NIL ((char)0) -#ifndef FALSE -# define FALSE (1 == 0) -# define TRUE (! FALSE) -#endif -#define BOOLEAN_T int - -/* mincore() can be used for debugging purposes */ -#define VALID(x) (NULL != (x)) - -#if TRIO_FEATURE_ERRORCODE - /* - * Encode the error code and the position. This is decoded - * with TRIO_ERROR_CODE and TRIO_ERROR_POSITION. - */ -# define TRIO_ERROR_RETURN(x,y) (- ((x) + ((y) << 8))) -#else -# define TRIO_ERROR_RETURN(x,y) (-1) -#endif - -typedef unsigned long trio_flags_t; - - -/************************************************************************* - * Platform specific definitions - */ -#if defined(TRIO_PLATFORM_UNIX) -# include -# include -# include -# if !defined(TRIO_FEATURE_LOCALE) -# define USE_LOCALE -# endif -#endif /* TRIO_PLATFORM_UNIX */ -#if defined(TRIO_PLATFORM_VMS) -# include -#endif -#if defined(TRIO_PLATFORM_WIN32) -# if defined(TRIO_PLATFORM_WINCE) -int read(int handle, char *buffer, unsigned int length); -int write(int handle, const char *buffer, unsigned int length); -# else -# include -# define read _read -# define write _write -# endif -#endif /* TRIO_PLATFORM_WIN32 */ - -#if TRIO_FEATURE_WIDECHAR -# if defined(PREDEF_STANDARD_C94) -# include -# include -typedef wchar_t trio_wchar_t; -typedef wint_t trio_wint_t; -# else -typedef char trio_wchar_t; -typedef int trio_wint_t; -# define WCONST(x) L ## x -# define WEOF EOF -# define iswalnum(x) isalnum(x) -# define iswalpha(x) isalpha(x) -# define iswcntrl(x) iscntrl(x) -# define iswdigit(x) isdigit(x) -# define iswgraph(x) isgraph(x) -# define iswlower(x) islower(x) -# define iswprint(x) isprint(x) -# define iswpunct(x) ispunct(x) -# define iswspace(x) isspace(x) -# define iswupper(x) isupper(x) -# define iswxdigit(x) isxdigit(x) -# endif -#endif - - -/************************************************************************* - * Compiler dependent definitions - */ - -/* Support for long long */ -#ifndef __cplusplus -# if !defined(USE_LONGLONG) -# if defined(TRIO_COMPILER_GCC) && !defined(__STRICT_ANSI__) -# define USE_LONGLONG -# else -# if defined(TRIO_COMPILER_SUNPRO) -# define USE_LONGLONG -# else -# if defined(TRIO_COMPILER_MSVC) && (_MSC_VER >= 1400) -# define USE_LONGLONG -# else -# if defined(_LONG_LONG) || defined(_LONGLONG) -# define USE_LONGLONG -# endif -# endif -# endif -# endif -# endif -#endif - -/* The extra long numbers */ -#if defined(USE_LONGLONG) -typedef signed long long int trio_longlong_t; -typedef unsigned long long int trio_ulonglong_t; -#else -# if defined(TRIO_COMPILER_SUPPORTS_VISUALC_INT) -typedef signed __int64 trio_longlong_t; -typedef unsigned __int64 trio_ulonglong_t; -# else -typedef TRIO_SIGNED long int trio_longlong_t; -typedef unsigned long int trio_ulonglong_t; -# endif -#endif - -/* Maximal and fixed integer types */ -#if defined(PREDEF_STANDARD_C99) -# include -typedef intmax_t trio_intmax_t; -typedef uintmax_t trio_uintmax_t; -typedef int8_t trio_int8_t; -typedef int16_t trio_int16_t; -typedef int32_t trio_int32_t; -typedef int64_t trio_int64_t; -#else -# if defined(PREDEF_STANDARD_UNIX98) -# include -typedef intmax_t trio_intmax_t; -typedef uintmax_t trio_uintmax_t; -typedef int8_t trio_int8_t; -typedef int16_t trio_int16_t; -typedef int32_t trio_int32_t; -typedef int64_t trio_int64_t; -# else -# if defined(TRIO_COMPILER_SUPPORTS_VISUALC_INT) -typedef trio_longlong_t trio_intmax_t; -typedef trio_ulonglong_t trio_uintmax_t; -typedef __int8 trio_int8_t; -typedef __int16 trio_int16_t; -typedef __int32 trio_int32_t; -typedef __int64 trio_int64_t; -# else -typedef trio_longlong_t trio_intmax_t; -typedef trio_ulonglong_t trio_uintmax_t; -# if defined(TRIO_INT8_T) -typedef TRIO_INT8_T trio_int8_t; -# else -typedef TRIO_SIGNED char trio_int8_t; -# endif -# if defined(TRIO_INT16_T) -typedef TRIO_INT16_T trio_int16_t; -# else -typedef TRIO_SIGNED short trio_int16_t; -# endif -# if defined(TRIO_INT32_T) -typedef TRIO_INT32_T trio_int32_t; -# else -typedef TRIO_SIGNED int trio_int32_t; -# endif -# if defined(TRIO_INT64_T) -typedef TRIO_INT64_T trio_int64_t; -# else -typedef trio_longlong_t trio_int64_t; -# endif -# endif -# endif -#endif - -#if defined(HAVE_FLOORL) -# define trio_floor(x) floorl((x)) -#else -# define trio_floor(x) floor((double)(x)) -#endif - -#if defined(HAVE_CEILL) -# define trio_ceil(x) ceill((x)) -#else -# define trio_ceil(x) ceil((double)(x)) -#endif - -#if defined(HAVE_FMODL) -# define trio_fmod(x,y) fmodl((x),(y)) -#else -# define trio_fmod(x,y) fmod((double)(x),(double)(y)) -#endif - -#if defined(HAVE_POWL) -# define trio_pow(x,y) powl((x),(y)) -#else -# define trio_pow(x,y) pow((double)(x),(double)(y)) -#endif - -#if defined(HAVE_LOG10L) -# define trio_log10(x) log10l((x)) -#else -# define trio_log10(x) log10((double)(x)) -#endif - -#if TRIO_FEATURE_FLOAT -# define TRIO_FABS(x) (((x) < 0.0) ? -(x) : (x)) -#endif - -/************************************************************************* - * Internal Definitions - */ - -#if TRIO_FEATURE_FLOAT - -# if !defined(DECIMAL_DIG) -# define DECIMAL_DIG DBL_DIG -# endif - -/* Long double sizes */ -# ifdef LDBL_DIG -# define MAX_MANTISSA_DIGITS LDBL_DIG -# define MAX_EXPONENT_DIGITS 4 -# define MAX_DOUBLE_DIGITS LDBL_MAX_10_EXP -# else -# define MAX_MANTISSA_DIGITS DECIMAL_DIG -# define MAX_EXPONENT_DIGITS 3 -# define MAX_DOUBLE_DIGITS DBL_MAX_10_EXP -# endif - -# if defined(TRIO_COMPILER_ANCIENT) || !defined(LDBL_DIG) -# undef LDBL_DIG -# undef LDBL_MANT_DIG -# undef LDBL_EPSILON -# define LDBL_DIG DBL_DIG -# define LDBL_MANT_DIG DBL_MANT_DIG -# define LDBL_EPSILON DBL_EPSILON -# endif - -#endif /* TRIO_FEATURE_FLOAT */ - -/* The maximal number of digits is for base 2 */ -#define MAX_CHARS_IN(x) (sizeof(x) * CHAR_BIT) -/* The width of a pointer. The number of bits in a hex digit is 4 */ -#define POINTER_WIDTH ((sizeof("0x") - 1) + sizeof(trio_pointer_t) * CHAR_BIT / 4) - -#if TRIO_FEATURE_FLOAT -/* Infinite and Not-A-Number for floating-point */ -# define INFINITE_LOWER "inf" -# define INFINITE_UPPER "INF" -# define LONG_INFINITE_LOWER "infinite" -# define LONG_INFINITE_UPPER "INFINITE" -# define NAN_LOWER "nan" -# define NAN_UPPER "NAN" -#endif - -/* Various constants */ -enum { - TYPE_PRINT = 1, -#if TRIO_FEATURE_SCANF - TYPE_SCAN = 2, -#endif - - /* Flags. FLAGS_LAST must be less than ULONG_MAX */ - FLAGS_NEW = 0, - FLAGS_STICKY = 1, - FLAGS_SPACE = 2 * FLAGS_STICKY, - FLAGS_SHOWSIGN = 2 * FLAGS_SPACE, - FLAGS_LEFTADJUST = 2 * FLAGS_SHOWSIGN, - FLAGS_ALTERNATIVE = 2 * FLAGS_LEFTADJUST, - FLAGS_SHORT = 2 * FLAGS_ALTERNATIVE, - FLAGS_SHORTSHORT = 2 * FLAGS_SHORT, - FLAGS_LONG = 2 * FLAGS_SHORTSHORT, - FLAGS_QUAD = 2 * FLAGS_LONG, - FLAGS_LONGDOUBLE = 2 * FLAGS_QUAD, - FLAGS_SIZE_T = 2 * FLAGS_LONGDOUBLE, - FLAGS_PTRDIFF_T = 2 * FLAGS_SIZE_T, - FLAGS_INTMAX_T = 2 * FLAGS_PTRDIFF_T, - FLAGS_NILPADDING = 2 * FLAGS_INTMAX_T, - FLAGS_UNSIGNED = 2 * FLAGS_NILPADDING, - FLAGS_UPPER = 2UL * FLAGS_UNSIGNED, - FLAGS_WIDTH = 2 * FLAGS_UPPER, - FLAGS_WIDTH_PARAMETER = 2 * FLAGS_WIDTH, - FLAGS_PRECISION = 2 * FLAGS_WIDTH_PARAMETER, - FLAGS_PRECISION_PARAMETER = 2 * FLAGS_PRECISION, - FLAGS_BASE = 2 * FLAGS_PRECISION_PARAMETER, - FLAGS_BASE_PARAMETER = 2 * FLAGS_BASE, - FLAGS_FLOAT_E = 2 * FLAGS_BASE_PARAMETER, - FLAGS_FLOAT_G = 2 * FLAGS_FLOAT_E, - FLAGS_QUOTE = 2 * FLAGS_FLOAT_G, - FLAGS_WIDECHAR = 2 * FLAGS_QUOTE, - FLAGS_IGNORE = 2 * FLAGS_WIDECHAR, - FLAGS_IGNORE_PARAMETER = 2 * FLAGS_IGNORE, - FLAGS_VARSIZE_PARAMETER = 2 * FLAGS_IGNORE_PARAMETER, - FLAGS_FIXED_SIZE = 2 * FLAGS_VARSIZE_PARAMETER, - FLAGS_LAST = FLAGS_FIXED_SIZE, - /* Reused flags */ - FLAGS_EXCLUDE = FLAGS_SHORT, - FLAGS_USER_DEFINED = FLAGS_IGNORE, - FLAGS_USER_DEFINED_PARAMETER = FLAGS_IGNORE_PARAMETER, - FLAGS_ROUNDING = FLAGS_INTMAX_T, - /* Compounded flags */ - FLAGS_ALL_VARSIZES = FLAGS_LONG | FLAGS_QUAD | FLAGS_INTMAX_T | FLAGS_PTRDIFF_T | FLAGS_SIZE_T, - FLAGS_ALL_SIZES = FLAGS_ALL_VARSIZES | FLAGS_SHORTSHORT | FLAGS_SHORT, - - NO_POSITION = -1, - NO_WIDTH = 0, - NO_PRECISION = -1, - NO_SIZE = -1, - - /* Do not change these */ - NO_BASE = -1, - MIN_BASE = 2, - MAX_BASE = 36, - BASE_BINARY = 2, - BASE_OCTAL = 8, - BASE_DECIMAL = 10, - BASE_HEX = 16, - - /* Maximal number of allowed parameters */ - MAX_PARAMETERS = 64, - /* Maximal number of characters in class */ - MAX_CHARACTER_CLASS = UCHAR_MAX + 1, - -#if TRIO_FEATURE_USER_DEFINED - /* Maximal string lengths for user-defined specifiers */ - MAX_USER_NAME = 64, - MAX_USER_DATA = 256, -#endif - - /* Maximal length of locale separator strings */ - MAX_LOCALE_SEPARATOR_LENGTH = MB_LEN_MAX, - /* Maximal number of integers in grouping */ - MAX_LOCALE_GROUPS = 64 -}; - -#define NO_GROUPING ((int)CHAR_MAX) - -/* Fundamental formatting parameter types */ -#define FORMAT_SENTINEL -1 /* marks end of parameters array */ -#define FORMAT_UNKNOWN 0 -#define FORMAT_INT 1 -#define FORMAT_DOUBLE 2 -#define FORMAT_CHAR 3 -#define FORMAT_STRING 4 -#define FORMAT_POINTER 5 -#define FORMAT_COUNT 6 -#define FORMAT_PARAMETER 7 -#define FORMAT_GROUP 8 -#define FORMAT_ERRNO 9 -#define FORMAT_USER_DEFINED 10 - -/* Character constants */ -#define CHAR_IDENTIFIER '%' -#define CHAR_ALT_IDENTIFIER '$' -#define CHAR_BACKSLASH '\\' -#define CHAR_QUOTE '\"' -#define CHAR_ADJUST ' ' - -#if TRIO_EXTENSION -/* Character class expressions */ -# define CLASS_ALNUM "[:alnum:]" -# define CLASS_ALPHA "[:alpha:]" -# define CLASS_BLANK "[:blank:]" -# define CLASS_CNTRL "[:cntrl:]" -# define CLASS_DIGIT "[:digit:]" -# define CLASS_GRAPH "[:graph:]" -# define CLASS_LOWER "[:lower:]" -# define CLASS_PRINT "[:print:]" -# define CLASS_PUNCT "[:punct:]" -# define CLASS_SPACE "[:space:]" -# define CLASS_UPPER "[:upper:]" -# define CLASS_XDIGIT "[:xdigit:]" -#endif - -/* - * SPECIFIERS: - * - * - * a Hex-float - * A Hex-float - * c Character - * C Widechar character (wint_t) - * d Decimal - * e Float - * E Float - * F Float - * F Float - * g Float - * G Float - * i Integer - * m Error message - * n Count - * o Octal - * p Pointer - * s String - * S Widechar string (wchar_t *) - * u Unsigned - * x Hex - * X Hex - * [] Group - * <> User-defined - * - * Reserved: - * - * D Binary Coded Decimal %D(length,precision) (OS/390) - */ -#define SPECIFIER_CHAR 'c' -#define SPECIFIER_STRING 's' -#define SPECIFIER_DECIMAL 'd' -#define SPECIFIER_INTEGER 'i' -#define SPECIFIER_UNSIGNED 'u' -#define SPECIFIER_OCTAL 'o' -#define SPECIFIER_HEX 'x' -#define SPECIFIER_HEX_UPPER 'X' -#if TRIO_FEATURE_FLOAT -# define SPECIFIER_FLOAT_E 'e' -# define SPECIFIER_FLOAT_E_UPPER 'E' -# define SPECIFIER_FLOAT_F 'f' -# define SPECIFIER_FLOAT_F_UPPER 'F' -# define SPECIFIER_FLOAT_G 'g' -# define SPECIFIER_FLOAT_G_UPPER 'G' -#endif -#define SPECIFIER_POINTER 'p' -#if TRIO_FEATURE_SCANF -# define SPECIFIER_GROUP '[' -# define SPECIFIER_UNGROUP ']' -#endif -#define SPECIFIER_COUNT 'n' -#if TRIO_UNIX98 -# define SPECIFIER_CHAR_UPPER 'C' -# define SPECIFIER_STRING_UPPER 'S' -#endif -#define SPECIFIER_HEXFLOAT 'a' -#define SPECIFIER_HEXFLOAT_UPPER 'A' -#define SPECIFIER_ERRNO 'm' -#if TRIO_FEATURE_BINARY -# define SPECIFIER_BINARY 'b' -# define SPECIFIER_BINARY_UPPER 'B' -#endif -#if TRIO_FEATURE_USER_DEFINED -# define SPECIFIER_USER_DEFINED_BEGIN '<' -# define SPECIFIER_USER_DEFINED_END '>' -# define SPECIFIER_USER_DEFINED_SEPARATOR ':' -# define SPECIFIER_USER_DEFINED_EXTRA '|' -#endif - -/* - * QUALIFIERS: - * - * - * Numbers = d,i,o,u,x,X - * Float = a,A,e,E,f,F,g,G - * String = s - * Char = c - * - * - * 9$ Position - * Use the 9th parameter. 9 can be any number between 1 and - * the maximal argument - * - * 9 Width - * Set width to 9. 9 can be any number, but must not be postfixed - * by '$' - * - * h Short - * Numbers: - * (unsigned) short int - * - * hh Short short - * Numbers: - * (unsigned) char - * - * l Long - * Numbers: - * (unsigned) long int - * String: - * as the S specifier - * Char: - * as the C specifier - * - * ll Long Long - * Numbers: - * (unsigned) long long int - * - * L Long Double - * Float - * long double - * - * # Alternative - * Float: - * Decimal-point is always present - * String: - * non-printable characters are handled as \number - * - * Spacing - * - * + Sign - * - * - Alignment - * - * . Precision - * - * * Parameter - * print: use parameter - * scan: no parameter (ignore) - * - * q Quad - * - * Z size_t - * - * w Widechar - * - * ' Thousands/quote - * Numbers: - * Integer part grouped in thousands - * Binary numbers: - * Number grouped in nibbles (4 bits) - * String: - * Quoted string - * - * j intmax_t - * t prtdiff_t - * z size_t - * - * ! Sticky - * @ Parameter (for both print and scan) - * - * I n-bit Integer - * Numbers: - * The following options exists - * I8 = 8-bit integer - * I16 = 16-bit integer - * I32 = 32-bit integer - * I64 = 64-bit integer - */ -#define QUALIFIER_POSITION '$' -#define QUALIFIER_SHORT 'h' -#define QUALIFIER_LONG 'l' -#define QUALIFIER_LONG_UPPER 'L' -#define QUALIFIER_ALTERNATIVE '#' -#define QUALIFIER_SPACE ' ' -#define QUALIFIER_PLUS '+' -#define QUALIFIER_MINUS '-' -#define QUALIFIER_DOT '.' -#define QUALIFIER_STAR '*' -#define QUALIFIER_CIRCUMFLEX '^' /* For scanlists */ -#define QUALIFIER_SIZE_T 'z' -#define QUALIFIER_PTRDIFF_T 't' -#define QUALIFIER_INTMAX_T 'j' -#define QUALIFIER_QUAD 'q' -#define QUALIFIER_SIZE_T_UPPER 'Z' -#if TRIO_MISC -# define QUALIFIER_WIDECHAR 'w' -#endif -#define QUALIFIER_FIXED_SIZE 'I' -#define QUALIFIER_QUOTE '\'' -#define QUALIFIER_STICKY '!' -#define QUALIFIER_VARSIZE '&' /* This should remain undocumented */ -#define QUALIFIER_ROUNDING_UPPER 'R' -#if TRIO_EXTENSION -# define QUALIFIER_PARAM '@' /* Experimental */ -# define QUALIFIER_COLON ':' /* For scanlists */ -# define QUALIFIER_EQUAL '=' /* For scanlists */ -#endif - - -/************************************************************************* - * - * Internal Structures - * - *************************************************************************/ - -/* Parameters */ -typedef struct { - /* An indication of which entry in the data union is used */ - int type; - /* The flags */ - trio_flags_t flags; - /* The width qualifier */ - int width; - /* The precision qualifier */ - int precision; - /* The base qualifier */ - int base; - /* Base from specifier */ - int baseSpecifier; - /* The size for the variable size qualifier */ - int varsize; - /* Offset of the first character of the specifier */ - int beginOffset; - /* Offset of the first character after the specifier */ - int endOffset; - /* Position in the argument list that this parameter refers to */ - int position; - /* The data from the argument list */ - union { - char *string; -#if TRIO_FEATURE_WIDECHAR - trio_wchar_t *wstring; -#endif - trio_pointer_t pointer; - union { - trio_intmax_t as_signed; - trio_uintmax_t as_unsigned; - } number; -#if TRIO_FEATURE_FLOAT - double doubleNumber; - double *doublePointer; - trio_long_double_t longdoubleNumber; - trio_long_double_t *longdoublePointer; -#endif - int errorNumber; - } data; -#if TRIO_FEATURE_USER_DEFINED - /* For the user-defined specifier */ - union { - char namespace[MAX_USER_NAME]; - int handler; /* if flags & FLAGS_USER_DEFINED_PARAMETER */ - } user_defined; - char user_data[MAX_USER_DATA]; -#endif -} trio_parameter_t; - -/* Container for customized functions */ -typedef struct { - union { - trio_outstream_t out; - trio_instream_t in; - } stream; - trio_pointer_t closure; -} trio_custom_t; - -/* General trio "class" */ -typedef struct _trio_class_t { - /* - * The function to write characters to a stream. - */ - void (*OutStream) TRIO_PROTO((struct _trio_class_t *, int)); - /* - * The function to read characters from a stream. - */ - void (*InStream) TRIO_PROTO((struct _trio_class_t *, int *)); - /* - * The function to undo read characters from a stream. - */ - void (*UndoStream) TRIO_PROTO((struct _trio_class_t *)); - /* - * The current location in the stream. - */ - trio_pointer_t location; - /* - * The character currently being processed. - */ - int current; - /* - * The number of characters that would have been written/read - * if there had been sufficient space. - */ - int processed; - union { - /* - * The number of characters that are actually written. Processed and - * committed will only differ for the *nprintf functions. - */ - int committed; - /* - * The number of look-ahead characters read. - */ - int cached; - } actually; - /* - * The upper limit of characters that may be written/read. - */ - int max; - /* - * The last output error that was detected. - */ - int error; -} trio_class_t; - -/* References (for user-defined callbacks) */ -typedef struct _trio_reference_t { - trio_class_t *data; - trio_parameter_t *parameter; -} trio_reference_t; - -#if TRIO_FEATURE_USER_DEFINED -/* Registered entries (for user-defined callbacks) */ -typedef struct _trio_userdef_t { - struct _trio_userdef_t *next; - trio_callback_t callback; - char *name; -} trio_userdef_t; -#endif - -/************************************************************************* - * - * Internal Variables - * - *************************************************************************/ - -#if TRIO_FEATURE_FLOAT -/* - * Need this to workaround a parser bug in HP C/iX compiler that fails - * to resolves macro definitions that includes type 'long double', - * e.g: va_arg(arg_ptr, long double) - */ -# if defined(TRIO_PLATFORM_MPEIX) -static TRIO_CONST trio_long_double_t ___dummy_long_double = 0; -# endif -#endif - -static TRIO_CONST char internalNullString[] = "(nil)"; - -#if defined(USE_LOCALE) -static struct lconv *internalLocaleValues = NULL; -#endif - -/* - * UNIX98 says "in a locale where the radix character is not defined, - * the radix character defaults to a period (.)" - */ -#if TRIO_FEATURE_FLOAT || TRIO_FEATURE_LOCALE || defined(USE_LOCALE) -static int internalDecimalPointLength = 1; -static char internalDecimalPoint = '.'; -static char internalDecimalPointString[MAX_LOCALE_SEPARATOR_LENGTH + 1] = "."; -#endif -#if TRIO_FEATURE_QUOTE || TRIO_FEATURE_LOCALE || TRIO_EXTENSION -static int internalThousandSeparatorLength = 1; -static char internalThousandSeparator[MAX_LOCALE_SEPARATOR_LENGTH + 1] = ","; -static char internalGrouping[MAX_LOCALE_GROUPS] = { (char)NO_GROUPING }; -#endif - -static TRIO_CONST char internalDigitsLower[] = "0123456789abcdefghijklmnopqrstuvwxyz"; -static TRIO_CONST char internalDigitsUpper[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; -#if TRIO_FEATURE_SCANF -static BOOLEAN_T internalDigitsUnconverted = TRUE; -static int internalDigitArray[128]; -# if TRIO_EXTENSION -static BOOLEAN_T internalCollationUnconverted = TRUE; -static char internalCollationArray[MAX_CHARACTER_CLASS][MAX_CHARACTER_CLASS]; -# endif -#endif - -#if TRIO_FEATURE_USER_DEFINED -static TRIO_VOLATILE trio_callback_t internalEnterCriticalRegion = NULL; -static TRIO_VOLATILE trio_callback_t internalLeaveCriticalRegion = NULL; -static trio_userdef_t *internalUserDef = NULL; -#endif - - -/************************************************************************* - * - * Internal Functions - * - ************************************************************************/ - -#if defined(TRIO_EMBED_STRING) -# include "triostr.c" -#endif - -/************************************************************************* - * TrioInitializeParameter - * - * Description: - * Initialize a trio_parameter_t struct. - */ -TRIO_PRIVATE void -TrioInitializeParameter -TRIO_ARGS1((parameter), - trio_parameter_t *parameter) -{ - parameter->type = FORMAT_UNKNOWN; - parameter->flags = 0; - parameter->width = 0; - parameter->precision = 0; - parameter->base = 0; - parameter->baseSpecifier = 0; - parameter->varsize = 0; - parameter->beginOffset = 0; - parameter->endOffset = 0; - parameter->position = 0; - parameter->data.pointer = 0; -#if TRIO_FEATURE_USER_DEFINED - parameter->user_defined.handler = 0; - parameter->user_data[0] = 0; -#endif -} - -/************************************************************************* - * TrioCopyParameter - * - * Description: - * Copies one trio_parameter_t struct to another. - */ -TRIO_PRIVATE void -TrioCopyParameter -TRIO_ARGS2((target, source), - trio_parameter_t *target, - TRIO_CONST trio_parameter_t *source) -{ -#if TRIO_FEATURE_USER_DEFINED - size_t i; -#endif - - target->type = source->type; - target->flags = source->flags; - target->width = source->width; - target->precision = source->precision; - target->base = source->base; - target->baseSpecifier = source->baseSpecifier; - target->varsize = source->varsize; - target->beginOffset = source->beginOffset; - target->endOffset = source->endOffset; - target->position = source->position; - target->data = source->data; - -#if TRIO_FEATURE_USER_DEFINED - target->user_defined = source->user_defined; - - for (i = 0U; i < sizeof(target->user_data); ++i) - { - if ((target->user_data[i] = source->user_data[i]) == NIL) - break; - } -#endif -} - -/************************************************************************* - * TrioIsQualifier - * - * Description: - * Remember to add all new qualifiers to this function. - * QUALIFIER_POSITION must not be added. - */ -TRIO_PRIVATE BOOLEAN_T -TrioIsQualifier -TRIO_ARGS1((character), - TRIO_CONST char character) -{ - /* QUALIFIER_POSITION is not included */ - switch (character) - { - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - case QUALIFIER_PLUS: - case QUALIFIER_MINUS: - case QUALIFIER_SPACE: - case QUALIFIER_DOT: - case QUALIFIER_STAR: - case QUALIFIER_ALTERNATIVE: - case QUALIFIER_SHORT: - case QUALIFIER_LONG: - case QUALIFIER_CIRCUMFLEX: - case QUALIFIER_LONG_UPPER: - case QUALIFIER_SIZE_T: - case QUALIFIER_PTRDIFF_T: - case QUALIFIER_INTMAX_T: - case QUALIFIER_QUAD: - case QUALIFIER_SIZE_T_UPPER: -#if defined(QUALIFIER_WIDECHAR) - case QUALIFIER_WIDECHAR: -#endif - case QUALIFIER_QUOTE: - case QUALIFIER_STICKY: - case QUALIFIER_VARSIZE: -#if defined(QUALIFIER_PARAM) - case QUALIFIER_PARAM: -#endif - case QUALIFIER_FIXED_SIZE: - case QUALIFIER_ROUNDING_UPPER: - return TRUE; - default: - return FALSE; - } -} - -/************************************************************************* - * TrioSetLocale - */ -#if defined(USE_LOCALE) -TRIO_PRIVATE void -TrioSetLocale(TRIO_NOARGS) -{ - internalLocaleValues = (struct lconv *)localeconv(); - if (internalLocaleValues) - { - if ((internalLocaleValues->decimal_point) && - (internalLocaleValues->decimal_point[0] != NIL)) - { - internalDecimalPointLength = trio_length(internalLocaleValues->decimal_point); - if (internalDecimalPointLength == 1) - { - internalDecimalPoint = internalLocaleValues->decimal_point[0]; - } - else - { - internalDecimalPoint = NIL; - trio_copy_max(internalDecimalPointString, - sizeof(internalDecimalPointString), - internalLocaleValues->decimal_point); - } - } -# if TRIO_EXTENSION - if ((internalLocaleValues->thousands_sep) && - (internalLocaleValues->thousands_sep[0] != NIL)) - { - trio_copy_max(internalThousandSeparator, - sizeof(internalThousandSeparator), - internalLocaleValues->thousands_sep); - internalThousandSeparatorLength = trio_length(internalThousandSeparator); - } -# endif -# if TRIO_EXTENSION - if ((internalLocaleValues->grouping) && - (internalLocaleValues->grouping[0] != NIL)) - { - trio_copy_max(internalGrouping, - sizeof(internalGrouping), - internalLocaleValues->grouping); - } -# endif - } -} -#endif /* defined(USE_LOCALE) */ - -#if TRIO_FEATURE_FLOAT && TRIO_FEATURE_QUOTE -TRIO_PRIVATE int -TrioCalcThousandSeparatorLength -TRIO_ARGS1((digits), - int digits) -{ - int count = 0; - int step = NO_GROUPING; - char *groupingPointer = internalGrouping; - - while (digits > 0) - { - if (*groupingPointer == CHAR_MAX) - { - /* Disable grouping */ - break; /* while */ - } - else if (*groupingPointer == 0) - { - /* Repeat last group */ - if (step == NO_GROUPING) - { - /* Error in locale */ - break; /* while */ - } - } - else - { - step = *groupingPointer++; - } - if (digits > step) - count += internalThousandSeparatorLength; - digits -= step; - } - return count; -} -#endif /* TRIO_FEATURE_FLOAT && TRIO_FEATURE_QUOTE */ - -#if TRIO_FEATURE_QUOTE -TRIO_PRIVATE BOOLEAN_T -TrioFollowedBySeparator -TRIO_ARGS1((position), - int position) -{ - int step = 0; - char *groupingPointer = internalGrouping; - - position--; - if (position == 0) - return FALSE; - while (position > 0) - { - if (*groupingPointer == CHAR_MAX) - { - /* Disable grouping */ - break; /* while */ - } - else if (*groupingPointer != 0) - { - step = *groupingPointer++; - } - if (step == 0) - break; - position -= step; - } - return (position == 0); -} -#endif /* TRIO_FEATURE_QUOTE */ - -/************************************************************************* - * TrioGetPosition - * - * Get the %n$ position. - */ -TRIO_PRIVATE int -TrioGetPosition -TRIO_ARGS2((format, offsetPointer), - TRIO_CONST char *format, - int *offsetPointer) -{ -#if TRIO_FEATURE_POSITIONAL - char *tmpformat; - int number = 0; - int offset = *offsetPointer; - - number = (int)trio_to_long(&format[offset], &tmpformat, BASE_DECIMAL); - offset = (int)(tmpformat - format); - if ((number != 0) && (QUALIFIER_POSITION == format[offset++])) - { - *offsetPointer = offset; - /* - * number is decreased by 1, because n$ starts from 1, whereas - * the array it is indexing starts from 0. - */ - return number - 1; - } -#endif - return NO_POSITION; -} - -/************************************************************************* - * TrioFindNamespace - * - * Find registered user-defined specifier. - * The prev argument is used for optimization only. - */ -#if TRIO_FEATURE_USER_DEFINED -TRIO_PRIVATE trio_userdef_t * -TrioFindNamespace -TRIO_ARGS2((name, prev), - TRIO_CONST char *name, - trio_userdef_t **prev) -{ - trio_userdef_t *def; - - if (internalEnterCriticalRegion) - (void)internalEnterCriticalRegion(NULL); - - for (def = internalUserDef; def; def = def->next) - { - /* Case-sensitive string comparison */ - if (trio_equal_case(def->name, name)) - break; - - if (prev) - *prev = def; - } - - if (internalLeaveCriticalRegion) - (void)internalLeaveCriticalRegion(NULL); - - return def; -} -#endif - -/************************************************************************* - * TrioPower - * - * Description: - * Calculate pow(base, exponent), where number and exponent are integers. - */ -#if TRIO_FEATURE_FLOAT -TRIO_PRIVATE trio_long_double_t -TrioPower -TRIO_ARGS2((number, exponent), - int number, - int exponent) -{ - trio_long_double_t result; - - if (number == 10) - { - switch (exponent) - { - /* Speed up calculation of common cases */ - case 0: - result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E-1); - break; - case 1: - result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+0); - break; - case 2: - result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+1); - break; - case 3: - result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+2); - break; - case 4: - result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+3); - break; - case 5: - result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+4); - break; - case 6: - result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+5); - break; - case 7: - result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+6); - break; - case 8: - result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+7); - break; - case 9: - result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+8); - break; - default: - result = trio_pow((trio_long_double_t)number, - (trio_long_double_t)exponent); - break; - } - } - else - { - return trio_pow((trio_long_double_t)number, - (trio_long_double_t)exponent); - } - return result; -} -#endif /* TRIO_FEATURE_FLOAT */ - -/************************************************************************* - * TrioLogarithm - */ -#if TRIO_FEATURE_FLOAT -TRIO_PRIVATE trio_long_double_t -TrioLogarithm -TRIO_ARGS2((number, base), - trio_long_double_t number, - int base) -{ - trio_long_double_t result; - - if (number <= 0.0) - { - /* xlC crashes on log(0) */ - result = (number == 0.0) ? trio_ninf() : trio_nan(); - } - else - { - if (base == 10) - { - result = trio_log10(number); - } - else - { - result = trio_log10(number) / trio_log10((double)base); - } - } - return result; -} -#endif /* TRIO_FEATURE_FLOAT */ - -/************************************************************************* - * TrioLogarithmBase - */ -#if TRIO_FEATURE_FLOAT -TRIO_PRIVATE double -TrioLogarithmBase -TRIO_ARGS1((base), - int base) -{ - switch (base) - { - case BASE_BINARY : return 1.0; - case BASE_OCTAL : return 3.0; - case BASE_DECIMAL: return 3.321928094887362345; - case BASE_HEX : return 4.0; - default : return TrioLogarithm((double)base, 2); - } -} -#endif /* TRIO_FEATURE_FLOAT */ - -/************************************************************************* - * TrioParseQualifiers - * - * Description: - * Parse the qualifiers of a potential conversion specifier - */ -TRIO_PRIVATE int -TrioParseQualifiers -TRIO_ARGS4((type, format, offset, parameter), - int type, - TRIO_CONST char *format, - int offset, - trio_parameter_t *parameter) -{ - char ch; - int dots = 0; /* Count number of dots in modifier part */ - char *tmpformat; - - parameter->beginOffset = offset - 1; - parameter->flags = FLAGS_NEW; - parameter->position = TrioGetPosition(format, &offset); - - /* Default values */ - parameter->width = NO_WIDTH; - parameter->precision = NO_PRECISION; - parameter->base = NO_BASE; - parameter->varsize = NO_SIZE; - - while (TrioIsQualifier(format[offset])) - { - ch = format[offset++]; - - switch (ch) - { - case QUALIFIER_SPACE: - parameter->flags |= FLAGS_SPACE; - break; - - case QUALIFIER_PLUS: - parameter->flags |= FLAGS_SHOWSIGN; - break; - - case QUALIFIER_MINUS: - parameter->flags |= FLAGS_LEFTADJUST; - parameter->flags &= ~FLAGS_NILPADDING; - break; - - case QUALIFIER_ALTERNATIVE: - parameter->flags |= FLAGS_ALTERNATIVE; - break; - - case QUALIFIER_DOT: - if (dots == 0) /* Precision */ - { - dots++; - - /* Skip if no precision */ - if (QUALIFIER_DOT == format[offset]) - break; - - /* After the first dot we have the precision */ - parameter->flags |= FLAGS_PRECISION; - if ((QUALIFIER_STAR == format[offset]) -#if defined(QUALIFIER_PARAM) - || (QUALIFIER_PARAM == format[offset]) -#endif - ) - { - offset++; - parameter->flags |= FLAGS_PRECISION_PARAMETER; - parameter->precision = TrioGetPosition(format, &offset); - } - else - { - parameter->precision = trio_to_long(&format[offset], - &tmpformat, - BASE_DECIMAL); - offset = (int)(tmpformat - format); - } - } - else if (dots == 1) /* Base */ - { - dots++; - - /* After the second dot we have the base */ - parameter->flags |= FLAGS_BASE; - if ((QUALIFIER_STAR == format[offset]) -#if defined(QUALIFIER_PARAM) - || (QUALIFIER_PARAM == format[offset]) -#endif - ) - { - offset++; - parameter->flags |= FLAGS_BASE_PARAMETER; - parameter->base = TrioGetPosition(format, &offset); - } - else - { - parameter->base = trio_to_long(&format[offset], - &tmpformat, - BASE_DECIMAL); - if (parameter->base > MAX_BASE) - return TRIO_ERROR_RETURN(TRIO_EINVAL, offset); - offset = (int)(tmpformat - format); - } - } - else - { - return TRIO_ERROR_RETURN(TRIO_EINVAL, offset); - } - break; /* QUALIFIER_DOT */ - -#if defined(QUALIFIER_PARAM) - case QUALIFIER_PARAM: - parameter->type = TYPE_PRINT; - /* FALLTHROUGH */ -#endif - case QUALIFIER_STAR: - /* This has different meanings for print and scan */ - if (TYPE_PRINT == type) - { - /* Read with from parameter */ - int width = TrioGetPosition(format, &offset); - parameter->flags |= (FLAGS_WIDTH | FLAGS_WIDTH_PARAMETER); - if (NO_POSITION != width) - parameter->width = width; - /* else keep parameter->width = NO_WIDTH which != NO_POSITION */ - } -#if TRIO_FEATURE_SCANF - else - { - /* Scan, but do not store result */ - parameter->flags |= FLAGS_IGNORE; - } -#endif - break; /* QUALIFIER_STAR */ - - case '0': - if (! (parameter->flags & FLAGS_LEFTADJUST)) - parameter->flags |= FLAGS_NILPADDING; - /* FALLTHROUGH */ - case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - parameter->flags |= FLAGS_WIDTH; - /* - * &format[offset - 1] is used to "rewind" the read - * character from format - */ - parameter->width = trio_to_long(&format[offset - 1], - &tmpformat, - BASE_DECIMAL); - offset = (int)(tmpformat - format); - break; - - case QUALIFIER_SHORT: - if (parameter->flags & FLAGS_SHORTSHORT) - return TRIO_ERROR_RETURN(TRIO_EINVAL, offset); - else if (parameter->flags & FLAGS_SHORT) - parameter->flags |= FLAGS_SHORTSHORT; - else - parameter->flags |= FLAGS_SHORT; - break; - - case QUALIFIER_LONG: - if (parameter->flags & FLAGS_QUAD) - return TRIO_ERROR_RETURN(TRIO_EINVAL, offset); - else if (parameter->flags & FLAGS_LONG) - parameter->flags |= FLAGS_QUAD; - else - parameter->flags |= FLAGS_LONG; - break; - -#if TRIO_FEATURE_LONGDOUBLE - case QUALIFIER_LONG_UPPER: - parameter->flags |= FLAGS_LONGDOUBLE; - break; -#endif - -#if TRIO_FEATURE_SIZE_T - case QUALIFIER_SIZE_T: - parameter->flags |= FLAGS_SIZE_T; - /* Modify flags for later truncation of number */ - if (sizeof(size_t) == sizeof(trio_ulonglong_t)) - parameter->flags |= FLAGS_QUAD; - else if (sizeof(size_t) == sizeof(long)) - parameter->flags |= FLAGS_LONG; - break; -#endif - -#if TRIO_FEATURE_PTRDIFF_T - case QUALIFIER_PTRDIFF_T: - parameter->flags |= FLAGS_PTRDIFF_T; - if (sizeof(ptrdiff_t) == sizeof(trio_ulonglong_t)) - parameter->flags |= FLAGS_QUAD; - else if (sizeof(ptrdiff_t) == sizeof(long)) - parameter->flags |= FLAGS_LONG; - break; -#endif - -#if TRIO_FEATURE_INTMAX_T - case QUALIFIER_INTMAX_T: - parameter->flags |= FLAGS_INTMAX_T; - if (sizeof(trio_intmax_t) == sizeof(trio_ulonglong_t)) - parameter->flags |= FLAGS_QUAD; - else if (sizeof(trio_intmax_t) == sizeof(long)) - parameter->flags |= FLAGS_LONG; - break; -#endif - -#if TRIO_FEATURE_QUAD - case QUALIFIER_QUAD: - parameter->flags |= FLAGS_QUAD; - break; -#endif - -#if TRIO_FEATURE_FIXED_SIZE - case QUALIFIER_FIXED_SIZE: - if (parameter->flags & FLAGS_FIXED_SIZE) - return TRIO_ERROR_RETURN(TRIO_EINVAL, offset); - - if (parameter->flags & (FLAGS_ALL_SIZES | - FLAGS_LONGDOUBLE | - FLAGS_WIDECHAR | - FLAGS_VARSIZE_PARAMETER)) - return TRIO_ERROR_RETURN(TRIO_EINVAL, offset); - - if ((format[offset] == '6') && - (format[offset + 1] == '4')) - { - parameter->varsize = sizeof(trio_int64_t); - offset += 2; - } - else if ((format[offset] == '3') && - (format[offset + 1] == '2')) - { - parameter->varsize = sizeof(trio_int32_t); - offset += 2; - } - else if ((format[offset] == '1') && - (format[offset + 1] == '6')) - { - parameter->varsize = sizeof(trio_int16_t); - offset += 2; - } - else if (format[offset] == '8') - { - parameter->varsize = sizeof(trio_int8_t); - offset++; - } - else - return TRIO_ERROR_RETURN(TRIO_EINVAL, offset); - - parameter->flags |= FLAGS_FIXED_SIZE; - break; -#endif /* TRIO_FEATURE_FIXED_SIZE */ - -#if defined(QUALIFIER_WIDECHAR) - case QUALIFIER_WIDECHAR: - parameter->flags |= FLAGS_WIDECHAR; - break; -#endif - -#if TRIO_FEATURE_SIZE_T_UPPER - case QUALIFIER_SIZE_T_UPPER: - break; -#endif - -#if TRIO_FEATURE_QUOTE - case QUALIFIER_QUOTE: - parameter->flags |= FLAGS_QUOTE; - break; -#endif - -#if TRIO_FEATURE_STICKY - case QUALIFIER_STICKY: - parameter->flags |= FLAGS_STICKY; - break; -#endif - -#if TRIO_FEATURE_VARSIZE - case QUALIFIER_VARSIZE: - parameter->flags |= FLAGS_VARSIZE_PARAMETER; - break; -#endif - -#if TRIO_FEATURE_ROUNDING - case QUALIFIER_ROUNDING_UPPER: - parameter->flags |= FLAGS_ROUNDING; - break; -#endif - - default: - /* Bail out completely to make the error more obvious */ - return TRIO_ERROR_RETURN(TRIO_EINVAL, offset); - } - } /* while qualifier */ - - parameter->endOffset = offset; - - return 0; -} - -/************************************************************************* - * TrioParseSpecifier - * - * Description: - * Parse the specifier part of a potential conversion specifier - */ -TRIO_PRIVATE int -TrioParseSpecifier -TRIO_ARGS4((type, format, offset, parameter), - int type, - TRIO_CONST char *format, - int offset, - trio_parameter_t *parameter) -{ - parameter->baseSpecifier = NO_BASE; - - switch (format[offset++]) - { -#if defined(SPECIFIER_CHAR_UPPER) - case SPECIFIER_CHAR_UPPER: - parameter->flags |= FLAGS_WIDECHAR; - /* FALLTHROUGH */ -#endif - case SPECIFIER_CHAR: - if (parameter->flags & FLAGS_LONG) - parameter->flags |= FLAGS_WIDECHAR; - else if (parameter->flags & FLAGS_SHORT) - parameter->flags &= ~FLAGS_WIDECHAR; - parameter->type = FORMAT_CHAR; - break; - -#if defined(SPECIFIER_STRING_UPPER) - case SPECIFIER_STRING_UPPER: - parameter->flags |= FLAGS_WIDECHAR; - /* FALLTHROUGH */ -#endif - case SPECIFIER_STRING: - if (parameter->flags & FLAGS_LONG) - parameter->flags |= FLAGS_WIDECHAR; - else if (parameter->flags & FLAGS_SHORT) - parameter->flags &= ~FLAGS_WIDECHAR; - parameter->type = FORMAT_STRING; - break; - -#if defined(SPECIFIER_GROUP) - case SPECIFIER_GROUP: - if (TYPE_SCAN == type) - { - int depth = 1; - parameter->type = FORMAT_GROUP; - if (format[offset] == QUALIFIER_CIRCUMFLEX) - offset++; - if (format[offset] == SPECIFIER_UNGROUP) - offset++; - if (format[offset] == QUALIFIER_MINUS) - offset++; - /* Skip nested brackets */ - while (format[offset] != NIL) - { - if (format[offset] == SPECIFIER_GROUP) - { - depth++; - } - else if (format[offset] == SPECIFIER_UNGROUP) - { - if (--depth <= 0) - { - offset++; - break; - } - } - offset++; - } - } - break; -#endif /* defined(SPECIFIER_GROUP) */ - - case SPECIFIER_INTEGER: - parameter->type = FORMAT_INT; - break; - - case SPECIFIER_UNSIGNED: - parameter->flags |= FLAGS_UNSIGNED; - parameter->type = FORMAT_INT; - break; - - case SPECIFIER_DECIMAL: - parameter->baseSpecifier = BASE_DECIMAL; - parameter->type = FORMAT_INT; - break; - - case SPECIFIER_OCTAL: - parameter->flags |= FLAGS_UNSIGNED; - parameter->baseSpecifier = BASE_OCTAL; - parameter->type = FORMAT_INT; - break; - -#if TRIO_FEATURE_BINARY - case SPECIFIER_BINARY_UPPER: - parameter->flags |= FLAGS_UPPER; - /* FALLTHROUGH */ - case SPECIFIER_BINARY: - parameter->flags |= FLAGS_NILPADDING; - parameter->baseSpecifier = BASE_BINARY; - parameter->type = FORMAT_INT; - break; -#endif - - case SPECIFIER_HEX_UPPER: - parameter->flags |= FLAGS_UPPER; - /* FALLTHROUGH */ - case SPECIFIER_HEX: - parameter->flags |= FLAGS_UNSIGNED; - parameter->baseSpecifier = BASE_HEX; - parameter->type = FORMAT_INT; - break; - -#if defined(SPECIFIER_FLOAT_E) -# if defined(SPECIFIER_FLOAT_E_UPPER) - case SPECIFIER_FLOAT_E_UPPER: - parameter->flags |= FLAGS_UPPER; - /* FALLTHROUGH */ -# endif - case SPECIFIER_FLOAT_E: - parameter->flags |= FLAGS_FLOAT_E; - parameter->type = FORMAT_DOUBLE; - break; -#endif - -#if defined(SPECIFIER_FLOAT_G) -# if defined(SPECIFIER_FLOAT_G_UPPER) - case SPECIFIER_FLOAT_G_UPPER: - parameter->flags |= FLAGS_UPPER; - /* FALLTHROUGH */ -# endif - case SPECIFIER_FLOAT_G: - parameter->flags |= FLAGS_FLOAT_G; - parameter->type = FORMAT_DOUBLE; - break; -#endif - -#if defined(SPECIFIER_FLOAT_F) -# if defined(SPECIFIER_FLOAT_F_UPPER) - case SPECIFIER_FLOAT_F_UPPER: - parameter->flags |= FLAGS_UPPER; - /* FALLTHROUGH */ -# endif - case SPECIFIER_FLOAT_F: - parameter->type = FORMAT_DOUBLE; - break; -#endif - -#if defined(TRIO_COMPILER_VISUALC) -# pragma warning( push ) -# pragma warning( disable : 4127 ) /* Conditional expression is constant */ -#endif - case SPECIFIER_POINTER: - if (sizeof(trio_pointer_t) == sizeof(trio_ulonglong_t)) - parameter->flags |= FLAGS_QUAD; - else if (sizeof(trio_pointer_t) == sizeof(long)) - parameter->flags |= FLAGS_LONG; - parameter->type = FORMAT_POINTER; - break; -#if defined(TRIO_COMPILER_VISUALC) -# pragma warning( pop ) -#endif - - case SPECIFIER_COUNT: - parameter->type = FORMAT_COUNT; - break; - -#if TRIO_FEATURE_HEXFLOAT - case SPECIFIER_HEXFLOAT_UPPER: - parameter->flags |= FLAGS_UPPER; - /* FALLTHROUGH */ - case SPECIFIER_HEXFLOAT: - parameter->baseSpecifier = BASE_HEX; - parameter->type = FORMAT_DOUBLE; - break; -#endif - -#if TRIO_FEATURE_ERRNO - case SPECIFIER_ERRNO: - parameter->type = FORMAT_ERRNO; - break; -#endif - -#if TRIO_FEATURE_USER_DEFINED - case SPECIFIER_USER_DEFINED_BEGIN: - { - unsigned int max; - int without_namespace = TRUE; - char* tmpformat = (char *)&format[offset]; - int ch; - - parameter->type = FORMAT_USER_DEFINED; - parameter->user_defined.namespace[0] = NIL; - - while ((ch = format[offset]) != NIL) - { - offset++; - if ((ch == SPECIFIER_USER_DEFINED_END) || (ch == SPECIFIER_USER_DEFINED_EXTRA)) - { - if (without_namespace) - /* No namespace, handler will be passed as an argument */ - parameter->flags |= FLAGS_USER_DEFINED_PARAMETER; - - /* Copy the user data */ - max = (unsigned int)(&format[offset] - tmpformat); - if (max > MAX_USER_DATA) - max = MAX_USER_DATA; - trio_copy_max(parameter->user_data, max, tmpformat); - - /* Skip extra data (which is only there to keep the compiler happy) */ - while ((ch != NIL) && (ch != SPECIFIER_USER_DEFINED_END)) - ch = format[offset++]; - - break; /* while */ - } - - if (ch == SPECIFIER_USER_DEFINED_SEPARATOR) - { - without_namespace = FALSE; - /* Copy the namespace for later looking-up */ - max = (int)(&format[offset] - tmpformat); - if (max > MAX_USER_NAME) - max = MAX_USER_NAME; - trio_copy_max(parameter->user_defined.namespace, max, tmpformat); - tmpformat = (char *)&format[offset]; - } - } - - if (ch != SPECIFIER_USER_DEFINED_END) - return TRIO_ERROR_RETURN(TRIO_EINVAL, offset); - } - break; -#endif /* TRIO_FEATURE_USER_DEFINED */ - - default: - /* Bail out completely to make the error more obvious */ - return TRIO_ERROR_RETURN(TRIO_EINVAL, offset); - } - - parameter->endOffset = offset; - - return 0; -} - -/************************************************************************* - * TrioParse - * - * Description: - * Parse the format string - */ -TRIO_PRIVATE int -TrioParse -TRIO_ARGS5((type, format, parameters, arglist, argarray), - int type, - TRIO_CONST char *format, - trio_parameter_t *parameters, - va_list arglist, - trio_pointer_t *argarray) -{ - /* Count the number of times a parameter is referenced */ - unsigned short usedEntries[MAX_PARAMETERS]; - /* Parameter counters */ - int parameterPosition; - int maxParam = -1; - /* Utility variables */ - int offset; /* Offset into formatting string */ - BOOLEAN_T positional; /* Does the specifier have a positional? */ -#if TRIO_FEATURE_STICKY - BOOLEAN_T gotSticky = FALSE; /* Are there any sticky modifiers at all? */ -#endif - /* - * indices specifies the order in which the parameters must be - * read from the va_args (this is necessary to handle positionals) - */ - int indices[MAX_PARAMETERS]; - int pos = 0; - /* Various variables */ - int save_errno; - int i = -1; - int num; - trio_parameter_t workParameter; - int status; - - /* - * The 'parameters' array is not initialized, but we need to - * know which entries we have used. - */ - memset(usedEntries, 0, sizeof(usedEntries)); - - save_errno = errno; - offset = 0; - parameterPosition = 0; - - while (format[offset]) - { - TrioInitializeParameter(&workParameter); - - switch(format[offset++]) { - - case CHAR_IDENTIFIER: - { - if (CHAR_IDENTIFIER == format[offset]) - { - /* skip double "%" */ - offset++; - continue; /* while */ - } - - status = TrioParseQualifiers(type, format, offset, &workParameter); - if (status < 0) - return status; /* Return qualifier syntax error */ - - status = TrioParseSpecifier(type, format, workParameter.endOffset, &workParameter); - if (status < 0) - return status; /* Return specifier syntax error */ - } - break; - -#if TRIO_EXTENSION - case CHAR_ALT_IDENTIFIER: - { - status = TrioParseQualifiers(type, format, offset, &workParameter); - if (status < 0) - continue; /* False alert, not a user defined specifier */ - - status = TrioParseSpecifier(type, format, workParameter.endOffset, &workParameter); - if ((status < 0) || (FORMAT_USER_DEFINED != workParameter.type)) - continue; /* False alert, not a user defined specifier */ - } - break; -#endif - - default: - continue; /* while */ - } - - /* now handle the parsed conversion specification */ - positional = (NO_POSITION != workParameter.position); - - /* - * Parameters only need the type and value. The value is - * read later. - */ - if (workParameter.flags & FLAGS_WIDTH_PARAMETER) - { - if (workParameter.width == NO_WIDTH) - { - workParameter.width = parameterPosition++; - } - else - { - if (! positional) - workParameter.position = workParameter.width + 1; - } - - usedEntries[workParameter.width] += 1; - if (workParameter.width > maxParam) - maxParam = workParameter.width; - parameters[pos].type = FORMAT_PARAMETER; - parameters[pos].flags = 0; - indices[workParameter.width] = pos; - workParameter.width = pos++; - } - if (workParameter.flags & FLAGS_PRECISION_PARAMETER) - { - if (workParameter.precision == NO_PRECISION) - { - workParameter.precision = parameterPosition++; - } - else - { - if (! positional) - workParameter.position = workParameter.precision + 1; - } - - usedEntries[workParameter.precision] += 1; - if (workParameter.precision > maxParam) - maxParam = workParameter.precision; - parameters[pos].type = FORMAT_PARAMETER; - parameters[pos].flags = 0; - indices[workParameter.precision] = pos; - workParameter.precision = pos++; - } - if (workParameter.flags & FLAGS_BASE_PARAMETER) - { - if (workParameter.base == NO_BASE) - { - workParameter.base = parameterPosition++; - } - else - { - if (! positional) - workParameter.position = workParameter.base + 1; - } - - usedEntries[workParameter.base] += 1; - if (workParameter.base > maxParam) - maxParam = workParameter.base; - parameters[pos].type = FORMAT_PARAMETER; - parameters[pos].flags = 0; - indices[workParameter.base] = pos; - workParameter.base = pos++; - } -#if TRIO_FEATURE_VARSIZE - if (workParameter.flags & FLAGS_VARSIZE_PARAMETER) - { - workParameter.varsize = parameterPosition++; - - usedEntries[workParameter.varsize] += 1; - if (workParameter.varsize > maxParam) - maxParam = workParameter.varsize; - parameters[pos].type = FORMAT_PARAMETER; - parameters[pos].flags = 0; - indices[workParameter.varsize] = pos; - workParameter.varsize = pos++; - } -#endif -#if TRIO_FEATURE_USER_DEFINED - if (workParameter.flags & FLAGS_USER_DEFINED_PARAMETER) - { - workParameter.user_defined.handler = parameterPosition++; - - usedEntries[workParameter.user_defined.handler] += 1; - if (workParameter.user_defined.handler > maxParam) - maxParam = workParameter.user_defined.handler; - parameters[pos].type = FORMAT_PARAMETER; - parameters[pos].flags = FLAGS_USER_DEFINED; - indices[workParameter.user_defined.handler] = pos; - workParameter.user_defined.handler = pos++; - } -#endif - - if (NO_POSITION == workParameter.position) - { - workParameter.position = parameterPosition++; - } - - if (workParameter.position > maxParam) - maxParam = workParameter.position; - - if (workParameter.position >= MAX_PARAMETERS) - { - /* Bail out completely to make the error more obvious */ - return TRIO_ERROR_RETURN(TRIO_ETOOMANY, offset); - } - - indices[workParameter.position] = pos; - - /* Count the number of times this entry has been used */ - usedEntries[workParameter.position] += 1; - - /* Find last sticky parameters */ -#if TRIO_FEATURE_STICKY - if (workParameter.flags & FLAGS_STICKY) - { - gotSticky = TRUE; - } - else if (gotSticky) - { - for (i = pos - 1; i >= 0; i--) - { - if (parameters[i].type == FORMAT_PARAMETER) - continue; - if ((parameters[i].flags & FLAGS_STICKY) && - (parameters[i].type == workParameter.type)) - { - /* Do not overwrite current qualifiers */ - workParameter.flags |= (parameters[i].flags & (unsigned long)~FLAGS_STICKY); - if (workParameter.width == NO_WIDTH) - workParameter.width = parameters[i].width; - if (workParameter.precision == NO_PRECISION) - workParameter.precision = parameters[i].precision; - if (workParameter.base == NO_BASE) - workParameter.base = parameters[i].base; - break; - } - } - } -#endif - - if (workParameter.base == NO_BASE) - workParameter.base = BASE_DECIMAL; - - offset = workParameter.endOffset; - - TrioCopyParameter(¶meters[pos++], &workParameter); - } /* while format characters left */ - - parameters[pos].type = FORMAT_SENTINEL; /* end parameter array with sentinel */ - parameters[pos].beginOffset = offset; - - for (num = 0; num <= maxParam; num++) - { - if (usedEntries[num] != 1) - { - if (usedEntries[num] == 0) /* gap detected */ - return TRIO_ERROR_RETURN(TRIO_EGAP, num); - else /* double references detected */ - return TRIO_ERROR_RETURN(TRIO_EDBLREF, num); - } - - i = indices[num]; - - /* - * FORMAT_PARAMETERS are only present if they must be read, - * so it makes no sense to check the ignore flag (besides, - * the flags variable is not set for that particular type) - */ - if ((parameters[i].type != FORMAT_PARAMETER) && - (parameters[i].flags & FLAGS_IGNORE)) - continue; /* for all arguments */ - - /* - * The stack arguments are read according to ANSI C89 - * default argument promotions: - * - * char = int - * short = int - * unsigned char = unsigned int - * unsigned short = unsigned int - * float = double - * - * In addition to the ANSI C89 these types are read (the - * default argument promotions of C99 has not been - * considered yet) - * - * long long - * long double - * size_t - * ptrdiff_t - * intmax_t - */ - switch (parameters[i].type) - { - case FORMAT_GROUP: - case FORMAT_STRING: -#if TRIO_FEATURE_WIDECHAR - if (parameters[i].flags & FLAGS_WIDECHAR) - { - parameters[i].data.wstring = (argarray == NULL) - ? va_arg(arglist, trio_wchar_t *) - : (trio_wchar_t *)(argarray[num]); - } - else -#endif - { - parameters[i].data.string = (argarray == NULL) - ? va_arg(arglist, char *) - : (char *)(argarray[num]); - } - break; - -#if TRIO_FEATURE_USER_DEFINED - case FORMAT_USER_DEFINED: -#endif - case FORMAT_POINTER: - case FORMAT_COUNT: - case FORMAT_UNKNOWN: - parameters[i].data.pointer = (argarray == NULL) - ? va_arg(arglist, trio_pointer_t ) - : argarray[num]; - break; - - case FORMAT_CHAR: - case FORMAT_INT: -#if TRIO_FEATURE_SCANF - if (TYPE_SCAN == type) - { - if (argarray == NULL) - parameters[i].data.pointer = - (trio_pointer_t)va_arg(arglist, trio_pointer_t); - else - { - if (parameters[i].type == FORMAT_CHAR) - parameters[i].data.pointer = - (trio_pointer_t)((char *)argarray[num]); - else if (parameters[i].flags & FLAGS_SHORT) - parameters[i].data.pointer = - (trio_pointer_t)((short *)argarray[num]); - else - parameters[i].data.pointer = - (trio_pointer_t)((int *)argarray[num]); - } - } - else -#endif /* TRIO_FEATURE_SCANF */ - { -#if TRIO_FEATURE_VARSIZE || TRIO_FEATURE_FIXED_SIZE - if (parameters[i].flags - & (FLAGS_VARSIZE_PARAMETER | FLAGS_FIXED_SIZE)) - { - int varsize; - if (parameters[i].flags & FLAGS_VARSIZE_PARAMETER) - { - /* - * Variable sizes are mapped onto the fixed sizes, in - * accordance with integer promotion. - * - * Please note that this may not be portable, as we - * only guess the size, not the layout of the numbers. - * For example, if int is little-endian, and long is - * big-endian, then this will fail. - */ - varsize = (int)parameters[parameters[i].varsize].data.number.as_unsigned; - } - else - { - /* Used for the I modifiers */ - varsize = parameters[i].varsize; - } - parameters[i].flags &= ~FLAGS_ALL_VARSIZES; - - if (varsize <= (int)sizeof(int)) - ; - else if (varsize <= (int)sizeof(long)) - parameters[i].flags |= FLAGS_LONG; -#if TRIO_FEATURE_INTMAX_T - else if (varsize <= (int)sizeof(trio_longlong_t)) - parameters[i].flags |= FLAGS_QUAD; - else - parameters[i].flags |= FLAGS_INTMAX_T; -#else - else - parameters[i].flags |= FLAGS_QUAD; -#endif - } -#endif /* TRIO_FEATURE_VARSIZE */ -#if TRIO_FEATURE_SIZE_T || TRIO_FEATURE_SIZE_T_UPPER - if (parameters[i].flags & FLAGS_SIZE_T) - parameters[i].data.number.as_unsigned = (argarray == NULL) - ? (trio_uintmax_t)va_arg(arglist, size_t) - : (trio_uintmax_t)(*((size_t *)argarray[num])); - else -#endif -#if TRIO_FEATURE_PTRDIFF_T - if (parameters[i].flags & FLAGS_PTRDIFF_T) - parameters[i].data.number.as_unsigned = (argarray == NULL) - ? (trio_uintmax_t)va_arg(arglist, ptrdiff_t) - : (trio_uintmax_t)(*((ptrdiff_t *)argarray[num])); - else -#endif -#if TRIO_FEATURE_INTMAX_T - if (parameters[i].flags & FLAGS_INTMAX_T) - parameters[i].data.number.as_unsigned = (argarray == NULL) - ? (trio_uintmax_t)va_arg(arglist, trio_intmax_t) - : (trio_uintmax_t)(*((trio_intmax_t *)argarray[num])); - else -#endif - if (parameters[i].flags & FLAGS_QUAD) - parameters[i].data.number.as_unsigned = (argarray == NULL) - ? (trio_uintmax_t)va_arg(arglist, trio_ulonglong_t) - : (trio_uintmax_t)(*((trio_ulonglong_t *)argarray[num])); - else if (parameters[i].flags & FLAGS_LONG) - parameters[i].data.number.as_unsigned = (argarray == NULL) - ? (trio_uintmax_t)va_arg(arglist, long) - : (trio_uintmax_t)(*((long *)argarray[num])); - else - { - if (argarray == NULL) - parameters[i].data.number.as_unsigned = (trio_uintmax_t)va_arg(arglist, int); - else - { - if (parameters[i].type == FORMAT_CHAR) - parameters[i].data.number.as_unsigned = (trio_uintmax_t)(*((char *)argarray[num])); - else if (parameters[i].flags & FLAGS_SHORT) - parameters[i].data.number.as_unsigned = (trio_uintmax_t)(*((short *)argarray[num])); - else - parameters[i].data.number.as_unsigned = (trio_uintmax_t)(*((int *)argarray[num])); - } - } - } - break; - - case FORMAT_PARAMETER: - /* - * The parameter for the user-defined specifier is a pointer, - * whereas the rest (width, precision, base) uses an integer. - */ - if (parameters[i].flags & FLAGS_USER_DEFINED) - parameters[i].data.pointer = (argarray == NULL) - ? va_arg(arglist, trio_pointer_t ) - : argarray[num]; - else - parameters[i].data.number.as_unsigned = (argarray == NULL) - ? (trio_uintmax_t)va_arg(arglist, int) - : (trio_uintmax_t)(*((int *)argarray[num])); - break; - -#if TRIO_FEATURE_FLOAT - case FORMAT_DOUBLE: -# if TRIO_FEATURE_SCANF - if (TYPE_SCAN == type) - { - if (parameters[i].flags & FLAGS_LONGDOUBLE) - parameters[i].data.longdoublePointer = (argarray == NULL) - ? va_arg(arglist, trio_long_double_t *) - : (trio_long_double_t *)argarray[num]; - else - { - if (parameters[i].flags & FLAGS_LONG) - parameters[i].data.doublePointer = (argarray == NULL) - ? va_arg(arglist, double *) - : (double *)argarray[num]; - else - parameters[i].data.doublePointer = (argarray == NULL) - ? (double *)va_arg(arglist, float *) - : (double *)((float *)argarray[num]); - } - } - else -# endif /* TRIO_FEATURE_SCANF */ - { - if (parameters[i].flags & FLAGS_LONGDOUBLE) - parameters[i].data.longdoubleNumber = (argarray == NULL) - ? va_arg(arglist, trio_long_double_t) - : (trio_long_double_t)(*((trio_long_double_t *)argarray[num])); - else - { - if (argarray == NULL) - parameters[i].data.longdoubleNumber = - (trio_long_double_t)va_arg(arglist, double); - else - { - if (parameters[i].flags & FLAGS_SHORT) - parameters[i].data.longdoubleNumber = - (trio_long_double_t)(*((float *)argarray[num])); - else - parameters[i].data.longdoubleNumber = - (trio_long_double_t)(*((double *)argarray[num])); - } - } - } - break; -#endif /* TRIO_FEATURE_FLOAT */ - -#if TRIO_FEATURE_ERRNO - case FORMAT_ERRNO: - parameters[i].data.errorNumber = save_errno; - break; -#endif - - default: - break; - } - } /* for all specifiers */ - return num; -} - - -/************************************************************************* - * - * FORMATTING - * - ************************************************************************/ - - -/************************************************************************* - * TrioWriteNumber - * - * Description: - * Output a number. - * The complexity of this function is a result of the complexity - * of the dependencies of the flags. - */ -TRIO_PRIVATE void -TrioWriteNumber -TRIO_ARGS6((self, number, flags, width, precision, base), - trio_class_t *self, - trio_uintmax_t number, - trio_flags_t flags, - int width, - int precision, - int base) -{ - BOOLEAN_T isNegative; - BOOLEAN_T isNumberZero; - BOOLEAN_T isPrecisionZero; - BOOLEAN_T ignoreNumber; - char buffer[MAX_CHARS_IN(trio_uintmax_t) * (1 + MAX_LOCALE_SEPARATOR_LENGTH) + 1]; - char *bufferend; - char *pointer; - TRIO_CONST char *digits; - int i; -#if TRIO_FEATURE_QUOTE - int length; - char *p; -#endif - int count; - int digitOffset; - - assert(VALID(self)); - assert(VALID(self->OutStream)); - assert(((base >= MIN_BASE) && (base <= MAX_BASE)) || (base == NO_BASE)); - - digits = (flags & FLAGS_UPPER) ? internalDigitsUpper : internalDigitsLower; - if (base == NO_BASE) - base = BASE_DECIMAL; - - isNumberZero = (number == 0); - isPrecisionZero = (precision == 0); - ignoreNumber = (isNumberZero - && isPrecisionZero - && !((flags & FLAGS_ALTERNATIVE) && (base == BASE_OCTAL))); - - if (flags & FLAGS_UNSIGNED) - { - isNegative = FALSE; - flags &= ~FLAGS_SHOWSIGN; - } - else - { - isNegative = ((trio_intmax_t)number < 0); - if (isNegative) - number = -((trio_intmax_t)number); - } - - if (flags & FLAGS_QUAD) - number &= (trio_ulonglong_t)-1; - else if (flags & FLAGS_LONG) - number &= (unsigned long)-1; - else - number &= (unsigned int)-1; - - /* Build number */ - pointer = bufferend = &buffer[sizeof(buffer) - 1]; - *pointer-- = NIL; - for (i = 1; i < (int)sizeof(buffer); i++) - { - digitOffset = number % base; - *pointer-- = digits[digitOffset]; - number /= base; - if (number == 0) - break; - -#if TRIO_FEATURE_QUOTE - if ((flags & FLAGS_QUOTE) && TrioFollowedBySeparator(i + 1)) - { - /* - * We are building the number from the least significant - * to the most significant digit, so we have to copy the - * thousand separator backwards - */ - length = internalThousandSeparatorLength; - if (((int)(pointer - buffer) - length) > 0) - { - p = &internalThousandSeparator[length - 1]; - while (length-- > 0) - *pointer-- = *p--; - } - } -#endif - } - - if (! ignoreNumber) - { - /* Adjust width */ - width -= (bufferend - pointer) - 1; - } - - /* Adjust precision */ - if (NO_PRECISION != precision) - { - precision -= (bufferend - pointer) - 1; - if (precision < 0) - precision = 0; - flags |= FLAGS_NILPADDING; - } - - /* Calculate padding */ - count = (! ((flags & FLAGS_LEFTADJUST) || (precision == NO_PRECISION))) - ? precision - : 0; - - /* Adjust width further */ - if (isNegative || (flags & FLAGS_SHOWSIGN) || (flags & FLAGS_SPACE)) - width--; - if ((flags & FLAGS_ALTERNATIVE) && !isNumberZero) - { - switch (base) - { - case BASE_BINARY: - case BASE_HEX: - width -= 2; - break; - case BASE_OCTAL: - if (!(flags & FLAGS_NILPADDING) || (count == 0)) - width--; - break; - default: - break; - } - } - - /* Output prefixes spaces if needed */ - if (! ((flags & FLAGS_LEFTADJUST) || - ((flags & FLAGS_NILPADDING) && (precision == NO_PRECISION)))) - { - while (width-- > count) - self->OutStream(self, CHAR_ADJUST); - } - - /* width has been adjusted for signs and alternatives */ - if (isNegative) - self->OutStream(self, '-'); - else if (flags & FLAGS_SHOWSIGN) - self->OutStream(self, '+'); - else if (flags & FLAGS_SPACE) - self->OutStream(self, ' '); - - /* Prefix is not written when the value is zero */ - if ((flags & FLAGS_ALTERNATIVE) && !isNumberZero) - { - switch (base) - { - case BASE_BINARY: - self->OutStream(self, '0'); - self->OutStream(self, (flags & FLAGS_UPPER) ? 'B' : 'b'); - break; - - case BASE_OCTAL: - if (!(flags & FLAGS_NILPADDING) || (count == 0)) - self->OutStream(self, '0'); - break; - - case BASE_HEX: - self->OutStream(self, '0'); - self->OutStream(self, (flags & FLAGS_UPPER) ? 'X' : 'x'); - break; - - default: - break; - } /* switch base */ - } - - /* Output prefixed zero padding if needed */ - if (flags & FLAGS_NILPADDING) - { - if (precision == NO_PRECISION) - precision = width; - while (precision-- > 0) - { - self->OutStream(self, '0'); - width--; - } - } - - if (! ignoreNumber) - { - /* Output the number itself */ - while (*(++pointer)) - { - self->OutStream(self, *pointer); - } - } - - /* Output trailing spaces if needed */ - if (flags & FLAGS_LEFTADJUST) - { - while (width-- > 0) - self->OutStream(self, CHAR_ADJUST); - } -} - -/************************************************************************* - * TrioWriteStringCharacter - * - * Description: - * Output a single character of a string - */ -TRIO_PRIVATE void -TrioWriteStringCharacter -TRIO_ARGS3((self, ch, flags), - trio_class_t *self, - int ch, - trio_flags_t flags) -{ - if (flags & FLAGS_ALTERNATIVE) - { - if (! isprint(ch)) - { - /* - * Non-printable characters are converted to C escapes or - * \number, if no C escape exists. - */ - self->OutStream(self, CHAR_BACKSLASH); - switch (ch) - { - case '\007': self->OutStream(self, 'a'); break; - case '\b': self->OutStream(self, 'b'); break; - case '\f': self->OutStream(self, 'f'); break; - case '\n': self->OutStream(self, 'n'); break; - case '\r': self->OutStream(self, 'r'); break; - case '\t': self->OutStream(self, 't'); break; - case '\v': self->OutStream(self, 'v'); break; - case '\\': self->OutStream(self, '\\'); break; - default: - self->OutStream(self, 'x'); - TrioWriteNumber(self, (trio_uintmax_t)ch, - FLAGS_UNSIGNED | FLAGS_NILPADDING, - 2, 2, BASE_HEX); - break; - } - } - else if (ch == CHAR_BACKSLASH) - { - self->OutStream(self, CHAR_BACKSLASH); - self->OutStream(self, CHAR_BACKSLASH); - } - else - { - self->OutStream(self, ch); - } - } - else - { - self->OutStream(self, ch); - } -} - -/************************************************************************* - * TrioWriteString - * - * Description: - * Output a string - */ -TRIO_PRIVATE void -TrioWriteString -TRIO_ARGS5((self, string, flags, width, precision), - trio_class_t *self, - TRIO_CONST char *string, - trio_flags_t flags, - int width, - int precision) -{ - int length; - int ch; - - assert(VALID(self)); - assert(VALID(self->OutStream)); - - if (string == NULL) - { - string = internalNullString; - length = sizeof(internalNullString) - 1; -#if TRIO_FEATURE_QUOTE - /* Disable quoting for the null pointer */ - flags &= (~FLAGS_QUOTE); -#endif - width = 0; - } - else - { - if (precision == 0) - { - length = trio_length(string); - } - else - { - length = trio_length_max(string, precision); - } - } - if ((NO_PRECISION != precision) && - (precision < length)) - { - length = precision; - } - width -= length; - -#if TRIO_FEATURE_QUOTE - if (flags & FLAGS_QUOTE) - self->OutStream(self, CHAR_QUOTE); -#endif - - if (! (flags & FLAGS_LEFTADJUST)) - { - while (width-- > 0) - self->OutStream(self, CHAR_ADJUST); - } - - while (length-- > 0) - { - /* The ctype parameters must be an unsigned char (or EOF) */ - ch = (int)((unsigned char)(*string++)); - TrioWriteStringCharacter(self, ch, flags); - } - - if (flags & FLAGS_LEFTADJUST) - { - while (width-- > 0) - self->OutStream(self, CHAR_ADJUST); - } -#if TRIO_FEATURE_QUOTE - if (flags & FLAGS_QUOTE) - self->OutStream(self, CHAR_QUOTE); -#endif -} - -/************************************************************************* - * TrioWriteWideStringCharacter - * - * Description: - * Output a wide string as a multi-byte sequence - */ -#if TRIO_FEATURE_WIDECHAR -TRIO_PRIVATE int -TrioWriteWideStringCharacter -TRIO_ARGS4((self, wch, flags, width), - trio_class_t *self, - trio_wchar_t wch, - trio_flags_t flags, - int width) -{ - int size; - int i; - int ch; - char *string; - char buffer[MB_LEN_MAX + 1]; - - if (width == NO_WIDTH) - width = sizeof(buffer); - - size = wctomb(buffer, wch); - if ((size <= 0) || (size > width) || (buffer[0] == NIL)) - return 0; - - string = buffer; - i = size; - while ((width >= i) && (width-- > 0) && (i-- > 0)) - { - /* The ctype parameters must be an unsigned char (or EOF) */ - ch = (int)((unsigned char)(*string++)); - TrioWriteStringCharacter(self, ch, flags); - } - return size; -} -#endif /* TRIO_FEATURE_WIDECHAR */ - -/************************************************************************* - * TrioWriteWideString - * - * Description: - * Output a wide character string as a multi-byte string - */ -#if TRIO_FEATURE_WIDECHAR -TRIO_PRIVATE void -TrioWriteWideString -TRIO_ARGS5((self, wstring, flags, width, precision), - trio_class_t *self, - TRIO_CONST trio_wchar_t *wstring, - trio_flags_t flags, - int width, - int precision) -{ - int length; - int size; - - assert(VALID(self)); - assert(VALID(self->OutStream)); - -#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE) - /* Required by TrioWriteWideStringCharacter */ - (void)mblen(NULL, 0); -#endif - - if (wstring == NULL) - { - TrioWriteString(self, NULL, flags, width, precision); - return; - } - - if (NO_PRECISION == precision) - { - length = INT_MAX; - } - else - { - length = precision; - width -= length; - } - -#if TRIO_FEATURE_QUOTE - if (flags & FLAGS_QUOTE) - self->OutStream(self, CHAR_QUOTE); -#endif - - if (! (flags & FLAGS_LEFTADJUST)) - { - while (width-- > 0) - self->OutStream(self, CHAR_ADJUST); - } - - while (length > 0) - { - size = TrioWriteWideStringCharacter(self, *wstring++, flags, length); - if (size == 0) - break; /* while */ - length -= size; - } - - if (flags & FLAGS_LEFTADJUST) - { - while (width-- > 0) - self->OutStream(self, CHAR_ADJUST); - } -#if TRIO_FEATURE_QUOTE - if (flags & FLAGS_QUOTE) - self->OutStream(self, CHAR_QUOTE); -#endif -} -#endif /* TRIO_FEATURE_WIDECHAR */ - -/************************************************************************* - * TrioWriteDouble - * - * http://wwwold.dkuug.dk/JTC1/SC22/WG14/www/docs/dr_211.htm - * - * "5.2.4.2.2 paragraph #4 - * - * The accuracy [...] is implementation defined, as is the accuracy - * of the conversion between floating-point internal representations - * and string representations performed by the libray routine in - * " - */ -/* FIXME: handle all instances of constant long-double number (L) - * and *l() math functions. - */ -#if TRIO_FEATURE_FLOAT -TRIO_PRIVATE void -TrioWriteDouble -TRIO_ARGS6((self, number, flags, width, precision, base), - trio_class_t *self, - trio_long_double_t number, - trio_flags_t flags, - int width, - int precision, - int base) -{ - trio_long_double_t integerNumber; - trio_long_double_t fractionNumber; - trio_long_double_t workNumber; - int integerDigits; - int fractionDigits; - int exponentDigits; - int workDigits; - int baseDigits; - int integerThreshold; - int fractionThreshold; - int expectedWidth; - int exponent = 0; - unsigned int uExponent = 0; - int exponentBase; - trio_long_double_t dblBase; - trio_long_double_t dblFractionBase; - trio_long_double_t integerAdjust; - trio_long_double_t fractionAdjust; - trio_long_double_t workFractionNumber; - trio_long_double_t workFractionAdjust; - int fractionDigitsInspect; - BOOLEAN_T isNegative; - BOOLEAN_T isExponentNegative = FALSE; - BOOLEAN_T requireTwoDigitExponent; - BOOLEAN_T isHex; - TRIO_CONST char *digits; -# if TRIO_FEATURE_QUOTE - char *groupingPointer; -# endif - int i; - int offset; - BOOLEAN_T hasOnlyZeroes; - int leadingFractionZeroes = -1; - register int trailingZeroes; - BOOLEAN_T keepTrailingZeroes; - BOOLEAN_T keepDecimalPoint; - trio_long_double_t epsilon; - BOOLEAN_T adjustNumber = FALSE; - - assert(VALID(self)); - assert(VALID(self->OutStream)); - assert(((base >= MIN_BASE) && (base <= MAX_BASE)) || (base == NO_BASE)); - - /* Determine sign and look for special quantities */ - switch (trio_fpclassify_and_signbit(number, &isNegative)) - { - case TRIO_FP_NAN: - TrioWriteString(self, - (flags & FLAGS_UPPER) - ? NAN_UPPER - : NAN_LOWER, - flags, width, precision); - return; - - case TRIO_FP_INFINITE: - if (isNegative) - { - /* Negative infinity */ - TrioWriteString(self, - (flags & FLAGS_UPPER) - ? "-" INFINITE_UPPER - : "-" INFINITE_LOWER, - flags, width, precision); - return; - } - else - { - /* Positive infinity */ - TrioWriteString(self, - (flags & FLAGS_UPPER) - ? INFINITE_UPPER - : INFINITE_LOWER, - flags, width, precision); - return; - } - - default: - /* Finitude */ - break; - } - - /* Normal numbers */ - if (flags & FLAGS_LONGDOUBLE) - { - baseDigits = (base == 10) - ? LDBL_DIG - : (int)trio_floor(LDBL_MANT_DIG / TrioLogarithmBase(base)); - epsilon = LDBL_EPSILON; - } - else if (flags & FLAGS_SHORT) - { - baseDigits = (base == BASE_DECIMAL) - ? FLT_DIG - : (int)trio_floor(FLT_MANT_DIG / TrioLogarithmBase(base)); - epsilon = FLT_EPSILON; - } - else - { - baseDigits = (base == BASE_DECIMAL) - ? DBL_DIG - : (int)trio_floor(DBL_MANT_DIG / TrioLogarithmBase(base)); - epsilon = DBL_EPSILON; - } - - digits = (flags & FLAGS_UPPER) ? internalDigitsUpper : internalDigitsLower; - isHex = (base == BASE_HEX); - if (base == NO_BASE) - base = BASE_DECIMAL; - dblBase = (trio_long_double_t)base; - keepTrailingZeroes = !( (flags & FLAGS_ROUNDING) || - ( (flags & FLAGS_FLOAT_G) && - !(flags & FLAGS_ALTERNATIVE) ) ); - -# if TRIO_FEATURE_ROUNDING - if (flags & FLAGS_ROUNDING) - { - precision = baseDigits; - } -# endif - - if (precision == NO_PRECISION) - { - if (isHex) - { - keepTrailingZeroes = FALSE; - precision = FLT_MANT_DIG; - } - else - { - precision = FLT_DIG; - } - } - - if (isNegative) - { - number = -number; - } - - if (isHex) - { - flags |= FLAGS_FLOAT_E; - } - - reprocess: - - if (flags & FLAGS_FLOAT_G) - { - if (precision == 0) - precision = 1; - - if ( (number < TRIO_SUFFIX_LONG(1.0E-4)) || - (number >= TrioPower(base, (trio_long_double_t)precision)) ) - { - /* Use scientific notation */ - flags |= FLAGS_FLOAT_E; - } - else if (number < 1.0) - { - /* - * Use normal notation. If the integer part of the number is - * zero, then adjust the precision to include leading fractional - * zeros. - */ - workNumber = TrioLogarithm(number, base); - workNumber = TRIO_FABS(workNumber); - if (workNumber - trio_floor(workNumber) < epsilon) - workNumber--; - leadingFractionZeroes = (int)trio_floor(workNumber); - } - } - - if (flags & FLAGS_FLOAT_E) - { - /* Scale the number */ - workNumber = TrioLogarithm(number, base); - if (trio_isinf(workNumber) == -1) - { - exponent = 0; - /* Undo setting */ - if (flags & FLAGS_FLOAT_G) - flags &= ~FLAGS_FLOAT_E; - } - else - { - exponent = (int)trio_floor(workNumber); - workNumber = number; - /* - * The expression A * 10^-B is equivalent to A / 10^B but the former - * usually gives better accuracy. - */ - workNumber *= TrioPower(dblBase, (trio_long_double_t)-exponent); - if (trio_isinf(workNumber)) { - /* - * Scaling is done it two steps to avoid problems with subnormal - * numbers. - */ - workNumber /= TrioPower(dblBase, (trio_long_double_t)(exponent / 2)); - workNumber /= TrioPower(dblBase, (trio_long_double_t)(exponent - (exponent / 2))); - } - number = workNumber; - isExponentNegative = (exponent < 0); - uExponent = (isExponentNegative) ? -exponent : exponent; - if (isHex) - uExponent *= 4; /* log16(2) */ -#if TRIO_FEATURE_QUOTE - /* No thousand separators */ - flags &= ~FLAGS_QUOTE; -#endif - } - } - - integerNumber = trio_floor(number); - fractionNumber = number - integerNumber; - - /* - * Truncated number. - * - * Precision is number of significant digits for FLOAT_G and number of - * fractional digits for others. - */ - integerDigits = 1; - if (integerNumber > epsilon) - { - integerDigits += (int)TrioLogarithm(integerNumber, base); - } - - fractionDigits = precision; - if (flags & FLAGS_FLOAT_G) - { - if (leadingFractionZeroes > 0) - { - fractionDigits += leadingFractionZeroes; - } - if ((integerNumber > epsilon) || (number <= epsilon)) - { - fractionDigits -= integerDigits; - } - } - - dblFractionBase = TrioPower(base, fractionDigits); - - if (integerNumber < 1.0) - { - workNumber = number * dblFractionBase + TRIO_SUFFIX_LONG(0.5); - if (trio_floor(number * dblFractionBase) != trio_floor(workNumber)) - { - adjustNumber = TRUE; - /* Remove a leading fraction zero if fraction is rounded up */ - if ((int)TrioLogarithm(number * dblFractionBase, base) != (int)TrioLogarithm(workNumber, base)) - { - --leadingFractionZeroes; - } - } - workNumber /= dblFractionBase; - } - else - { - workNumber = number + TRIO_SUFFIX_LONG(0.5) / dblFractionBase; - adjustNumber = (trio_floor(number) != trio_floor(workNumber)); - } - if (adjustNumber) - { - if ((flags & FLAGS_FLOAT_G) && !(flags & FLAGS_FLOAT_E)) - { - /* The adjustment may require a change to scientific notation */ - if ( (workNumber < TRIO_SUFFIX_LONG(1.0E-4)) || - (workNumber >= TrioPower(base, (trio_long_double_t)precision)) ) - { - /* Use scientific notation */ - flags |= FLAGS_FLOAT_E; - goto reprocess; - } - } - - if (flags & FLAGS_FLOAT_E) - { - workDigits = 1 + TrioLogarithm(trio_floor(workNumber), base); - if (integerDigits == workDigits) - { - /* Adjust if the same number of digits are used */ - number += TRIO_SUFFIX_LONG(0.5) / dblFractionBase; - integerNumber = trio_floor(number); - fractionNumber = number - integerNumber; - } - else - { - /* Adjust if number was rounded up one digit (ie. 0.99 to 1.00) */ - exponent++; - isExponentNegative = (exponent < 0); - uExponent = (isExponentNegative) ? -exponent : exponent; - if (isHex) - uExponent *= 4; /* log16(2) */ - workNumber = (number + TRIO_SUFFIX_LONG(0.5) / dblFractionBase) / dblBase; - integerNumber = trio_floor(workNumber); - fractionNumber = workNumber - integerNumber; - } - } - else - { - if (workNumber > 1.0) - { - /* Adjust if number was rounded up one digit (ie. 99 to 100) */ - integerNumber = trio_floor(workNumber); - fractionNumber = 0.0; - integerDigits = (integerNumber > epsilon) - ? 1 + (int)TrioLogarithm(integerNumber, base) - : 1; - if (flags & FLAGS_FLOAT_G) - { - if (flags & FLAGS_ALTERNATIVE) - { - if ((integerNumber > epsilon) || (number <= epsilon)) - { - fractionDigits -= integerDigits; - } - } - else - { - fractionDigits = 0; - } - } - } - else - { - integerNumber = trio_floor(workNumber); - fractionNumber = workNumber - integerNumber; - if (flags & FLAGS_FLOAT_G) - { - if (flags & FLAGS_ALTERNATIVE) - { - fractionDigits = precision; - if (leadingFractionZeroes > 0) - { - fractionDigits += leadingFractionZeroes; - } - if ((integerNumber > epsilon) || (number <= epsilon)) - { - fractionDigits -= integerDigits; - } - } - } - } - } - } - - /* Estimate accuracy */ - integerAdjust = fractionAdjust = TRIO_SUFFIX_LONG(0.5); -# if TRIO_FEATURE_ROUNDING - if (flags & FLAGS_ROUNDING) - { - if (integerDigits > baseDigits) - { - integerThreshold = baseDigits; - fractionDigits = 0; - dblFractionBase = 1.0; - fractionThreshold = 0; - precision = 0; /* Disable decimal-point */ - integerAdjust = TrioPower(base, integerDigits - integerThreshold - 1); - fractionAdjust = 0.0; - } - else - { - integerThreshold = integerDigits; - fractionThreshold = fractionDigits - integerThreshold; - fractionAdjust = 1.0; - } - } - else -# endif - { - integerThreshold = INT_MAX; - fractionThreshold = INT_MAX; - } - - /* - * Calculate expected width. - * sign + integer part + thousands separators + decimal point - * + fraction + exponent - */ - fractionAdjust /= dblFractionBase; - hasOnlyZeroes = (trio_floor((fractionNumber + fractionAdjust) * - dblFractionBase) < epsilon); - keepDecimalPoint = ( (flags & FLAGS_ALTERNATIVE) || - !((precision == 0) || - (!keepTrailingZeroes && hasOnlyZeroes)) ); - - expectedWidth = integerDigits + fractionDigits; - - if (!keepTrailingZeroes) - { - trailingZeroes = 0; - workFractionNumber = fractionNumber; - workFractionAdjust = fractionAdjust; - fractionDigitsInspect = fractionDigits; - - if (integerDigits > integerThreshold) - { - fractionDigitsInspect = 0; - } - else if (fractionThreshold <= fractionDigits) - { - fractionDigitsInspect = fractionThreshold + 1; - } - - trailingZeroes = fractionDigits - fractionDigitsInspect; - for (i = 0; i < fractionDigitsInspect; i++) - { - workFractionNumber *= dblBase; - workFractionAdjust *= dblBase; - workNumber = trio_floor(workFractionNumber + workFractionAdjust); - workFractionNumber -= workNumber; - offset = (int)trio_fmod(workNumber, dblBase); - if (offset == 0) - { - trailingZeroes++; - } - else - { - trailingZeroes = 0; - } - } - expectedWidth -= trailingZeroes; - } - - if (keepDecimalPoint) - { - expectedWidth += internalDecimalPointLength; - } - -#if TRIO_FEATURE_QUOTE - if (flags & FLAGS_QUOTE) - { - expectedWidth += TrioCalcThousandSeparatorLength(integerDigits); - } -#endif - - if (isNegative || (flags & FLAGS_SHOWSIGN) || (flags & FLAGS_SPACE)) - { - expectedWidth += sizeof("-") - 1; - } - - exponentDigits = 0; - if (flags & FLAGS_FLOAT_E) - { - exponentDigits = (uExponent == 0) - ? 1 - : (int)trio_ceil(TrioLogarithm((double)(uExponent + 1), - (isHex) ? 10 : base)); - } - requireTwoDigitExponent = ((base == BASE_DECIMAL) && (exponentDigits == 1)); - if (exponentDigits > 0) - { - expectedWidth += exponentDigits; - expectedWidth += (requireTwoDigitExponent - ? sizeof("E+0") - 1 - : sizeof("E+") - 1); - } - - if (isHex) - { - expectedWidth += sizeof("0X") - 1; - } - - /* Output prefixing */ - if (flags & FLAGS_NILPADDING) - { - /* Leading zeros must be after sign */ - if (isNegative) - self->OutStream(self, '-'); - else if (flags & FLAGS_SHOWSIGN) - self->OutStream(self, '+'); - else if (flags & FLAGS_SPACE) - self->OutStream(self, ' '); - if (isHex) - { - self->OutStream(self, '0'); - self->OutStream(self, (flags & FLAGS_UPPER) ? 'X' : 'x'); - } - if (!(flags & FLAGS_LEFTADJUST)) - { - for (i = expectedWidth; i < width; i++) - { - self->OutStream(self, '0'); - } - } - } - else - { - /* Leading spaces must be before sign */ - if (!(flags & FLAGS_LEFTADJUST)) - { - for (i = expectedWidth; i < width; i++) - { - self->OutStream(self, CHAR_ADJUST); - } - } - if (isNegative) - self->OutStream(self, '-'); - else if (flags & FLAGS_SHOWSIGN) - self->OutStream(self, '+'); - else if (flags & FLAGS_SPACE) - self->OutStream(self, ' '); - if (isHex) - { - self->OutStream(self, '0'); - self->OutStream(self, (flags & FLAGS_UPPER) ? 'X' : 'x'); - } - } - - /* Output the integer part and thousand separators */ - for (i = 0; i < integerDigits; i++) - { - workNumber = trio_floor(((integerNumber + integerAdjust) - / TrioPower(base, integerDigits - i - 1))); - if (i > integerThreshold) - { - /* Beyond accuracy */ - self->OutStream(self, digits[0]); - } - else - { - self->OutStream(self, digits[(int)trio_fmod(workNumber, dblBase)]); - } - -#if TRIO_FEATURE_QUOTE - if (((flags & (FLAGS_FLOAT_E | FLAGS_QUOTE)) == FLAGS_QUOTE) - && TrioFollowedBySeparator(integerDigits - i)) - { - for (groupingPointer = internalThousandSeparator; - *groupingPointer != NIL; - groupingPointer++) - { - self->OutStream(self, *groupingPointer); - } - } -#endif - } - - /* Insert decimal point and build the fraction part */ - trailingZeroes = 0; - - if (keepDecimalPoint) - { - if (internalDecimalPoint) - { - self->OutStream(self, internalDecimalPoint); - } - else - { - for (i = 0; i < internalDecimalPointLength; i++) - { - self->OutStream(self, internalDecimalPointString[i]); - } - } - } - - for (i = 0; i < fractionDigits; i++) - { - if ((integerDigits > integerThreshold) || (i > fractionThreshold)) - { - /* Beyond accuracy */ - trailingZeroes++; - } - else - { - fractionNumber *= dblBase; - fractionAdjust *= dblBase; - workNumber = trio_floor(fractionNumber + fractionAdjust); - if (workNumber > fractionNumber) - { - /* fractionNumber should never become negative */ - fractionNumber = 0.0; - fractionAdjust = 0.0; - } - else - { - fractionNumber -= workNumber; - } - offset = (int)trio_fmod(workNumber, dblBase); - if (offset == 0) - { - trailingZeroes++; - } - else - { - while (trailingZeroes > 0) - { - /* Not trailing zeroes after all */ - self->OutStream(self, digits[0]); - trailingZeroes--; - } - self->OutStream(self, digits[offset]); - } - } - } - - if (keepTrailingZeroes) - { - while (trailingZeroes > 0) - { - self->OutStream(self, digits[0]); - trailingZeroes--; - } - } - - /* Output exponent */ - if (exponentDigits > 0) - { - self->OutStream(self, - isHex - ? ((flags & FLAGS_UPPER) ? 'P' : 'p') - : ((flags & FLAGS_UPPER) ? 'E' : 'e')); - self->OutStream(self, (isExponentNegative) ? '-' : '+'); - - /* The exponent must contain at least two digits */ - if (requireTwoDigitExponent) - self->OutStream(self, '0'); - - if (isHex) - base = 10; - exponentBase = (int)TrioPower(base, exponentDigits - 1); - for (i = 0; i < exponentDigits; i++) - { - self->OutStream(self, digits[(uExponent / exponentBase) % base]); - exponentBase /= base; - } - } - /* Output trailing spaces */ - if (flags & FLAGS_LEFTADJUST) - { - for (i = expectedWidth; i < width; i++) - { - self->OutStream(self, CHAR_ADJUST); - } - } -} -#endif /* TRIO_FEATURE_FLOAT */ - -/************************************************************************* - * TrioFormatProcess - * - * Description: - * This is the main engine for formatting output - */ -TRIO_PRIVATE int -TrioFormatProcess -TRIO_ARGS3((data, format, parameters), - trio_class_t *data, - TRIO_CONST char *format, - trio_parameter_t *parameters) -{ - int i; -#if TRIO_FEATURE_ERRNO - TRIO_CONST char *string; -#endif - trio_pointer_t pointer; - trio_flags_t flags; - int width; - int precision; - int base; - int offset; - - offset = 0; - i = 0; - - for (;;) - { - /* Skip the parameter entries */ - while (parameters[i].type == FORMAT_PARAMETER) - i++; - - /* Copy non conversion-specifier part of format string */ - while (offset < parameters[i].beginOffset) - { - if (CHAR_IDENTIFIER == format[offset] && CHAR_IDENTIFIER == format[offset + 1]) - { - data->OutStream(data, CHAR_IDENTIFIER); - offset += 2; - } - else - { - data->OutStream(data, format[offset++]); - } - } - - /* Abort if we reached end of format string */ - if (parameters[i].type == FORMAT_SENTINEL) - break; - - /* Ouput parameter */ - flags = parameters[i].flags; - - /* Find width */ - width = parameters[i].width; - if (flags & FLAGS_WIDTH_PARAMETER) - { - /* Get width from parameter list */ - width = (int)parameters[width].data.number.as_signed; - if (width < 0) - { - /* - * A negative width is the same as the - flag and - * a positive width. - */ - flags |= FLAGS_LEFTADJUST; - flags &= ~FLAGS_NILPADDING; - width = -width; - } - } - - /* Find precision */ - if (flags & FLAGS_PRECISION) - { - precision = parameters[i].precision; - if (flags & FLAGS_PRECISION_PARAMETER) - { - /* Get precision from parameter list */ - precision = (int)parameters[precision].data.number.as_signed; - if (precision < 0) - { - /* - * A negative precision is the same as no - * precision - */ - precision = NO_PRECISION; - } - } - } - else - { - precision = NO_PRECISION; - } - - /* Find base */ - if (NO_BASE != parameters[i].baseSpecifier) - { - /* Base from specifier has priority */ - base = parameters[i].baseSpecifier; - } - else if (flags & FLAGS_BASE_PARAMETER) - { - /* Get base from parameter list */ - base = parameters[i].base; - base = (int)parameters[base].data.number.as_signed; - } - else - { - /* Use base from format string */ - base = parameters[i].base; - } - - switch (parameters[i].type) - { - case FORMAT_CHAR: -#if TRIO_FEATURE_QUOTE - if (flags & FLAGS_QUOTE) - data->OutStream(data, CHAR_QUOTE); -#endif - if (! (flags & FLAGS_LEFTADJUST)) - { - while (--width > 0) - data->OutStream(data, CHAR_ADJUST); - } -#if TRIO_FEATURE_WIDECHAR - if (flags & FLAGS_WIDECHAR) - { - TrioWriteWideStringCharacter(data, - (trio_wchar_t)parameters[i].data.number.as_signed, - flags, - NO_WIDTH); - } - else -#endif - { - TrioWriteStringCharacter(data, - (int)parameters[i].data.number.as_signed, - flags); - } - - if (flags & FLAGS_LEFTADJUST) - { - while(--width > 0) - data->OutStream(data, CHAR_ADJUST); - } -#if TRIO_FEATURE_QUOTE - if (flags & FLAGS_QUOTE) - data->OutStream(data, CHAR_QUOTE); -#endif - - break; /* FORMAT_CHAR */ - - case FORMAT_INT: - TrioWriteNumber(data, - parameters[i].data.number.as_unsigned, - flags, - width, - precision, - base); - - break; /* FORMAT_INT */ - -#if TRIO_FEATURE_FLOAT - case FORMAT_DOUBLE: - TrioWriteDouble(data, - parameters[i].data.longdoubleNumber, - flags, - width, - precision, - base); - break; /* FORMAT_DOUBLE */ -#endif - - case FORMAT_STRING: -#if TRIO_FEATURE_WIDECHAR - if (flags & FLAGS_WIDECHAR) - { - TrioWriteWideString(data, - parameters[i].data.wstring, - flags, - width, - precision); - } - else -#endif - { - TrioWriteString(data, - parameters[i].data.string, - flags, - width, - precision); - } - break; /* FORMAT_STRING */ - - case FORMAT_POINTER: - { - trio_reference_t reference; - - reference.data = data; - reference.parameter = ¶meters[i]; - trio_print_pointer(&reference, parameters[i].data.pointer); - } - break; /* FORMAT_POINTER */ - - case FORMAT_COUNT: - pointer = parameters[i].data.pointer; - if (NULL != pointer) - { - /* - * C99 paragraph 7.19.6.1.8 says "the number of - * characters written to the output stream so far by - * this call", which is data->actually.committed - */ -#if TRIO_FEATURE_SIZE_T || TRIO_FEATURE_SIZE_T_UPPER - if (flags & FLAGS_SIZE_T) - *(size_t *)pointer = (size_t)data->actually.committed; - else -#endif -#if TRIO_FEATURE_PTRDIFF_T - if (flags & FLAGS_PTRDIFF_T) - *(ptrdiff_t *)pointer = (ptrdiff_t)data->actually.committed; - else -#endif -#if TRIO_FEATURE_INTMAX_T - if (flags & FLAGS_INTMAX_T) - *(trio_intmax_t *)pointer = (trio_intmax_t)data->actually.committed; - else -#endif - if (flags & FLAGS_QUAD) - { - *(trio_ulonglong_t *)pointer = (trio_ulonglong_t)data->actually.committed; - } - else if (flags & FLAGS_LONG) - { - *(long int *)pointer = (long int)data->actually.committed; - } - else if (flags & FLAGS_SHORT) - { - *(short int *)pointer = (short int)data->actually.committed; - } - else - { - *(int *)pointer = (int)data->actually.committed; - } - } - break; /* FORMAT_COUNT */ - - case FORMAT_PARAMETER: - break; /* FORMAT_PARAMETER */ - -#if TRIO_FEATURE_ERRNO - case FORMAT_ERRNO: - string = trio_error(parameters[i].data.errorNumber); - if (string) - { - TrioWriteString(data, - string, - flags, - width, - precision); - } - else - { - data->OutStream(data, '#'); - TrioWriteNumber(data, - (trio_uintmax_t)parameters[i].data.errorNumber, - flags, - width, - precision, - BASE_DECIMAL); - } - break; /* FORMAT_ERRNO */ -#endif /* TRIO_FEATURE_ERRNO */ - -#if TRIO_FEATURE_USER_DEFINED - case FORMAT_USER_DEFINED: - { - trio_reference_t reference; - trio_userdef_t *def = NULL; - - if (parameters[i].flags & FLAGS_USER_DEFINED_PARAMETER) - { - /* Use handle */ - if ((i > 0) || - (parameters[i - 1].type == FORMAT_PARAMETER)) - def = (trio_userdef_t *)parameters[i - 1].data.pointer; - } - else - { - /* Look up namespace */ - def = TrioFindNamespace(parameters[i].user_defined.namespace, NULL); - } - if (def) - { - reference.data = data; - reference.parameter = ¶meters[i]; - def->callback(&reference); - } - } - break; -#endif /* TRIO_FEATURE_USER_DEFINED */ - - default: - break; - } /* switch parameter type */ - - /* Prepare for next */ - offset = parameters[i].endOffset; - i++; - } - - return data->processed; -} - -/************************************************************************* - * TrioFormatRef - */ -#if TRIO_EXTENSION -TRIO_PRIVATE int -TrioFormatRef -TRIO_ARGS4((reference, format, arglist, argarray), - trio_reference_t *reference, - TRIO_CONST char *format, - va_list arglist, - trio_pointer_t *argarray) -{ - int status; - trio_parameter_t parameters[MAX_PARAMETERS]; - - status = TrioParse(TYPE_PRINT, format, parameters, arglist, argarray); - if (status < 0) - return status; - - status = TrioFormatProcess(reference->data, format, parameters); - if (reference->data->error != 0) - { - status = reference->data->error; - } - return status; -} -#endif /* TRIO_EXTENSION */ - -/************************************************************************* - * TrioFormat - */ -TRIO_PRIVATE int -TrioFormat -TRIO_ARGS6((destination, destinationSize, OutStream, format, arglist, argarray), - trio_pointer_t destination, - size_t destinationSize, - void (*OutStream) TRIO_PROTO((trio_class_t *, int)), - TRIO_CONST char *format, - va_list arglist, - trio_pointer_t *argarray) -{ - int status; - trio_class_t data; - trio_parameter_t parameters[MAX_PARAMETERS]; - - assert(VALID(OutStream)); - assert(VALID(format)); - - memset(&data, 0, sizeof(data)); - data.OutStream = OutStream; - data.location = destination; - data.max = destinationSize; - data.error = 0; - -#if defined(USE_LOCALE) - if (NULL == internalLocaleValues) - { - TrioSetLocale(); - } -#endif - - status = TrioParse(TYPE_PRINT, format, parameters, arglist, argarray); - if (status < 0) - return status; - - status = TrioFormatProcess(&data, format, parameters); - if (data.error != 0) - { - status = data.error; - } - return status; -} - -/************************************************************************* - * TrioOutStreamFile - */ -#if TRIO_FEATURE_FILE || TRIO_FEATURE_STDIO -TRIO_PRIVATE void -TrioOutStreamFile -TRIO_ARGS2((self, output), - trio_class_t *self, - int output) -{ - FILE *file; - - assert(VALID(self)); - assert(VALID(self->location)); - - file = (FILE *)self->location; - self->processed++; - if (fputc(output, file) == EOF) - { - self->error = TRIO_ERROR_RETURN(TRIO_EOF, 0); - } - else - { - self->actually.committed++; - } -} -#endif /* TRIO_FEATURE_FILE || TRIO_FEATURE_STDIO */ - -/************************************************************************* - * TrioOutStreamFileDescriptor - */ -#if TRIO_FEATURE_FD -TRIO_PRIVATE void -TrioOutStreamFileDescriptor -TRIO_ARGS2((self, output), - trio_class_t *self, - int output) -{ - int fd; - char ch; - - assert(VALID(self)); - - fd = *((int *)self->location); - ch = (char)output; - self->processed++; - if (write(fd, &ch, sizeof(char)) == -1) - { - self->error = TRIO_ERROR_RETURN(TRIO_ERRNO, 0); - } - else - { - self->actually.committed++; - } -} -#endif /* TRIO_FEATURE_FD */ - -/************************************************************************* - * TrioOutStreamCustom - */ -#if TRIO_FEATURE_CLOSURE -TRIO_PRIVATE void -TrioOutStreamCustom -TRIO_ARGS2((self, output), - trio_class_t *self, - int output) -{ - int status; - trio_custom_t *data; - - assert(VALID(self)); - assert(VALID(self->location)); - - data = (trio_custom_t *)self->location; - if (data->stream.out) - { - status = (data->stream.out)(data->closure, output); - if (status >= 0) - { - self->actually.committed++; - } - else - { - if (self->error == 0) - { - self->error = TRIO_ERROR_RETURN(TRIO_ECUSTOM, -status); - } - } - } - self->processed++; -} -#endif /* TRIO_FEATURE_CLOSURE */ - -/************************************************************************* - * TrioOutStreamString - */ -TRIO_PRIVATE void -TrioOutStreamString -TRIO_ARGS2((self, output), - trio_class_t *self, - int output) -{ - char **buffer; - - assert(VALID(self)); - assert(VALID(self->location)); - - buffer = (char **)self->location; - **buffer = (char)output; - (*buffer)++; - self->processed++; - self->actually.committed++; -} - -/************************************************************************* - * TrioOutStreamStringMax - */ -TRIO_PRIVATE void -TrioOutStreamStringMax -TRIO_ARGS2((self, output), - trio_class_t *self, - int output) -{ - char **buffer; - - assert(VALID(self)); - assert(VALID(self->location)); - - buffer = (char **)self->location; - - if (self->processed < self->max) - { - **buffer = (char)output; - (*buffer)++; - self->actually.committed++; - } - self->processed++; -} - -/************************************************************************* - * TrioOutStreamStringDynamic - */ -#if TRIO_FEATURE_DYNAMICSTRING -TRIO_PRIVATE void -TrioOutStreamStringDynamic -TRIO_ARGS2((self, output), - trio_class_t *self, - int output) -{ - assert(VALID(self)); - assert(VALID(self->location)); - - if (self->error == 0) - { - trio_xstring_append_char((trio_string_t *)self->location, - (char)output); - self->actually.committed++; - } - /* The processed variable must always be increased */ - self->processed++; -} -#endif /* TRIO_FEATURE_DYNAMICSTRING */ - -/************************************************************************* - * - * Formatted printing functions - * - ************************************************************************/ - -#if defined(TRIO_DOCUMENTATION) -# include "doc/doc_printf.h" -#endif -/** @addtogroup Printf - @{ -*/ - -/************************************************************************* - * printf - */ - -/** - Print to standard output stream. - - @param format Formatting string. - @param ... Arguments. - @return Number of printed characters. - */ -#if TRIO_FEATURE_STDIO -TRIO_PUBLIC int -trio_printf -TRIO_VARGS2((format, va_alist), - TRIO_CONST char *format, - TRIO_VA_DECL) -{ - int status; - va_list args; - - assert(VALID(format)); - - TRIO_VA_START(args, format); - status = TrioFormat(stdout, 0, TrioOutStreamFile, format, args, NULL); - TRIO_VA_END(args); - return status; -} -#endif /* TRIO_FEATURE_STDIO */ - -/** - Print to standard output stream. - - @param format Formatting string. - @param args Arguments. - @return Number of printed characters. - */ -#if TRIO_FEATURE_STDIO -TRIO_PUBLIC int -trio_vprintf -TRIO_ARGS2((format, args), - TRIO_CONST char *format, - va_list args) -{ - assert(VALID(format)); - - return TrioFormat(stdout, 0, TrioOutStreamFile, format, args, NULL); -} -#endif /* TRIO_FEATURE_STDIO */ - -/** - Print to standard output stream. - - @param format Formatting string. - @param args Arguments. - @return Number of printed characters. - */ -#if TRIO_FEATURE_STDIO -TRIO_PUBLIC int -trio_printfv -TRIO_ARGS2((format, args), - TRIO_CONST char *format, - trio_pointer_t * args) -{ - static va_list unused; - - assert(VALID(format)); - - return TrioFormat(stdout, 0, TrioOutStreamFile, format, unused, args); -} -#endif /* TRIO_FEATURE_STDIO */ - -/************************************************************************* - * fprintf - */ - -/** - Print to file. - - @param file File pointer. - @param format Formatting string. - @param ... Arguments. - @return Number of printed characters. - */ -#if TRIO_FEATURE_FILE -TRIO_PUBLIC int -trio_fprintf -TRIO_VARGS3((file, format, va_alist), - FILE *file, - TRIO_CONST char *format, - TRIO_VA_DECL) -{ - int status; - va_list args; - - assert(VALID(file)); - assert(VALID(format)); - - TRIO_VA_START(args, format); - status = TrioFormat(file, 0, TrioOutStreamFile, format, args, NULL); - TRIO_VA_END(args); - return status; -} -#endif /* TRIO_FEATURE_FILE */ - -/** - Print to file. - - @param file File pointer. - @param format Formatting string. - @param args Arguments. - @return Number of printed characters. - */ -#if TRIO_FEATURE_FILE -TRIO_PUBLIC int -trio_vfprintf -TRIO_ARGS3((file, format, args), - FILE *file, - TRIO_CONST char *format, - va_list args) -{ - assert(VALID(file)); - assert(VALID(format)); - - return TrioFormat(file, 0, TrioOutStreamFile, format, args, NULL); -} -#endif /* TRIO_FEATURE_FILE */ - -/** - Print to file. - - @param file File pointer. - @param format Formatting string. - @param args Arguments. - @return Number of printed characters. - */ -#if TRIO_FEATURE_FILE -TRIO_PUBLIC int -trio_fprintfv -TRIO_ARGS3((file, format, args), - FILE *file, - TRIO_CONST char *format, - trio_pointer_t * args) -{ - static va_list unused; - - assert(VALID(file)); - assert(VALID(format)); - - return TrioFormat(file, 0, TrioOutStreamFile, format, unused, args); -} -#endif /* TRIO_FEATURE_FILE */ - -/************************************************************************* - * dprintf - */ - -/** - Print to file descriptor. - - @param fd File descriptor. - @param format Formatting string. - @param ... Arguments. - @return Number of printed characters. - */ -#if TRIO_FEATURE_FD -TRIO_PUBLIC int -trio_dprintf -TRIO_VARGS3((fd, format, va_alist), - int fd, - TRIO_CONST char *format, - TRIO_VA_DECL) -{ - int status; - va_list args; - - assert(VALID(format)); - - TRIO_VA_START(args, format); - status = TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, args, NULL); - TRIO_VA_END(args); - return status; -} -#endif /* TRIO_FEATURE_FD */ - -/** - Print to file descriptor. - - @param fd File descriptor. - @param format Formatting string. - @param args Arguments. - @return Number of printed characters. - */ -#if TRIO_FEATURE_FD -TRIO_PUBLIC int -trio_vdprintf -TRIO_ARGS3((fd, format, args), - int fd, - TRIO_CONST char *format, - va_list args) -{ - assert(VALID(format)); - - return TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, args, NULL); -} -#endif /* TRIO_FEATURE_FD */ - -/** - Print to file descriptor. - - @param fd File descriptor. - @param format Formatting string. - @param args Arguments. - @return Number of printed characters. - */ -#if TRIO_FEATURE_FD -TRIO_PUBLIC int -trio_dprintfv -TRIO_ARGS3((fd, format, args), - int fd, - TRIO_CONST char *format, - trio_pointer_t *args) -{ - static va_list unused; - - assert(VALID(format)); - - return TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, unused, args); -} -#endif /* TRIO_FEATURE_FD */ - -/************************************************************************* - * cprintf - */ -#if TRIO_FEATURE_CLOSURE -TRIO_PUBLIC int -trio_cprintf -TRIO_VARGS4((stream, closure, format, va_alist), - trio_outstream_t stream, - trio_pointer_t closure, - TRIO_CONST char *format, - TRIO_VA_DECL) -{ - int status; - va_list args; - trio_custom_t data; - - assert(VALID(stream)); - assert(VALID(format)); - - TRIO_VA_START(args, format); - data.stream.out = stream; - data.closure = closure; - status = TrioFormat(&data, 0, TrioOutStreamCustom, format, args, NULL); - TRIO_VA_END(args); - return status; -} -#endif /* TRIO_FEATURE_CLOSURE */ - -#if TRIO_FEATURE_CLOSURE -TRIO_PUBLIC int -trio_vcprintf -TRIO_ARGS4((stream, closure, format, args), - trio_outstream_t stream, - trio_pointer_t closure, - TRIO_CONST char *format, - va_list args) -{ - trio_custom_t data; - - assert(VALID(stream)); - assert(VALID(format)); - - data.stream.out = stream; - data.closure = closure; - return TrioFormat(&data, 0, TrioOutStreamCustom, format, args, NULL); -} -#endif /* TRIO_FEATURE_CLOSURE */ - -#if TRIO_FEATURE_CLOSURE -TRIO_PUBLIC int -trio_cprintfv -TRIO_ARGS4((stream, closure, format, args), - trio_outstream_t stream, - trio_pointer_t closure, - TRIO_CONST char *format, - void **args) -{ - static va_list unused; - trio_custom_t data; - - assert(VALID(stream)); - assert(VALID(format)); - - data.stream.out = stream; - data.closure = closure; - return TrioFormat(&data, 0, TrioOutStreamCustom, format, unused, args); -} -#endif /* TRIO_FEATURE_CLOSURE */ - -/************************************************************************* - * sprintf - */ - -/** - Print to string. - - @param buffer Output string. - @param format Formatting string. - @param ... Arguments. - @return Number of printed characters. - */ -TRIO_PUBLIC int -trio_sprintf -TRIO_VARGS3((buffer, format, va_alist), - char *buffer, - TRIO_CONST char *format, - TRIO_VA_DECL) -{ - int status; - va_list args; - - assert(VALID(buffer)); - assert(VALID(format)); - - TRIO_VA_START(args, format); - status = TrioFormat(&buffer, 0, TrioOutStreamString, format, args, NULL); - *buffer = NIL; /* Terminate with NIL character */ - TRIO_VA_END(args); - return status; -} - -/** - Print to string. - - @param buffer Output string. - @param format Formatting string. - @param args Arguments. - @return Number of printed characters. - */ -TRIO_PUBLIC int -trio_vsprintf -TRIO_ARGS3((buffer, format, args), - char *buffer, - TRIO_CONST char *format, - va_list args) -{ - int status; - - assert(VALID(buffer)); - assert(VALID(format)); - - status = TrioFormat(&buffer, 0, TrioOutStreamString, format, args, NULL); - *buffer = NIL; - return status; -} - -/** - Print to string. - - @param buffer Output string. - @param format Formatting string. - @param args Arguments. - @return Number of printed characters. - */ -TRIO_PUBLIC int -trio_sprintfv -TRIO_ARGS3((buffer, format, args), - char *buffer, - TRIO_CONST char *format, - trio_pointer_t *args) -{ - static va_list unused; - int status; - - assert(VALID(buffer)); - assert(VALID(format)); - - status = TrioFormat(&buffer, 0, TrioOutStreamString, format, unused, args); - *buffer = NIL; - return status; -} - -/************************************************************************* - * snprintf - */ - -/** - Print at most @p max characters to string. - - @param buffer Output string. - @param max Maximum number of characters to print. - @param format Formatting string. - @param ... Arguments. - @return Number of printed characters. - */ -TRIO_PUBLIC int -trio_snprintf -TRIO_VARGS4((buffer, max, format, va_alist), - char *buffer, - size_t max, - TRIO_CONST char *format, - TRIO_VA_DECL) -{ - int status; - va_list args; - - assert(VALID(buffer) || (max == 0)); - assert(VALID(format)); - - TRIO_VA_START(args, format); - status = TrioFormat(&buffer, max > 0 ? max - 1 : 0, - TrioOutStreamStringMax, format, args, NULL); - if (max > 0) - *buffer = NIL; - TRIO_VA_END(args); - return status; -} - -/** - Print at most @p max characters to string. - - @param buffer Output string. - @param max Maximum number of characters to print. - @param format Formatting string. - @param args Arguments. - @return Number of printed characters. - */ -TRIO_PUBLIC int -trio_vsnprintf -TRIO_ARGS4((buffer, max, format, args), - char *buffer, - size_t max, - TRIO_CONST char *format, - va_list args) -{ - int status; - - assert(VALID(buffer) || (max == 0)); - assert(VALID(format)); - - status = TrioFormat(&buffer, max > 0 ? max - 1 : 0, - TrioOutStreamStringMax, format, args, NULL); - if (max > 0) - *buffer = NIL; - return status; -} - -/** - Print at most @p max characters to string. - - @param buffer Output string. - @param max Maximum number of characters to print. - @param format Formatting string. - @param args Arguments. - @return Number of printed characters. - */ -TRIO_PUBLIC int -trio_snprintfv -TRIO_ARGS4((buffer, max, format, args), - char *buffer, - size_t max, - TRIO_CONST char *format, - trio_pointer_t *args) -{ - static va_list unused; - int status; - - assert(VALID(buffer) || (max == 0)); - assert(VALID(format)); - - status = TrioFormat(&buffer, max > 0 ? max - 1 : 0, - TrioOutStreamStringMax, format, unused, args); - if (max > 0) - *buffer = NIL; - return status; -} - -/************************************************************************* - * snprintfcat - * Appends the new string to the buffer string overwriting the '\0' - * character at the end of buffer. - */ -#if TRIO_EXTENSION -TRIO_PUBLIC int -trio_snprintfcat -TRIO_VARGS4((buffer, max, format, va_alist), - char *buffer, - size_t max, - TRIO_CONST char *format, - TRIO_VA_DECL) -{ - int status; - va_list args; - size_t buf_len; - - TRIO_VA_START(args, format); - - assert(VALID(buffer)); - assert(VALID(format)); - - buf_len = trio_length(buffer); - buffer = &buffer[buf_len]; - - status = TrioFormat(&buffer, max - 1 - buf_len, - TrioOutStreamStringMax, format, args, NULL); - TRIO_VA_END(args); - *buffer = NIL; - return status; -} -#endif - -#if TRIO_EXTENSION -TRIO_PUBLIC int -trio_vsnprintfcat -TRIO_ARGS4((buffer, max, format, args), - char *buffer, - size_t max, - TRIO_CONST char *format, - va_list args) -{ - int status; - size_t buf_len; - - assert(VALID(buffer)); - assert(VALID(format)); - - buf_len = trio_length(buffer); - buffer = &buffer[buf_len]; - status = TrioFormat(&buffer, max - 1 - buf_len, - TrioOutStreamStringMax, format, args, NULL); - *buffer = NIL; - return status; -} -#endif - -/************************************************************************* - * trio_aprintf - */ - -#if TRIO_DEPRECATED && TRIO_FEATURE_DYNAMICSTRING -TRIO_PUBLIC char * -trio_aprintf -TRIO_VARGS2((format, va_alist), - TRIO_CONST char *format, - TRIO_VA_DECL) -{ - va_list args; - trio_string_t *info; - char *result = NULL; - - assert(VALID(format)); - - info = trio_xstring_duplicate(""); - if (info) - { - TRIO_VA_START(args, format); - (void)TrioFormat(info, 0, TrioOutStreamStringDynamic, - format, args, NULL); - TRIO_VA_END(args); - - trio_string_terminate(info); - result = trio_string_extract(info); - trio_string_destroy(info); - } - return result; -} -#endif /* TRIO_DEPRECATED && TRIO_FEATURE_DYNAMICSTRING */ - -#if TRIO_DEPRECATED && TRIO_FEATURE_DYNAMICSTRING -TRIO_PUBLIC char * -trio_vaprintf -TRIO_ARGS2((format, args), - TRIO_CONST char *format, - va_list args) -{ - trio_string_t *info; - char *result = NULL; - - assert(VALID(format)); - - info = trio_xstring_duplicate(""); - if (info) - { - (void)TrioFormat(info, 0, TrioOutStreamStringDynamic, - format, args, NULL); - trio_string_terminate(info); - result = trio_string_extract(info); - trio_string_destroy(info); - } - return result; -} -#endif /* TRIO_DEPRECATED && TRIO_FEATURE_DYNAMICSTRING */ - -/** - Allocate and print to string. - The memory allocated and returned by @p result must be freed by the - calling application. - - @param result Output string. - @param format Formatting string. - @param ... Arguments. - @return Number of printed characters. - */ -#if TRIO_FEATURE_DYNAMICSTRING -TRIO_PUBLIC int -trio_asprintf -TRIO_VARGS3((result, format, va_alist), - char **result, - TRIO_CONST char *format, - TRIO_VA_DECL) -{ - va_list args; - int status; - trio_string_t *info; - - assert(VALID(format)); - - *result = NULL; - - info = trio_xstring_duplicate(""); - if (info == NULL) - { - status = TRIO_ERROR_RETURN(TRIO_ENOMEM, 0); - } - else - { - TRIO_VA_START(args, format); - status = TrioFormat(info, 0, TrioOutStreamStringDynamic, - format, args, NULL); - TRIO_VA_END(args); - if (status >= 0) - { - trio_string_terminate(info); - *result = trio_string_extract(info); - } - trio_string_destroy(info); - } - return status; -} -#endif /* TRIO_FEATURE_DYNAMICSTRING */ - -/** - Allocate and print to string. - The memory allocated and returned by @p result must be freed by the - calling application. - - @param result Output string. - @param format Formatting string. - @param args Arguments. - @return Number of printed characters. - */ -#if TRIO_FEATURE_DYNAMICSTRING -TRIO_PUBLIC int -trio_vasprintf -TRIO_ARGS3((result, format, args), - char **result, - TRIO_CONST char *format, - va_list args) -{ - int status; - trio_string_t *info; - - assert(VALID(format)); - - *result = NULL; - - info = trio_xstring_duplicate(""); - if (info == NULL) - { - status = TRIO_ERROR_RETURN(TRIO_ENOMEM, 0); - } - else - { - status = TrioFormat(info, 0, TrioOutStreamStringDynamic, - format, args, NULL); - if (status >= 0) - { - trio_string_terminate(info); - *result = trio_string_extract(info); - } - trio_string_destroy(info); - } - return status; -} -#endif /* TRIO_FEATURE_DYNAMICSTRING */ - -/** - Allocate and print to string. - The memory allocated and returned by @p result must be freed by the - calling application. - - @param result Output string. - @param format Formatting string. - @param args Arguments. - @return Number of printed characters. - */ -#if TRIO_FEATURE_DYNAMICSTRING -TRIO_PUBLIC int -trio_asprintfv -TRIO_ARGS3((result, format, args), - char **result, - TRIO_CONST char *format, - trio_pointer_t * args) -{ - static va_list unused; - int status; - trio_string_t *info; - - assert(VALID(format)); - - *result = NULL; - - info = trio_xstring_duplicate(""); - if (info == NULL) - { - status = TRIO_ERROR_RETURN(TRIO_ENOMEM, 0); - } - else - { - status = TrioFormat(info, 0, TrioOutStreamStringDynamic, - format, unused, args); - if (status >= 0) - { - trio_string_terminate(info); - *result = trio_string_extract(info); - } - trio_string_destroy(info); - } - return status; -} -#endif /* TRIO_FEATURE_DYNAMICSTRING */ - -/** @} End of Printf documentation module */ - -/************************************************************************* - * - * CALLBACK - * - ************************************************************************/ - -#if defined(TRIO_DOCUMENTATION) -# include "doc/doc_register.h" -#endif -/** - @addtogroup UserDefined - @{ -*/ - -#if TRIO_FEATURE_USER_DEFINED - -/************************************************************************* - * trio_register - */ - -/** - Register new user-defined specifier. - - @param callback - @param name - @return Handle. - */ -TRIO_PUBLIC trio_pointer_t -trio_register -TRIO_ARGS2((callback, name), - trio_callback_t callback, - TRIO_CONST char *name) -{ - trio_userdef_t *def; - trio_userdef_t *prev = NULL; - - if (callback == NULL) - return NULL; - - if (name) - { - /* Handle built-in namespaces */ - if (name[0] == ':') - { - if (trio_equal(name, ":enter")) - { - internalEnterCriticalRegion = callback; - } - else if (trio_equal(name, ":leave")) - { - internalLeaveCriticalRegion = callback; - } - return NULL; - } - - /* Bail out if namespace is too long */ - if (trio_length(name) >= MAX_USER_NAME) - return NULL; - - /* Bail out if namespace already is registered */ - def = TrioFindNamespace(name, &prev); - if (def) - return NULL; - } - - def = (trio_userdef_t *)TRIO_MALLOC(sizeof(trio_userdef_t)); - if (def) - { - if (internalEnterCriticalRegion) - (void)internalEnterCriticalRegion(NULL); - - if (name) - { - /* Link into internal list */ - if (prev == NULL) - internalUserDef = def; - else - prev->next = def; - } - /* Initialize */ - def->callback = callback; - def->name = (name == NULL) - ? NULL - : trio_duplicate(name); - def->next = NULL; - - if (internalLeaveCriticalRegion) - (void)internalLeaveCriticalRegion(NULL); - } - return (trio_pointer_t)def; -} - -/** - Unregister an existing user-defined specifier. - - @param handle - */ -void -trio_unregister -TRIO_ARGS1((handle), - trio_pointer_t handle) -{ - trio_userdef_t *self = (trio_userdef_t *)handle; - trio_userdef_t *def; - trio_userdef_t *prev = NULL; - - assert(VALID(self)); - - if (self->name) - { - def = TrioFindNamespace(self->name, &prev); - if (def) - { - if (internalEnterCriticalRegion) - (void)internalEnterCriticalRegion(NULL); - - if (prev == NULL) - internalUserDef = internalUserDef->next; - else - prev->next = def->next; - - if (internalLeaveCriticalRegion) - (void)internalLeaveCriticalRegion(NULL); - } - trio_destroy(self->name); - } - TRIO_FREE(self); -} - -/************************************************************************* - * trio_get_format [public] - */ -TRIO_CONST char * -trio_get_format -TRIO_ARGS1((ref), - trio_pointer_t ref) -{ -#if TRIO_FEATURE_USER_DEFINED - assert(((trio_reference_t *)ref)->parameter->type == FORMAT_USER_DEFINED); -#endif - - return (((trio_reference_t *)ref)->parameter->user_data); -} - -/************************************************************************* - * trio_get_argument [public] - */ -TRIO_CONST trio_pointer_t -trio_get_argument -TRIO_ARGS1((ref), - trio_pointer_t ref) -{ -#if TRIO_FEATURE_USER_DEFINED - assert(((trio_reference_t *)ref)->parameter->type == FORMAT_USER_DEFINED); -#endif - - return ((trio_reference_t *)ref)->parameter->data.pointer; -} - -/************************************************************************* - * trio_get_width / trio_set_width [public] - */ -int -trio_get_width -TRIO_ARGS1((ref), - trio_pointer_t ref) -{ - return ((trio_reference_t *)ref)->parameter->width; -} - -void -trio_set_width -TRIO_ARGS2((ref, width), - trio_pointer_t ref, - int width) -{ - ((trio_reference_t *)ref)->parameter->width = width; -} - -/************************************************************************* - * trio_get_precision / trio_set_precision [public] - */ -int -trio_get_precision -TRIO_ARGS1((ref), - trio_pointer_t ref) -{ - return (((trio_reference_t *)ref)->parameter->precision); -} - -void -trio_set_precision -TRIO_ARGS2((ref, precision), - trio_pointer_t ref, - int precision) -{ - ((trio_reference_t *)ref)->parameter->precision = precision; -} - -/************************************************************************* - * trio_get_base / trio_set_base [public] - */ -int -trio_get_base -TRIO_ARGS1((ref), - trio_pointer_t ref) -{ - return (((trio_reference_t *)ref)->parameter->base); -} - -void -trio_set_base -TRIO_ARGS2((ref, base), - trio_pointer_t ref, - int base) -{ - ((trio_reference_t *)ref)->parameter->base = base; -} - -/************************************************************************* - * trio_get_long / trio_set_long [public] - */ -int -trio_get_long -TRIO_ARGS1((ref), - trio_pointer_t ref) -{ - return (((trio_reference_t *)ref)->parameter->flags & FLAGS_LONG) - ? TRUE - : FALSE; -} - -void -trio_set_long -TRIO_ARGS2((ref, is_long), - trio_pointer_t ref, - int is_long) -{ - if (is_long) - ((trio_reference_t *)ref)->parameter->flags |= FLAGS_LONG; - else - ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_LONG; -} - -/************************************************************************* - * trio_get_longlong / trio_set_longlong [public] - */ -int -trio_get_longlong -TRIO_ARGS1((ref), - trio_pointer_t ref) -{ - return (((trio_reference_t *)ref)->parameter->flags & FLAGS_QUAD) - ? TRUE - : FALSE; -} - -void -trio_set_longlong -TRIO_ARGS2((ref, is_longlong), - trio_pointer_t ref, - int is_longlong) -{ - if (is_longlong) - ((trio_reference_t *)ref)->parameter->flags |= FLAGS_QUAD; - else - ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_QUAD; -} - -/************************************************************************* - * trio_get_longdouble / trio_set_longdouble [public] - */ -# if TRIO_FEATURE_FLOAT -int -trio_get_longdouble -TRIO_ARGS1((ref), - trio_pointer_t ref) -{ - return (((trio_reference_t *)ref)->parameter->flags & FLAGS_LONGDOUBLE) - ? TRUE - : FALSE; -} - -void -trio_set_longdouble -TRIO_ARGS2((ref, is_longdouble), - trio_pointer_t ref, - int is_longdouble) -{ - if (is_longdouble) - ((trio_reference_t *)ref)->parameter->flags |= FLAGS_LONGDOUBLE; - else - ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_LONGDOUBLE; -} -# endif /* TRIO_FEATURE_FLOAT */ - -/************************************************************************* - * trio_get_short / trio_set_short [public] - */ -int -trio_get_short -TRIO_ARGS1((ref), - trio_pointer_t ref) -{ - return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SHORT) - ? TRUE - : FALSE; -} - -void -trio_set_short -TRIO_ARGS2((ref, is_short), - trio_pointer_t ref, - int is_short) -{ - if (is_short) - ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SHORT; - else - ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SHORT; -} - -/************************************************************************* - * trio_get_shortshort / trio_set_shortshort [public] - */ -int -trio_get_shortshort -TRIO_ARGS1((ref), - trio_pointer_t ref) -{ - return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SHORTSHORT) - ? TRUE - : FALSE; -} - -void -trio_set_shortshort -TRIO_ARGS2((ref, is_shortshort), - trio_pointer_t ref, - int is_shortshort) -{ - if (is_shortshort) - ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SHORTSHORT; - else - ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SHORTSHORT; -} - -/************************************************************************* - * trio_get_alternative / trio_set_alternative [public] - */ -int -trio_get_alternative -TRIO_ARGS1((ref), - trio_pointer_t ref) -{ - return (((trio_reference_t *)ref)->parameter->flags & FLAGS_ALTERNATIVE) - ? TRUE - : FALSE; -} - -void -trio_set_alternative -TRIO_ARGS2((ref, is_alternative), - trio_pointer_t ref, - int is_alternative) -{ - if (is_alternative) - ((trio_reference_t *)ref)->parameter->flags |= FLAGS_ALTERNATIVE; - else - ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_ALTERNATIVE; -} - -/************************************************************************* - * trio_get_alignment / trio_set_alignment [public] - */ -int -trio_get_alignment -TRIO_ARGS1((ref), - trio_pointer_t ref) -{ - return (((trio_reference_t *)ref)->parameter->flags & FLAGS_LEFTADJUST) - ? TRUE - : FALSE; -} - -void -trio_set_alignment -TRIO_ARGS2((ref, is_leftaligned), - trio_pointer_t ref, - int is_leftaligned) -{ - if (is_leftaligned) - ((trio_reference_t *)ref)->parameter->flags |= FLAGS_LEFTADJUST; - else - ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_LEFTADJUST; -} - -/************************************************************************* - * trio_get_spacing /trio_set_spacing [public] - */ -int -trio_get_spacing -TRIO_ARGS1((ref), - trio_pointer_t ref) -{ - return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SPACE) - ? TRUE - : FALSE; -} - -void -trio_set_spacing -TRIO_ARGS2((ref, is_space), - trio_pointer_t ref, - int is_space) -{ - if (is_space) - ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SPACE; - else - ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SPACE; -} - -/************************************************************************* - * trio_get_sign / trio_set_sign [public] - */ -int -trio_get_sign -TRIO_ARGS1((ref), - trio_pointer_t ref) -{ - return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SHOWSIGN) - ? TRUE - : FALSE; -} - -void -trio_set_sign -TRIO_ARGS2((ref, is_sign), - trio_pointer_t ref, - int is_sign) -{ - if (is_sign) - ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SHOWSIGN; - else - ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SHOWSIGN; -} - -/************************************************************************* - * trio_get_padding / trio_set_padding [public] - */ -int -trio_get_padding -TRIO_ARGS1((ref), - trio_pointer_t ref) -{ - return (((trio_reference_t *)ref)->parameter->flags & FLAGS_NILPADDING) - ? TRUE - : FALSE; -} - -void -trio_set_padding -TRIO_ARGS2((ref, is_padding), - trio_pointer_t ref, - int is_padding) -{ - if (is_padding) - ((trio_reference_t *)ref)->parameter->flags |= FLAGS_NILPADDING; - else - ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_NILPADDING; -} - -/************************************************************************* - * trio_get_quote / trio_set_quote [public] - */ -# if TRIO_FEATURE_QUOTE -int -trio_get_quote -TRIO_ARGS1((ref), - trio_pointer_t ref) -{ - return (((trio_reference_t *)ref)->parameter->flags & FLAGS_QUOTE) - ? TRUE - : FALSE; -} - -void -trio_set_quote -TRIO_ARGS2((ref, is_quote), - trio_pointer_t ref, - int is_quote) -{ - if (is_quote) - ((trio_reference_t *)ref)->parameter->flags |= FLAGS_QUOTE; - else - ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_QUOTE; -} -#endif /* TRIO_FEATURE_QUOTE */ - -/************************************************************************* - * trio_get_upper / trio_set_upper [public] - */ -int -trio_get_upper -TRIO_ARGS1((ref), - trio_pointer_t ref) -{ - return (((trio_reference_t *)ref)->parameter->flags & FLAGS_UPPER) - ? TRUE - : FALSE; -} - -void -trio_set_upper -TRIO_ARGS2((ref, is_upper), - trio_pointer_t ref, - int is_upper) -{ - if (is_upper) - ((trio_reference_t *)ref)->parameter->flags |= FLAGS_UPPER; - else - ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_UPPER; -} - -/************************************************************************* - * trio_get_largest / trio_set_largest [public] - */ -#if TRIO_FEATURE_INTMAX_T -int -trio_get_largest -TRIO_ARGS1((ref), - trio_pointer_t ref) -{ - return (((trio_reference_t *)ref)->parameter->flags & FLAGS_INTMAX_T) - ? TRUE - : FALSE; -} - -void -trio_set_largest -TRIO_ARGS2((ref, is_largest), - trio_pointer_t ref, - int is_largest) -{ - if (is_largest) - ((trio_reference_t *)ref)->parameter->flags |= FLAGS_INTMAX_T; - else - ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_INTMAX_T; -} -#endif /* TRIO_FEATURE_INTMAX_T */ - -/************************************************************************* - * trio_get_ptrdiff / trio_set_ptrdiff [public] - */ -#if TRIO_FEATURE_PTRDIFF_T -int -trio_get_ptrdiff -TRIO_ARGS1((ref), - trio_pointer_t ref) -{ - return (((trio_reference_t *)ref)->parameter->flags & FLAGS_PTRDIFF_T) - ? TRUE - : FALSE; -} - -void -trio_set_ptrdiff -TRIO_ARGS2((ref, is_ptrdiff), - trio_pointer_t ref, - int is_ptrdiff) -{ - if (is_ptrdiff) - ((trio_reference_t *)ref)->parameter->flags |= FLAGS_PTRDIFF_T; - else - ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_PTRDIFF_T; -} -#endif /* TRIO_FEATURE_PTRDIFF_T */ - -/************************************************************************* - * trio_get_size / trio_set_size [public] - */ -#if TRIO_FEATURE_SIZE_T -int -trio_get_size -TRIO_ARGS1((ref), - trio_pointer_t ref) -{ - return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SIZE_T) - ? TRUE - : FALSE; -} - -void -trio_set_size -TRIO_ARGS2((ref, is_size), - trio_pointer_t ref, - int is_size) -{ - if (is_size) - ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SIZE_T; - else - ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SIZE_T; -} -#endif /* TRIO_FEATURE_SIZE_T */ - -/************************************************************************* - * trio_print_int [public] - */ -void -trio_print_int -TRIO_ARGS2((ref, number), - trio_pointer_t ref, - int number) -{ - trio_reference_t *self = (trio_reference_t *)ref; - - TrioWriteNumber(self->data, - (trio_uintmax_t)number, - self->parameter->flags, - self->parameter->width, - self->parameter->precision, - self->parameter->base); -} - -/************************************************************************* - * trio_print_uint [public] - */ -void -trio_print_uint -TRIO_ARGS2((ref, number), - trio_pointer_t ref, - unsigned int number) -{ - trio_reference_t *self = (trio_reference_t *)ref; - - TrioWriteNumber(self->data, - (trio_uintmax_t)number, - self->parameter->flags | FLAGS_UNSIGNED, - self->parameter->width, - self->parameter->precision, - self->parameter->base); -} - -/************************************************************************* - * trio_print_double [public] - */ -#if TRIO_FEATURE_FLOAT -void -trio_print_double -TRIO_ARGS2((ref, number), - trio_pointer_t ref, - double number) -{ - trio_reference_t *self = (trio_reference_t *)ref; - - TrioWriteDouble(self->data, - number, - self->parameter->flags, - self->parameter->width, - self->parameter->precision, - self->parameter->base); -} -#endif /* TRIO_FEATURE_FLOAT */ - -/************************************************************************* - * trio_print_string [public] - */ -void -trio_print_string -TRIO_ARGS2((ref, string), - trio_pointer_t ref, - TRIO_CONST char *string) -{ - trio_reference_t *self = (trio_reference_t *)ref; - - TrioWriteString(self->data, - string, - self->parameter->flags, - self->parameter->width, - self->parameter->precision); -} - -/************************************************************************* - * trio_print_ref [public] - */ -int -trio_print_ref -TRIO_VARGS3((ref, format, va_alist), - trio_pointer_t ref, - TRIO_CONST char *format, - TRIO_VA_DECL) -{ - int status; - va_list arglist; - - assert(VALID(format)); - - TRIO_VA_START(arglist, format); - status = TrioFormatRef((trio_reference_t *)ref, format, arglist, NULL); - TRIO_VA_END(arglist); - return status; -} - -/************************************************************************* - * trio_vprint_ref [public] - */ -int -trio_vprint_ref -TRIO_ARGS3((ref, format, arglist), - trio_pointer_t ref, - TRIO_CONST char *format, - va_list arglist) -{ - assert(VALID(format)); - - return TrioFormatRef((trio_reference_t *)ref, format, arglist, NULL); -} - -/************************************************************************* - * trio_printv_ref [public] - */ -int -trio_printv_ref -TRIO_ARGS3((ref, format, argarray), - trio_pointer_t ref, - TRIO_CONST char *format, - trio_pointer_t *argarray) -{ - static va_list unused; - - assert(VALID(format)); - - return TrioFormatRef((trio_reference_t *)ref, format, unused, argarray); -} - -#endif - -/************************************************************************* - * trio_print_pointer [public] - */ -void -trio_print_pointer -TRIO_ARGS2((ref, pointer), - trio_pointer_t ref, - trio_pointer_t pointer) -{ - trio_reference_t *self = (trio_reference_t *)ref; - trio_flags_t flags; - trio_uintmax_t number; - - if (NULL == pointer) - { - TRIO_CONST char *string = internalNullString; - while (*string) - self->data->OutStream(self->data, *string++); - } - else - { - /* - * The subtraction of the null pointer is a workaround - * to avoid a compiler warning. The performance overhead - * is negligible (and likely to be removed by an - * optimizing compiler). The (char *) casting is done - * to please ANSI C++. - */ - number = (trio_uintmax_t)((char *)pointer - (char *)0); - /* Shrink to size of pointer */ - number &= (trio_uintmax_t)-1; - flags = self->parameter->flags; - flags |= (FLAGS_UNSIGNED | FLAGS_ALTERNATIVE | - FLAGS_NILPADDING); - TrioWriteNumber(self->data, - number, - flags, - POINTER_WIDTH, - NO_PRECISION, - BASE_HEX); - } -} - -/** @} End of UserDefined documentation module */ - -/************************************************************************* - * - * LOCALES - * - ************************************************************************/ - -/************************************************************************* - * trio_locale_set_decimal_point - * - * Decimal point can only be one character. The input argument is a - * string to enable multibyte characters. At most MB_LEN_MAX characters - * will be used. - */ -#if TRIO_FEATURE_LOCALE -TRIO_PUBLIC void -trio_locale_set_decimal_point -TRIO_ARGS1((decimalPoint), - char *decimalPoint) -{ -#if defined(USE_LOCALE) - if (NULL == internalLocaleValues) - { - TrioSetLocale(); - } -#endif - internalDecimalPointLength = trio_length(decimalPoint); - if (internalDecimalPointLength == 1) - { - internalDecimalPoint = *decimalPoint; - } - else - { - internalDecimalPoint = NIL; - trio_copy_max(internalDecimalPointString, - sizeof(internalDecimalPointString), - decimalPoint); - } -} -#endif - -/************************************************************************* - * trio_locale_set_thousand_separator - * - * See trio_locale_set_decimal_point - */ -#if TRIO_FEATURE_LOCALE || TRIO_EXTENSION -TRIO_PUBLIC void -trio_locale_set_thousand_separator -TRIO_ARGS1((thousandSeparator), - char *thousandSeparator) -{ -# if defined(USE_LOCALE) - if (NULL == internalLocaleValues) - { - TrioSetLocale(); - } -# endif - trio_copy_max(internalThousandSeparator, - sizeof(internalThousandSeparator), - thousandSeparator); - internalThousandSeparatorLength = trio_length(internalThousandSeparator); -} -#endif - -/************************************************************************* - * trio_locale_set_grouping - * - * Array of bytes. Reversed order. - * - * CHAR_MAX : No further grouping - * 0 : Repeat last group for the remaining digits (not necessary - * as C strings are zero-terminated) - * n : Set current group to n - * - * Same order as the grouping attribute in LC_NUMERIC. - */ -#if TRIO_FEATURE_LOCALE || TRIO_EXTENSION -TRIO_PUBLIC void -trio_locale_set_grouping -TRIO_ARGS1((grouping), - char *grouping) -{ -# if defined(USE_LOCALE) - if (NULL == internalLocaleValues) - { - TrioSetLocale(); - } -# endif - trio_copy_max(internalGrouping, - sizeof(internalGrouping), - grouping); -} -#endif - - -/************************************************************************* - * - * SCANNING - * - ************************************************************************/ - -#if TRIO_FEATURE_SCANF - -/************************************************************************* - * TrioSkipWhitespaces - */ -TRIO_PRIVATE int -TrioSkipWhitespaces -TRIO_ARGS1((self), - trio_class_t *self) -{ - int ch; - - ch = self->current; - while (isspace(ch)) - { - self->InStream(self, &ch); - } - return ch; -} - -/************************************************************************* - * TrioGetCollation - */ -#if TRIO_EXTENSION -TRIO_PRIVATE void -TrioGetCollation(TRIO_NOARGS) -{ - int i; - int j; - int k; - char first[2]; - char second[2]; - - /* This is computationally expensive */ - first[1] = NIL; - second[1] = NIL; - for (i = 0; i < MAX_CHARACTER_CLASS; i++) - { - k = 0; - first[0] = (char)i; - for (j = 0; j < MAX_CHARACTER_CLASS; j++) - { - second[0] = (char)j; - if (trio_equal_locale(first, second)) - internalCollationArray[i][k++] = (char)j; - } - internalCollationArray[i][k] = NIL; - } -} -#endif - -/************************************************************************* - * TrioGetCharacterClass - * - * FIXME: - * multibyte - */ -TRIO_PRIVATE int -TrioGetCharacterClass -TRIO_ARGS4((format, offsetPointer, flagsPointer, characterclass), - TRIO_CONST char *format, - int *offsetPointer, - trio_flags_t *flagsPointer, - int *characterclass) -{ - int offset = *offsetPointer; - int i; - char ch; - char range_begin; - char range_end; - - *flagsPointer &= ~FLAGS_EXCLUDE; - - if (format[offset] == QUALIFIER_CIRCUMFLEX) - { - *flagsPointer |= FLAGS_EXCLUDE; - offset++; - } - /* - * If the ungroup character is at the beginning of the scanlist, - * it will be part of the class, and a second ungroup character - * must follow to end the group. - */ - if (format[offset] == SPECIFIER_UNGROUP) - { - characterclass[(int)SPECIFIER_UNGROUP]++; - offset++; - } - /* - * Minus is used to specify ranges. To include minus in the class, - * it must be at the beginning of the list - */ - if (format[offset] == QUALIFIER_MINUS) - { - characterclass[(int)QUALIFIER_MINUS]++; - offset++; - } - /* Collect characters */ - for (ch = format[offset]; - (ch != SPECIFIER_UNGROUP) && (ch != NIL); - ch = format[++offset]) - { - switch (ch) - { - case QUALIFIER_MINUS: /* Scanlist ranges */ - - /* - * Both C99 and UNIX98 describes ranges as implementation- - * defined. - * - * We support the following behaviour (although this may - * change as we become wiser) - * - only increasing ranges, ie. [a-b] but not [b-a] - * - transitive ranges, ie. [a-b-c] == [a-c] - * - trailing minus, ie. [a-] is interpreted as an 'a' - * and a '-' - * - duplicates (although we can easily convert these - * into errors) - */ - range_begin = format[offset - 1]; - range_end = format[++offset]; - if (range_end == SPECIFIER_UNGROUP) - { - /* Trailing minus is included */ - characterclass[(int)ch]++; - ch = range_end; - break; /* for */ - } - if (range_end == NIL) - return TRIO_ERROR_RETURN(TRIO_EINVAL, offset); - if (range_begin > range_end) - return TRIO_ERROR_RETURN(TRIO_ERANGE, offset); - - for (i = (int)range_begin; i <= (int)range_end; i++) - characterclass[i]++; - - ch = range_end; - break; - -#if TRIO_EXTENSION - - case SPECIFIER_GROUP: - - switch (format[offset + 1]) - { - case QUALIFIER_DOT: /* Collating symbol */ - /* - * FIXME: This will be easier to implement when multibyte - * characters have been implemented. Until now, we ignore - * this feature. - */ - for (i = offset + 2; ; i++) - { - if (format[i] == NIL) - /* Error in syntax */ - return -1; - else if (format[i] == QUALIFIER_DOT) - break; /* for */ - } - if (format[++i] != SPECIFIER_UNGROUP) - return -1; - - offset = i; - break; - - case QUALIFIER_EQUAL: /* Equivalence class expressions */ - { - unsigned int j; - unsigned int k; - - if (internalCollationUnconverted) - { - /* Lazy evaluation of collation array */ - TrioGetCollation(); - internalCollationUnconverted = FALSE; - } - for (i = offset + 2; ; i++) - { - if (format[i] == NIL) - /* Error in syntax */ - return -1; - else if (format[i] == QUALIFIER_EQUAL) - break; /* for */ - else - { - /* Mark any equivalent character */ - k = (unsigned int)format[i]; - for (j = 0; internalCollationArray[k][j] != NIL; j++) - characterclass[(int)internalCollationArray[k][j]]++; - } - } - if (format[++i] != SPECIFIER_UNGROUP) - return -1; - - offset = i; - } - break; - - case QUALIFIER_COLON: /* Character class expressions */ - - if (trio_equal_max(CLASS_ALNUM, sizeof(CLASS_ALNUM) - 1, - &format[offset])) - { - for (i = 0; i < MAX_CHARACTER_CLASS; i++) - if (isalnum(i)) - characterclass[i]++; - offset += sizeof(CLASS_ALNUM) - 1; - } - else if (trio_equal_max(CLASS_ALPHA, sizeof(CLASS_ALPHA) - 1, - &format[offset])) - { - for (i = 0; i < MAX_CHARACTER_CLASS; i++) - if (isalpha(i)) - characterclass[i]++; - offset += sizeof(CLASS_ALPHA) - 1; - } - else if (trio_equal_max(CLASS_CNTRL, sizeof(CLASS_CNTRL) - 1, - &format[offset])) - { - for (i = 0; i < MAX_CHARACTER_CLASS; i++) - if (iscntrl(i)) - characterclass[i]++; - offset += sizeof(CLASS_CNTRL) - 1; - } - else if (trio_equal_max(CLASS_DIGIT, sizeof(CLASS_DIGIT) - 1, - &format[offset])) - { - for (i = 0; i < MAX_CHARACTER_CLASS; i++) - if (isdigit(i)) - characterclass[i]++; - offset += sizeof(CLASS_DIGIT) - 1; - } - else if (trio_equal_max(CLASS_GRAPH, sizeof(CLASS_GRAPH) - 1, - &format[offset])) - { - for (i = 0; i < MAX_CHARACTER_CLASS; i++) - if (isgraph(i)) - characterclass[i]++; - offset += sizeof(CLASS_GRAPH) - 1; - } - else if (trio_equal_max(CLASS_LOWER, sizeof(CLASS_LOWER) - 1, - &format[offset])) - { - for (i = 0; i < MAX_CHARACTER_CLASS; i++) - if (islower(i)) - characterclass[i]++; - offset += sizeof(CLASS_LOWER) - 1; - } - else if (trio_equal_max(CLASS_PRINT, sizeof(CLASS_PRINT) - 1, - &format[offset])) - { - for (i = 0; i < MAX_CHARACTER_CLASS; i++) - if (isprint(i)) - characterclass[i]++; - offset += sizeof(CLASS_PRINT) - 1; - } - else if (trio_equal_max(CLASS_PUNCT, sizeof(CLASS_PUNCT) - 1, - &format[offset])) - { - for (i = 0; i < MAX_CHARACTER_CLASS; i++) - if (ispunct(i)) - characterclass[i]++; - offset += sizeof(CLASS_PUNCT) - 1; - } - else if (trio_equal_max(CLASS_SPACE, sizeof(CLASS_SPACE) - 1, - &format[offset])) - { - for (i = 0; i < MAX_CHARACTER_CLASS; i++) - if (isspace(i)) - characterclass[i]++; - offset += sizeof(CLASS_SPACE) - 1; - } - else if (trio_equal_max(CLASS_UPPER, sizeof(CLASS_UPPER) - 1, - &format[offset])) - { - for (i = 0; i < MAX_CHARACTER_CLASS; i++) - if (isupper(i)) - characterclass[i]++; - offset += sizeof(CLASS_UPPER) - 1; - } - else if (trio_equal_max(CLASS_XDIGIT, sizeof(CLASS_XDIGIT) - 1, - &format[offset])) - { - for (i = 0; i < MAX_CHARACTER_CLASS; i++) - if (isxdigit(i)) - characterclass[i]++; - offset += sizeof(CLASS_XDIGIT) - 1; - } - else - { - characterclass[(int)ch]++; - } - break; - - default: - characterclass[(int)ch]++; - break; - } - break; - -#endif /* TRIO_EXTENSION */ - - default: - characterclass[(int)ch]++; - break; - } - } - return 0; -} - -/************************************************************************* - * TrioReadNumber - * - * We implement our own number conversion in preference of strtol and - * strtoul, because we must handle 'long long' and thousand separators. - */ -TRIO_PRIVATE BOOLEAN_T -TrioReadNumber -TRIO_ARGS5((self, target, flags, width, base), - trio_class_t *self, - trio_uintmax_t *target, - trio_flags_t flags, - int width, - int base) -{ - trio_uintmax_t number = 0; - int digit; - int count; - BOOLEAN_T isNegative = FALSE; - BOOLEAN_T gotNumber = FALSE; - int j; - - assert(VALID(self)); - assert(VALID(self->InStream)); - assert((base >= MIN_BASE && base <= MAX_BASE) || (base == NO_BASE)); - - if (internalDigitsUnconverted) - { - /* Lazy evaluation of digits array */ - memset(internalDigitArray, -1, sizeof(internalDigitArray)); - for (j = 0; j < (int)sizeof(internalDigitsLower) - 1; j++) - { - internalDigitArray[(int)internalDigitsLower[j]] = j; - internalDigitArray[(int)internalDigitsUpper[j]] = j; - } - internalDigitsUnconverted = FALSE; - } - - TrioSkipWhitespaces(self); - - /* Leading sign */ - if (self->current == '+') - { - self->InStream(self, NULL); - } - else if (self->current == '-') - { - self->InStream(self, NULL); - isNegative = TRUE; - } - - count = self->processed; - - if (flags & FLAGS_ALTERNATIVE) - { - switch (base) - { - case NO_BASE: - case BASE_OCTAL: - case BASE_HEX: - case BASE_BINARY: - if (self->current == '0') - { - self->InStream(self, NULL); - if (self->current) - { - if ((base == BASE_HEX) && - (trio_to_upper(self->current) == 'X')) - { - self->InStream(self, NULL); - } - else if ((base == BASE_BINARY) && - (trio_to_upper(self->current) == 'B')) - { - self->InStream(self, NULL); - } - } - } - else - return FALSE; - break; - default: - break; - } - } - - while (((width == NO_WIDTH) || (self->processed - count < width)) && - (! ((self->current == EOF) || isspace(self->current)))) - { - if (isascii(self->current)) - { - digit = internalDigitArray[self->current]; - /* Abort if digit is not allowed in the specified base */ - if ((digit == -1) || (digit >= base)) - break; - } -#if TRIO_FEATURE_QUOTE - else if (flags & FLAGS_QUOTE) - { - /* Compare with thousands separator */ - for (j = 0; internalThousandSeparator[j] && self->current; j++) - { - if (internalThousandSeparator[j] != self->current) - break; - - self->InStream(self, NULL); - } - if (internalThousandSeparator[j]) - break; /* Mismatch */ - else - continue; /* Match */ - } -#endif - else - break; - - number *= base; - number += digit; - gotNumber = TRUE; /* we need at least one digit */ - - self->InStream(self, NULL); - } - - /* Was anything read at all? */ - if (!gotNumber) - return FALSE; - - if (target) - *target = (isNegative) ? (trio_uintmax_t)(-((trio_intmax_t)number)) : number; - return TRUE; -} - -/************************************************************************* - * TrioReadChar - */ -TRIO_PRIVATE int -TrioReadChar -TRIO_ARGS4((self, target, flags, width), - trio_class_t *self, - char *target, - trio_flags_t flags, - int width) -{ - int i; - char ch; - trio_uintmax_t number; - - assert(VALID(self)); - assert(VALID(self->InStream)); - - for (i = 0; - (self->current != EOF) && (i < width); - i++) - { - ch = (char)self->current; - self->InStream(self, NULL); - if ((flags & FLAGS_ALTERNATIVE) && (ch == CHAR_BACKSLASH)) - { - switch (self->current) - { - case '\\': ch = '\\'; break; - case 'a': ch = '\007'; break; - case 'b': ch = '\b'; break; - case 'f': ch = '\f'; break; - case 'n': ch = '\n'; break; - case 'r': ch = '\r'; break; - case 't': ch = '\t'; break; - case 'v': ch = '\v'; break; - default: - if (isdigit(self->current)) - { - /* Read octal number */ - if (!TrioReadNumber(self, &number, 0, 3, BASE_OCTAL)) - return 0; - ch = (char)number; - } - else if (trio_to_upper(self->current) == 'X') - { - /* Read hexadecimal number */ - self->InStream(self, NULL); - if (!TrioReadNumber(self, &number, 0, 2, BASE_HEX)) - return 0; - ch = (char)number; - } - else - { - ch = (char)self->current; - } - break; - } - } - - if (target) - target[i] = ch; - } - return i + 1; -} - -/************************************************************************* - * TrioReadString - */ -TRIO_PRIVATE BOOLEAN_T -TrioReadString -TRIO_ARGS4((self, target, flags, width), - trio_class_t *self, - char *target, - trio_flags_t flags, - int width) -{ - int i; - - assert(VALID(self)); - assert(VALID(self->InStream)); - - TrioSkipWhitespaces(self); - - /* - * Continue until end of string is reached, a whitespace is encountered, - * or width is exceeded - */ - for (i = 0; - ((width == NO_WIDTH) || (i < width)) && - (! ((self->current == EOF) || isspace(self->current))); - i++) - { - if (TrioReadChar(self, (target ? &target[i] : 0), flags, 1) == 0) - break; /* for */ - } - if (target) - target[i] = NIL; - return TRUE; -} - -/************************************************************************* - * TrioReadWideChar - */ -#if TRIO_FEATURE_WIDECHAR -TRIO_PRIVATE int -TrioReadWideChar -TRIO_ARGS4((self, target, flags, width), - trio_class_t *self, - trio_wchar_t *target, - trio_flags_t flags, - int width) -{ - int i; - int j; - int size; - int amount = 0; - trio_wchar_t wch; - char buffer[MB_LEN_MAX + 1]; - - assert(VALID(self)); - assert(VALID(self->InStream)); - - for (i = 0; - (self->current != EOF) && (i < width); - i++) - { - if (isascii(self->current)) - { - if (TrioReadChar(self, buffer, flags, 1) == 0) - return 0; - buffer[1] = NIL; - } - else - { - /* - * Collect a multibyte character, by enlarging buffer until - * it contains a fully legal multibyte character, or the - * buffer is full. - */ - j = 0; - do - { - buffer[j++] = (char)self->current; - buffer[j] = NIL; - self->InStream(self, NULL); - } - while ((j < (int)sizeof(buffer)) && (mblen(buffer, (size_t)j) != j)); - } - if (target) - { - size = mbtowc(&wch, buffer, sizeof(buffer)); - if (size > 0) - target[i] = wch; - } - amount += size; - self->InStream(self, NULL); - } - return amount; -} -#endif /* TRIO_FEATURE_WIDECHAR */ - -/************************************************************************* - * TrioReadWideString - */ -#if TRIO_FEATURE_WIDECHAR -TRIO_PRIVATE BOOLEAN_T -TrioReadWideString -TRIO_ARGS4((self, target, flags, width), - trio_class_t *self, - trio_wchar_t *target, - trio_flags_t flags, - int width) -{ - int i; - int size; - - assert(VALID(self)); - assert(VALID(self->InStream)); - - TrioSkipWhitespaces(self); - -#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE) - /* Required by TrioReadWideChar */ - (void)mblen(NULL, 0); -#endif - - /* - * Continue until end of string is reached, a whitespace is encountered, - * or width is exceeded - */ - for (i = 0; - ((width == NO_WIDTH) || (i < width)) && - (! ((self->current == EOF) || isspace(self->current))); - ) - { - size = TrioReadWideChar(self, &target[i], flags, 1); - if (size == 0) - break; /* for */ - - i += size; - } - if (target) - target[i] = WCONST('\0'); - return TRUE; -} -#endif /* TRIO_FEATURE_WIDECHAR */ - -/************************************************************************* - * TrioReadGroup - * - * Reads non-empty character groups. - * - * FIXME: characterclass does not work with multibyte characters - */ -TRIO_PRIVATE BOOLEAN_T -TrioReadGroup -TRIO_ARGS5((self, target, characterclass, flags, width), - trio_class_t *self, - char *target, - int *characterclass, - trio_flags_t flags, - int width) -{ - int ch; - int i; - - assert(VALID(self)); - assert(VALID(self->InStream)); - - ch = self->current; - for (i = 0; - ((width == NO_WIDTH) || (i < width)) && - (! ((ch == EOF) || - (((flags & FLAGS_EXCLUDE) != 0) ^ (characterclass[ch] == 0)))); - i++) - { - if (target) - target[i] = (char)ch; - self->InStream(self, &ch); - } - - if (i == 0) - return FALSE; - - /* Terminate the string if input saved */ - if (target) - target[i] = NIL; - return TRUE; -} - -/************************************************************************* - * TrioReadDouble - * - * FIXME: - * add long double - * handle base - */ -#if TRIO_FEATURE_FLOAT -TRIO_PRIVATE BOOLEAN_T -TrioReadDouble -TRIO_ARGS4((self, target, flags, width), - trio_class_t *self, - trio_pointer_t target, - trio_flags_t flags, - int width) -{ - int ch; - char doubleString[512]; - int offset = 0; - int start; -# if TRIO_FEATURE_QUOTE - int j; -# endif - BOOLEAN_T isHex = FALSE; - trio_long_double_t infinity; - - doubleString[0] = 0; - - if ((width == NO_WIDTH) || (width > (int)sizeof(doubleString) - 1)) - width = sizeof(doubleString) - 1; - - TrioSkipWhitespaces(self); - - /* - * Read entire double number from stream. trio_to_double requires - * a string as input, but InStream can be anything, so we have to - * collect all characters. - */ - ch = self->current; - if ((ch == '+') || (ch == '-')) - { - doubleString[offset++] = (char)ch; - self->InStream(self, &ch); - width--; - } - - start = offset; - switch (ch) - { - case 'n': - case 'N': - /* Not-a-number */ - if (offset != 0) - break; - /* FALLTHROUGH */ - case 'i': - case 'I': - /* Infinity */ - while (isalpha(ch) && (offset - start < width)) - { - doubleString[offset++] = (char)ch; - self->InStream(self, &ch); - } - doubleString[offset] = NIL; - - /* Case insensitive string comparison */ - if (trio_equal(&doubleString[start], INFINITE_UPPER) || - trio_equal(&doubleString[start], LONG_INFINITE_UPPER)) - { - infinity = ((start == 1) && (doubleString[0] == '-')) - ? trio_ninf() - : trio_pinf(); - if (flags & FLAGS_LONGDOUBLE) - { - *((trio_long_double_t *)target) = infinity; - } - else if (flags & FLAGS_LONG) - { - *((double *)target) = infinity; - } - else - { - *((float *)target) = infinity; - } - return TRUE; - } - if (trio_equal(doubleString, NAN_UPPER)) - { - /* NaN must not have a preceeding + nor - */ - if (flags & FLAGS_LONGDOUBLE) - { - *((trio_long_double_t *)target) = trio_nan(); - } - else if (flags & FLAGS_LONG) - { - *((double *)target) = trio_nan(); - } - else - { - *((float *)target) = trio_nan(); - } - return TRUE; - } - return FALSE; - - case '0': - doubleString[offset++] = (char)ch; - self->InStream(self, &ch); - if (trio_to_upper(ch) == 'X') - { - isHex = TRUE; - doubleString[offset++] = (char)ch; - self->InStream(self, &ch); - } - break; - - default: - break; - } - - while ((ch != EOF) && (offset - start < width)) - { - /* Integer part */ - if (isHex ? isxdigit(ch) : isdigit(ch)) - { - doubleString[offset++] = (char)ch; - self->InStream(self, &ch); - } -# if TRIO_FEATURE_QUOTE - else if (flags & FLAGS_QUOTE) - { - /* Compare with thousands separator */ - for (j = 0; internalThousandSeparator[j] && self->current; j++) - { - if (internalThousandSeparator[j] != self->current) - break; - - self->InStream(self, &ch); - } - if (internalThousandSeparator[j]) - break; /* Mismatch */ - else - continue; /* Match */ - } -# endif - else - break; /* while */ - } - if (ch == '.') - { - /* Decimal part */ - doubleString[offset++] = (char)ch; - self->InStream(self, &ch); - while ((isHex ? isxdigit(ch) : isdigit(ch)) && - (offset - start < width)) - { - doubleString[offset++] = (char)ch; - self->InStream(self, &ch); - } - } - if (isHex ? (trio_to_upper(ch) == 'P') : (trio_to_upper(ch) == 'E')) - { - /* Exponent */ - doubleString[offset++] = (char)ch; - self->InStream(self, &ch); - if ((ch == '+') || (ch == '-')) - { - doubleString[offset++] = (char)ch; - self->InStream(self, &ch); - } - while (isdigit(ch) && (offset - start < width)) - { - doubleString[offset++] = (char)ch; - self->InStream(self, &ch); - } - } - - if ((offset == start) || (*doubleString == NIL)) - return FALSE; - - doubleString[offset] = 0; - - if (flags & FLAGS_LONGDOUBLE) - { - *((trio_long_double_t *)target) = trio_to_long_double(doubleString, NULL); - } - else if (flags & FLAGS_LONG) - { - *((double *)target) = trio_to_double(doubleString, NULL); - } - else - { - *((float *)target) = trio_to_float(doubleString, NULL); - } - return TRUE; -} -#endif /* TRIO_FEATURE_FLOAT */ - -/************************************************************************* - * TrioReadPointer - */ -TRIO_PRIVATE BOOLEAN_T -TrioReadPointer -TRIO_ARGS3((self, target, flags), - trio_class_t *self, - trio_pointer_t *target, - trio_flags_t flags) -{ - trio_uintmax_t number; - char buffer[sizeof(internalNullString)]; - - flags |= (FLAGS_UNSIGNED | FLAGS_ALTERNATIVE | FLAGS_NILPADDING); - - if (TrioReadNumber(self, - &number, - flags, - POINTER_WIDTH, - BASE_HEX)) - { - if (target) - { -#if defined(TRIO_COMPILER_GCC) || defined(TRIO_COMPILER_MIPSPRO) - /* - * The strange assignment of number is a workaround for a compiler - * warning - */ - *target = &((char *)0)[number]; -#else - *target = (trio_pointer_t)number; -#endif - } - return TRUE; - } - else if (TrioReadString(self, - (flags & FLAGS_IGNORE) - ? NULL - : buffer, - 0, - sizeof(internalNullString) - 1)) - { - if (trio_equal_case(buffer, internalNullString)) - { - if (target) - *target = NULL; - return TRUE; - } - } - return FALSE; -} - -/************************************************************************* - * TrioScanProcess - */ -TRIO_PRIVATE int -TrioScanProcess -TRIO_ARGS3((data, format, parameters), - trio_class_t *data, - TRIO_CONST char *format, - trio_parameter_t *parameters) -{ - int status; - int assignment; - int ch; - int offset; /* Offset of format string */ - int i; /* Offset of current parameter */ - trio_flags_t flags; - int width; - int base; - trio_pointer_t pointer; - - /* Return on empty format string */ - if (format[0] == NIL) - return 0; - - status = 0; - assignment = 0; - i = 0; - offset = 0; - data->InStream(data, &ch); - - for (;;) - { - /* Skip the parameter entries */ - while (parameters[i].type == FORMAT_PARAMETER) - { - assert(i <= MAX_PARAMETERS); - i++; - } - - /* Compare non conversion-specifier part of format string */ - while (offset < parameters[i].beginOffset) - { - if ((CHAR_IDENTIFIER == format[offset]) && - (CHAR_IDENTIFIER == format[offset + 1])) - { - /* Two % in format matches one % in input stream */ - if (CHAR_IDENTIFIER == ch) - { - data->InStream(data, &ch); - offset += 2; - continue; /* while format chars left */ - } - else - { - status = TRIO_ERROR_RETURN(TRIO_EINVAL, offset); - goto end; - } - } - else /* Not an % identifier */ - { - if (isspace((int)format[offset])) - { - /* Whitespaces may match any amount of whitespaces */ - ch = TrioSkipWhitespaces(data); - } - else if (ch == format[offset]) - { - data->InStream(data, &ch); - } - else - { - status = assignment; - goto end; - } - - offset++; - } - } - - if (parameters[i].type == FORMAT_SENTINEL) - break; - - if ((EOF == ch) && (parameters[i].type != FORMAT_COUNT)) - { - status = (assignment > 0) ? assignment : EOF; - goto end; - } - - flags = parameters[i].flags; - - /* Find width */ - width = parameters[i].width; - if (flags & FLAGS_WIDTH_PARAMETER) - { - /* Get width from parameter list */ - width = (int)parameters[width].data.number.as_signed; - } - - /* Find base */ - if (NO_BASE != parameters[i].baseSpecifier) - { - /* Base from specifier has priority */ - base = parameters[i].baseSpecifier; - } - else if (flags & FLAGS_BASE_PARAMETER) - { - /* Get base from parameter list */ - base = parameters[i].base; - base = (int)parameters[base].data.number.as_signed; - } - else - { - /* Use base from format string */ - base = parameters[i].base; - } - - switch (parameters[i].type) - { - case FORMAT_INT: - { - trio_uintmax_t number; - - if (0 == base) - base = BASE_DECIMAL; - - if (!TrioReadNumber(data, - &number, - flags, - width, - base)) - { - status = assignment; - goto end; - } - - if (!(flags & FLAGS_IGNORE)) - { - assignment++; - - pointer = parameters[i].data.pointer; -#if TRIO_FEATURE_SIZE_T || TRIO_FEATURE_SIZE_T_UPPER - if (flags & FLAGS_SIZE_T) - *(size_t *)pointer = (size_t)number; - else -#endif -#if TRIO_FEATURE_PTRDIFF_T - if (flags & FLAGS_PTRDIFF_T) - *(ptrdiff_t *)pointer = (ptrdiff_t)number; - else -#endif -#if TRIO_FEATURE_INTMAX_T - if (flags & FLAGS_INTMAX_T) - *(trio_intmax_t *)pointer = (trio_intmax_t)number; - else -#endif - if (flags & FLAGS_QUAD) - *(trio_ulonglong_t *)pointer = (trio_ulonglong_t)number; - else if (flags & FLAGS_LONG) - *(long int *)pointer = (long int)number; - else if (flags & FLAGS_SHORT) - *(short int *)pointer = (short int)number; - else - *(int *)pointer = (int)number; - } - } - break; /* FORMAT_INT */ - - case FORMAT_STRING: -#if TRIO_FEATURE_WIDECHAR - if (flags & FLAGS_WIDECHAR) - { - if (!TrioReadWideString(data, - (flags & FLAGS_IGNORE) - ? NULL - : parameters[i].data.wstring, - flags, - width)) - { - status = assignment; - goto end; - } - } - else -#endif - { - if (!TrioReadString(data, - (flags & FLAGS_IGNORE) - ? NULL - : parameters[i].data.string, - flags, - width)) - { - status = assignment; - goto end; - } - } - if (!(flags & FLAGS_IGNORE)) - assignment++; - break; /* FORMAT_STRING */ - -#if TRIO_FEATURE_FLOAT - case FORMAT_DOUBLE: - { - if (flags & FLAGS_IGNORE) - { - pointer = NULL; - } - else - { - pointer = (flags & FLAGS_LONGDOUBLE) - ? (trio_pointer_t)parameters[i].data.longdoublePointer - : (trio_pointer_t)parameters[i].data.doublePointer; - } - if (!TrioReadDouble(data, pointer, flags, width)) - { - status = assignment; - goto end; - } - if (!(flags & FLAGS_IGNORE)) - { - assignment++; - } - break; /* FORMAT_DOUBLE */ - } -#endif - - case FORMAT_GROUP: - { - int characterclass[MAX_CHARACTER_CLASS + 1]; - - /* Skip over modifiers */ - while (format[offset] != SPECIFIER_GROUP) - { - offset++; - } - /* Skip over group specifier */ - offset++; - - memset(characterclass, 0, sizeof(characterclass)); - status = TrioGetCharacterClass(format, - &offset, - &flags, - characterclass); - if (status < 0) - goto end; - - if (!TrioReadGroup(data, - (flags & FLAGS_IGNORE) - ? NULL - : parameters[i].data.string, - characterclass, - flags, - parameters[i].width)) - { - status = assignment; - goto end; - } - if (!(flags & FLAGS_IGNORE)) - assignment++; - } - break; /* FORMAT_GROUP */ - - case FORMAT_COUNT: - pointer = parameters[i].data.pointer; - if (NULL != pointer) - { - int count = data->processed; - if (ch != EOF) - count--; /* a character is read, but is not consumed yet */ -#if TRIO_FEATURE_SIZE_T || TRIO_FEATURE_SIZE_T_UPPER - if (flags & FLAGS_SIZE_T) - *(size_t *)pointer = (size_t)count; - else -#endif -#if TRIO_FEATURE_PTRDIFF_T - if (flags & FLAGS_PTRDIFF_T) - *(ptrdiff_t *)pointer = (ptrdiff_t)count; - else -#endif -#if TRIO_FEATURE_INTMAX_T - if (flags & FLAGS_INTMAX_T) - *(trio_intmax_t *)pointer = (trio_intmax_t)count; - else -#endif - if (flags & FLAGS_QUAD) - { - *(trio_ulonglong_t *)pointer = (trio_ulonglong_t)count; - } - else if (flags & FLAGS_LONG) - { - *(long int *)pointer = (long int)count; - } - else if (flags & FLAGS_SHORT) - { - *(short int *)pointer = (short int)count; - } - else - { - *(int *)pointer = (int)count; - } - } - break; /* FORMAT_COUNT */ - - case FORMAT_CHAR: -#if TRIO_FEATURE_WIDECHAR - if (flags & FLAGS_WIDECHAR) - { - if (TrioReadWideChar(data, - (flags & FLAGS_IGNORE) - ? NULL - : parameters[i].data.wstring, - flags, - (width == NO_WIDTH) ? 1 : width) == 0) - { - status = assignment; - goto end; - } - } - else -#endif - { - if (TrioReadChar(data, - (flags & FLAGS_IGNORE) - ? NULL - : parameters[i].data.string, - flags, - (width == NO_WIDTH) ? 1 : width) == 0) - { - status = assignment; - goto end; - } - } - if (!(flags & FLAGS_IGNORE)) - assignment++; - break; /* FORMAT_CHAR */ - - case FORMAT_POINTER: - if (!TrioReadPointer(data, - (flags & FLAGS_IGNORE) - ? NULL - : (trio_pointer_t *)parameters[i].data.pointer, - flags)) - { - status = assignment; - goto end; - } - if (!(flags & FLAGS_IGNORE)) - assignment++; - break; /* FORMAT_POINTER */ - - case FORMAT_PARAMETER: - break; /* FORMAT_PARAMETER */ - - default: - status = TRIO_ERROR_RETURN(TRIO_EINVAL, offset); - goto end; - } - - ch = data->current; - offset = parameters[i].endOffset; - i++; - } - - status = assignment; - end: - if (data->UndoStream) - data->UndoStream(data); - return status; -} - -/************************************************************************* - * TrioScan - */ -TRIO_PRIVATE int -TrioScan -TRIO_ARGS7((source, sourceSize, InStream, UndoStream, format, arglist, argarray), - trio_pointer_t source, - size_t sourceSize, - void (*InStream) TRIO_PROTO((trio_class_t *, int *)), - void (*UndoStream) TRIO_PROTO((trio_class_t *)), - TRIO_CONST char *format, - va_list arglist, - trio_pointer_t *argarray) -{ - int status; - trio_parameter_t parameters[MAX_PARAMETERS]; - trio_class_t data; - - assert(VALID(InStream)); - assert(VALID(format)); - - memset(&data, 0, sizeof(data)); - data.InStream = InStream; - data.UndoStream = UndoStream; - data.location = (trio_pointer_t)source; - data.max = sourceSize; - data.error = 0; - -#if defined(USE_LOCALE) - if (NULL == internalLocaleValues) - { - TrioSetLocale(); - } -#endif - - status = TrioParse(TYPE_SCAN, format, parameters, arglist, argarray); - if (status < 0) - return status; - - status = TrioScanProcess(&data, format, parameters); - if (data.error != 0) - { - status = data.error; - } - return status; -} - -/************************************************************************* - * TrioInStreamFile - */ -#if TRIO_FEATURE_FILE || TRIO_FEATURE_STDIO -TRIO_PRIVATE void -TrioInStreamFile -TRIO_ARGS2((self, intPointer), - trio_class_t *self, - int *intPointer) -{ - FILE *file = (FILE *)self->location; - - assert(VALID(self)); - assert(VALID(file)); - - self->actually.cached = 0; - - /* The initial value of self->current is zero */ - if (self->current == EOF) - { - self->error = (ferror(file)) - ? TRIO_ERROR_RETURN(TRIO_ERRNO, 0) - : TRIO_ERROR_RETURN(TRIO_EOF, 0); - } - else - { - self->processed++; - self->actually.cached++; - } - - self->current = fgetc(file); - - if (VALID(intPointer)) - { - *intPointer = self->current; - } -} -#endif /* TRIO_FEATURE_FILE || TRIO_FEATURE_STDIO */ - -/************************************************************************* - * TrioUndoStreamFile - */ -#if TRIO_FEATURE_FILE || TRIO_FEATURE_STDIO -TRIO_PRIVATE void -TrioUndoStreamFile -TRIO_ARGS1((self), - trio_class_t *self) -{ - FILE *file = (FILE *)self->location; - - assert(VALID(self)); - assert(VALID(file)); - - if (self->actually.cached > 0) - { - assert(self->actually.cached == 1); - - self->current = ungetc(self->current, file); - self->actually.cached = 0; - } -} -#endif /* TRIO_FEATURE_FILE || TRIO_FEATURE_STDIO */ - -/************************************************************************* - * TrioInStreamFileDescriptor - */ -#if TRIO_FEATURE_FD -TRIO_PRIVATE void -TrioInStreamFileDescriptor -TRIO_ARGS2((self, intPointer), - trio_class_t *self, - int *intPointer) -{ - int fd = *((int *)self->location); - int size; - unsigned char input; - - assert(VALID(self)); - - self->actually.cached = 0; - - size = read(fd, &input, sizeof(char)); - if (size == -1) - { - self->error = TRIO_ERROR_RETURN(TRIO_ERRNO, 0); - self->current = EOF; - } - else - { - self->current = (size == 0) ? EOF : input; - } - if (self->current != EOF) - { - self->actually.cached++; - self->processed++; - } - - if (VALID(intPointer)) - { - *intPointer = self->current; - } -} -#endif /* TRIO_FEATURE_FD */ - -/************************************************************************* - * TrioInStreamCustom - */ -#if TRIO_FEATURE_CLOSURE -TRIO_PRIVATE void -TrioInStreamCustom -TRIO_ARGS2((self, intPointer), - trio_class_t *self, - int *intPointer) -{ - trio_custom_t *data; - - assert(VALID(self)); - assert(VALID(self->location)); - - self->actually.cached = 0; - - data = (trio_custom_t *)self->location; - - self->current = (data->stream.in == NULL) - ? NIL - : (data->stream.in)(data->closure); - - if (self->current == NIL) - { - self->current = EOF; - } - else - { - self->processed++; - self->actually.cached++; - } - - if (VALID(intPointer)) - { - *intPointer = self->current; - } -} -#endif /* TRIO_FEATURE_CLOSURE */ - -/************************************************************************* - * TrioInStreamString - */ -TRIO_PRIVATE void -TrioInStreamString -TRIO_ARGS2((self, intPointer), - trio_class_t *self, - int *intPointer) -{ - unsigned char **buffer; - - assert(VALID(self)); - assert(VALID(self->location)); - - self->actually.cached = 0; - - buffer = (unsigned char **)self->location; - self->current = (*buffer)[0]; - if (self->current == NIL) - { - self->current = EOF; - } - else - { - (*buffer)++; - self->processed++; - self->actually.cached++; - } - - if (VALID(intPointer)) - { - *intPointer = self->current; - } -} - -/************************************************************************* - * - * Formatted scanning functions - * - ************************************************************************/ - -#if defined(TRIO_DOCUMENTATION) -# include "doc/doc_scanf.h" -#endif -/** @addtogroup Scanf - @{ -*/ - -/************************************************************************* - * scanf - */ - -/** - Scan characters from standard input stream. - - @param format Formatting string. - @param ... Arguments. - @return Number of scanned characters. - */ -#if TRIO_FEATURE_STDIO -TRIO_PUBLIC int -trio_scanf -TRIO_VARGS2((format, va_alist), - TRIO_CONST char *format, - TRIO_VA_DECL) -{ - int status; - va_list args; - - assert(VALID(format)); - - TRIO_VA_START(args, format); - status = TrioScan((trio_pointer_t)stdin, 0, - TrioInStreamFile, - TrioUndoStreamFile, - format, args, NULL); - TRIO_VA_END(args); - return status; -} -#endif /* TRIO_FEATURE_STDIO */ - -/** - Scan characters from standard input stream. - - @param format Formatting string. - @param args Arguments. - @return Number of scanned characters. - */ -#if TRIO_FEATURE_STDIO -TRIO_PUBLIC int -trio_vscanf -TRIO_ARGS2((format, args), - TRIO_CONST char *format, - va_list args) -{ - assert(VALID(format)); - - return TrioScan((trio_pointer_t)stdin, 0, - TrioInStreamFile, - TrioUndoStreamFile, - format, args, NULL); -} -#endif /* TRIO_FEATURE_STDIO */ - -/** - Scan characters from standard input stream. - - @param format Formatting string. - @param args Arguments. - @return Number of scanned characters. - */ -#if TRIO_FEATURE_STDIO -TRIO_PUBLIC int -trio_scanfv -TRIO_ARGS2((format, args), - TRIO_CONST char *format, - trio_pointer_t *args) -{ - static va_list unused; - - assert(VALID(format)); - - return TrioScan((trio_pointer_t)stdin, 0, - TrioInStreamFile, - TrioUndoStreamFile, - format, unused, args); -} -#endif /* TRIO_FEATURE_STDIO */ - -/************************************************************************* - * fscanf - */ - -/** - Scan characters from file. - - @param file File pointer. - @param format Formatting string. - @param ... Arguments. - @return Number of scanned characters. - */ -#if TRIO_FEATURE_FILE -TRIO_PUBLIC int -trio_fscanf -TRIO_VARGS3((file, format, va_alist), - FILE *file, - TRIO_CONST char *format, - TRIO_VA_DECL) -{ - int status; - va_list args; - - assert(VALID(file)); - assert(VALID(format)); - - TRIO_VA_START(args, format); - status = TrioScan((trio_pointer_t)file, 0, - TrioInStreamFile, - TrioUndoStreamFile, - format, args, NULL); - TRIO_VA_END(args); - return status; -} -#endif /* TRIO_FEATURE_FILE */ - -/** - Scan characters from file. - - @param file File pointer. - @param format Formatting string. - @param args Arguments. - @return Number of scanned characters. - */ -#if TRIO_FEATURE_FILE -TRIO_PUBLIC int -trio_vfscanf -TRIO_ARGS3((file, format, args), - FILE *file, - TRIO_CONST char *format, - va_list args) -{ - assert(VALID(file)); - assert(VALID(format)); - - return TrioScan((trio_pointer_t)file, 0, - TrioInStreamFile, - TrioUndoStreamFile, - format, args, NULL); -} -#endif /* TRIO_FEATURE_FILE */ - -/** - Scan characters from file. - - @param file File pointer. - @param format Formatting string. - @param args Arguments. - @return Number of scanned characters. - */ -#if TRIO_FEATURE_FILE -TRIO_PUBLIC int -trio_fscanfv -TRIO_ARGS3((file, format, args), - FILE *file, - TRIO_CONST char *format, - trio_pointer_t *args) -{ - static va_list unused; - - assert(VALID(file)); - assert(VALID(format)); - - return TrioScan((trio_pointer_t)file, 0, - TrioInStreamFile, - TrioUndoStreamFile, - format, unused, args); -} -#endif /* TRIO_FEATURE_FILE */ - -/************************************************************************* - * dscanf - */ - -/** - Scan characters from file descriptor. - - @param fd File descriptor. - @param format Formatting string. - @param ... Arguments. - @return Number of scanned characters. - */ -#if TRIO_FEATURE_FD -TRIO_PUBLIC int -trio_dscanf -TRIO_VARGS3((fd, format, va_alist), - int fd, - TRIO_CONST char *format, - TRIO_VA_DECL) -{ - int status; - va_list args; - - assert(VALID(format)); - - TRIO_VA_START(args, format); - status = TrioScan((trio_pointer_t)&fd, 0, - TrioInStreamFileDescriptor, - NULL, - format, args, NULL); - TRIO_VA_END(args); - return status; -} -#endif /* TRIO_FEATURE_FD */ - -/** - Scan characters from file descriptor. - - @param fd File descriptor. - @param format Formatting string. - @param args Arguments. - @return Number of scanned characters. - */ -#if TRIO_FEATURE_FD -TRIO_PUBLIC int -trio_vdscanf -TRIO_ARGS3((fd, format, args), - int fd, - TRIO_CONST char *format, - va_list args) -{ - assert(VALID(format)); - - return TrioScan((trio_pointer_t)&fd, 0, - TrioInStreamFileDescriptor, - NULL, - format, args, NULL); -} -#endif /* TRIO_FEATURE_FD */ - -/** - Scan characters from file descriptor. - - @param fd File descriptor. - @param format Formatting string. - @param args Arguments. - @return Number of scanned characters. - */ -#if TRIO_FEATURE_FD -TRIO_PUBLIC int -trio_dscanfv -TRIO_ARGS3((fd, format, args), - int fd, - TRIO_CONST char *format, - trio_pointer_t *args) -{ - static va_list unused; - - assert(VALID(format)); - - return TrioScan((trio_pointer_t)&fd, 0, - TrioInStreamFileDescriptor, - NULL, - format, unused, args); -} -#endif /* TRIO_FEATURE_FD */ - -/************************************************************************* - * cscanf - */ -#if TRIO_FEATURE_CLOSURE -TRIO_PUBLIC int -trio_cscanf -TRIO_VARGS4((stream, closure, format, va_alist), - trio_instream_t stream, - trio_pointer_t closure, - TRIO_CONST char *format, - TRIO_VA_DECL) -{ - int status; - va_list args; - trio_custom_t data; - - assert(VALID(stream)); - assert(VALID(format)); - - TRIO_VA_START(args, format); - data.stream.in = stream; - data.closure = closure; - status = TrioScan(&data, 0, TrioInStreamCustom, NULL, format, args, NULL); - TRIO_VA_END(args); - return status; -} -#endif /* TRIO_FEATURE_CLOSURE */ - -#if TRIO_FEATURE_CLOSURE -TRIO_PUBLIC int -trio_vcscanf -TRIO_ARGS4((stream, closure, format, args), - trio_instream_t stream, - trio_pointer_t closure, - TRIO_CONST char *format, - va_list args) -{ - trio_custom_t data; - - assert(VALID(stream)); - assert(VALID(format)); - - data.stream.in = stream; - data.closure = closure; - return TrioScan(&data, 0, TrioInStreamCustom, NULL, format, args, NULL); -} -#endif /* TRIO_FEATURE_CLOSURE */ - -#if TRIO_FEATURE_CLOSURE -TRIO_PUBLIC int -trio_cscanfv -TRIO_ARGS4((stream, closure, format, args), - trio_instream_t stream, - trio_pointer_t closure, - TRIO_CONST char *format, - trio_pointer_t *args) -{ - static va_list unused; - trio_custom_t data; - - assert(VALID(stream)); - assert(VALID(format)); - - data.stream.in = stream; - data.closure = closure; - return TrioScan(&data, 0, TrioInStreamCustom, NULL, format, unused, args); -} -#endif /* TRIO_FEATURE_CLOSURE */ - -/************************************************************************* - * sscanf - */ - -/** - Scan characters from string. - - @param buffer Input string. - @param format Formatting string. - @param ... Arguments. - @return Number of scanned characters. - */ -TRIO_PUBLIC int -trio_sscanf -TRIO_VARGS3((buffer, format, va_alist), - TRIO_CONST char *buffer, - TRIO_CONST char *format, - TRIO_VA_DECL) -{ - int status; - va_list args; - - assert(VALID(buffer)); - assert(VALID(format)); - - TRIO_VA_START(args, format); - status = TrioScan((trio_pointer_t)&buffer, 0, - TrioInStreamString, - NULL, - format, args, NULL); - TRIO_VA_END(args); - return status; -} - -/** - Scan characters from string. - - @param buffer Input string. - @param format Formatting string. - @param args Arguments. - @return Number of scanned characters. - */ -TRIO_PUBLIC int -trio_vsscanf -TRIO_ARGS3((buffer, format, args), - TRIO_CONST char *buffer, - TRIO_CONST char *format, - va_list args) -{ - assert(VALID(buffer)); - assert(VALID(format)); - - return TrioScan((trio_pointer_t)&buffer, 0, - TrioInStreamString, - NULL, - format, args, NULL); -} - -/** - Scan characters from string. - - @param buffer Input string. - @param format Formatting string. - @param args Arguments. - @return Number of scanned characters. - */ -TRIO_PUBLIC int -trio_sscanfv -TRIO_ARGS3((buffer, format, args), - TRIO_CONST char *buffer, - TRIO_CONST char *format, - trio_pointer_t *args) -{ - static va_list unused; - - assert(VALID(buffer)); - assert(VALID(format)); - - return TrioScan((trio_pointer_t)&buffer, 0, - TrioInStreamString, - NULL, - format, unused, args); -} - -#endif /* TRIO_FEATURE_SCANF */ - -/** @} End of Scanf documentation module */ - -/************************************************************************* - * trio_strerror - */ -TRIO_PUBLIC TRIO_CONST char * -trio_strerror -TRIO_ARGS1((errorcode), - int errorcode) -{ -#if TRIO_FEATURE_STRERR - /* Textual versions of the error codes */ - switch (TRIO_ERROR_CODE(errorcode)) - { - case TRIO_EOF: - return "End of file"; - case TRIO_EINVAL: - return "Invalid argument"; - case TRIO_ETOOMANY: - return "Too many arguments"; - case TRIO_EDBLREF: - return "Double reference"; - case TRIO_EGAP: - return "Reference gap"; - case TRIO_ENOMEM: - return "Out of memory"; - case TRIO_ERANGE: - return "Invalid range"; - case TRIO_ECUSTOM: - return "Custom error"; - default: - return "Unknown"; - } -#else - return "Unknown"; -#endif -} - -/* BEEBS heap is just an array */ - -#include - -#define HEAP_SIZE 8192 -static char heap[HEAP_SIZE]; -static void *heap_ptr; -static void *heap_end; - -/* Initialize the BEEBS heap pointers */ - -void -init_heap (void) -{ - heap_ptr = (void *) heap; - heap_end = heap_ptr + HEAP_SIZE; -} - -/* BEEBS version of malloc. - - This is primarily to reduce library and OS dependencies. Malloc is - generally not used in embedded code, or if it is, only in well defined - contexts to pre-allocate a fixed amount of memory. So this simplistic - implementation is just fine. */ - -void * -malloc_beebs (size_t size) -{ - void *new_ptr = heap_ptr; - - if (((heap_ptr + size) > heap_end) || (0 == size)) - return NULL; - else - { - heap_ptr += size; - return new_ptr; - } -} - -/* BEEBS version of realloc. - - This is primarily to reduce library and OS dependencies. We just have to - allocate new memory and copy stuff across. */ - -void * -realloc_beebs (void *ptr, size_t size) -{ - void *new_ptr = heap_ptr; - - if (((heap_ptr + size) > heap_end) || (0 == size)) - return NULL; - else - { - heap_ptr += size; - - /* This is clunky, since we don't know the size of the original - pointer. However it is a read only action and we know it must - be big enough if we right off the end, or we couldn't have - allocated here. If the size is smaller, it doesn't matter. */ - - if (NULL != ptr) - { - int i; - - for (i = 0; i < size; i++) - ((char *) new_ptr)[i] = ((char *)ptr)[i]; - } - - return new_ptr; - } -} - -/* BEEBS version of free. - - For our simplified version of memory handling, free can just do nothing. */ - -void -free_beebs (void *ptr) -{ -} diff --git a/src/trio/trio.h b/src/trio/trio.h deleted file mode 100644 index 345b6056..00000000 --- a/src/trio/trio.h +++ /dev/null @@ -1,259 +0,0 @@ -/* BEEBS trio benchmark - - Copyright (C) 2014 Embecosm Limited and University of Bristol - - This file is part of the Bristol/Embecosm Embedded Benchmark Suite. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* The original source of this file was from: - * http://daniel.haxx.se/projects/trio/ - * and is covered by the following copyright and licence: - * - * Copyright (C) 1998 Bjorn Reese and Daniel Stenberg. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND - * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. - * - ************************************************************************* - * - * http://ctrio.sourceforge.net/ - * - ************************************************************************/ - -#ifndef TRIO_TRIO_H -#define TRIO_TRIO_H - -#if !defined(WITHOUT_TRIO) - -/* - * Use autoconf defines if present. Packages using trio must define - * HAVE_CONFIG_H as a compiler option themselves. - */ -#if defined(HAVE_CONFIG_H) -# include -#endif - -#include "triop.h" - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Error codes. - * - * Remember to add a textual description to trio_strerror. - */ -enum { - TRIO_EOF = 1, - TRIO_EINVAL = 2, - TRIO_ETOOMANY = 3, - TRIO_EDBLREF = 4, - TRIO_EGAP = 5, - TRIO_ENOMEM = 6, - TRIO_ERANGE = 7, - TRIO_ERRNO = 8, - TRIO_ECUSTOM = 9 -}; - -/* Error macros */ -#define TRIO_ERROR_CODE(x) ((-(x)) & 0x00FF) -#define TRIO_ERROR_POSITION(x) ((-(x)) >> 8) -#define TRIO_ERROR_NAME(x) trio_strerror(x) - -typedef int (*trio_outstream_t) TRIO_PROTO((trio_pointer_t, int)); -typedef int (*trio_instream_t) TRIO_PROTO((trio_pointer_t)); - -TRIO_CONST char *trio_strerror TRIO_PROTO((int)); - -/************************************************************************* - * Print Functions - */ - -int trio_printf TRIO_PROTO((TRIO_CONST char *format, ...)); -int trio_vprintf TRIO_PROTO((TRIO_CONST char *format, va_list args)); -int trio_printfv TRIO_PROTO((TRIO_CONST char *format, void **args)); - -int trio_fprintf TRIO_PROTO((FILE *file, TRIO_CONST char *format, ...)); -int trio_vfprintf TRIO_PROTO((FILE *file, TRIO_CONST char *format, va_list args)); -int trio_fprintfv TRIO_PROTO((FILE *file, TRIO_CONST char *format, void **args)); - -int trio_dprintf TRIO_PROTO((int fd, TRIO_CONST char *format, ...)); -int trio_vdprintf TRIO_PROTO((int fd, TRIO_CONST char *format, va_list args)); -int trio_dprintfv TRIO_PROTO((int fd, TRIO_CONST char *format, void **args)); - -int trio_cprintf TRIO_PROTO((trio_outstream_t stream, trio_pointer_t closure, - TRIO_CONST char *format, ...)); -int trio_vcprintf TRIO_PROTO((trio_outstream_t stream, trio_pointer_t closure, - TRIO_CONST char *format, va_list args)); -int trio_cprintfv TRIO_PROTO((trio_outstream_t stream, trio_pointer_t closure, - TRIO_CONST char *format, void **args)); - -int trio_sprintf TRIO_PROTO((char *buffer, TRIO_CONST char *format, ...)); -int trio_vsprintf TRIO_PROTO((char *buffer, TRIO_CONST char *format, va_list args)); -int trio_sprintfv TRIO_PROTO((char *buffer, TRIO_CONST char *format, void **args)); - -int trio_snprintf TRIO_PROTO((char *buffer, size_t max, TRIO_CONST char *format, ...)); -int trio_vsnprintf TRIO_PROTO((char *buffer, size_t bufferSize, TRIO_CONST char *format, - va_list args)); -int trio_snprintfv TRIO_PROTO((char *buffer, size_t bufferSize, TRIO_CONST char *format, - void **args)); - -int trio_snprintfcat TRIO_PROTO((char *buffer, size_t max, TRIO_CONST char *format, ...)); -int trio_vsnprintfcat TRIO_PROTO((char *buffer, size_t bufferSize, TRIO_CONST char *format, - va_list args)); - -#if defined(TRIO_DEPRECATED) -char *trio_aprintf TRIO_PROTO((TRIO_CONST char *format, ...)); -char *trio_vaprintf TRIO_PROTO((TRIO_CONST char *format, va_list args)); -#endif - -int trio_asprintf TRIO_PROTO((char **ret, TRIO_CONST char *format, ...)); -int trio_vasprintf TRIO_PROTO((char **ret, TRIO_CONST char *format, va_list args)); -int trio_asprintfv TRIO_PROTO((char **result, TRIO_CONST char *format, trio_pointer_t * args)); - -/************************************************************************* - * Scan Functions - */ -int trio_scanf TRIO_PROTO((TRIO_CONST char *format, ...)); -int trio_vscanf TRIO_PROTO((TRIO_CONST char *format, va_list args)); -int trio_scanfv TRIO_PROTO((TRIO_CONST char *format, void **args)); - -int trio_fscanf TRIO_PROTO((FILE *file, TRIO_CONST char *format, ...)); -int trio_vfscanf TRIO_PROTO((FILE *file, TRIO_CONST char *format, va_list args)); -int trio_fscanfv TRIO_PROTO((FILE *file, TRIO_CONST char *format, void **args)); - -int trio_dscanf TRIO_PROTO((int fd, TRIO_CONST char *format, ...)); -int trio_vdscanf TRIO_PROTO((int fd, TRIO_CONST char *format, va_list args)); -int trio_dscanfv TRIO_PROTO((int fd, TRIO_CONST char *format, void **args)); - -int trio_cscanf TRIO_PROTO((trio_instream_t stream, trio_pointer_t closure, - TRIO_CONST char *format, ...)); -int trio_vcscanf TRIO_PROTO((trio_instream_t stream, trio_pointer_t closure, - TRIO_CONST char *format, va_list args)); -int trio_cscanfv TRIO_PROTO((trio_instream_t stream, trio_pointer_t closure, - TRIO_CONST char *format, void **args)); - -int trio_sscanf TRIO_PROTO((TRIO_CONST char *buffer, TRIO_CONST char *format, ...)); -int trio_vsscanf TRIO_PROTO((TRIO_CONST char *buffer, TRIO_CONST char *format, va_list args)); -int trio_sscanfv TRIO_PROTO((TRIO_CONST char *buffer, TRIO_CONST char *format, void **args)); - -/************************************************************************* - * Locale Functions - */ -void trio_locale_set_decimal_point TRIO_PROTO((char *decimalPoint)); -void trio_locale_set_thousand_separator TRIO_PROTO((char *thousandSeparator)); -void trio_locale_set_grouping TRIO_PROTO((char *grouping)); - -/************************************************************************* - * Renaming - */ -#ifdef TRIO_REPLACE_STDIO -/* Replace the functions */ -#ifndef HAVE_PRINTF -# undef printf -# define printf trio_printf -#endif -#ifndef HAVE_VPRINTF -# undef vprintf -# define vprintf trio_vprintf -#endif -#ifndef HAVE_FPRINTF -# undef fprintf -# define fprintf trio_fprintf -#endif -#ifndef HAVE_VFPRINTF -# undef vfprintf -# define vfprintf trio_vfprintf -#endif -#ifndef HAVE_SPRINTF -# undef sprintf -# define sprintf trio_sprintf -#endif -#ifndef HAVE_VSPRINTF -# undef vsprintf -# define vsprintf trio_vsprintf -#endif -#ifndef HAVE_SNPRINTF -# undef snprintf -# define snprintf trio_snprintf -#endif -#ifndef HAVE_VSNPRINTF -# undef vsnprintf -# define vsnprintf trio_vsnprintf -#endif -#ifndef HAVE_SCANF -# undef scanf -# define scanf trio_scanf -#endif -#ifndef HAVE_VSCANF -# undef vscanf -# define vscanf trio_vscanf -#endif -#ifndef HAVE_FSCANF -# undef fscanf -# define fscanf trio_fscanf -#endif -#ifndef HAVE_VFSCANF -# undef vfscanf -# define vfscanf trio_vfscanf -#endif -#ifndef HAVE_SSCANF -# undef sscanf -# define sscanf trio_sscanf -#endif -#ifndef HAVE_VSSCANF -# undef vsscanf -# define vsscanf trio_vsscanf -#endif -/* These aren't stdio functions, but we make them look similar */ -#undef dprintf -#define dprintf trio_dprintf -#undef vdprintf -#define vdprintf trio_vdprintf -#undef aprintf -#define aprintf trio_aprintf -#undef vaprintf -#define vaprintf trio_vaprintf -#undef asprintf -#define asprintf trio_asprintf -#undef vasprintf -#define vasprintf trio_vasprintf -#undef dscanf -#define dscanf trio_dscanf -#undef vdscanf -#define vdscanf trio_vdscanf -#endif - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* WITHOUT_TRIO */ - -void init_heap (void); -void *malloc_beebs (size_t size); -void *realloc_beebs (void *ptr, size_t size); -void free_beebs (void *ptr); - -#endif /* TRIO_TRIO_H */ diff --git a/src/trio/trio_test.c b/src/trio/trio_test.c deleted file mode 100644 index 4f5582b5..00000000 --- a/src/trio/trio_test.c +++ /dev/null @@ -1,97 +0,0 @@ - -/* BEEBS template benchmark - - Copyright (C) 2014 Embecosm Limited and University of Bristol - - Contributor James Pallister - - This file is part of the Bristol/Embecosm Embedded Benchmark Suite. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#include "support.h" -#include "trio.h" - -/* This scale factor will be changed to equalise the runtime of the - benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 0) - -#ifdef TRIO_SNPRINTF - -/* This version of the benchmark does not support verification */ - -int -verify_benchmark (int res __attribute ((unused)) ) -{ - return -1; -} - - -void -initialise_benchmark (void) -{ - init_heap (); /* BEEBS memory allocator */ -} - - -int -benchmark (void) -{ - char output[50]; - - trio_snprintf(output, 50, "%d", 123); - trio_snprintf(output, 50, "%ld", 123); - trio_snprintf(output, 50, "%5d", 123); - trio_snprintf(output, 50, "%05x", 123); - trio_snprintf(output, 50, "%*d", 5, 10); - - return 0; -} -#elif TRIO_SSCANF - -/* Global variables, so calls in BENCHMARK are not optimised away. */ -volatile int int_dest; -volatile char char_dest [20]; - - -void -initialise_benchmark (void) -{ -} - - -int -benchmark (void) -{ - trio_sscanf("123", "%d", &int_dest); - trio_sscanf("123 456", "%d %d", &int_dest, &int_dest); - trio_sscanf("000000123", "%d", &int_dest); - trio_sscanf("abcdefg", "%x", &int_dest); - trio_sscanf("FF", "%x",&int_dest); - trio_sscanf("abcdefg", "%[^f]%xg", char_dest, &int_dest); - - return 0; -} - -int verify_benchmark(int unused) { - int expected = 15; - if (int_dest != expected) - return 0; - return 1; -} -#else -#error "Missing a TRIO_SSCANF or TRIO_SNPRINTF macro" -#endif - - diff --git a/src/trio/triodef.h b/src/trio/triodef.h deleted file mode 100644 index 037c1da7..00000000 --- a/src/trio/triodef.h +++ /dev/null @@ -1,354 +0,0 @@ -/* BEEBS trio benchmark - - Copyright (C) 2014 Embecosm Limited and University of Bristol - - This file is part of the Bristol/Embecosm Embedded Benchmark Suite. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* The original source of this file was from: - * http://daniel.haxx.se/projects/trio/ - * and is covered by the following copyright and licence: - * - * Copyright (C) 2001 Bjorn Reese - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND - * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. - * - ************************************************************************/ - -#ifndef TRIO_TRIODEF_H -#define TRIO_TRIODEF_H - -/************************************************************************* - * Compiler support detection - */ - -#if defined(__GNUC__) -# define TRIO_COMPILER_GCC -#endif - -#if defined(__SUNPRO_CC) -# define TRIO_COMPILER_SUNPRO __SUNPRO_CC -#else -# if defined(__SUNPRO_C) -# define TRIO_COMPILER_SUNPRO __SUNPRO_C -# endif -#endif - -#if defined(__xlC__) || defined(__IBMC__) || defined(__IBMCPP__) -# define TRIO_COMPILER_XLC -#else -# if defined(_AIX) && !defined(__GNUC__) -# define TRIO_COMPILER_XLC /* Workaround for old xlc */ -# endif -#endif - -#if defined(__DECC) || defined(__DECCXX) -# define TRIO_COMPILER_DECC -#else -# if defined(__osf__) && defined(__LANGUAGE_C__) && !defined(__GNUC__) -# define TRIO_COMPILER_DECC /* Workaround for old DEC C compilers */ -# endif -#endif - -#if defined(__HP_aCC) || defined(__HP_cc) -# define TRIO_COMPILER_HP -#endif - -#if defined(sgi) || defined(__sgi) -# define TRIO_COMPILER_MIPSPRO -#endif - -#if defined(_MSC_VER) -# define TRIO_COMPILER_MSVC -#endif - -#if defined(__BORLANDC__) -# define TRIO_COMPILER_BCB -#endif - -/************************************************************************* - * Platform support detection - */ - -#if defined(VMS) || defined(__VMS) -# define TRIO_PLATFORM_VMS -#endif - -#if defined(unix) || defined(__unix) || defined(__unix__) -# define TRIO_PLATFORM_UNIX -#endif - -#if defined(TRIO_COMPILER_XLC) || defined(_AIX) -# define TRIO_PLATFORM_UNIX -#endif - -#if defined(TRIO_COMPILER_DECC) || defined(__osf___) -# if !defined(TRIO_PLATFORM_VMS) -# define TRIO_PLATFORM_UNIX -# endif -#endif - -#if defined(__NetBSD__) -# define TRIO_PLATFORM_UNIX -#endif - -#if defined(__Lynx__) -# define TRIO_PLATFORM_UNIX -# define TRIO_PLATFORM_LYNX -#endif - -#if defined(__APPLE__) && defined(__MACH__) -# define TRIO_PLATFORM_UNIX -#endif - -#if defined(__QNX__) -# define TRIO_PLATFORM_UNIX -# define TRIO_PLATFORM_QNX -#endif - -#if defined(__CYGWIN__) -# define TRIO_PLATFORM_UNIX -#endif - -#if defined(AMIGA) && defined(TRIO_COMPILER_GCC) -# define TRIO_PLATFORM_UNIX -#endif - -#if defined(TRIO_COMPILER_MSVC) || defined(WIN32) || defined(_WIN32) -# define TRIO_PLATFORM_WIN32 -#endif - -#if defined(_WIN32_WCE) -# define TRIO_PLATFORM_WINCE -#endif - -#if defined(mpeix) || defined(__mpexl) -# define TRIO_PLATFORM_MPEIX -#endif - -#if defined(_AIX) -# define TRIO_PLATFORM_AIX -#endif - -#if defined(__hpux) -# define TRIO_PLATFORM_HPUX -#endif - -#if defined(sun) || defined(__sun__) -# if defined(__SVR4) || defined(__svr4__) -# define TRIO_PLATFORM_SOLARIS -# else -# define TRIO_PLATFORM_SUNOS -# endif -#endif - -/************************************************************************* - * Standards support detection - */ - -#if defined(__STDC__) \ - || defined(_MSC_EXTENSIONS) \ - || defined(TRIO_COMPILER_BCB) -# define PREDEF_STANDARD_C89 -#endif -#if defined(__STDC_VERSION__) -# define PREDEF_STANDARD_C90 -#endif -#if (__STDC_VERSION__ - 0 >= 199409L) -# define PREDEF_STANDARD_C94 -#endif -#if (__STDC_VERSION__ - 0 >= 199901L) -# define PREDEF_STANDARD_C99 -#endif -#if defined(TRIO_COMPILER_SUNPRO) && (TRIO_COMPILER_SUNPRO >= 0x420) -# if !defined(PREDEF_STANDARD_C94) -# define PREDEF_STANDARD_C94 -# endif -#endif - -#if defined(__cplusplus) -# define PREDEF_STANDARD_CXX -#endif -#if __cplusplus - 0 >= 199711L -# define PREDEF_STANDARD_CXX89 -#endif - -#if defined(TRIO_PLATFORM_UNIX) -# include -#endif - -#if defined(_POSIX_VERSION) -# define PREDEF_STANDARD_POSIX _POSIX_VERSION -# if (_POSIX_VERSION >= 199506L) -# define PREDEF_STANDARD_POSIX_1996 -# endif -#endif - -#if (_XOPEN_VERSION - 0 >= 3) || defined(_XOPEN_XPG3) -# define PREDEF_STANDARD_XPG3 -#endif -#if (_XOPEN_VERSION - 0 >= 4) || defined(_XOPEN_XPG4) -# define PREDEF_STANDARD_XPG4 -#endif -#if (_XOPEN_VERSION - 0 > 4) \ - || (defined(_XOPEN_UNIX) && (_XOPEN_VERSION - 0 == 4)) -# define PREDEF_STANDARD_UNIX95 -#endif -#if (_XOPEN_VERSION - 0 >= 500) -# define PREDEF_STANDARD_UNIX98 -#endif -#if (_XOPEN_VERSION - 0 >= 600) -# define PREDEF_STANDARD_UNIX03 -#endif - -/************************************************************************* - * Generic defines - */ - -#if !defined(TRIO_PUBLIC) -# define TRIO_PUBLIC -#endif -#if !defined(TRIO_PRIVATE) -# define TRIO_PRIVATE static -#endif - -#if !(defined(PREDEF_STANDARD_C89) || defined(PREDEF_STANDARD_CXX)) -# define TRIO_COMPILER_ANCIENT -#endif - -#if defined(TRIO_COMPILER_ANCIENT) -# define TRIO_CONST -# define TRIO_VOLATILE -# define TRIO_SIGNED -typedef double trio_long_double_t; -typedef char * trio_pointer_t; -# define TRIO_SUFFIX_LONG(x) x -# define TRIO_PROTO(x) () -# define TRIO_NOARGS -# define TRIO_ARGS1(list,a1) list a1; -# define TRIO_ARGS2(list,a1,a2) list a1; a2; -# define TRIO_ARGS3(list,a1,a2,a3) list a1; a2; a3; -# define TRIO_ARGS4(list,a1,a2,a3,a4) list a1; a2; a3; a4; -# define TRIO_ARGS5(list,a1,a2,a3,a4,a5) list a1; a2; a3; a4; a5; -# define TRIO_ARGS6(list,a1,a2,a3,a4,a5,a6) list a1; a2; a3; a4; a5; a6; -# define TRIO_ARGS7(list,a1,a2,a3,a4,a5,a6,a7) list a1; a2; a3; a4; a5; a6; a7; -# define TRIO_VARGS2(list,a1,a2) list a1; a2 -# define TRIO_VARGS3(list,a1,a2,a3) list a1; a2; a3 -# define TRIO_VARGS4(list,a1,a2,a3,a4) list a1; a2; a3; a4 -# define TRIO_VARGS5(list,a1,a2,a3,a4,a5) list a1; a2; a3; a4; a5 -# define TRIO_VA_DECL va_dcl -# define TRIO_VA_START(x,y) va_start(x) -# define TRIO_VA_END(x) va_end(x) -#else /* ANSI C */ -# define TRIO_CONST const -# define TRIO_VOLATILE volatile -# define TRIO_SIGNED signed -typedef long double trio_long_double_t; -typedef void * trio_pointer_t; -# define TRIO_SUFFIX_LONG(x) x ## L -# define TRIO_PROTO(x) x -# define TRIO_NOARGS void -# define TRIO_ARGS1(list,a1) (a1) -# define TRIO_ARGS2(list,a1,a2) (a1,a2) -# define TRIO_ARGS3(list,a1,a2,a3) (a1,a2,a3) -# define TRIO_ARGS4(list,a1,a2,a3,a4) (a1,a2,a3,a4) -# define TRIO_ARGS5(list,a1,a2,a3,a4,a5) (a1,a2,a3,a4,a5) -# define TRIO_ARGS6(list,a1,a2,a3,a4,a5,a6) (a1,a2,a3,a4,a5,a6) -# define TRIO_ARGS7(list,a1,a2,a3,a4,a5,a6,a7) (a1,a2,a3,a4,a5,a6,a7) -# define TRIO_VARGS2 TRIO_ARGS2 -# define TRIO_VARGS3 TRIO_ARGS3 -# define TRIO_VARGS4 TRIO_ARGS4 -# define TRIO_VARGS5 TRIO_ARGS5 -# define TRIO_VA_DECL ... -# define TRIO_VA_START(x,y) va_start(x,y) -# define TRIO_VA_END(x) va_end(x) -#endif - -#if defined(PREDEF_STANDARD_C99) || defined(PREDEF_STANDARD_CXX) -# define TRIO_INLINE inline -#else -# if defined(TRIO_COMPILER_GCC) -# define TRIO_INLINE __inline__ -# endif -# if defined(TRIO_COMPILER_MSVC) -# define TRIO_INLINE _inline -# endif -# if defined(TRIO_COMPILER_BCB) -# define TRIO_INLINE __inline -# endif -#endif -#if !defined(TRIO_INLINE) -# define TRIO_INLINE -#endif - -/************************************************************************* - * Workarounds - */ - -#if defined(TRIO_PLATFORM_VMS) -/* - * Computations done with constants at compile time can trigger these - * even when compiling with IEEE enabled. - */ -# pragma message disable (UNDERFLOW, FLOATOVERFL) - -# if (__CRTL_VER < 80210001) -/* - * Although the compiler supports C99 language constructs, the C - * run-time library does not contain all C99 functions. - */ -# if defined(PREDEF_STANDARD_C99) -# undef PREDEF_STANDARD_C99 -# endif -# endif -#endif - -/* - * Not all preprocessors supports the LL token. - */ -#if defined(TRIO_COMPILER_MSVC) || defined(TRIO_COMPILER_BCB) -#else -# define TRIO_COMPILER_SUPPORTS_LL -#endif - -#if defined(__CYGWIN__) -/* - * Cygwin defines the macros for hosted C99, but does not support certain - * long double math functions. - */ -# include -# define TRIO_CYGWIN_VERSION_API CYGWIN_VERSION_API_MAJOR * 1000 + \ - CYGWIN_VERSION_API_MINOR -/* - * Please change the version number below when the Cygwin API supports - * long double math functions (powl, fmodl, etc.) - */ -# if TRIO_CYGWIN_VERSION_API < 99999999 -# define TRIO_NO_FLOORL 1 -# define TRIO_NO_CEILL 1 -# define TRIO_NO_POWL 1 -# define TRIO_NO_FMODL 1 -# define TRIO_NO_LOG10L 1 -# endif -#endif - -#endif /* TRIO_TRIODEF_H */ diff --git a/src/trio/triop.h b/src/trio/triop.h deleted file mode 100644 index 60aaacef..00000000 --- a/src/trio/triop.h +++ /dev/null @@ -1,491 +0,0 @@ -/* BEEBS trio benchmark - - Copyright (C) 2014 Embecosm Limited and University of Bristol - - This file is part of the Bristol/Embecosm Embedded Benchmark Suite. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* The original source of this file was from: - * http://daniel.haxx.se/projects/trio/ - * and is covered by the following copyright and licence: - * - * Copyright (C) 2000 Bjorn Reese and Daniel Stenberg. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND - * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. - * - ************************************************************************ - * - * Private functions, types, etc. used for callback functions. - * - * The ref pointer is an opaque type and should remain as such. - * Private data must only be accessible through the getter and - * setter functions. - * - ************************************************************************/ - -#ifndef TRIO_TRIOP_H -#define TRIO_TRIOP_H - -#include "triodef.h" - -#include -#if defined(TRIO_COMPILER_ANCIENT) -# include -#else -# include -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/************************************************************************* - * Supported standards - */ - -/* - * TRIO_C99 (=0 or =1) - * - * Define this to 0 to disable C99 format specifier extensions, or - * define to 1 to enable them. The format specifiers that are - * disabled by this switch are labelled with [C99] in the format - * specifier documentation. - */ -#if !defined(TRIO_C99) -# define TRIO_C99 1 -#endif - -/* - * TRIO_BSD (=0 or =1) - * - * Define this to 0 to disable BSD format specifier extensions, or - * define to 1 to enable them. The format specifiers that are - * disabled by this switch are labelled with [BSD] in the format - * specifier documentation. - */ -#if !defined(TRIO_BSD) -# define TRIO_BSD 1 -#endif - -/* - * TRIO_GNU (=0 or =1) - * - * Define this to 0 to disable GNU format specifier extensions, or - * define to 1 to enable them. The format specifiers that are - * disabled by this switch are labelled with [GNU] in the format - * specifier documentation. - */ -#if !defined(TRIO_GNU) -# define TRIO_GNU 1 -#endif - -/* - * TRIO_MISC (=0 or =1) - * - * Define this to 0 to disable miscellaneous format specifier - * extensions, or define to 1 to enable them. The format specifiers - * that are disabled by this switch are labelled with [MISC] in the - * format specifier documentation. - */ -#if !defined(TRIO_MISC) -# define TRIO_MISC 1 -#endif - -/* - * TRIO_UNIX98 (=0 or =1) - * - * Define this to 0 to disable UNIX98 format specifier extensions, - * or define to 1 to enable them. The format specifiers that are - * disabled by this switch are labelled with [UNIX98] in the format - * specifier documentation. - */ -#if !defined(TRIO_UNIX98) -# define TRIO_UNIX98 1 -#endif - -/* - * TRIO_MICROSOFT (=0 or =1) - * - * Define this to 0 to disable Microsoft Visual C format specifier - * extensions, or define to 1 to enable them. The format specifiers - * that are disabled by this switch are labelled with [MSVC] in the - * format specifier documentation. - */ -#if !defined(TRIO_MICROSOFT) -# define TRIO_MICROSOFT 1 -#endif - -/* - * TRIO_EXTENSION (=0 or =1) - * - * Define this to 0 to disable Trio-specific extensions, or define - * to 1 to enable them. This has two effects: it controls whether - * or not the Trio user-defined formating mechanism - * (trio_register() etc) is supported, and it enables or disables - * Trio's own format specifier extensions. The format specifiers - * that are disabled by this switch are labelled with [TRIO] in - * the format specifier documentation. - */ -#if !defined(TRIO_EXTENSION) -# define TRIO_EXTENSION 1 -#endif - -/* - * TRIO_DEPRECATED (=0 or =1) - * - * Define this to 0 to disable deprecated functionality, or define - * to 1 to enable them. - */ -#if !defined(TRIO_DEPRECATED) -# define TRIO_DEPRECATED 1 -#endif - -/************************************************************************* - * Features - */ - -#if defined(TRIO_SNPRINTF_ONLY) -# define TRIO_FEATURE_SCANF 0 -# define TRIO_FEATURE_FILE 0 -# define TRIO_FEATURE_STDIO 0 -# define TRIO_FEATURE_FD 0 -# define TRIO_FEATURE_DYNAMICSTRING 0 -# define TRIO_FEATURE_CLOSURE 0 -# define TRIO_FEATURE_STRERR 0 -# define TRIO_FEATURE_LOCALE 0 -# define TRIO_EMBED_NAN 1 -# define TRIO_EMBED_STRING 1 -#endif - -/* - * TRIO_FEATURE_SCANF (=0 or =1) - * - * Define this to 0 to disable all the scanf() variants, or define to 1 - * to enable them. - */ -#if !defined(TRIO_FEATURE_SCANF) -# define TRIO_FEATURE_SCANF 1 -#endif - -/* - * TRIO_FEATURE_FILE (=0 or =1) - * - * Define this to 0 to disable compilation of the trio_fprintf() and - * trio_fscanf() family of functions, or define to 1 to enable them. - * - * This may be useful on an embedded platform with no filesystem. - * Note that trio_printf() uses fwrite to write to stdout, so if you - * do not have an implementation of fwrite() at all then you must also - * define TRIO_FEATURE_STDIO to 0. - */ -#if !defined(TRIO_FEATURE_FILE) -# define TRIO_FEATURE_FILE 1 -#endif - -/* - * TRIO_FEATURE_STDIO (=0 or =1) - * - * Define this to 0 to disable compilation of the trio_printf() and - * trio_scanf() family of functions, or define to 1 to enable them. - * - * This may be useful on an embedded platform with no standard I/O. - */ -#if !defined(TRIO_FEATURE_STDIO) -# define TRIO_FEATURE_STDIO 1 -#endif - -/* - * TRIO_FEATURE_FD (=0 or =1) - * - * Define this to 0 to disable compilation of the trio_dprintf() and - * trio_dscanf() family of functions, or define to 1 to enable them. - * - * This may be useful on an embedded platform with no filesystem, or on - * a platform that supports file I/O using FILE* but not using raw file - * descriptors. - */ -#if !defined(TRIO_FEATURE_FD) -# define TRIO_FEATURE_FD 1 -#endif - -/* - * TRIO_FEATURE_DYNAMICSTRING (=0 or =1) - * - * Define this to 0 to disable compilation of the trio_aprintf() - * family of functions, or define to 1 to enable them. - * - * If you define both this and TRIO_MINIMAL to 0, then Trio will never - * call malloc or free. - */ -#if !defined(TRIO_FEATURE_DYNAMICSTRING) -# define TRIO_FEATURE_DYNAMICSTRING 1 -#endif - -/* - * TRIO_FEATURE_CLOSURE (=0 or =1) - * - * Define this to 0 to disable compilation of the trio_cprintf() and - * trio_cscanf() family of functions, or define to 1 to enable them. - * - * These functions are rarely needed. This saves a (small) amount of code. - */ -#if !defined(TRIO_FEATURE_CLOSURE) -# define TRIO_FEATURE_CLOSURE 1 -#endif - -/* - * TRIO_FEATURE_ERRORCODE (=0 or =1) - * - * Define this to 0 to return -1 from the print and scan function on - * error, or define to 1 to return a negative number with debugging - * information as part of the return code. - * - * If enabled, the return code will be a negative number, which encodes - * an error code and an error location. These can be decoded with the - * TRIO_ERROR_CODE and TRIO_ERROR_POSITION macros. - */ -#if defined(TRIO_ERRORS) -# define TRIO_FEATURE_ERRORCODE TRIO_ERRORS -#endif -#if !defined(TRIO_FEATURE_ERRORCODE) -# define TRIO_FEATURE_ERRORCODE 1 -#endif - -/* - * TRIO_FEATURE_STRERR (=0 or =1) - * - * Define this to 0 if you do not use trio_strerror(), or define to 1 if - * you do use it. - * - * This saves a (small) amount of code. - */ -#if !defined(TRIO_FEATURE_STRERR) -# define TRIO_FEATURE_STRERR 1 -#endif - -/* - * TRIO_FEATURE_FLOAT (=0 or =1) - * - * Define this to 0 to disable all floating-point support, or define - * to 1 to enable it. - * - * This is useful in restricted embedded platforms that do not support - * floating-point. Obviously you cannot use floating-point format - * specifiers if you define this. - * - * Do not compile trionan.c if you disable this. - */ -#if !defined(TRIO_FEATURE_FLOAT) -# define TRIO_FEATURE_FLOAT 1 -#endif - -/* - * TRIO_FEATURE_LOCALE (=0 or =1) - * - * Define this to 0 to disable customized locale support, or define - * to 1 to enable it. - * - * This saves a (small) amount of code. - */ -#if !defined(TRIO_FEATURE_LOCALE) -# define TRIO_FEATURE_LOCALE 1 -#endif - -/* - * TRIO_MINIMAL - * - * Define this to disable building the public trionan.h and triostr.h. - * If you define this, then you must not compile trionan.c and triostr.c - * separately. - */ -#if defined(TRIO_MINIMAL) -# if !defined(TRIO_EMBED_NAN) -# define TRIO_EMBED_NAN -# endif -# if !defined(TRIO_EMBED_STRING) -# define TRIO_EMBED_STRING -# endif -#endif - -/* Does not work yet. Do not enable */ -#ifndef TRIO_FEATURE_WIDECHAR -# define TRIO_FEATURE_WIDECHAR 0 -#endif - -/************************************************************************* - * Mapping standards to internal features - */ - -#if !defined(TRIO_FEATURE_HEXFLOAT) -# define TRIO_FEATURE_HEXFLOAT (TRIO_C99 && TRIO_FEATURE_FLOAT) -#endif - -#if !defined(TRIO_FEATURE_LONGDOUBLE) -# define TRIO_FEATURE_LONGDOUBLE TRIO_FEATURE_FLOAT -#endif - -#if !defined(TRIO_FEATURE_ERRNO) -# define TRIO_FEATURE_ERRNO TRIO_GNU -#endif - -#if !defined(TRIO_FEATURE_QUAD) -# define TRIO_FEATURE_QUAD (TRIO_BSD || TRIO_GNU) -#endif - -#if !defined(TRIO_FEATURE_SIZE_T) -# define TRIO_FEATURE_SIZE_T TRIO_C99 -#endif - -#if !defined(TRIO_FEATURE_SIZE_T_UPPER) -# define TRIO_FEATURE_SIZE_T_UPPER TRIO_GNU -#endif - -#if !defined(TRIO_FEATURE_PTRDIFF_T) -# define TRIO_FEATURE_PTRDIFF_T TRIO_C99 -#endif - -#if !defined(TRIO_FEATURE_INTMAX_T) -# define TRIO_FEATURE_INTMAX_T TRIO_C99 -#endif - -#if !defined(TRIO_FEATURE_FIXED_SIZE) -# define TRIO_FEATURE_FIXED_SIZE TRIO_MICROSOFT -#endif - -#if !defined(TRIO_FEATURE_POSITIONAL) -# define TRIO_FEATURE_POSITIONAL TRIO_UNIX98 -#endif - -#if !defined(TRIO_FEATURE_USER_DEFINED) -# define TRIO_FEATURE_USER_DEFINED TRIO_EXTENSION -#endif - -#if !defined(TRIO_FEATURE_BINARY) -# define TRIO_FEATURE_BINARY TRIO_EXTENSION -#endif - -#if !defined(TRIO_FEATURE_QUOTE) -# define TRIO_FEATURE_QUOTE TRIO_EXTENSION -#endif - -#if !defined(TRIO_FEATURE_STICKY) -# define TRIO_FEATURE_STICKY TRIO_EXTENSION -#endif - -#if !defined(TRIO_FEATURE_VARSIZE) -# define TRIO_FEATURE_VARSIZE TRIO_EXTENSION -#endif - -#if !defined(TRIO_FEATURE_ROUNDING) -# define TRIO_FEATURE_ROUNDING TRIO_EXTENSION -#endif - -/************************************************************************* - * Memory handling - */ -#ifndef TRIO_MALLOC -# define TRIO_MALLOC(n) malloc_beebs(n) -#endif -#ifndef TRIO_REALLOC -# define TRIO_REALLOC(x,n) realloc_beebs((x),(n)) -#endif -#ifndef TRIO_FREE -# define TRIO_FREE(x) free_beebs(x) -#endif - - -/************************************************************************* - * User-defined specifiers - */ - -typedef int (*trio_callback_t) TRIO_PROTO((trio_pointer_t)); - -trio_pointer_t trio_register TRIO_PROTO((trio_callback_t callback, const char *name)); -void trio_unregister TRIO_PROTO((trio_pointer_t handle)); - -TRIO_CONST char *trio_get_format TRIO_PROTO((trio_pointer_t ref)); -TRIO_CONST trio_pointer_t trio_get_argument TRIO_PROTO((trio_pointer_t ref)); - -/* Modifiers */ -int trio_get_width TRIO_PROTO((trio_pointer_t ref)); -void trio_set_width TRIO_PROTO((trio_pointer_t ref, int width)); -int trio_get_precision TRIO_PROTO((trio_pointer_t ref)); -void trio_set_precision TRIO_PROTO((trio_pointer_t ref, int precision)); -int trio_get_base TRIO_PROTO((trio_pointer_t ref)); -void trio_set_base TRIO_PROTO((trio_pointer_t ref, int base)); -int trio_get_padding TRIO_PROTO((trio_pointer_t ref)); -void trio_set_padding TRIO_PROTO((trio_pointer_t ref, int is_padding)); -int trio_get_short TRIO_PROTO((trio_pointer_t ref)); /* h */ -void trio_set_shortshort TRIO_PROTO((trio_pointer_t ref, int is_shortshort)); -int trio_get_shortshort TRIO_PROTO((trio_pointer_t ref)); /* hh */ -void trio_set_short TRIO_PROTO((trio_pointer_t ref, int is_short)); -int trio_get_long TRIO_PROTO((trio_pointer_t ref)); /* l */ -void trio_set_long TRIO_PROTO((trio_pointer_t ref, int is_long)); -int trio_get_longlong TRIO_PROTO((trio_pointer_t ref)); /* ll */ -void trio_set_longlong TRIO_PROTO((trio_pointer_t ref, int is_longlong)); -int trio_get_longdouble TRIO_PROTO((trio_pointer_t ref)); /* L */ -void trio_set_longdouble TRIO_PROTO((trio_pointer_t ref, int is_longdouble)); -int trio_get_alternative TRIO_PROTO((trio_pointer_t ref)); /* # */ -void trio_set_alternative TRIO_PROTO((trio_pointer_t ref, int is_alternative)); -int trio_get_alignment TRIO_PROTO((trio_pointer_t ref)); /* - */ -void trio_set_alignment TRIO_PROTO((trio_pointer_t ref, int is_leftaligned)); -int trio_get_spacing TRIO_PROTO((trio_pointer_t ref)); /* (space) */ -void trio_set_spacing TRIO_PROTO((trio_pointer_t ref, int is_space)); -int trio_get_sign TRIO_PROTO((trio_pointer_t ref)); /* + */ -void trio_set_sign TRIO_PROTO((trio_pointer_t ref, int is_showsign)); -#if TRIO_FEATURE_QUOTE -int trio_get_quote TRIO_PROTO((trio_pointer_t ref)); /* ' */ -void trio_set_quote TRIO_PROTO((trio_pointer_t ref, int is_quote)); -#endif -int trio_get_upper TRIO_PROTO((trio_pointer_t ref)); -void trio_set_upper TRIO_PROTO((trio_pointer_t ref, int is_upper)); -#if TRIO_FEATURE_INTMAX_T -int trio_get_largest TRIO_PROTO((trio_pointer_t ref)); /* j */ -void trio_set_largest TRIO_PROTO((trio_pointer_t ref, int is_largest)); -#endif -#if TRIO_FEATURE_PTRDIFF_T -int trio_get_ptrdiff TRIO_PROTO((trio_pointer_t ref)); /* t */ -void trio_set_ptrdiff TRIO_PROTO((trio_pointer_t ref, int is_ptrdiff)); -#endif -#if TRIO_FEATURE_SIZE_T -int trio_get_size TRIO_PROTO((trio_pointer_t ref)); /* z / Z */ -void trio_set_size TRIO_PROTO((trio_pointer_t ref, int is_size)); -#endif - -/* Printing */ -int trio_print_ref TRIO_PROTO((trio_pointer_t ref, const char *format, ...)); -int trio_vprint_ref TRIO_PROTO((trio_pointer_t ref, const char *format, va_list args)); -int trio_printv_ref TRIO_PROTO((trio_pointer_t ref, const char *format, trio_pointer_t *args)); - -void trio_print_int TRIO_PROTO((trio_pointer_t ref, int number)); -void trio_print_uint TRIO_PROTO((trio_pointer_t ref, unsigned int number)); -/* void trio_print_long TRIO_PROTO((trio_pointer_t ref, long number)); */ -/* void trio_print_ulong TRIO_PROTO((trio_pointer_t ref, unsigned long number)); */ -void trio_print_double TRIO_PROTO((trio_pointer_t ref, double number)); -void trio_print_string TRIO_PROTO((trio_pointer_t ref, TRIO_CONST char *string)); -void trio_print_pointer TRIO_PROTO((trio_pointer_t ref, trio_pointer_t pointer)); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* TRIO_TRIOP_H */ diff --git a/src/trio/triostr.c b/src/trio/triostr.c deleted file mode 100644 index c42822d9..00000000 --- a/src/trio/triostr.c +++ /dev/null @@ -1,2404 +0,0 @@ -/* BEEBS trio benchmark - - Copyright (C) 2014 Embecosm Limited and University of Bristol - - This file is part of the Bristol/Embecosm Embedded Benchmark Suite. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* The original source of this file was from: - * http://daniel.haxx.se/projects/trio/ - * and is covered by the following copyright and licence: - * - * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND - * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. - * - ************************************************************************/ - -/************************************************************************* - * Include files - */ - -#if defined(HAVE_CONFIG_H) -# include -#endif -#include -#include -#include -#include -#include "triodef.h" -#include "triostr.h" -#if defined(TRIO_FUNC_TO_LONG_DOUBLE) -# define USE_MATH -#endif -#if defined(USE_MATH) -# include -#endif - -/************************************************************************* - * Definitions - */ - -#if !defined(TRIO_PUBLIC_STRING) -# define TRIO_PUBLIC_STRING TRIO_PUBLIC -#endif -#if !defined(TRIO_PRIVATE_STRING) -# define TRIO_PRIVATE_STRING TRIO_PRIVATE -#endif - -#if !defined(NULL) -# define NULL 0 -#endif -#if !defined(NIL) -# define NIL ((char)0) -#endif -#if !defined(FALSE) -# define FALSE (1 == 0) -# define TRUE (! FALSE) -#endif -#if !defined(BOOLEAN_T) -# define BOOLEAN_T int -#endif - -#if defined(USE_MATH) -# if defined(PREDEF_STANDARD_C99) -# if defined(TRIO_COMPILER_DECC) -# if (TRIO_COMPILER_DECC - 0 > 80000000) -/* - * The OSF/1 runtime that comes with the DECC compiler does not support - * hexfloats conversion. - */ -# define USE_STRTOD -# define USE_STRTOF -# endif -# else -# define USE_STRTOD -# define USE_STRTOF -# endif -# else -# if defined(TRIO_COMPILER_VISUALC) -# define USE_STRTOD -# endif -#endif -#endif - -#if defined(TRIO_PLATFORM_UNIX) -# if defined(PREDEF_STANDARD_UNIX95) -# define USE_STRCASECMP -# define USE_STRNCASECMP -# endif -# if defined(TRIO_PLATFORM_SUNOS) -# define USE_SYS_ERRLIST -# else -# define USE_STRERROR -# endif -# if defined(TRIO_PLATFORM_QNX) -# define strcasecmp(x,y) stricmp(x,y) -# define strncasecmp(x,y,n) strnicmp(x,y,n) -# endif -#endif - -#if defined(TRIO_PLATFORM_WIN32) -# define USE_STRCASECMP -# if defined(TRIO_PLATFORM_WINCE) -# define strcasecmp(x,y) _stricmp(x,y) -# else -# define strcasecmp(x,y) strcmpi(x,y) -# endif -#endif - -#if !defined(HAVE_CONFIG_H) -# if !(defined(TRIO_PLATFORM_SUNOS)) -# define HAVE_TOLOWER -# define HAVE_TOUPPER -# endif -#endif - -#if defined(USE_MATH) && !defined(TRIO_NO_POWL) -# if !defined(HAVE_POWL) -# if defined(PREDEF_STANDARD_C99) \ - || defined(PREDEF_STANDARD_UNIX03) -# define HAVE_POWL -# else -# if defined(TRIO_COMPILER_VISUALC) -# if defined(powl) -# define HAVE_POWL -# endif -# endif -# endif -# endif -#endif - -#if defined(HAVE_POWL) -# define trio_powl(x,y) powl((x),(y)) -#else -# define trio_powl(x,y) pow((double)(x),(double)(y)) -#endif - -#if defined(TRIO_FUNC_TO_UPPER) \ - || (defined(TRIO_FUNC_EQUAL) && !defined(USE_STRCASECMP)) \ - || (defined(TRIO_FUNC_EQUAL_MAX) && !defined(USE_STRNCASECMP)) \ - || defined(TRIO_FUNC_MATCH) \ - || defined(TRIO_FUNC_TO_LONG_DOUBLE) \ - || defined(TRIO_FUNC_UPPER) -# define TRIO_FUNC_INTERNAL_TO_UPPER -#endif - -/************************************************************************* - * Structures - */ - -struct _trio_string_t -{ - char *content; - size_t length; - size_t allocated; -}; - -/************************************************************************* - * Constants - */ - -#if !defined(TRIO_EMBED_STRING) -static TRIO_CONST char rcsid[] = "@(#)$Id: triostr.c,v 1.36 2010/01/26 13:02:02 breese Exp $"; -#endif - -/************************************************************************* - * Static String Functions - */ - -#if defined(TRIO_DOCUMENTATION) -# include "doc/doc_static.h" -#endif -/** @addtogroup StaticStrings - @{ -*/ - -/* - * internal_duplicate_max - */ -#if defined(TRIO_FUNC_DUPLICATE) \ - || defined(TRIO_FUNC_DUPLICATE_MAX) \ - || defined(TRIO_FUNC_STRING_DUPLICATE) \ - || defined(TRIO_FUNC_XSTRING_DUPLICATE) - -TRIO_PRIVATE_STRING char * -internal_duplicate_max -TRIO_ARGS2((source, size), - TRIO_CONST char *source, - size_t size) -{ - char *target; - - assert(source); - - /* Make room for string plus a terminating zero */ - size++; - target = trio_create(size); - if (target) - { - trio_copy_max(target, size, source); - } - return target; -} - -#endif - -/* - * internal_string_alloc - */ -#if defined(TRIO_FUNC_STRING_CREATE) \ - || defined(TRIO_FUNC_STRING_DUPLICATE) \ - || defined(TRIO_FUNC_XSTRING_DUPLICATE) - -TRIO_PRIVATE_STRING trio_string_t * -internal_string_alloc(TRIO_NOARGS) -{ - trio_string_t *self; - - self = (trio_string_t *)TRIO_MALLOC(sizeof(trio_string_t)); - if (self) - { - self->content = NULL; - self->length = 0; - self->allocated = 0; - } - return self; -} - -#endif - -/* - * internal_string_grow - * - * The size of the string will be increased by 'delta' characters. If - * 'delta' is zero, the size will be doubled. - */ -#if defined(TRIO_FUNC_STRING_CREATE) \ - || defined(TRIO_FUNC_STRING_APPEND) \ - || defined(TRIO_FUNC_XSTRING_APPEND) \ - || defined(TRIO_FUNC_XSTRING_APPEND_CHAR) - -TRIO_PRIVATE_STRING BOOLEAN_T -internal_string_grow -TRIO_ARGS2((self, delta), - trio_string_t *self, - size_t delta) -{ - BOOLEAN_T status = FALSE; - char *new_content; - size_t new_size; - - new_size = (delta == 0) - ? ( (self->allocated == 0) ? 1 : self->allocated * 2 ) - : self->allocated + delta; - - new_content = (char *)TRIO_REALLOC(self->content, new_size); - if (new_content) - { - self->content = new_content; - self->allocated = new_size; - status = TRUE; - } - return status; -} - -#endif - -/* - * internal_string_grow_to - * - * The size of the string will be increased to 'length' plus one characters. - * If 'length' is less than the original size, the original size will be - * used (that is, the size of the string is never decreased). - */ -#if defined(TRIO_FUNC_STRING_APPEND) \ - || defined(TRIO_FUNC_XSTRING_APPEND) \ - || defined(TRIO_FUNC_XSTRING_APPEND_MAX) - -TRIO_PRIVATE_STRING BOOLEAN_T -internal_string_grow_to -TRIO_ARGS2((self, length), - trio_string_t *self, - size_t length) -{ - length++; /* Room for terminating zero */ - return (self->allocated < length) - ? internal_string_grow(self, length - self->allocated) - : TRUE; -} - -#endif - -#if defined(TRIO_FUNC_INTERNAL_TO_UPPER) - -TRIO_PRIVATE_STRING TRIO_INLINE int -internal_to_upper -TRIO_ARGS1((source), - int source) -{ -# if defined(HAVE_TOUPPER) - - return toupper(source); - -# else - - /* Does not handle locales or non-contiguous alphabetic characters */ - return ((source >= (int)'a') && (source <= (int)'z')) - ? source - 'a' + 'A' - : source; - -# endif -} - -#endif - - -/** - Create new string. - - @param size Size of new string. - @return Pointer to string, or NULL if allocation failed. -*/ -#if defined(TRIO_FUNC_CREATE) - -TRIO_PUBLIC_STRING char * -trio_create -TRIO_ARGS1((size), - size_t size) -{ - return (char *)TRIO_MALLOC(size); -} - -#endif - -/** - Destroy string. - - @param string String to be freed. -*/ -#if defined(TRIO_FUNC_DESTROY) - -TRIO_PUBLIC_STRING void -trio_destroy -TRIO_ARGS1((string), - char *string) -{ - if (string) - { - TRIO_FREE(string); - } -} - -#endif - -/** - Count the number of characters in a string. - - @param string String to measure. - @return Number of characters in @p string. -*/ -#if defined(TRIO_FUNC_LENGTH) - -TRIO_PUBLIC_STRING size_t -trio_length -TRIO_ARGS1((string), - TRIO_CONST char *string) -{ - return strlen(string); -} - -#endif - -/** - Count at most @p max characters in a string. - - @param string String to measure. - @param max Maximum number of characters to count. - @return The maximum value of @p max and number of characters in @p string. -*/ -#if defined(TRIO_FUNC_LENGTH_MAX) - -TRIO_PUBLIC_STRING size_t -trio_length_max -TRIO_ARGS2((string, max), - TRIO_CONST char *string, - size_t max) -{ - size_t i; - - for (i = 0; i < max; ++i) - { - if (string[i] == 0) - break; - } - return i; -} - -#endif - -/** - Append @p source at the end of @p target. - - @param target Target string. - @param source Source string. - @return Boolean value indicating success or failure. - - @pre @p target must point to a memory chunk with sufficient room to - contain the @p target string and @p source string. - @pre No boundary checking is performed, so insufficient memory will - result in a buffer overrun. - @post @p target will be zero terminated. -*/ -#if defined(TRIO_FUNC_APPEND) - -TRIO_PUBLIC_STRING int -trio_append -TRIO_ARGS2((target, source), - char *target, - TRIO_CONST char *source) -{ - assert(target); - assert(source); - - return (strcat(target, source) != NULL); -} - -#endif - -/** - Append at most @p max characters from @p source to @p target. - - @param target Target string. - @param max Maximum number of characters to append. - @param source Source string. - @return Boolean value indicating success or failure. - - @pre @p target must point to a memory chuck with sufficient room to - contain the @p target string and the @p source string (at most @p max - characters). - @pre No boundary checking is performed, so insufficient memory will - result in a buffer overrun. - @post @p target will be zero terminated. -*/ -#if defined(TRIO_FUNC_APPEND_MAX) - -TRIO_PUBLIC_STRING int -trio_append_max -TRIO_ARGS3((target, max, source), - char *target, - size_t max, - TRIO_CONST char *source) -{ - size_t length; - - assert(target); - assert(source); - - length = trio_length(target); - - if (max > length) - { - strncat(target, source, max - length - 1); - } - return TRUE; -} - -#endif - -/** - Determine if a string contains a substring. - - @param string String to be searched. - @param substring String to be found. - @return Boolean value indicating success or failure. -*/ -#if defined(TRIO_FUNC_CONTAINS) - -TRIO_PUBLIC_STRING int -trio_contains -TRIO_ARGS2((string, substring), - TRIO_CONST char *string, - TRIO_CONST char *substring) -{ - assert(string); - assert(substring); - - return (0 != strstr(string, substring)); -} - -#endif - -/** - Copy @p source to @p target. - - @param target Target string. - @param source Source string. - @return Boolean value indicating success or failure. - - @pre @p target must point to a memory chunk with sufficient room to - contain the @p source string. - @pre No boundary checking is performed, so insufficient memory will - result in a buffer overrun. - @post @p target will be zero terminated. -*/ -#if defined(TRIO_FUNC_COPY) - -TRIO_PUBLIC_STRING int -trio_copy -TRIO_ARGS2((target, source), - char *target, - TRIO_CONST char *source) -{ - assert(target); - assert(source); - - (void)strcpy(target, source); - return TRUE; -} - -#endif - -/** - Copy at most @p max - 1 characters from @p source to @p target. - - @param target Target string. - @param max Maximum number of characters to append (one of which is - a NUL terminator). In other words @p source must point to at least - @p max - 1 bytes, but @p target must point to at least @p max - bytes. - @param source Source string. - @return Boolean value indicating success or failure. - - @pre @p target must point to a memory chunk with sufficient room to - contain the @p source string and a NUL terminator (at most @p max - bytes total). - @pre No boundary checking is performed, so insufficient memory will - result in a buffer overrun. - @post @p target will be zero terminated. -*/ -#if defined(TRIO_FUNC_COPY_MAX) - -TRIO_PUBLIC_STRING int -trio_copy_max -TRIO_ARGS3((target, max, source), - char *target, - size_t max, - TRIO_CONST char *source) -{ - assert(target); - assert(source); - assert(max > 0); /* Includes != 0 */ - - (void)strncpy(target, source, max - 1); - target[max - 1] = (char)0; - return TRUE; -} - -#endif - -/** - Duplicate @p source. - - @param source Source string. - @return A copy of the @p source string. - - @post @p target will be zero terminated. -*/ -#if defined(TRIO_FUNC_DUPLICATE) - -TRIO_PUBLIC_STRING char * -trio_duplicate -TRIO_ARGS1((source), - TRIO_CONST char *source) -{ - return internal_duplicate_max(source, trio_length(source)); -} - -#endif - -/** - Duplicate at most @p max characters of @p source. - - @param source Source string. - @param max Maximum number of characters to duplicate. - @return A copy of the @p source string. - - @post @p target will be zero terminated. -*/ -#if defined(TRIO_FUNC_DUPLICATE_MAX) - -TRIO_PUBLIC_STRING char * -trio_duplicate_max -TRIO_ARGS2((source, max), - TRIO_CONST char *source, - size_t max) -{ - size_t length; - - assert(source); - assert(max > 0); - - length = trio_length(source); - if (length > max) - { - length = max; - } - return internal_duplicate_max(source, length); -} - -#endif - -/** - Compare if two strings are equal. - - @param first First string. - @param second Second string. - @return Boolean indicating whether the two strings are equal or not. - - Case-insensitive comparison. -*/ -#if defined(TRIO_FUNC_EQUAL) - -TRIO_PUBLIC_STRING int -trio_equal -TRIO_ARGS2((first, second), - TRIO_CONST char *first, - TRIO_CONST char *second) -{ - assert(first); - assert(second); - - if ((first != NULL) && (second != NULL)) - { -# if defined(USE_STRCASECMP) - return (0 == strcasecmp(first, second)); -# else - while ((*first != NIL) && (*second != NIL)) - { - if (internal_to_upper(*first) != internal_to_upper(*second)) - { - break; - } - first++; - second++; - } - return ((*first == NIL) && (*second == NIL)); -# endif - } - return FALSE; -} - -#endif - -/** - Compare if two strings are equal. - - @param first First string. - @param second Second string. - @return Boolean indicating whether the two strings are equal or not. - - Case-sensitive comparison. -*/ -#if defined(TRIO_FUNC_EQUAL_CASE) - -TRIO_PUBLIC_STRING int -trio_equal_case -TRIO_ARGS2((first, second), - TRIO_CONST char *first, - TRIO_CONST char *second) -{ - assert(first); - assert(second); - - if ((first != NULL) && (second != NULL)) - { - return (0 == strcmp(first, second)); - } - return FALSE; -} - -#endif - -/** - Compare if two strings up until the first @p max characters are equal. - - @param first First string. - @param max Maximum number of characters to compare. - @param second Second string. - @return Boolean indicating whether the two strings are equal or not. - - Case-sensitive comparison. -*/ -#if defined(TRIO_FUNC_EQUAL_CASE_MAX) - -TRIO_PUBLIC_STRING int -trio_equal_case_max -TRIO_ARGS3((first, max, second), - TRIO_CONST char *first, - size_t max, - TRIO_CONST char *second) -{ - assert(first); - assert(second); - - if ((first != NULL) && (second != NULL)) - { - return (0 == strncmp(first, second, max)); - } - return FALSE; -} - -#endif - -/** - Compare if two strings are equal. - - @param first First string. - @param second Second string. - @return Boolean indicating whether the two strings are equal or not. - - Collating characters are considered equal. -*/ -#if defined(TRIO_FUNC_EQUAL_LOCALE) - -TRIO_PUBLIC_STRING int -trio_equal_locale -TRIO_ARGS2((first, second), - TRIO_CONST char *first, - TRIO_CONST char *second) -{ - assert(first); - assert(second); - -# if defined(LC_COLLATE) - return (strcoll(first, second) == 0); -# else - return trio_equal(first, second); -# endif -} - -#endif - -/** - Compare if two strings up until the first @p max characters are equal. - - @param first First string. - @param max Maximum number of characters to compare. - @param second Second string. - @return Boolean indicating whether the two strings are equal or not. - - Case-insensitive comparison. -*/ -#if defined(TRIO_FUNC_EQUAL_MAX) - -TRIO_PUBLIC_STRING int -trio_equal_max -TRIO_ARGS3((first, max, second), - TRIO_CONST char *first, - size_t max, - TRIO_CONST char *second) -{ - assert(first); - assert(second); - - if ((first != NULL) && (second != NULL)) - { -# if defined(USE_STRNCASECMP) - return (0 == strncasecmp(first, second, max)); -# else - /* Not adequately tested yet */ - size_t cnt = 0; - while ((*first != NIL) && (*second != NIL) && (cnt <= max)) - { - if (internal_to_upper(*first) != internal_to_upper(*second)) - { - break; - } - first++; - second++; - cnt++; - } - return ((cnt == max) || ((*first == NIL) && (*second == NIL))); -# endif - } - return FALSE; -} - -#endif - -/** - Provide a textual description of an error code (errno). - - @param error_number Error number. - @return Textual description of @p error_number. -*/ -#if defined(TRIO_FUNC_ERROR) - -TRIO_PUBLIC_STRING TRIO_CONST char * -trio_error -TRIO_ARGS1((error_number), - int error_number) -{ -# if defined(USE_STRERROR) - - return strerror(error_number); - -# else -# if defined(USE_SYS_ERRLIST) - - extern char *sys_errlist[]; - extern int sys_nerr; - - return ((error_number < 0) || (error_number >= sys_nerr)) - ? "unknown" - : sys_errlist[error_number]; - -# else - - return "unknown"; - -# endif -# endif -} - -#endif - -/** - Format the date/time according to @p format. - - @param target Target string. - @param max Maximum number of characters to format. - @param format Formatting string. - @param datetime Date/time structure. - @return Number of formatted characters. - - The formatting string accepts the same specifiers as the standard C - function strftime. -*/ -#if defined(TRIO_FUNC_FORMAT_DATE_MAX) - -TRIO_PUBLIC_STRING size_t -trio_format_date_max -TRIO_ARGS4((target, max, format, datetime), - char *target, - size_t max, - TRIO_CONST char *format, - TRIO_CONST struct tm *datetime) -{ - assert(target); - assert(format); - assert(datetime); - assert(max > 0); - - return strftime(target, max, format, datetime); -} - -#endif - -/** - Calculate a hash value for a string. - - @param string String to be calculated on. - @param type Hash function. - @return Calculated hash value. - - @p type can be one of the following - @li @c TRIO_HASH_PLAIN Plain hash function. -*/ -#if defined(TRIO_FUNC_HASH) - -TRIO_PUBLIC_STRING unsigned long -trio_hash -TRIO_ARGS2((string, type), - TRIO_CONST char *string, - int type) -{ - unsigned long value = 0L; - char ch; - - assert(string); - - switch (type) - { - case TRIO_HASH_PLAIN: - while ( (ch = *string++) != NIL ) - { - value *= 31; - value += (unsigned long)ch; - } - break; - default: - assert(FALSE); - break; - } - return value; -} - -#endif - -/** - Find first occurrence of a character in a string. - - @param string String to be searched. - @param character Character to be found. - @return A pointer to the found character, or NULL if character was not found. - */ -#if defined(TRIO_FUNC_INDEX) - -TRIO_PUBLIC_STRING char * -trio_index -TRIO_ARGS2((string, character), - TRIO_CONST char *string, - int character) -{ - assert(string); - - return strchr(string, character); -} - -#endif - -/** - Find last occurrence of a character in a string. - - @param string String to be searched. - @param character Character to be found. - @return A pointer to the found character, or NULL if character was not found. - */ -#if defined(TRIO_FUNC_INDEX_LAST) - -TRIO_PUBLIC_STRING char * -trio_index_last -TRIO_ARGS2((string, character), - TRIO_CONST char *string, - int character) -{ - assert(string); - - return strchr(string, character); -} - -#endif - -/** - Convert the alphabetic letters in the string to lower-case. - - @param target String to be converted. - @return Number of processed characters (converted or not). -*/ -#if defined(TRIO_FUNC_LOWER) - -TRIO_PUBLIC_STRING int -trio_lower -TRIO_ARGS1((target), - char *target) -{ - assert(target); - - return trio_span_function(target, target, trio_to_lower); -} - -#endif - -/** - Compare two strings using wildcards. - - @param string String to be searched. - @param pattern Pattern, including wildcards, to search for. - @return Boolean value indicating success or failure. - - Case-insensitive comparison. - - The following wildcards can be used - @li @c * Match any number of characters. - @li @c ? Match a single character. -*/ -#if defined(TRIO_FUNC_MATCH) - -TRIO_PUBLIC_STRING int -trio_match -TRIO_ARGS2((string, pattern), - TRIO_CONST char *string, - TRIO_CONST char *pattern) -{ - assert(string); - assert(pattern); - - for (; ('*' != *pattern); ++pattern, ++string) - { - if (NIL == *string) - { - return (NIL == *pattern); - } - if ((internal_to_upper((int)*string) != internal_to_upper((int)*pattern)) - && ('?' != *pattern)) - { - return FALSE; - } - } - /* two-line patch to prevent *too* much recursiveness: */ - while ('*' == pattern[1]) - pattern++; - - do - { - if ( trio_match(string, &pattern[1]) ) - { - return TRUE; - } - } - while (*string++); - - return FALSE; -} - -#endif - -/** - Compare two strings using wildcards. - - @param string String to be searched. - @param pattern Pattern, including wildcards, to search for. - @return Boolean value indicating success or failure. - - Case-sensitive comparison. - - The following wildcards can be used - @li @c * Match any number of characters. - @li @c ? Match a single character. -*/ -#if defined(TRIO_FUNC_MATCH_CASE) - -TRIO_PUBLIC_STRING int -trio_match_case -TRIO_ARGS2((string, pattern), - TRIO_CONST char *string, - TRIO_CONST char *pattern) -{ - assert(string); - assert(pattern); - - for (; ('*' != *pattern); ++pattern, ++string) - { - if (NIL == *string) - { - return (NIL == *pattern); - } - if ((*string != *pattern) - && ('?' != *pattern)) - { - return FALSE; - } - } - /* two-line patch to prevent *too* much recursiveness: */ - while ('*' == pattern[1]) - pattern++; - - do - { - if ( trio_match_case(string, &pattern[1]) ) - { - return TRUE; - } - } - while (*string++); - - return FALSE; -} - -#endif - -/** - Execute a function on each character in string. - - @param target Target string. - @param source Source string. - @param Function Function to be executed. - @return Number of processed characters. -*/ -#if defined(TRIO_FUNC_SPAN_FUNCTION) - -TRIO_PUBLIC_STRING size_t -trio_span_function -TRIO_ARGS3((target, source, Function), - char *target, - TRIO_CONST char *source, - int (*Function) TRIO_PROTO((int))) -{ - size_t count = 0; - - assert(target); - assert(source); - assert(Function); - - while (*source != NIL) - { - *target++ = Function(*source++); - count++; - } - return count; -} - -#endif - -/** - Search for a substring in a string. - - @param string String to be searched. - @param substring String to be found. - @return Pointer to first occurrence of @p substring in @p string, or NULL - if no match was found. -*/ -#if defined(TRIO_FUNC_SUBSTRING) - -TRIO_PUBLIC_STRING char * -trio_substring -TRIO_ARGS2((string, substring), - TRIO_CONST char *string, - TRIO_CONST char *substring) -{ - assert(string); - assert(substring); - - return strstr(string, substring); -} - -#endif - -/** - Search for a substring in the first @p max characters of a string. - - @param string String to be searched. - @param max Maximum characters to be searched. - @param substring String to be found. - @return Pointer to first occurrence of @p substring in @p string, or NULL - if no match was found. -*/ -#if defined(TRIO_FUNC_SUBSTRING_MAX) - -TRIO_PUBLIC_STRING char * -trio_substring_max -TRIO_ARGS3((string, max, substring), - TRIO_CONST char *string, - size_t max, - TRIO_CONST char *substring) -{ - size_t count; - size_t size; - char *result = NULL; - - assert(string); - assert(substring); - - size = trio_length(substring); - if (size <= max) - { - for (count = 0; count <= max - size; count++) - { - if (trio_equal_max(substring, size, &string[count])) - { - result = (char *)&string[count]; - break; - } - } - } - return result; -} - -#endif - -/** - Tokenize string. - - @param string String to be tokenized. - @param delimiters String containing list of delimiting characters. - @return Start of new token. - - @warning @p string will be destroyed. -*/ -#if defined(TRIO_FUNC_TOKENIZE) - -TRIO_PUBLIC_STRING char * -trio_tokenize -TRIO_ARGS2((string, delimiters), - char *string, - TRIO_CONST char *delimiters) -{ - assert(delimiters); - - return strtok(string, delimiters); -} - -#endif - -/** - Convert string to floating-point number. - - @param source String to be converted. - @param endp Pointer to end of the converted string. - @return A floating-point number. - - The following Extended Backus-Naur form is used - @verbatim - double ::= [ ] - ( | - | - ) - [ [ ] ] - number ::= 1*( ) - digit ::= ( '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' ) - exponential ::= ( 'e' | 'E' ) - sign ::= ( '-' | '+' ) - decimal_point ::= '.' - @endverbatim -*/ -#if defined(TRIO_FUNC_TO_LONG_DOUBLE) - -/* FIXME: Add EBNF for hex-floats */ -TRIO_PUBLIC_STRING trio_long_double_t -trio_to_long_double -TRIO_ARGS2((source, endp), - TRIO_CONST char *source, - char **endp) -{ -# if defined(USE_STRTOLD) - return strtold(source, endp); -# else - int isNegative = FALSE; - int isExponentNegative = FALSE; - trio_long_double_t integer = 0.0; - trio_long_double_t fraction = 0.0; - unsigned long exponent = 0; - trio_long_double_t base; - trio_long_double_t fracdiv = 1.0; - trio_long_double_t value = 0.0; - - /* First try hex-floats */ - if ((source[0] == '0') && ((source[1] == 'x') || (source[1] == 'X'))) - { - base = 16.0; - source += 2; - while (isxdigit((int)*source)) - { - integer *= base; - integer += (isdigit((int)*source) - ? (*source - '0') - : 10 + (internal_to_upper((int)*source) - 'A')); - source++; - } - if (*source == '.') - { - source++; - while (isxdigit((int)*source)) - { - fracdiv /= base; - fraction += fracdiv * (isdigit((int)*source) - ? (*source - '0') - : 10 + (internal_to_upper((int)*source) - 'A')); - source++; - } - if ((*source == 'p') || (*source == 'P')) - { - source++; - if ((*source == '+') || (*source == '-')) - { - isExponentNegative = (*source == '-'); - source++; - } - while (isdigit((int)*source)) - { - exponent *= 10; - exponent += (*source - '0'); - source++; - } - } - } - /* For later use with exponent */ - base = 2.0; - } - else /* Then try normal decimal floats */ - { - base = 10.0; - isNegative = (*source == '-'); - /* Skip sign */ - if ((*source == '+') || (*source == '-')) - source++; - - /* Integer part */ - while (isdigit((int)*source)) - { - integer *= base; - integer += (*source - '0'); - source++; - } - - if (*source == '.') - { - source++; /* skip decimal point */ - while (isdigit((int)*source)) - { - fracdiv /= base; - fraction += (*source - '0') * fracdiv; - source++; - } - } - if ((*source == 'e') - || (*source == 'E') -# if TRIO_MICROSOFT - || (*source == 'd') - || (*source == 'D') -# endif - ) - { - source++; /* Skip exponential indicator */ - isExponentNegative = (*source == '-'); - if ((*source == '+') || (*source == '-')) - source++; - while (isdigit((int)*source)) - { - exponent *= (int)base; - exponent += (*source - '0'); - source++; - } - } - } - - value = integer + fraction; - if (exponent != 0) - { - if (isExponentNegative) - value /= trio_powl(base, (trio_long_double_t)exponent); - else - value *= trio_powl(base, (trio_long_double_t)exponent); - } - if (isNegative) - value = -value; - - if (endp) - *endp = (char *)source; - return value; -# endif -} - -#endif - -/** - Convert string to floating-point number. - - @param source String to be converted. - @param endp Pointer to end of the converted string. - @return A floating-point number. - - See @ref trio_to_long_double. -*/ -#if defined(TRIO_FUNC_TO_DOUBLE) - -TRIO_PUBLIC_STRING double -trio_to_double -TRIO_ARGS2((source, endp), - TRIO_CONST char *source, - char **endp) -{ -#if defined(USE_STRTOD) - return strtod(source, endp); -#else - return (double)trio_to_long_double(source, endp); -#endif -} - -#endif - -/** - Convert string to floating-point number. - - @param source String to be converted. - @param endp Pointer to end of the converted string. - @return A floating-point number. - - See @ref trio_to_long_double. -*/ -#if defined(TRIO_FUNC_TO_FLOAT) - -TRIO_PUBLIC_STRING float -trio_to_float -TRIO_ARGS2((source, endp), - TRIO_CONST char *source, - char **endp) -{ -# if defined(USE_STRTOF) - return strtof(source, endp); -# else - return (float)trio_to_long_double(source, endp); -# endif -} - -#endif - -/** - Convert string to signed integer. - - @param string String to be converted. - @param endp Pointer to end of converted string. - @param base Radix number of number. -*/ -#if defined(TRIO_FUNC_TO_LONG) - -TRIO_PUBLIC_STRING long -trio_to_long -TRIO_ARGS3((string, endp, base), - TRIO_CONST char *string, - char **endp, - int base) -{ - assert(string); - assert((base >= 2) && (base <= 36)); - - return strtol(string, endp, base); -} - -#endif - -/** - Convert one alphabetic letter to lower-case. - - @param source The letter to be converted. - @return The converted letter. -*/ -#if defined(TRIO_FUNC_TO_LOWER) - -TRIO_PUBLIC_STRING int -trio_to_lower -TRIO_ARGS1((source), - int source) -{ -# if defined(HAVE_TOLOWER) - - return tolower(source); - -# else - - /* Does not handle locales or non-contiguous alphabetic characters */ - return ((source >= (int)'A') && (source <= (int)'Z')) - ? source - 'A' + 'a' - : source; - -# endif -} - -#endif - -/** - Convert string to unsigned integer. - - @param string String to be converted. - @param endp Pointer to end of converted string. - @param base Radix number of number. -*/ -#if defined(TRIO_FUNC_TO_UNSIGNED_LONG) - -TRIO_PUBLIC_STRING unsigned long -trio_to_unsigned_long -TRIO_ARGS3((string, endp, base), - TRIO_CONST char *string, - char **endp, - int base) -{ - assert(string); - assert((base >= 2) && (base <= 36)); - - return strtoul(string, endp, base); -} - -#endif - -/** - Convert one alphabetic letter to upper-case. - - @param source The letter to be converted. - @return The converted letter. -*/ -#if defined(TRIO_FUNC_TO_UPPER) - -TRIO_PUBLIC_STRING int -trio_to_upper -TRIO_ARGS1((source), - int source) -{ - return internal_to_upper(source); -} - -#endif - -/** - Convert the alphabetic letters in the string to upper-case. - - @param target The string to be converted. - @return The number of processed characters (converted or not). -*/ -#if defined(TRIO_FUNC_UPPER) - -TRIO_PUBLIC_STRING int -trio_upper -TRIO_ARGS1((target), - char *target) -{ - assert(target); - - return trio_span_function(target, target, internal_to_upper); -} - -#endif - -/** @} End of StaticStrings */ - - -/************************************************************************* - * Dynamic String Functions - */ - -#if defined(TRIO_DOCUMENTATION) -# include "doc/doc_dynamic.h" -#endif -/** @addtogroup DynamicStrings - @{ -*/ - -/** - Create a new dynamic string. - - @param initial_size Initial size of the buffer. - @return Newly allocated dynamic string, or NULL if memory allocation failed. -*/ -#if defined(TRIO_FUNC_STRING_CREATE) - -TRIO_PUBLIC_STRING trio_string_t * -trio_string_create -TRIO_ARGS1((initial_size), - int initial_size) -{ - trio_string_t *self; - - self = internal_string_alloc(); - if (self) - { - if (internal_string_grow(self, - (size_t)((initial_size > 0) ? initial_size : 1))) - { - self->content[0] = (char)0; - self->allocated = initial_size; - } - else - { - trio_string_destroy(self); - self = NULL; - } - } - return self; -} - -#endif - -/** - Deallocate the dynamic string and its contents. - - @param self Dynamic string -*/ -#if defined(TRIO_FUNC_STRING_DESTROY) - -TRIO_PUBLIC_STRING void -trio_string_destroy -TRIO_ARGS1((self), - trio_string_t *self) -{ - assert(self); - - if (self) - { - trio_destroy(self->content); - TRIO_FREE(self); - } -} - -#endif - -/** - Get a pointer to the content. - - @param self Dynamic string. - @param offset Offset into content. - @return Pointer to the content. - - @p Offset can be zero, positive, or negative. If @p offset is zero, - then the start of the content will be returned. If @p offset is positive, - then a pointer to @p offset number of characters from the beginning of the - content is returned. If @p offset is negative, then a pointer to @p offset - number of characters from the ending of the string, starting at the - terminating zero, is returned. -*/ -#if defined(TRIO_FUNC_STRING_GET) - -TRIO_PUBLIC_STRING char * -trio_string_get -TRIO_ARGS2((self, offset), - trio_string_t *self, - int offset) -{ - char *result = NULL; - - assert(self); - - if (self->content != NULL) - { - if (self->length == 0) - { - (void)trio_string_length(self); - } - if (offset >= 0) - { - if (offset > (int)self->length) - { - offset = self->length; - } - } - else - { - offset += self->length + 1; - if (offset < 0) - { - offset = 0; - } - } - result = &(self->content[offset]); - } - return result; -} - -#endif - -/** - Extract the content. - - @param self Dynamic String - @return Content of dynamic string. - - The content is removed from the dynamic string. This enables destruction - of the dynamic string without deallocation of the content. -*/ -#if defined(TRIO_FUNC_STRING_EXTRACT) - -TRIO_PUBLIC_STRING char * -trio_string_extract -TRIO_ARGS1((self), - trio_string_t *self) -{ - char *result; - - assert(self); - - result = self->content; - /* FIXME: Allocate new empty buffer? */ - self->content = NULL; - self->length = self->allocated = 0; - return result; -} - -#endif - -/** - Set the content of the dynamic string. - - @param self Dynamic String - @param buffer The new content. - - Sets the content of the dynamic string to a copy @p buffer. - An existing content will be deallocated first, if necessary. - - @remark - This function will make a copy of @p buffer. - You are responsible for deallocating @p buffer yourself. -*/ -#if defined(TRIO_FUNC_XSTRING_SET) - -TRIO_PUBLIC_STRING void -trio_xstring_set -TRIO_ARGS2((self, buffer), - trio_string_t *self, - char *buffer) -{ - assert(self); - - trio_destroy(self->content); - self->content = trio_duplicate(buffer); -} - -#endif - -/* - * trio_string_size - */ -#if defined(TRIO_FUNC_STRING_SIZE) - -TRIO_PUBLIC_STRING int -trio_string_size -TRIO_ARGS1((self), - trio_string_t *self) -{ - assert(self); - - return self->allocated; -} - -#endif - -/* - * trio_string_terminate - */ -#if defined(TRIO_FUNC_STRING_TERMINATE) - -TRIO_PUBLIC_STRING void -trio_string_terminate -TRIO_ARGS1((self), - trio_string_t *self) -{ - trio_xstring_append_char(self, 0); -} - -#endif - -/** - Append the second string to the first. - - @param self Dynamic string to be modified. - @param other Dynamic string to copy from. - @return Boolean value indicating success or failure. -*/ -#if defined(TRIO_FUNC_STRING_APPEND) - -TRIO_PUBLIC_STRING int -trio_string_append -TRIO_ARGS2((self, other), - trio_string_t *self, - trio_string_t *other) -{ - size_t length; - - assert(self); - assert(other); - - length = self->length + other->length; - if (!internal_string_grow_to(self, length)) - goto error; - trio_copy(&self->content[self->length], other->content); - self->length = length; - return TRUE; - - error: - return FALSE; -} - -#endif - - -/* - * trio_xstring_append - */ -#if defined(TRIO_FUNC_XSTRING_APPEND) - -TRIO_PUBLIC_STRING int -trio_xstring_append -TRIO_ARGS2((self, other), - trio_string_t *self, - TRIO_CONST char *other) -{ - size_t length; - - assert(self); - assert(other); - - length = self->length + trio_length(other); - if (!internal_string_grow_to(self, length)) - goto error; - trio_copy(&self->content[self->length], other); - self->length = length; - return TRUE; - - error: - return FALSE; -} - -#endif - -/* - * trio_xstring_append_char - */ -#if defined(TRIO_FUNC_XSTRING_APPEND_CHAR) - -TRIO_PUBLIC_STRING int -trio_xstring_append_char -TRIO_ARGS2((self, character), - trio_string_t *self, - char character) -{ - assert(self); - - if ((int)self->length >= trio_string_size(self)) - { - if (!internal_string_grow(self, 0)) - goto error; - } - self->content[self->length] = character; - self->length++; - return TRUE; - - error: - return FALSE; -} - -#endif - -/* - * trio_xstring_append_max - */ -#if defined(TRIO_FUNC_XSTRING_APPEND_MAX) - -TRIO_PUBLIC_STRING int -trio_xstring_append_max -TRIO_ARGS3((self, other, max), - trio_string_t *self, - TRIO_CONST char *other, - size_t max) -{ - size_t length; - - assert(self); - assert(other); - - length = self->length + trio_length_max(other, max); - if (!internal_string_grow_to(self, length)) - goto error; - - /* - * Pass max + 1 since trio_copy_max copies one character less than - * this from the source to make room for a terminating zero. - */ - trio_copy_max(&self->content[self->length], max + 1, other); - self->length = length; - return TRUE; - - error: - return FALSE; -} - -#endif - -/** - Search for the first occurrence of second parameter in the first. - - @param self Dynamic string to be modified. - @param other Dynamic string to copy from. - @return Boolean value indicating success or failure. -*/ -#if defined(TRIO_FUNC_STRING_CONTAINS) - -TRIO_PUBLIC_STRING int -trio_string_contains -TRIO_ARGS2((self, other), - trio_string_t *self, - trio_string_t *other) -{ - assert(self); - assert(other); - - return trio_contains(self->content, other->content); -} - -#endif - -/* - * trio_xstring_contains - */ -#if defined(TRIO_FUNC_XSTRING_CONTAINS) - -TRIO_PUBLIC_STRING int -trio_xstring_contains -TRIO_ARGS2((self, other), - trio_string_t *self, - TRIO_CONST char *other) -{ - assert(self); - assert(other); - - return trio_contains(self->content, other); -} - -#endif - -/* - * trio_string_copy - */ -#if defined(TRIO_FUNC_STRING_COPY) - -TRIO_PUBLIC_STRING int -trio_string_copy -TRIO_ARGS2((self, other), - trio_string_t *self, - trio_string_t *other) -{ - assert(self); - assert(other); - - self->length = 0; - return trio_string_append(self, other); -} - -#endif - - -/* - * trio_xstring_copy - */ -#if defined(TRIO_FUNC_XSTRING_COPY) - -TRIO_PUBLIC_STRING int -trio_xstring_copy -TRIO_ARGS2((self, other), - trio_string_t *self, - TRIO_CONST char *other) -{ - assert(self); - assert(other); - - self->length = 0; - return trio_xstring_append(self, other); -} - -#endif - -/* - * trio_string_duplicate - */ -#if defined(TRIO_FUNC_STRING_DUPLICATE) - -TRIO_PUBLIC_STRING trio_string_t * -trio_string_duplicate -TRIO_ARGS1((other), - trio_string_t *other) -{ - trio_string_t *self; - - assert(other); - - self = internal_string_alloc(); - if (self) - { - self->content = internal_duplicate_max(other->content, other->length); - if (self->content) - { - self->length = other->length; - self->allocated = self->length + 1; - } - else - { - self->length = self->allocated = 0; - } - } - return self; -} - -#endif - -/* - * trio_xstring_duplicate - */ -#if defined(TRIO_FUNC_XSTRING_DUPLICATE) - -TRIO_PUBLIC_STRING trio_string_t * -trio_xstring_duplicate -TRIO_ARGS1((other), - TRIO_CONST char *other) -{ - trio_string_t *self; - - assert(other); - - self = internal_string_alloc(); - if (self) - { - self->content = internal_duplicate_max(other, trio_length(other)); - if (self->content) - { - self->length = trio_length(self->content); - self->allocated = self->length + 1; - } - else - { - self->length = self->allocated = 0; - } - } - return self; -} - -#endif - -/* - * trio_string_equal - */ -#if defined(TRIO_FUNC_STRING_EQUAL) - -TRIO_PUBLIC_STRING int -trio_string_equal -TRIO_ARGS2((self, other), - trio_string_t *self, - trio_string_t *other) -{ - assert(self); - assert(other); - - return trio_equal(self->content, other->content); -} - -#endif - - -/* - * trio_xstring_equal - */ -#if defined(TRIO_FUNC_XSTRING_EQUAL) - -TRIO_PUBLIC_STRING int -trio_xstring_equal -TRIO_ARGS2((self, other), - trio_string_t *self, - TRIO_CONST char *other) -{ - assert(self); - assert(other); - - return trio_equal(self->content, other); -} - -#endif - -/* - * trio_string_equal_max - */ -#if defined(TRIO_FUNC_STRING_EQUAL_MAX) - -TRIO_PUBLIC_STRING int -trio_string_equal_max -TRIO_ARGS3((self, max, other), - trio_string_t *self, - size_t max, - trio_string_t *other) -{ - assert(self); - assert(other); - - return trio_equal_max(self->content, max, other->content); -} -#endif - -/* - * trio_xstring_equal_max - */ -#if defined(TRIO_FUNC_XSTRING_EQUAL_MAX) - -TRIO_PUBLIC_STRING int -trio_xstring_equal_max -TRIO_ARGS3((self, max, other), - trio_string_t *self, - size_t max, - TRIO_CONST char *other) -{ - assert(self); - assert(other); - - return trio_equal_max(self->content, max, other); -} - -#endif - -/* - * trio_string_equal_case - */ -#if defined(TRIO_FUNC_STRING_EQUAL_CASE) - -TRIO_PUBLIC_STRING int -trio_string_equal_case -TRIO_ARGS2((self, other), - trio_string_t *self, - trio_string_t *other) -{ - assert(self); - assert(other); - - return trio_equal_case(self->content, other->content); -} - -#endif - -/* - * trio_xstring_equal_case - */ -#if defined(TRIO_FUNC_XSTRING_EQUAL_CASE) - -TRIO_PUBLIC_STRING int -trio_xstring_equal_case -TRIO_ARGS2((self, other), - trio_string_t *self, - TRIO_CONST char *other) -{ - assert(self); - assert(other); - - return trio_equal_case(self->content, other); -} - -#endif - -/* - * trio_string_equal_case_max - */ -#if defined(TRIO_FUNC_STRING_EQUAL_CASE_MAX) - -TRIO_PUBLIC_STRING int -trio_string_equal_case_max -TRIO_ARGS3((self, max, other), - trio_string_t *self, - size_t max, - trio_string_t *other) -{ - assert(self); - assert(other); - - return trio_equal_case_max(self->content, max, other->content); -} - -#endif - -/* - * trio_xstring_equal_case_max - */ -#if defined(TRIO_FUNC_XSTRING_EQUAL_CASE_MAX) - -TRIO_PUBLIC_STRING int -trio_xstring_equal_case_max -TRIO_ARGS3((self, max, other), - trio_string_t *self, - size_t max, - TRIO_CONST char *other) -{ - assert(self); - assert(other); - - return trio_equal_case_max(self->content, max, other); -} - -#endif - -/* - * trio_string_format_data_max - */ -#if defined(TRIO_FUNC_STRING_FORMAT_DATE_MAX) - -TRIO_PUBLIC_STRING size_t -trio_string_format_date_max -TRIO_ARGS4((self, max, format, datetime), - trio_string_t *self, - size_t max, - TRIO_CONST char *format, - TRIO_CONST struct tm *datetime) -{ - assert(self); - - return trio_format_date_max(self->content, max, format, datetime); -} - -#endif - -/* - * trio_string_index - */ -#if defined(TRIO_FUNC_STRING_INDEX) - -TRIO_PUBLIC_STRING char * -trio_string_index -TRIO_ARGS2((self, character), - trio_string_t *self, - int character) -{ - assert(self); - - return trio_index(self->content, character); -} - -#endif - -/* - * trio_string_index_last - */ -#if defined(TRIO_FUNC_STRING_INDEX_LAST) - -TRIO_PUBLIC_STRING char * -trio_string_index_last -TRIO_ARGS2((self, character), - trio_string_t *self, - int character) -{ - assert(self); - - return trio_index_last(self->content, character); -} - -#endif - -/* - * trio_string_length - */ -#if defined(TRIO_FUNC_STRING_LENGTH) - -TRIO_PUBLIC_STRING int -trio_string_length -TRIO_ARGS1((self), - trio_string_t *self) -{ - assert(self); - - if (self->length == 0) - { - self->length = trio_length(self->content); - } - return self->length; -} - -#endif - -/* - * trio_string_lower - */ -#if defined(TRIO_FUNC_STRING_LOWER) - -TRIO_PUBLIC_STRING int -trio_string_lower -TRIO_ARGS1((self), - trio_string_t *self) -{ - assert(self); - - return trio_lower(self->content); -} - -#endif - -/* - * trio_string_match - */ -#if defined(TRIO_FUNC_STRING_MATCH) - -TRIO_PUBLIC_STRING int -trio_string_match -TRIO_ARGS2((self, other), - trio_string_t *self, - trio_string_t *other) -{ - assert(self); - assert(other); - - return trio_match(self->content, other->content); -} - -#endif - -/* - * trio_xstring_match - */ -#if defined(TRIO_FUNC_XSTRING_MATCH) - -TRIO_PUBLIC_STRING int -trio_xstring_match -TRIO_ARGS2((self, other), - trio_string_t *self, - TRIO_CONST char *other) -{ - assert(self); - assert(other); - - return trio_match(self->content, other); -} - -#endif - -/* - * trio_string_match_case - */ -#if defined(TRIO_FUNC_STRING_MATCH_CASE) - -TRIO_PUBLIC_STRING int -trio_string_match_case -TRIO_ARGS2((self, other), - trio_string_t *self, - trio_string_t *other) -{ - assert(self); - assert(other); - - return trio_match_case(self->content, other->content); -} - -#endif - -/* - * trio_xstring_match_case - */ -#if defined(TRIO_FUNC_XSTRING_MATCH_CASE) - -TRIO_PUBLIC_STRING int -trio_xstring_match_case -TRIO_ARGS2((self, other), - trio_string_t *self, - TRIO_CONST char *other) -{ - assert(self); - assert(other); - - return trio_match_case(self->content, other); -} - -#endif - -/* - * trio_string_substring - */ -#if defined(TRIO_FUNC_STRING_SUBSTRING) - -TRIO_PUBLIC_STRING char * -trio_string_substring -TRIO_ARGS2((self, other), - trio_string_t *self, - trio_string_t *other) -{ - assert(self); - assert(other); - - return trio_substring(self->content, other->content); -} - -#endif - -/* - * trio_xstring_substring - */ -#if defined(TRIO_FUNC_XSTRING_SUBSTRING) - -TRIO_PUBLIC_STRING char * -trio_xstring_substring -TRIO_ARGS2((self, other), - trio_string_t *self, - TRIO_CONST char *other) -{ - assert(self); - assert(other); - - return trio_substring(self->content, other); -} - -#endif - -/* - * trio_string_upper - */ -#if defined(TRIO_FUNC_STRING_UPPER) - -TRIO_PUBLIC_STRING int -trio_string_upper -TRIO_ARGS1((self), - trio_string_t *self) -{ - assert(self); - - return trio_upper(self->content); -} - -#endif - -/** @} End of DynamicStrings */ diff --git a/src/trio/triostr.h b/src/trio/triostr.h deleted file mode 100644 index 27fb7f93..00000000 --- a/src/trio/triostr.h +++ /dev/null @@ -1,699 +0,0 @@ -/* BEEBS trio benchmark - - Copyright (C) 2014 Embecosm Limited and University of Bristol - - This file is part of the Bristol/Embecosm Embedded Benchmark Suite. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* The original source of this file was from: - * http://daniel.haxx.se/projects/trio/ - * and is covered by the following copyright and licence: - * - * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND - * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. - * - ************************************************************************/ - -#ifndef TRIO_TRIOSTR_H -#define TRIO_TRIOSTR_H - -/* - * Documentation is located in triostr.c - */ - -#include -#include -#include -#include "triodef.h" -#include "triop.h" - -#ifdef __cplusplus -extern "C" { -#endif - -enum { - TRIO_HASH_NONE = 0, - TRIO_HASH_PLAIN, - TRIO_HASH_TWOSIGNED -}; - -#if !defined(TRIO_PUBLIC_STRING) -# if !defined(TRIO_PUBLIC) -# define TRIO_PUBLIC -# endif -# define TRIO_PUBLIC_STRING TRIO_PUBLIC -#endif - -/************************************************************************* - * Dependencies - */ - -#if defined(TRIO_EMBED_STRING) - -/* - * The application that triostr is embedded in must define which functions - * it uses. - * - * The following resolves internal dependencies. - */ - -# if defined(TRIO_FUNC_XSTRING_SET) -# if !defined(TRIO_FUNC_DUPLICATE) -# define TRIO_FUNC_DUPLICATE -# endif -# endif - -# if defined(TRIO_FUNC_DUPLICATE) \ - || defined(TRIO_FUNC_DUPLICATE_MAX) \ - || defined(TRIO_FUNC_STRING_DUPLICATE) \ - || defined(TRIO_FUNC_XSTRING_DUPLICATE) -# if !defined(TRIO_FUNC_CREATE) -# define TRIO_FUNC_CREATE -# endif -# if !defined(TRIO_FUNC_COPY_MAX) -# define TRIO_FUNC_COPY_MAX -# endif -# endif - -# if defined(TRIO_FUNC_STRING_CREATE) -# if !defined(TRIO_FUNC_STRING_DESTROY) -# define TRIO_FUNC_STRING_DESTROY -# endif -# endif - -# if defined(TRIO_FUNC_STRING_DESTROY) \ - || defined(TRIO_FUNC_XSTRING_SET) -# if !defined(TRIO_FUNC_DESTROY) -# define TRIO_FUNC_DESTROY -# endif -# endif - -# if defined(TRIO_FUNC_EQUAL_LOCALE) \ - || defined(TRIO_FUNC_STRING_EQUAL) \ - || defined(TRIO_FUNC_XSTRING_EQUAL) -# if !defined(TRIO_FUNC_EQUAL) -# define TRIO_FUNC_EQUAL -# endif -# endif - -# if defined(TRIO_FUNC_EQUAL_CASE) \ - || defined(TRIO_FUNC_STRING_EQUAL_CASE) \ - || defined(TRIO_FUNC_XSTRING_EQUAL_CASE) -# if !defined(TRIO_FUNC_EQUAL_CASE) -# define TRIO_FUNC_EQUAL_CASE -# endif -# endif - -# if defined(TRIO_FUNC_SUBSTRING_MAX) \ - || defined(TRIO_FUNC_STRING_EQUAL_MAX) \ - || defined(TRIO_FUNC_XSTRING_EQUAL_MAX) -# if !defined(TRIO_FUNC_EQUAL_MAX) -# define TRIO_FUNC_EQUAL_MAX -# endif -# endif - -# if defined(TRIO_FUNC_TO_DOUBLE) \ - || defined(TRIO_FUNC_TO_FLOAT) -# if !defined(TRIO_FUNC_TO_LONG_DOUBLE) -# define TRIO_FUNC_TO_LONG_DOUBLE -# endif -# endif - -# if defined(TRIO_FUNC_STRING_TERMINATE) -# if !defined(TRIO_FUNC_XSTRING_APPEND_CHAR) -# define TRIO_FUNC_XSTRING_APPEND_CHAR -# endif -# endif - -# if defined(TRIO_FUNC_XSTRING_APPEND_CHAR) -# if !defined(TRIO_FUNC_STRING_SIZE) -# define TRIO_FUNC_STRING_SIZE -# endif -# endif - -#else - -/* - * When triostr is not embedded all functions are defined. - */ - -# define TRIO_FUNC_APPEND -# define TRIO_FUNC_APPEND_MAX -# define TRIO_FUNC_CONTAINS -# define TRIO_FUNC_COPY -# define TRIO_FUNC_COPY_MAX -# define TRIO_FUNC_CREATE -# define TRIO_FUNC_DESTROY -# define TRIO_FUNC_DUPLICATE -# define TRIO_FUNC_DUPLICATE_MAX -# define TRIO_FUNC_EQUAL -# define TRIO_FUNC_EQUAL_CASE -# define TRIO_FUNC_EQUAL_CASE_MAX -# define TRIO_FUNC_EQUAL_LOCALE -# define TRIO_FUNC_EQUAL_MAX -# define TRIO_FUNC_ERROR -# if !defined(TRIO_PLATFORM_WINCE) -# define TRIO_FUNC_FORMAT_DATE_MAX -# endif -# define TRIO_FUNC_HASH -# define TRIO_FUNC_INDEX -# define TRIO_FUNC_INDEX_LAST -# define TRIO_FUNC_LENGTH -# define TRIO_FUNC_LENGTH_MAX -# define TRIO_FUNC_LOWER -# define TRIO_FUNC_MATCH -# define TRIO_FUNC_MATCH_CASE -# define TRIO_FUNC_SPAN_FUNCTION -# define TRIO_FUNC_SUBSTRING -# define TRIO_FUNC_SUBSTRING_MAX -# define TRIO_FUNC_TO_DOUBLE -# define TRIO_FUNC_TO_FLOAT -# define TRIO_FUNC_TO_LONG -# define TRIO_FUNC_TO_LONG_DOUBLE -# define TRIO_FUNC_TO_LOWER -# define TRIO_FUNC_TO_UNSIGNED_LONG -# define TRIO_FUNC_TO_UPPER -# define TRIO_FUNC_TOKENIZE -# define TRIO_FUNC_UPPER - -# define TRIO_FUNC_STRING_APPEND -# define TRIO_FUNC_STRING_CONTAINS -# define TRIO_FUNC_STRING_COPY -# define TRIO_FUNC_STRING_CREATE -# define TRIO_FUNC_STRING_DESTROY -# define TRIO_FUNC_STRING_DUPLICATE -# define TRIO_FUNC_STRING_EQUAL -# define TRIO_FUNC_STRING_EQUAL_CASE -# define TRIO_FUNC_STRING_EQUAL_CASE_MAX -# define TRIO_FUNC_STRING_EQUAL_MAX -# define TRIO_FUNC_STRING_EXTRACT -# if !defined(TRIO_PLATFORM_WINCE) -# define TRIO_FUNC_STRING_FORMAT_DATE_MAX -# endif -# define TRIO_FUNC_STRING_GET -# define TRIO_FUNC_STRING_INDEX -# define TRIO_FUNC_STRING_INDEX_LAST -# define TRIO_FUNC_STRING_LENGTH -# define TRIO_FUNC_STRING_LOWER -# define TRIO_FUNC_STRING_MATCH -# define TRIO_FUNC_STRING_MATCH_CASE -# define TRIO_FUNC_STRING_SIZE -# define TRIO_FUNC_STRING_SUBSTRING -# define TRIO_FUNC_STRING_TERMINATE -# define TRIO_FUNC_STRING_UPPER - -# define TRIO_FUNC_XSTRING_APPEND -# define TRIO_FUNC_XSTRING_APPEND_CHAR -# define TRIO_FUNC_XSTRING_APPEND_MAX -# define TRIO_FUNC_XSTRING_CONTAINS -# define TRIO_FUNC_XSTRING_COPY -# define TRIO_FUNC_XSTRING_DUPLICATE -# define TRIO_FUNC_XSTRING_EQUAL -# define TRIO_FUNC_XSTRING_EQUAL_CASE -# define TRIO_FUNC_XSTRING_EQUAL_CASE_MAX -# define TRIO_FUNC_XSTRING_EQUAL_MAX -# define TRIO_FUNC_XSTRING_MATCH -# define TRIO_FUNC_XSTRING_MATCH_CASE -# define TRIO_FUNC_XSTRING_SET -# define TRIO_FUNC_XSTRING_SUBSTRING - -#endif - - -/************************************************************************* - * String functions - */ - -#if defined(TRIO_FUNC_APPEND) -TRIO_PUBLIC_STRING int -trio_append -TRIO_PROTO((char *target, TRIO_CONST char *source)); -#endif - -#if defined(TRIO_FUNC_APPEND_MAX) -TRIO_PUBLIC_STRING int -trio_append_max -TRIO_PROTO((char *target, size_t max, TRIO_CONST char *source)); -#endif - -#if defined(TRIO_FUNC_CONTAINS) -TRIO_PUBLIC_STRING int -trio_contains -TRIO_PROTO((TRIO_CONST char *string, TRIO_CONST char *substring)); -#endif - -#if defined(TRIO_FUNC_COPY) -TRIO_PUBLIC_STRING int -trio_copy -TRIO_PROTO((char *target, TRIO_CONST char *source)); -#endif - -#if defined(TRIO_FUNC_COPY_MAX) -TRIO_PUBLIC_STRING int -trio_copy_max -TRIO_PROTO((char *target, size_t max, TRIO_CONST char *source)); -#endif - -#if defined(TRIO_FUNC_CREATE) -TRIO_PUBLIC_STRING char * -trio_create -TRIO_PROTO((size_t size)); -#endif - -#if defined(TRIO_FUNC_DESTROY) -TRIO_PUBLIC_STRING void -trio_destroy -TRIO_PROTO((char *string)); -#endif - -#if defined(TRIO_FUNC_DUPLICATE) -TRIO_PUBLIC_STRING char * -trio_duplicate -TRIO_PROTO((TRIO_CONST char *source)); -#endif - -#if defined(TRIO_FUNC_DUPLICATE_MAX) -TRIO_PUBLIC_STRING char * -trio_duplicate_max -TRIO_PROTO((TRIO_CONST char *source, size_t max)); -#endif - -#if defined(TRIO_FUNC_EQUAL) -TRIO_PUBLIC_STRING int -trio_equal -TRIO_PROTO((TRIO_CONST char *first, TRIO_CONST char *second)); -#endif - -#if defined(TRIO_FUNC_EQUAL_CASE) -TRIO_PUBLIC_STRING int -trio_equal_case -TRIO_PROTO((TRIO_CONST char *first, TRIO_CONST char *second)); -#endif - -#if defined(TRIO_FUNC_EQUAL_CASE_MAX) -TRIO_PUBLIC_STRING int -trio_equal_case_max -TRIO_PROTO((TRIO_CONST char *first, size_t max, TRIO_CONST char *second)); -#endif - -#if defined(TRIO_FUNC_EQUAL_LOCALE) -TRIO_PUBLIC_STRING int -trio_equal_locale -TRIO_PROTO((TRIO_CONST char *first, TRIO_CONST char *second)); -#endif - -#if defined(TRIO_FUNC_EQUAL_MAX) -TRIO_PUBLIC_STRING int -trio_equal_max -TRIO_PROTO((TRIO_CONST char *first, size_t max, TRIO_CONST char *second)); -#endif - -#if defined(TRIO_FUNC_ERROR) -TRIO_PUBLIC_STRING TRIO_CONST char * -trio_error -TRIO_PROTO((int)); -#endif - -#if defined(TRIO_FUNC_FORMAT_DATE_MAX) -TRIO_PUBLIC_STRING size_t -trio_format_date_max -TRIO_PROTO((char *target, size_t max, TRIO_CONST char *format, TRIO_CONST struct tm *datetime)); -#endif - -#if defined(TRIO_FUNC_HASH) -TRIO_PUBLIC_STRING unsigned long -trio_hash -TRIO_PROTO((TRIO_CONST char *string, int type)); -#endif - -#if defined(TRIO_FUNC_INDEX) -TRIO_PUBLIC_STRING char * -trio_index -TRIO_PROTO((TRIO_CONST char *string, int character)); -#endif - -#if defined(TRIO_FUNC_INDEX_LAST) -TRIO_PUBLIC_STRING char * -trio_index_last -TRIO_PROTO((TRIO_CONST char *string, int character)); -#endif - -#if defined(TRIO_FUNC_LENGTH) -TRIO_PUBLIC_STRING size_t -trio_length -TRIO_PROTO((TRIO_CONST char *string)); -#endif - -#if defined(TRIO_FUNC_LENGTH_MAX) -TRIO_PUBLIC_STRING size_t -trio_length_max -TRIO_PROTO((TRIO_CONST char *string, size_t max)); -#endif - -#if defined(TRIO_FUNC_LOWER) -TRIO_PUBLIC_STRING int -trio_lower -TRIO_PROTO((char *target)); -#endif - -#if defined(TRIO_FUNC_MATCH) -TRIO_PUBLIC_STRING int -trio_match -TRIO_PROTO((TRIO_CONST char *string, TRIO_CONST char *pattern)); -#endif - -#if defined(TRIO_FUNC_MATCH_CASE) -TRIO_PUBLIC_STRING int -trio_match_case -TRIO_PROTO((TRIO_CONST char *string, TRIO_CONST char *pattern)); -#endif - -#if defined(TRIO_FUNC_SPAN_FUNCTION) -TRIO_PUBLIC_STRING size_t -trio_span_function -TRIO_PROTO((char *target, TRIO_CONST char *source, int (*Function) TRIO_PROTO((int)))); -#endif - -#if defined(TRIO_FUNC_SUBSTRING) -TRIO_PUBLIC_STRING char * -trio_substring -TRIO_PROTO((TRIO_CONST char *string, TRIO_CONST char *substring)); -#endif - -#if defined(TRIO_FUNC_SUBSTRING_MAX) -TRIO_PUBLIC_STRING char * -trio_substring_max -TRIO_PROTO((TRIO_CONST char *string, size_t max, TRIO_CONST char *substring)); -#endif - -#if defined(TRIO_FUNC_TO_DOUBLE) -TRIO_PUBLIC_STRING double -trio_to_double -TRIO_PROTO((TRIO_CONST char *source, char **endp)); -#endif - -#if defined(TRIO_FUNC_TO_FLOAT) -TRIO_PUBLIC_STRING float -trio_to_float -TRIO_PROTO((TRIO_CONST char *source, char **endp)); -#endif - -#if defined(TRIO_FUNC_TO_LONG) -TRIO_PUBLIC_STRING long -trio_to_long -TRIO_PROTO((TRIO_CONST char *source, char **endp, int base)); -#endif - -#if defined(TRIO_FUNC_TO_LOWER) -TRIO_PUBLIC_STRING int -trio_to_lower -TRIO_PROTO((int source)); -#endif - -#if defined(TRIO_FUNC_TO_LONG_DOUBLE) -TRIO_PUBLIC_STRING trio_long_double_t -trio_to_long_double -TRIO_PROTO((TRIO_CONST char *source, char **endp)); -#endif - -#if defined(TRIO_FUNC_TO_UNSIGNED_LONG) -TRIO_PUBLIC_STRING unsigned long -trio_to_unsigned_long -TRIO_PROTO((TRIO_CONST char *source, char **endp, int base)); -#endif - -#if defined(TRIO_FUNC_TO_UPPER) -TRIO_PUBLIC_STRING int -trio_to_upper -TRIO_PROTO((int source)); -#endif - -#if defined(TRIO_FUNC_TOKENIZE) -TRIO_PUBLIC_STRING char * -trio_tokenize -TRIO_PROTO((char *string, TRIO_CONST char *delimiters)); -#endif - -#if defined(TRIO_FUNC_UPPER) -TRIO_PUBLIC_STRING int -trio_upper -TRIO_PROTO((char *target)); -#endif - -/************************************************************************* - * Dynamic string functions - */ - -/* - * Opaque type for dynamic strings - */ - -typedef struct _trio_string_t trio_string_t; - -#if defined(TRIO_FUNC_STRING_APPEND) -TRIO_PUBLIC_STRING int -trio_string_append -TRIO_PROTO((trio_string_t *self, trio_string_t *other)); -#endif - -#if defined(TRIO_FUNC_STRING_CONTAINS) -TRIO_PUBLIC_STRING int -trio_string_contains -TRIO_PROTO((trio_string_t *self, trio_string_t *other)); -#endif - -#if defined(TRIO_FUNC_STRING_COPY) -TRIO_PUBLIC_STRING int -trio_string_copy -TRIO_PROTO((trio_string_t *self, trio_string_t *other)); -#endif - -#if defined(TRIO_FUNC_STRING_CREATE) -TRIO_PUBLIC_STRING trio_string_t * -trio_string_create -TRIO_PROTO((int initial_size)); -#endif - -#if defined(TRIO_FUNC_STRING_DESTROY) -TRIO_PUBLIC_STRING void -trio_string_destroy -TRIO_PROTO((trio_string_t *self)); -#endif - -#if defined(TRIO_FUNC_STRING_DUPLICATE) -TRIO_PUBLIC_STRING trio_string_t * -trio_string_duplicate -TRIO_PROTO((trio_string_t *other)); -#endif - -#if defined(TRIO_FUNC_STRING_EQUAL) -TRIO_PUBLIC_STRING int -trio_string_equal -TRIO_PROTO((trio_string_t *self, trio_string_t *other)); -#endif - -#if defined(TRIO_FUNC_STRING_EQUAL_MAX) -TRIO_PUBLIC_STRING int -trio_string_equal_max -TRIO_PROTO((trio_string_t *self, size_t max, trio_string_t *second)); -#endif - -#if defined(TRIO_FUNC_STRING_EQUAL_CASE) -TRIO_PUBLIC_STRING int -trio_string_equal_case -TRIO_PROTO((trio_string_t *self, trio_string_t *other)); -#endif - -#if defined(TRIO_FUNC_STRING_EQUAL_CASE_MAX) -TRIO_PUBLIC_STRING int -trio_string_equal_case_max -TRIO_PROTO((trio_string_t *self, size_t max, trio_string_t *other)); -#endif - -#if defined(TRIO_FUNC_STRING_EXTRACT) -TRIO_PUBLIC_STRING char * -trio_string_extract -TRIO_PROTO((trio_string_t *self)); -#endif - -#if defined(TRIO_FUNC_STRING_FORMAT_DATE_MAX) -TRIO_PUBLIC_STRING size_t -trio_string_format_date_max -TRIO_PROTO((trio_string_t *self, size_t max, TRIO_CONST char *format, TRIO_CONST struct tm *datetime)); -#endif - -#if defined(TRIO_FUNC_STRING_GET) -TRIO_PUBLIC_STRING char * -trio_string_get -TRIO_PROTO((trio_string_t *self, int offset)); -#endif - -#if defined(TRIO_FUNC_STRING_INDEX) -TRIO_PUBLIC_STRING char * -trio_string_index -TRIO_PROTO((trio_string_t *self, int character)); -#endif - -#if defined(TRIO_FUNC_STRING_INDEX_LAST) -TRIO_PUBLIC_STRING char * -trio_string_index_last -TRIO_PROTO((trio_string_t *self, int character)); -#endif - -#if defined(TRIO_FUNC_STRING_LENGTH) -TRIO_PUBLIC_STRING int -trio_string_length -TRIO_PROTO((trio_string_t *self)); -#endif - -#if defined(TRIO_FUNC_STRING_LOWER) -TRIO_PUBLIC_STRING int -trio_string_lower -TRIO_PROTO((trio_string_t *self)); -#endif - -#if defined(TRIO_FUNC_STRING_MATCH) -TRIO_PUBLIC_STRING int -trio_string_match -TRIO_PROTO((trio_string_t *self, trio_string_t *other)); -#endif - -#if defined(TRIO_FUNC_STRING_MATCH_CASE) -TRIO_PUBLIC_STRING int -trio_string_match_case -TRIO_PROTO((trio_string_t *self, trio_string_t *other)); -#endif - -#if defined(TRIO_FUNC_STRING_SIZE) -TRIO_PUBLIC_STRING int -trio_string_size -TRIO_PROTO((trio_string_t *self)); -#endif - -#if defined(TRIO_FUNC_STRING_SUBSTRING) -TRIO_PUBLIC_STRING char * -trio_string_substring -TRIO_PROTO((trio_string_t *self, trio_string_t *other)); -#endif - -#if defined(TRIO_FUNC_STRING_TERMINATE) -TRIO_PUBLIC_STRING void -trio_string_terminate -TRIO_PROTO((trio_string_t *self)); -#endif - -#if defined(TRIO_FUNC_STRING_UPPER) -TRIO_PUBLIC_STRING int -trio_string_upper -TRIO_PROTO((trio_string_t *self)); -#endif - -#if defined(TRIO_FUNC_XSTRING_APPEND) -TRIO_PUBLIC_STRING int -trio_xstring_append -TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other)); -#endif - -#if defined(TRIO_FUNC_XSTRING_APPEND_CHAR) -TRIO_PUBLIC_STRING int -trio_xstring_append_char -TRIO_PROTO((trio_string_t *self, char character)); -#endif - -#if defined(TRIO_FUNC_XSTRING_APPEND_MAX) -TRIO_PUBLIC_STRING int -trio_xstring_append_max -TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other, size_t max)); -#endif - -#if defined(TRIO_FUNC_XSTRING_CONTAINS) -TRIO_PUBLIC_STRING int -trio_xstring_contains -TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other)); -#endif - -#if defined(TRIO_FUNC_XSTRING_COPY) -TRIO_PUBLIC_STRING int -trio_xstring_copy -TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other)); -#endif - -#if defined(TRIO_FUNC_XSTRING_DUPLICATE) -TRIO_PUBLIC_STRING trio_string_t * -trio_xstring_duplicate -TRIO_PROTO((TRIO_CONST char *other)); -#endif - -#if defined(TRIO_FUNC_XSTRING_EQUAL) -TRIO_PUBLIC_STRING int -trio_xstring_equal -TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other)); -#endif - -#if defined(TRIO_FUNC_XSTRING_EQUAL_MAX) -TRIO_PUBLIC_STRING int -trio_xstring_equal_max -TRIO_PROTO((trio_string_t *self, size_t max, TRIO_CONST char *other)); -#endif - -#if defined(TRIO_FUNC_XSTRING_EQUAL_CASE) -TRIO_PUBLIC_STRING int -trio_xstring_equal_case -TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other)); -#endif - -#if defined(TRIO_FUNC_XSTRING_EQUAL_CASE_MAX) -TRIO_PUBLIC_STRING int -trio_xstring_equal_case_max -TRIO_PROTO((trio_string_t *self, size_t max, TRIO_CONST char *other)); -#endif - -#if defined(TRIO_FUNC_XSTRING_MATCH) -TRIO_PUBLIC_STRING int -trio_xstring_match -TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other)); -#endif - -#if defined(TRIO_FUNC_XSTRING_MATCH_CASE) -TRIO_PUBLIC_STRING int -trio_xstring_match_case -TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other)); -#endif - -#if defined(TRIO_FUNC_XSTRING_SET) -TRIO_PUBLIC_STRING void -trio_xstring_set -TRIO_PROTO((trio_string_t *self, char *buffer)); -#endif - -#if defined(TRIO_FUNC_XSTRING_SUBSTRING) -TRIO_PUBLIC_STRING char * -trio_xstring_substring -TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other)); -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* TRIO_TRIOSTR_H */ diff --git a/src/ud/Makefile.am b/src/ud/Makefile.am index dfc68a2b..c846707e 100644 --- a/src/ud/Makefile.am +++ b/src/ud/Makefile.am @@ -34,7 +34,8 @@ libud_la_SOURCES = libud.c ud_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libud.la \ - $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) + $(top_builddir)/support/libbeebsc.la \ + $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) diff --git a/src/ud/Makefile.in b/src/ud/Makefile.in index 0969312e..79994594 100644 --- a/src/ud/Makefile.in +++ b/src/ud/Makefile.in @@ -169,7 +169,9 @@ ud_OBJECTS = $(am_ud_OBJECTS) am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_UD_TRUE@ud_DEPENDENCIES = $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_UD_TRUE@ $(top_builddir)/support/libsupport.la \ -@ENABLED_BENCHMARK_UD_TRUE@ libud.la $(am__DEPENDENCIES_1) \ +@ENABLED_BENCHMARK_UD_TRUE@ libud.la \ +@ENABLED_BENCHMARK_UD_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_UD_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_UD_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_UD_TRUE@ $(am__DEPENDENCIES_1) AM_V_P = $(am__v_P_@AM_V@) @@ -391,7 +393,8 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_UD_TRUE@ud_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_UD_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_UD_TRUE@ libud.la \ -@ENABLED_BENCHMARK_UD_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) +@ENABLED_BENCHMARK_UD_TRUE@ $(top_builddir)/support/libbeebsc.la \ +@ENABLED_BENCHMARK_UD_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) all: all-am diff --git a/src/ud/libud.c b/src/ud/libud.c index 9628e736..16580fbf 100644 --- a/src/ud/libud.c +++ b/src/ud/libud.c @@ -1,5 +1,3 @@ - - /* BEEBS ud benchmark Copyright (C) 2014 Embecosm Limited and University of Bristol @@ -21,11 +19,12 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ +#include #include "support.h" /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 3) +#define LOCAL_SCALE_FACTOR 1181 /* MDH WCET BENCHMARK SUITE. File version $Id: ud.c,v 1.4 2005/11/11 10:32:53 ael01 Exp $ */ @@ -118,17 +117,18 @@ int ludcmp(int nmax, int n); /* } */ /* Write to CHKERR from BENCHMARK to ensure calls are not optimised away. */ -volatile int chkerr = 0; - - - +volatile int chkerr; -/* This benchmark does not support verification */ int -verify_benchmark (int res __attribute ((unused)) ) +verify_benchmark (int res) { - return -1; + long int x_ref[20] = + { 0L, 0L, 1L, 1L, 1L, 2L, 0L, 0L, 0L, 0L, + 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L + }; + + return (0 == memcmp (x, x_ref, 20 * sizeof (x[0]))) && (0 == res); } @@ -141,28 +141,34 @@ initialise_benchmark (void) int benchmark() { - int i, j, nmax = 20, n = 5; - long int /* eps, */ w; - - /* eps = 1.0e-6; */ + int k; - /* Init loop */ - for(i = 0; i <= n; i++) + for (k = 0; k < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); k++) { - w = 0.0; /* data to fill in cells */ - for(j = 0; j <= n; j++) - { - a[i][j] = (i + 1) + (j + 1); - if(i == j) /* only once per loop pass */ - a[i][j] *= 2.0; - w += a[i][j]; - } - b[i] = w; + int i, j, nmax = 20, n = 5; + long int /* eps, */ w; + + /* eps = 1.0e-6; */ + + /* Init loop */ + for(i = 0; i <= n; i++) + { + w = 0.0; /* data to fill in cells */ + for(j = 0; j <= n; j++) + { + a[i][j] = (i + 1) + (j + 1); + if(i == j) /* only once per loop pass */ + a[i][j] *= 2.0; + w += a[i][j]; + } + b[i] = w; + } + + /* chkerr = ludcmp(nmax, n, eps); */ + chkerr = ludcmp(nmax,n); } - /* chkerr = ludcmp(nmax, n, eps); */ - chkerr = ludcmp(nmax,n); - return 0; + return chkerr; } int ludcmp(int nmax, int n) diff --git a/src/whetstone/Makefile.am b/src/whetstone/Makefile.am index d91f1c11..bfe96ca4 100644 --- a/src/whetstone/Makefile.am +++ b/src/whetstone/Makefile.am @@ -34,6 +34,7 @@ libwhetstone_la_SOURCES = libwhetstone.c whetstone_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libwhetstone.la \ + $(top_builddir)/support/libbeebsc.la \ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) \ $(LIBM) diff --git a/src/whetstone/Makefile.in b/src/whetstone/Makefile.in index bd6002e8..277dd55b 100644 --- a/src/whetstone/Makefile.in +++ b/src/whetstone/Makefile.in @@ -172,6 +172,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_WHETSTONE_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_WHETSTONE_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_WHETSTONE_TRUE@ libwhetstone.la \ +@ENABLED_BENCHMARK_WHETSTONE_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_WHETSTONE_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_WHETSTONE_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_WHETSTONE_TRUE@ $(am__DEPENDENCIES_1) \ @@ -396,6 +397,7 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_WHETSTONE_TRUE@whetstone_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_WHETSTONE_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_WHETSTONE_TRUE@ libwhetstone.la \ +@ENABLED_BENCHMARK_WHETSTONE_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_WHETSTONE_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) \ @ENABLED_BENCHMARK_WHETSTONE_TRUE@ $(LIBM) diff --git a/src/whetstone/libwhetstone.c b/src/whetstone/libwhetstone.c index da9388f1..70af39ab 100644 --- a/src/whetstone/libwhetstone.c +++ b/src/whetstone/libwhetstone.c @@ -84,7 +84,7 @@ C********************************************************************** /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 10) +#define LOCAL_SCALE_FACTOR 4 /* map the FORTRAN math functions, etc. to the C versions */ @@ -111,12 +111,17 @@ int J,K,L; -/* This benchmark does not support verification */ - int verify_benchmark (int res __attribute ((unused)) ) { - return -1; + int i; + double E1_exp[5] = { 0.0, 3.0, 2.0, 3.0, -1.1302716215293103 }; + + for (i = 0; i < 5; i++) + if (fabs(E1[i] - E1_exp[i]) > 1.0e-16) + return 0; + + return 1; } @@ -129,6 +134,10 @@ initialise_benchmark (void) int benchmark() { + int i; + + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + { /* used in the FORTRAN version */ long I; long N1, N2, N3, N4, N6, N7, N8, N9, N10, N11; @@ -387,7 +396,9 @@ C C where TIME is in seconds. C-------------------------------------------------------------------- */ - return(0); + } + + return(0); } void diff --git a/src/wikisort/Makefile.am b/src/wikisort/Makefile.am index 8fd3164f..0afcdd11 100644 --- a/src/wikisort/Makefile.am +++ b/src/wikisort/Makefile.am @@ -34,6 +34,7 @@ libwikisort_la_SOURCES = libwikisort.c wikisort_LDADD = $(DUMMY_CRT0) \ $(top_builddir)/support/libsupport.la \ libwikisort.la \ + $(top_builddir)/support/libbeebsc.la \ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) \ $(LIBM) diff --git a/src/wikisort/Makefile.in b/src/wikisort/Makefile.in index ee9909a9..6b0a43bc 100644 --- a/src/wikisort/Makefile.in +++ b/src/wikisort/Makefile.in @@ -172,6 +172,7 @@ am__DEPENDENCIES_1 = @ENABLED_BENCHMARK_WIKISORT_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_WIKISORT_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_WIKISORT_TRUE@ libwikisort.la \ +@ENABLED_BENCHMARK_WIKISORT_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_WIKISORT_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_WIKISORT_TRUE@ $(am__DEPENDENCIES_1) \ @ENABLED_BENCHMARK_WIKISORT_TRUE@ $(am__DEPENDENCIES_1) $(LIBM) @@ -394,6 +395,7 @@ top_srcdir = @top_srcdir@ @ENABLED_BENCHMARK_WIKISORT_TRUE@wikisort_LDADD = $(DUMMY_CRT0) \ @ENABLED_BENCHMARK_WIKISORT_TRUE@ $(top_builddir)/support/libsupport.la \ @ENABLED_BENCHMARK_WIKISORT_TRUE@ libwikisort.la \ +@ENABLED_BENCHMARK_WIKISORT_TRUE@ $(top_builddir)/support/libbeebsc.la \ @ENABLED_BENCHMARK_WIKISORT_TRUE@ $(DUMMY_LIBC) $(DUMMY_LIBGCC) $(DUMMY_COMPILERRT) \ @ENABLED_BENCHMARK_WIKISORT_TRUE@ $(LIBM) diff --git a/src/wikisort/libwikisort.c b/src/wikisort/libwikisort.c index c1d6b660..7754579b 100644 --- a/src/wikisort/libwikisort.c +++ b/src/wikisort/libwikisort.c @@ -22,11 +22,12 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ +#include #include "support.h" /* This scale factor will be changed to equalise the runtime of the benchmarks. */ -#define SCALE_FACTOR (REPEAT_FACTOR >> 10) +#define LOCAL_SCALE_FACTOR 2 #include #include @@ -48,32 +49,6 @@ #define Allocate(type, count) (type *)malloc((count) * sizeof(type)) */ -/* BEEBS fixes RAND_MAX to its lowest permitted value, 2^15-1 */ - -#ifdef RAND_MAX -#undef RAND_MAX -#endif -#define RAND_MAX ((1U << 15) - 1) - -/* Yield a sequence of random numbers in the range [0, 2^15-1]. - - The seed is always initialized to zero. long int is guaranteed to be at - least 32 bits. The seed only ever uses 31 bits (so is positive). - - For BEEBS this gets round different operating systems using different - multipliers and offsets and RAND_MAX variations. */ - -static int -rand_beebs () -{ - static long int seed = 0; - - seed = (seed * 1103515245L + 12345) & ((1UL << 31) - 1); - return (int) (seed >> 16); - -} - - long Min(const long a, const long b) { if (a < b) return a; return b; @@ -707,7 +682,7 @@ long TestingJittered(long index, long total) { } long TestingMostlyEqual(long index, long total) { - return 1000 + rand_beebs() * 1.0/RAND_MAX * 4; + return 1000L + (long) (rand_beebs() % 4); } @@ -720,7 +695,90 @@ Test array1[400]; int verify_benchmark (int res __attribute ((unused)) ) { - return -1; + Test exp[] = { + { 1000, 1 }, { 1000, 2 }, { 1000, 13 }, { 1000, 18 }, { 1000, 19 }, + { 1000, 26 }, { 1000, 31 }, { 1000, 32 }, { 1000, 35 }, { 1000, 36 }, + { 1000, 37 }, { 1000, 46 }, { 1000, 49 }, { 1000, 55 }, { 1000, 61 }, + { 1000, 62 }, { 1000, 66 }, { 1000, 72 }, { 1000, 73 }, { 1000, 74 }, + { 1000, 75 }, { 1000, 76 }, { 1000, 77 }, { 1000, 81 }, { 1000, 82 }, + { 1000, 83 }, { 1000, 87 }, { 1000, 89 }, { 1000, 91 }, { 1000, 92 }, + { 1000, 95 }, { 1000, 99 }, { 1000, 101 }, { 1000, 105 }, { 1000, 108 }, + { 1000, 109 }, { 1000, 114 }, { 1000, 119 }, { 1000, 120 }, { 1000, 128 }, + { 1000, 137 }, { 1000, 143 }, { 1000, 144 }, { 1000, 151 }, { 1000, 158 }, + { 1000, 161 }, { 1000, 162 }, { 1000, 165 }, { 1000, 169 }, { 1000, 181 }, + { 1000, 182 }, { 1000, 187 }, { 1000, 188 }, { 1000, 190 }, { 1000, 195 }, + { 1000, 196 }, { 1000, 198 }, { 1000, 200 }, { 1000, 201 }, { 1000, 205 }, + { 1000, 206 }, { 1000, 211 }, { 1000, 212 }, { 1000, 213 }, { 1000, 214 }, + { 1000, 215 }, { 1000, 217 }, { 1000, 221 }, { 1000, 223 }, { 1000, 225 }, + { 1000, 226 }, { 1000, 227 }, { 1000, 233 }, { 1000, 242 }, { 1000, 245 }, + { 1000, 249 }, { 1000, 250 }, { 1000, 266 }, { 1000, 270 }, { 1000, 271 }, + { 1000, 273 }, { 1000, 274 }, { 1000, 280 }, { 1000, 287 }, { 1000, 291 }, + { 1000, 295 }, { 1000, 299 }, { 1000, 303 }, { 1000, 304 }, { 1000, 312 }, + { 1000, 328 }, { 1000, 330 }, { 1000, 333 }, { 1000, 339 }, { 1000, 342 }, + { 1000, 346 }, { 1000, 350 }, { 1000, 361 }, { 1000, 371 }, { 1000, 376 }, + { 1000, 378 }, { 1000, 382 }, { 1000, 384 }, { 1000, 385 }, { 1000, 390 }, + { 1000, 396 }, { 1001, 5 }, { 1001, 7 }, { 1001, 8 }, { 1001, 11 }, + { 1001, 16 }, { 1001, 20 }, { 1001, 21 }, { 1001, 22 }, { 1001, 29 }, + { 1001, 34 }, { 1001, 39 }, { 1001, 40 }, { 1001, 41 }, { 1001, 42 }, + { 1001, 47 }, { 1001, 54 }, { 1001, 63 }, { 1001, 68 }, { 1001, 71 }, + { 1001, 78 }, { 1001, 84 }, { 1001, 85 }, { 1001, 93 }, { 1001, 96 }, + { 1001, 97 }, { 1001, 103 }, { 1001, 104 }, { 1001, 107 }, { 1001, 117 }, + { 1001, 129 }, { 1001, 139 }, { 1001, 140 }, { 1001, 148 }, { 1001, 156 }, + { 1001, 160 }, { 1001, 167 }, { 1001, 172 }, { 1001, 174 }, { 1001, 175 }, + { 1001, 179 }, { 1001, 185 }, { 1001, 186 }, { 1001, 193 }, { 1001, 194 }, + { 1001, 207 }, { 1001, 208 }, { 1001, 216 }, { 1001, 219 }, { 1001, 224 }, + { 1001, 228 }, { 1001, 229 }, { 1001, 235 }, { 1001, 237 }, { 1001, 240 }, + { 1001, 246 }, { 1001, 252 }, { 1001, 255 }, { 1001, 256 }, { 1001, 257 }, + { 1001, 259 }, { 1001, 260 }, { 1001, 261 }, { 1001, 265 }, { 1001, 267 }, + { 1001, 269 }, { 1001, 275 }, { 1001, 286 }, { 1001, 288 }, { 1001, 289 }, + { 1001, 294 }, { 1001, 301 }, { 1001, 302 }, { 1001, 308 }, { 1001, 309 }, + { 1001, 314 }, { 1001, 322 }, { 1001, 323 }, { 1001, 325 }, { 1001, 326 }, + { 1001, 327 }, { 1001, 334 }, { 1001, 337 }, { 1001, 341 }, { 1001, 347 }, + { 1001, 352 }, { 1001, 357 }, { 1001, 360 }, { 1001, 363 }, { 1001, 365 }, + { 1001, 366 }, { 1001, 369 }, { 1001, 375 }, { 1001, 379 }, { 1001, 381 }, + { 1001, 393 }, { 1001, 394 }, { 1001, 398 }, { 1002, 9 }, { 1002, 17 }, + { 1002, 23 }, { 1002, 24 }, { 1002, 30 }, { 1002, 33 }, { 1002, 38 }, + { 1002, 43 }, { 1002, 45 }, { 1002, 53 }, { 1002, 57 }, { 1002, 59 }, + { 1002, 60 }, { 1002, 64 }, { 1002, 69 }, { 1002, 70 }, { 1002, 79 }, + { 1002, 88 }, { 1002, 94 }, { 1002, 98 }, { 1002, 100 }, { 1002, 110 }, + { 1002, 111 }, { 1002, 115 }, { 1002, 118 }, { 1002, 123 }, { 1002, 125 }, + { 1002, 127 }, { 1002, 130 }, { 1002, 131 }, { 1002, 134 }, { 1002, 136 }, + { 1002, 138 }, { 1002, 142 }, { 1002, 146 }, { 1002, 149 }, { 1002, 150 }, + { 1002, 152 }, { 1002, 153 }, { 1002, 157 }, { 1002, 163 }, { 1002, 166 }, + { 1002, 168 }, { 1002, 170 }, { 1002, 171 }, { 1002, 173 }, { 1002, 176 }, + { 1002, 177 }, { 1002, 180 }, { 1002, 183 }, { 1002, 184 }, { 1002, 189 }, + { 1002, 191 }, { 1002, 197 }, { 1002, 202 }, { 1002, 203 }, { 1002, 204 }, + { 1002, 210 }, { 1002, 218 }, { 1002, 220 }, { 1002, 232 }, { 1002, 236 }, + { 1002, 238 }, { 1002, 241 }, { 1002, 243 }, { 1002, 244 }, { 1002, 251 }, + { 1002, 253 }, { 1002, 254 }, { 1002, 258 }, { 1002, 264 }, { 1002, 272 }, + { 1002, 277 }, { 1002, 279 }, { 1002, 282 }, { 1002, 283 }, { 1002, 284 }, + { 1002, 290 }, { 1002, 292 }, { 1002, 296 }, { 1002, 297 }, { 1002, 298 }, + { 1002, 300 }, { 1002, 306 }, { 1002, 307 }, { 1002, 310 }, { 1002, 311 }, + { 1002, 315 }, { 1002, 316 }, { 1002, 319 }, { 1002, 321 }, { 1002, 324 }, + { 1002, 331 }, { 1002, 335 }, { 1002, 340 }, { 1002, 344 }, { 1002, 349 }, + { 1002, 353 }, { 1002, 354 }, { 1002, 358 }, { 1002, 362 }, { 1002, 364 }, + { 1002, 370 }, { 1002, 374 }, { 1002, 380 }, { 1002, 383 }, { 1002, 386 }, + { 1002, 389 }, { 1002, 391 }, { 1002, 392 }, { 1002, 397 }, { 1003, 0 }, + { 1003, 3 }, { 1003, 4 }, { 1003, 6 }, { 1003, 10 }, { 1003, 12 }, + { 1003, 14 }, { 1003, 15 }, { 1003, 25 }, { 1003, 27 }, { 1003, 28 }, + { 1003, 44 }, { 1003, 48 }, { 1003, 50 }, { 1003, 51 }, { 1003, 52 }, + { 1003, 56 }, { 1003, 58 }, { 1003, 65 }, { 1003, 67 }, { 1003, 80 }, + { 1003, 86 }, { 1003, 90 }, { 1003, 102 }, { 1003, 106 }, { 1003, 112 }, + { 1003, 113 }, { 1003, 116 }, { 1003, 121 }, { 1003, 122 }, { 1003, 124 }, + { 1003, 126 }, { 1003, 132 }, { 1003, 133 }, { 1003, 135 }, { 1003, 141 }, + { 1003, 145 }, { 1003, 147 }, { 1003, 154 }, { 1003, 155 }, { 1003, 159 }, + { 1003, 164 }, { 1003, 178 }, { 1003, 192 }, { 1003, 199 }, { 1003, 209 }, + { 1003, 222 }, { 1003, 230 }, { 1003, 231 }, { 1003, 234 }, { 1003, 239 }, + { 1003, 247 }, { 1003, 248 }, { 1003, 262 }, { 1003, 263 }, { 1003, 268 }, + { 1003, 276 }, { 1003, 278 }, { 1003, 281 }, { 1003, 285 }, { 1003, 293 }, + { 1003, 305 }, { 1003, 313 }, { 1003, 317 }, { 1003, 318 }, { 1003, 320 }, + { 1003, 329 }, { 1003, 332 }, { 1003, 336 }, { 1003, 338 }, { 1003, 343 }, + { 1003, 345 }, { 1003, 348 }, { 1003, 351 }, { 1003, 355 }, { 1003, 356 }, + { 1003, 359 }, { 1003, 367 }, { 1003, 368 }, { 1003, 372 }, { 1003, 373 }, + { 1003, 377 }, { 1003, 387 }, { 1003, 388 }, { 1003, 395 }, { 1003, 399 } + }; + + return 0 == memcmp (array1, exp, max_size * sizeof (array1[0])); } @@ -731,46 +789,49 @@ initialise_benchmark (void) -int benchmark() { - long total, index, test_case; - Comparison compare = TestCompare; - - __typeof__(&TestingPathological) test_cases[] = { - TestingPathological, - TestingRandom, - TestingMostlyDescending, - TestingMostlyAscending, - TestingAscending, - TestingDescending, - TestingEqual, - TestingJittered, - TestingMostlyEqual - }; - - /* initialize the random-number generator */ - /* The original code used srand here, but not needed since we are - using a fixed random number generator for reproducibility. - srand(0); - */ - /*srand(10141985);*/ /* in case you want the same random numbers */ - - - total = max_size; - for (test_case = 0; test_case < sizeof(test_cases)/sizeof(test_cases[0]); test_case++) { - - for (index = 0; index < total; index++) { - Test item; - - item.value = test_cases[test_case](index, total); - item.index = index; - - array1[index] = item; - } - - WikiSort(array1, total, compare); - +int benchmark() +{ + long total, index, test_case; + Comparison compare = TestCompare; + + __typeof__(&TestingPathological) test_cases[9] = + { + &TestingPathological, + &TestingRandom, + &TestingMostlyDescending, + &TestingMostlyAscending, + &TestingAscending, + &TestingDescending, + &TestingEqual, + &TestingJittered, + &TestingMostlyEqual + }; + + int i; + + for (i = 0; i < (LOCAL_SCALE_FACTOR * REPEAT_FACTOR); i++) + { + /* initialize the random-number generator. */ + /* The original code used srand here, we use a value that will fit in + a 16-bit unsigned int. */ + srand_beebs (0); + /*srand(10141985);*/ /* in case you want the same random numbers */ + + total = max_size; + for (test_case = 0; test_case < 9; test_case++) { + + for (index = 0; index < total; index++) { + Test item; + + item.value = test_cases[test_case](index, total); + item.index = index; + + array1[index] = item; } - return 0; -} + WikiSort(array1, total, compare); + } + } + return 0; +} diff --git a/support/Makefile.am b/support/Makefile.am index b1637b22..985fc6ca 100644 --- a/support/Makefile.am +++ b/support/Makefile.am @@ -21,24 +21,29 @@ # SPDX-License-Identifier: GPL-3.0-or-later -noinst_LTLIBRARIES = libdummycrt0.la \ - libsupport.la \ +noinst_LTLIBRARIES = libbeebsc.la \ + libdummycrt0.la \ libdummygcc.la \ libdummyc.la \ - libdummym.la + libdummym.la \ + libsupport.la if ARC MAYBE_ARC_MILLICODE=arc-millicode.S endif +libbeebsc_la_SOURCES = beebsc.c \ + beebsc.h + libdummycrt0_la_SOURCES = dummy-crt0.c -libsupport_la_SOURCES = main.c \ - board.c \ - support.h libdummygcc_la_SOURCES = dummy-libgcc.c $(MAYBE_ARC_MILLICODE) libdummyc_la_SOURCES = dummy-libc.c libdummym_la_SOURCES = dummy-libm.c +libsupport_la_SOURCES = main.c \ + board.c \ + support.h + if CHIPSUPPORT_C libsupport_la_SOURCES += chip.c endif diff --git a/support/Makefile.in b/support/Makefile.in index ea2ffb60..7a76b5af 100644 --- a/support/Makefile.in +++ b/support/Makefile.in @@ -127,13 +127,16 @@ CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) -libdummyc_la_LIBADD = -am_libdummyc_la_OBJECTS = dummy-libc.lo -libdummyc_la_OBJECTS = $(am_libdummyc_la_OBJECTS) +libbeebsc_la_LIBADD = +am_libbeebsc_la_OBJECTS = beebsc.lo +libbeebsc_la_OBJECTS = $(am_libbeebsc_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = +libdummyc_la_LIBADD = +am_libdummyc_la_OBJECTS = dummy-libc.lo +libdummyc_la_OBJECTS = $(am_libdummyc_la_OBJECTS) libdummycrt0_la_LIBADD = am_libdummycrt0_la_OBJECTS = dummy-crt0.lo libdummycrt0_la_OBJECTS = $(am_libdummycrt0_la_OBJECTS) @@ -195,12 +198,12 @@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = -SOURCES = $(libdummyc_la_SOURCES) $(libdummycrt0_la_SOURCES) \ - $(libdummygcc_la_SOURCES) $(libdummym_la_SOURCES) \ - $(libsupport_la_SOURCES) -DIST_SOURCES = $(libdummyc_la_SOURCES) $(libdummycrt0_la_SOURCES) \ - $(am__libdummygcc_la_SOURCES_DIST) $(libdummym_la_SOURCES) \ - $(am__libsupport_la_SOURCES_DIST) +SOURCES = $(libbeebsc_la_SOURCES) $(libdummyc_la_SOURCES) \ + $(libdummycrt0_la_SOURCES) $(libdummygcc_la_SOURCES) \ + $(libdummym_la_SOURCES) $(libsupport_la_SOURCES) +DIST_SOURCES = $(libbeebsc_la_SOURCES) $(libdummyc_la_SOURCES) \ + $(libdummycrt0_la_SOURCES) $(am__libdummygcc_la_SOURCES_DIST) \ + $(libdummym_la_SOURCES) $(am__libsupport_la_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -361,18 +364,22 @@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -noinst_LTLIBRARIES = libdummycrt0.la \ - libsupport.la \ +noinst_LTLIBRARIES = libbeebsc.la \ + libdummycrt0.la \ libdummygcc.la \ libdummyc.la \ - libdummym.la + libdummym.la \ + libsupport.la @ARC_TRUE@MAYBE_ARC_MILLICODE = arc-millicode.S +libbeebsc_la_SOURCES = beebsc.c \ + beebsc.h + libdummycrt0_la_SOURCES = dummy-crt0.c -libsupport_la_SOURCES = main.c board.c support.h $(am__append_1) libdummygcc_la_SOURCES = dummy-libgcc.c $(MAYBE_ARC_MILLICODE) libdummyc_la_SOURCES = dummy-libc.c libdummym_la_SOURCES = dummy-libm.c +libsupport_la_SOURCES = main.c board.c support.h $(am__append_1) libsupport_la_CPPFLAGS = -I$(top_srcdir)/config/@ARCH@/boards/@BOARD@ \ -I$(top_srcdir)/config/@ARCH@/chips/@CHIP@ @@ -421,6 +428,9 @@ clean-noinstLTLIBRARIES: rm -f $${locs}; \ } +libbeebsc.la: $(libbeebsc_la_OBJECTS) $(libbeebsc_la_DEPENDENCIES) $(EXTRA_libbeebsc_la_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) $(libbeebsc_la_OBJECTS) $(libbeebsc_la_LIBADD) $(LIBS) + libdummyc.la: $(libdummyc_la_OBJECTS) $(libdummyc_la_DEPENDENCIES) $(EXTRA_libdummyc_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libdummyc_la_OBJECTS) $(libdummyc_la_LIBADD) $(LIBS) @@ -443,6 +453,7 @@ distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arc-millicode.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/beebsc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dummy-crt0.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dummy-libc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dummy-libgcc.Plo@am__quote@ diff --git a/support/beebsc.c b/support/beebsc.c new file mode 100644 index 00000000..417660a6 --- /dev/null +++ b/support/beebsc.c @@ -0,0 +1,177 @@ +/* Copyright (C) 2019 Embecosm Limited and the University of Bristol + + Contributor Jeremy Bennett + + This file is part of BEEBS + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along with + this program. If not, see . */ + +/* These are very simple local versions of library routines, to ensure the + code is compiled with the flags used for the benchmark. Not all library + routines are here, just ones that cause a lot of unecessary load, or where + there is variation between platforms and architectures. */ + +#include +#include +#include "beebsc.h" + +/* Seed for the random number generator */ + +static long int seed = 0; + +/* Heap records and sane initial values */ + +static void *heap_ptr = NULL; +static void *heap_end = NULL; +static size_t heap_requested = 0; + +/* Yield a sequence of random numbers in the range [0, 2^15-1]. + + long int is guaranteed to be at least 32 bits. The seed only ever uses 31 + bits (so is positive). + + For BEEBS this gets round different operating systems using different + multipliers and offsets and RAND_MAX variations. */ + +int +rand_beebs (void) +{ + seed = (seed * 1103515245L + 12345) & ((1UL << 31) - 1); + return (int) (seed >> 16); +} + + +/* Initialize the random number generator */ + +void +srand_beebs (unsigned int new_seed) +{ + seed = (long int) new_seed; +} + + +/* Initialize the BEEBS heap pointers. Note that the actual memory block is + in the caller code. */ + +void +init_heap_beebs (void *heap, + size_t heap_size) +{ + heap_ptr = (void *) heap; + heap_end = heap_ptr + heap_size; + heap_requested = 0; +} + + +/* Report if malloc ever failed. + + Return non-zero (TRUE) if malloc did not reqest more than was available + since the last call to init_heap_beebs, zero (FALSE) otherwise. */ + +int +check_heap_beebs (void *heap) +{ + return (heap + heap_requested <= heap_end); +} + + +/* BEEBS version of malloc. + + This is primarily to reduce library and OS dependencies. Malloc is + generally not used in embedded code, or if it is, only in well defined + contexts to pre-allocate a fixed amount of memory. So this simplistic + implementation is just fine. + + Note in particular the assumption that memory will never be freed! */ + +void * +malloc_beebs (size_t size) +{ + void *new_ptr = heap_ptr; + + heap_requested += size; + + if (((heap_ptr + size) > heap_end) || (0 == size)) + return NULL; + else + { + heap_ptr += size; + return new_ptr; + } +} + + +/* BEEBS version of calloc. + + Implement as wrapper for malloc */ + +void * +calloc_beebs (size_t nmemb, size_t size) +{ + void *new_ptr = malloc_beebs (nmemb * size); + + /* Calloc is defined to zero the memory. OK to use a function here, because + it will be handled specially by the compiler anyway. */ + + if (NULL != new_ptr) + memset (new_ptr, 0, nmemb * size); + + return new_ptr; +} + + +/* BEEBS version of realloc. + + This is primarily to reduce library and OS dependencies. We just have to + allocate new memory and copy stuff across. */ + +void * +realloc_beebs (void *ptr, size_t size) +{ + void *new_ptr = heap_ptr; + + heap_requested += size; + + if (((heap_ptr + size) > heap_end) || (0 == size)) + return NULL; + else + { + heap_ptr += size; + + /* This is clunky, since we don't know the size of the original + pointer. However it is a read only action and we know it must + be big enough if we right off the end, or we couldn't have + allocated here. If the size is smaller, it doesn't matter. */ + + if (NULL != ptr) + { + int i; + + for (i = 0; i < size; i++) + ((char *) new_ptr)[i] = ((char *)ptr)[i]; + } + + return new_ptr; + } +} + + +/* BEEBS version of free. + + For our simplified version of memory handling, free can just do nothing. */ + +void +free_beebs (void *ptr __attribute__ ((unused)) ) +{ +} diff --git a/support/beebsc.h b/support/beebsc.h new file mode 100644 index 00000000..09cdb3d3 --- /dev/null +++ b/support/beebsc.h @@ -0,0 +1,50 @@ +/* Copyright (C) 2019 Embecosm Limited and the University of Bristol + + Contributor Jeremy Bennett + + This file is part of BEEBS + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along with + this program. If not, see . */ + +#ifndef BEEBSC_H +#define BEEBSC_H + +#include + +/* BEEBS fixes RAND_MAX to its lowest permitted value, 2^15-1 */ + +#ifdef RAND_MAX +#undef RAND_MAX +#endif +#define RAND_MAX ((1U << 15) - 1) + +/* Local simplified versions of library functions */ + +int rand_beebs (void); +void srand_beebs (unsigned int new_seed); + +void init_heap_beebs (void *heap, const size_t heap_size); +int check_heap_beebs (void *heap); +void *malloc_beebs (size_t size); +void *calloc_beebs (size_t nmemb, size_t size); +void *realloc_beebs (void *ptr, size_t size); +void free_beebs (void *ptr); +#endif /* BEEBSC_H */ + +/* + Local Variables: + mode: C++ + c-file-style: "gnu" + End: +*/ diff --git a/support/main.c b/support/main.c index 1938ce74..24ab6d36 100644 --- a/support/main.c +++ b/support/main.c @@ -39,14 +39,9 @@ main (int argc __attribute__ ((unused)), initialise_board (); initialise_benchmark (); - start_trigger (); - - for (i = 0; i < REPEAT_FACTOR; i++) - { - initialise_benchmark (); - result = benchmark (); - } + start_trigger (); + result = benchmark (); stop_trigger (); /* bmarks that use arrays will check a global array rather than int result */ diff --git a/support/support.h b/support/support.h index c0928b82..311f439f 100644 --- a/support/support.h +++ b/support/support.h @@ -74,6 +74,10 @@ void stop_trigger (void); int benchmark (void) __attribute__ ((noinline)); +/* Local simplified versions of library functions */ + +#include "beebsc.h" + #endif /* SUPPORT_H */ /*