diff options
-rw-r--r-- | gen/bits/intconf.c | 52 | ||||
-rw-r--r-- | gen/bits/intconf.h | 117 | ||||
-rw-r--r-- | include/assert.h | 2 | ||||
-rw-r--r-- | include/bits/types.h | 3 | ||||
-rw-r--r-- | include/inttypes.h | 61 | ||||
-rw-r--r-- | include/iso646.h | 50 | ||||
-rw-r--r-- | include/memory.h | 10 | ||||
-rw-r--r-- | src/ctype.c | 6 | ||||
-rw-r--r-- | src/slibc-alloc.c | 23 | ||||
-rw-r--r-- | src/string/substring.h | 12 |
10 files changed, 335 insertions, 1 deletions
diff --git a/gen/bits/intconf.c b/gen/bits/intconf.c index 7e48fce..5a52d12 100644 --- a/gen/bits/intconf.c +++ b/gen/bits/intconf.c @@ -21,7 +21,18 @@ +/** + * Used to determine the signness of `char`. + */ volatile char nul = 0; + +/** + * Used to determine the signness of `wchar_t`. + * + * Note that `wchar_t` is set implicitly by the + * help of the compiler so that our libc does + * not taint the result. + */ volatile typeof(L'\0') wnul = 0; @@ -35,6 +46,15 @@ volatile typeof(L'\0') wnul = 0; */ +/** + * Measure the performance of a intrinsic integer type, + * and if it is faster than the previous candidate (or + * is the first candidate,) store it as the, yet, most + * performant candidate. + * + * @param VAR A volatile register variable of the + * type that shall be tested. + */ #define FAST_TEST(VAR) \ n = 0, *VAR##p = 0; \ if (clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start)) \ @@ -65,10 +85,26 @@ volatile typeof(L'\0') wnul = 0; last = this +/** + * Determine whether the performance of `typeof(VAR)` should be determined, + * when finding the most performant, compatiable intrinsic type of a `int_fastN_t`. + * + * @param VAR An variable of the type (or the type itself) that is a candidate. + * @return Determine whether the type shall be tested. + */ #define TEST(VAR) (this = 8 * (int)sizeof(VAR), ((this >= bits) && (this > last))) + #if defined(__GNUC__) __attribute__((optimize("-O0"))) #endif +/** + * Find the (in general) fastest intrinsic integer type, + * that has at least a specified number of bits. + * + * @param bits The minimum number of bits the type may have. + * @return The number of bits the most performance + * compatible integer type has. + */ static int fast(int bits) { int last = 0, this = 0, best = 0, n, m; @@ -103,11 +139,26 @@ static int fast(int bits) #undef TEST +/** + * @param argc The number of command line arguments, should + * be either 1 (print integer width information) + * or 2 (otherwise). + * @param argv Command line arguments, if `argc == 2`, `argv[2]` + * is interpreted as follows: + * - "fast8" Print the number of bits in `int_fast8_t` and `uint_fast8_t`. + * - "fast16" Print the number of bits in `int_fast16_t` and `uint_fast16_t`. + * - "fast32" Print the number of bits in `int_fast32_t` and `uint_fast32_t`. + * - "fast64" Print the number of bits in `int_fast64_t` and `uint_fast64_t`. + * - "char-signed" Print 1 if `char` is signed, and `0` if it is unsigned. + * - "wchar-signed" Print 1 if `wchar_t` is signed, and `0` if it is unsigned. + * @return 0 on success, 1 on error (including printing error.) + */ int main(int argc, char* argv[]) { int r = 0; if (argc < 2) { + /* Print the number of bits in the intrinsic integers types. */ r |= printf("CHAR_BIT %zu\n", 8 * sizeof(char)); r |= printf("SHORT_BIT %zu\n", 8 * sizeof(short int)); r |= printf("INT_BIT %zu\n", 8 * sizeof(int)); @@ -116,6 +167,7 @@ int main(int argc, char* argv[]) r |= printf("PTR_BIT %zu\n", 8 * sizeof(void*)); r |= printf("WCHAR_BIT %zu\n", 8 * sizeof(L'\0')); + /* Print the intrinsic type for specific numbers of bits. */ r |= printf("INT%zu %s\n", 8 * sizeof(char), "char"); r |= printf("INT%zu %s\n", 8 * sizeof(short int), "short int"); r |= printf("INT%zu %s\n", 8 * sizeof(int), "int"); diff --git a/gen/bits/intconf.h b/gen/bits/intconf.h index 128b0ba..69ea473 100644 --- a/gen/bits/intconf.h +++ b/gen/bits/intconf.h @@ -24,41 +24,156 @@ //>FAST32=$(bin/gen/bits/intconf fast32) //>FAST64=$(bin/gen/bits/intconf fast64) -#define __MAX_TO_MIN(max) (-(max) - 1) + +/** + * Converts an integer's maximum value to + * its [the integer's] minimum value. + */ +#define __MAX_TO_MIN(max) (-(max) - 1) /* TODO compiler-flag-dependent */ + +/* TODO compiler-flag-dependent */ #if //(bin/gen/bits/intconf char-signed) +/** + * Set if and only if `char` is signed by default. + */ # define __CHAR_SIGNED + +/** + * The default signness-modifiers for `char`. + */ # define __CHAR_SIGNNESS signed #else # define __CHAR_SIGNNESS unsigned #endif + #if //(bin/gen/bits/intconf wchar-signed) +/** + * Set if and only if `wchar_t` is signed by default. + */ # define __WCHAR_SIGNED + +/** + * The default signness-modifiers for `wchar_t`. + */ # define __WCHAR_SIGNNESS signed #else # define __WCHAR_SIGNNESS unsigned #endif + +/** + * The number of bits in `char`. + * (8 is mandatates, but I did it thus way for uniformity.) + */ #define __CHAR_BIT //(bin/gen/bits/intconf | grep ^CHAR_BIT | sed "s/^[^ ]* //") + +/** + * The number of bits in `short int`. + */ #define __SHORT_BIT //(bin/gen/bits/intconf | grep ^SHORT_BIT | sed "s/^[^ ]* //") + +/** + * The number of bits in `int`. + */ #define __INT_BIT //(bin/gen/bits/intconf | grep ^INT_BIT | sed "s/^[^ ]* //") + +/** + * The number of bits in `long int`. + */ #define __LONG_BIT //(bin/gen/bits/intconf | grep ^LONG_BIT | sed "s/^[^ ]* //") + +/** + * The number of bits in `long long int`. + */ #define __LONG_LONG_BIT //(bin/gen/bits/intconf | grep ^LONG_LONG_BIT | sed "s/^[^ ]* //") + +/** + * The number of bits in `void*`. + */ #define __PTR_BIT //(bin/gen/bits/intconf | grep ^PTR_BIT | sed "s/^[^ ]* //") + +/** + * The number of bits in `wchar`. + */ #define __WCHAR_BIT //(bin/gen/bits/intconf | grep ^WCHAR_BIT | sed "s/^[^ ]* //") + +/** + * The underlaying intrinsic type for `int8_t` or `uint8_t`. + */ #define __INT8 //(bin/gen/bits/intconf | grep ^INT8 | sed "s/^[^ ]* //" | sed 1q) + +/** + * The underlaying intrinsic type for `int16_t` or `uint16_t`. + */ #define __INT16 //(bin/gen/bits/intconf | grep ^INT16 | sed "s/^[^ ]* //" | sed 1q) + +/** + * The underlaying intrinsic type for `int32_t` or `uint32_t`. + */ #define __INT32 //(bin/gen/bits/intconf | grep ^INT32 | sed "s/^[^ ]* //" | sed 1q) + +/** + * The underlaying intrinsic type for `int64_t` or `uint64_t`. + */ #define __INT64 //(bin/gen/bits/intconf | grep ^INT64 | sed "s/^[^ ]* //" | sed 1q) + +/** + * The underlaying intrinsic type for `int8_t` or `uint8_t`. + */ #define __INT_FAST8 __INT//{FAST8} + +/** + * The underlaying intrinsic type for `int16_t` or `uint16_t`. + */ #define __INT_FAST16 __INT//{FAST16} + +/** + * The underlaying intrinsic type for `int32_t` or `uint32_t`. + */ #define __INT_FAST32 __INT//{FAST32} + +/** + * The underlaying intrinsic type for `int64_t` or `uint64_t`. + */ #define __INT_FAST64 __INT//{FAST64} + +/** + * The maximum value of `int_fast8_t`. + */ #define __INT_FAST8_MAX INT//{FAST8}_MAX + +/** + * The maximum value of `int_fast16_t`. + */ #define __INT_FAST16_MAX INT//{FAST16}_MAX + +/** + * The maximum value of `int_fast32_t`. + */ #define __INT_FAST32_MAX INT//{FAST32}_MAX + +/** + * The maximum value of `int_fast64_t`. + */ #define __INT_FAST64_MAX INT//{FAST64}_MAX + +/** + * The maximum value of `uint_fast8_t`. + */ #define __UINT_FAST8_MAX UINT//{FAST8}_MAX + +/** + * The maximum value of `uint_fast16_t`. + */ #define __UINT_FAST16_MAX UINT//{FAST16}_MAX + +/** + * The maximum value of `uint_fast32_t`. + */ #define __UINT_FAST32_MAX UINT//{FAST32}_MAX + +/** + * The maximum value of `uint_fast64_t`. + */ #define __UINT_FAST64_MAX UINT//{FAST64}_MAX diff --git a/include/assert.h b/include/assert.h index 9f964e0..12b20eb 100644 --- a/include/assert.h +++ b/include/assert.h @@ -72,6 +72,8 @@ +/* The definitions above shall be redefined at any time this header file + * is included. The definitions below are static, and thus guarded. */ #ifndef _ASSERT_H #define _ASSERT_H diff --git a/include/bits/types.h b/include/bits/types.h index b7d0bd6..8e40b87 100644 --- a/include/bits/types.h +++ b/include/bits/types.h @@ -23,6 +23,9 @@ #include <bits/intconf.h> +/* TODO [u]int(|_least|_fast)$N_t are compiler-dependent and may even + * be compiler-flag-dependent. Some CPP-magic is required to + * figure there exact underlaying intrinsic type and existence. */ /* Ensure that dependencies for type are defined. */ diff --git a/include/inttypes.h b/include/inttypes.h index 5272ebc..3bae82a 100644 --- a/include/inttypes.h +++ b/include/inttypes.h @@ -63,33 +63,94 @@ intmax_t imaxabs(intmax_t) /* Printing and scanning code affixes. */ +/** + * Length modifier affix for printing an `int8_t` or an `uint8_t`. + * For internal use, not libc-portable. + */ #define __PRI8 "" + +/** + * Length modifier affix for scanning an `int8_t` or an `uint8_t`. + * For internal use, not libc-portable. + */ #define __SCN8 "hh" + +/** + * Length modifier affix for printing an `int16_t` or an `uint16_t`. + * For internal use, not libc-portable. + */ #define __PRI16 "" + +/** + * Length modifier affix for scanning an `int16_t` or an `uint16_t`. + * For internal use, not libc-portable. + */ #define __SCN16 "h" + #if __INT_BIT == 32 +/** + * Length modifier affix for printing an `int32_t` or an `uint32_t`. + * For internal use, not libc-portable. + */ # define __PRI32 "" + +/** + * Length modifier affix for scanning an `int32_t` or an `uint32_t`. + * For internal use, not libc-portable. + */ # define __SCN32 "" #else # define __PRI32 "l" # define __SCN32 "l" #endif + #if __LONG_BIT == 64 +/** + * Length modifier affix for printing an `int64_t` or an `uint64_t`. + * For internal use, not libc-portable. + */ # define __PRI64 "l" + +/** + * Length modifier affix for scanning an `int64_t` or an `uint64_t`. + * For internal use, not libc-portable. + */ # define __SCN64 "l" #else # define __PRI64 "ll" # define __SCN64 "ll" #endif + +/** + * Length modifier affix for printing an `intmax_t` or an `uintmax_t`. + * For internal use, not libc-portable. + */ #define __PRIMAX "j" + +/** + * Length modifier affix for scanning an `intmax_t` or an `uintmax_t`. + * For internal use, not libc-portable. + */ #define __SCNMAX "j" + #if __PTR_BIT == 8 +/** + * Length modifier affix for printing an `intptr_t`, an `uintptr_t`, + * a `ptrdiff_t`, an `uptrdiff_t`, an `ssize_t, or a `size_t`. + * For internal use, not libc-portable. + */ # define __PRIPTR __PRI8 + +/** + * Length modifier affix for scanning an `intptr_t`, an `uintptr_t`, + * a `ptrdiff_t`, an `uptrdiff_t`, an `ssize_t, or a `size_t`. + * For internal use, not libc-portable. + */ # define __SCNPTR __SCN8 #elif __PTR_BIT == 16 # define __PRIPTR __PRI16 diff --git a/include/iso646.h b/include/iso646.h index c0c7a51..51edb6a 100644 --- a/include/iso646.h +++ b/include/iso646.h @@ -25,17 +25,67 @@ #endif +/* These defitions were added in C95 to make it easier incase + * your keyboard layout does not have these characters. + * Interestingly, all other ASCII punctuation was not considered. + * Also, if you really need this, using the terminal must be + * a pain in the ass for you. */ + + +/** + * Alias for logical and (&&). + */ #define and && + +/** + * Alias for bitwise and assignement (&=). + */ #define and_eq &= + +/** + * Alias for bitwise and (&). + */ #define bitand & + +/** + * Alias for bitwise inclusive or (|). + */ #define bitor | + +/** + * Alias for bitwise complement (~). + */ #define compl ~ + +/** + * Alias for logical complement (!). + */ #define not ! + +/** + * Alias for inequality comparer (!=). + */ #define not_eq != + +/** + * Alias for logical inclusive (||). + */ #define or || + +/** + * Alias for bitwise inclusive or assignment (|=). + */ #define or_eq |= + +/** + * Alias for bitwise exclusive or (^). + */ #define xor ^ + +/** + * Alias for bitwise exclusive or assignment (^=). + */ #define xor_eq ^= diff --git a/include/memory.h b/include/memory.h index 795e07e..f0a7f6f 100644 --- a/include/memory.h +++ b/include/memory.h @@ -15,5 +15,15 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#ifndef _MEMORY_H +#define _MEMORY_H #include <string.h> + +#if !defined(_SLIBC_SUPPRESS_WARNINGS) +# warning "Please include <string.h> instead of <memory.h>." +#endif + + +#endif + diff --git a/src/ctype.c b/src/ctype.c index 2c8fe83..3923def 100644 --- a/src/ctype.c +++ b/src/ctype.c @@ -268,6 +268,12 @@ int _toupper(int c) +/** + * Create a variant, with specifiable locale, + * of one of the functions. + * + * @param The name of the function without the `_l`-suffix. + */ #define CTYPE_LOCALE(F) \ int F##_l(int c, locale_t locale) \ { \ diff --git a/src/slibc-alloc.c b/src/slibc-alloc.c index 604eff1..a7ae30a 100644 --- a/src/slibc-alloc.c +++ b/src/slibc-alloc.c @@ -25,8 +25,31 @@ +/** + * Get the alignment-shift of a pointer. + * + * @param p:void* The pointer. + * @return :size_t The number of bytes added for alignment. + * This excludes the information this macro + * reads, and the storage of the allocation-size. + */ #define __ALIGN(p) (*(size_t*)(((char*)(p)) - sizeof(size_t))) + +/** + * Get the allocated pointer from a returned pointer. + * + * @param p:void* The pointer returned by a `malloc`-family function. + * @return The pointer allocated by a `malloc`-family function. + */ #define PURE_ALLOC(p) (((char*)(p)) - (__ALIGN(p) + 2 * sizeof(size_t))) + +/** + * Get the real allocation is of a pointer, including + * the size of the metadata storage and the alignment-padding. + * + * @param p:void* The pointer. + * @return :size_t The real allocation size of the pointer. + */ #define PURE_SIZE(p) (*(size_t*)PURE_ALLOC(p) + 2 * sizeof(size_t)) diff --git a/src/string/substring.h b/src/string/substring.h index 9d6dbfe..05ef7cc 100644 --- a/src/string/substring.h +++ b/src/string/substring.h @@ -30,6 +30,16 @@ /* The Knuth–Morris–Pratt algorithm. */ +/** + * Test whether to characters are equal. + * Case-sensitivity depends on `CASE` being defined. + * + * @param a One of the characters. + * @param b The other character. + * @return 1 if `a` and `b` or equal, 0 otherwise. + * The comparison is case-insensitive if + * `CASE` is defined. + */ #if !defined(CASE) # define CHREQ(a, b) (a == b) #elif !defined(WIDE) @@ -42,6 +52,8 @@ /* TODO add support for RIGHT */ +/* The implementation of the algorithm, read + * elsewhere for documentation/explanation. */ { ssize_t* next_map = alloca((needle_length + 1) * sizeof(ssize_t)); ssize_t hay, ned, skp; |