diff --git a/Architecture/amd64/Limine.c b/Architecture/amd64/Limine.c index 22412f0..e0d3415 100644 --- a/Architecture/amd64/Limine.c +++ b/Architecture/amd64/Limine.c @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include "../../kernel.h" diff --git a/Core/CPU.cpp b/Core/CPU.cpp index f630b2c..0761b61 100644 --- a/Core/CPU.cpp +++ b/Core/CPU.cpp @@ -1,7 +1,7 @@ #include #include -#include +#include #include #include "../kernel.h" diff --git a/Core/Memory/Memory.cpp b/Core/Memory/Memory.cpp index d3ba21e..fbed8fe 100644 --- a/Core/Memory/Memory.cpp +++ b/Core/Memory/Memory.cpp @@ -1,6 +1,6 @@ #include -#include +#include #include #include "HeapAllocators/Xalloc.hpp" @@ -11,14 +11,6 @@ using namespace Memory; Physical KernelAllocator; PageTable *KernelPageTable = nullptr; -enum MemoryAllocatorType -{ - None, - Pages, - XallocV1, - liballoc11 -}; - static MemoryAllocatorType AllocatorType = MemoryAllocatorType::None; Xalloc::AllocatorV1 *XallocV1Allocator = nullptr; diff --git a/Core/Memory/VirtualMemoryManager.cpp b/Core/Memory/VirtualMemoryManager.cpp index f011528..ce56beb 100644 --- a/Core/Memory/VirtualMemoryManager.cpp +++ b/Core/Memory/VirtualMemoryManager.cpp @@ -1,6 +1,6 @@ #include -#include +#include #include namespace Memory diff --git a/Core/Symbols.cpp b/Core/Symbols.cpp index 792b134..6aedcf8 100644 --- a/Core/Symbols.cpp +++ b/Core/Symbols.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include #include // #pragma GCC diagnostic ignored "-Wignored-qualifiers" diff --git a/Library/String.c b/Library/Convert.c similarity index 71% rename from Library/String.c rename to Library/Convert.c index 7f4d1c1..f563839 100644 --- a/Library/String.c +++ b/Library/Convert.c @@ -1,5 +1,6 @@ -#include +#include #include +#include // TODO: Replace mem* with assembly code @@ -418,6 +419,23 @@ char *strstr(const char *haystack, const char *needle) } } +char *strchr(const char *String, int Char) +{ + while (*String != (char)Char) + { + if (!*String++) + return 0; + } + return (char *)String; +} + +char *strdup(const char *String) +{ + char *OutBuffer = kmalloc(strlen((char *)String) + 1); + strcpy(OutBuffer, String); + return OutBuffer; +} + int isdigit(int c) { return c >= '0' && c <= '9'; @@ -440,3 +458,142 @@ int isempty(char *str) } return 1; } + +int abs(int i) { return i < 0 ? -i : i; } + +void swap(char *x, char *y) +{ + char t = *x; + *x = *y; + *y = t; +} + +char *reverse(char *Buffer, int i, int j) +{ + while (i < j) + swap(&Buffer[i++], &Buffer[j--]); + return Buffer; +} + +int atoi(const char *String) +{ + uint64_t Length = strlen((char *)String); + uint64_t OutBuffer = 0; + uint64_t Power = 1; + for (uint64_t i = Length; i > 0; --i) + { + OutBuffer += (String[i - 1] - 48) * Power; + Power *= 10; + } + return OutBuffer; +} + +double atof(const char *String) +{ + // Originally from https://github.com/GaloisInc/minlibc/blob/master/atof.c + /* + Copyright (c) 2014 Galois Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + * Neither the name of Galois, Inc. nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + double a = 0.0; + int e = 0; + int c; + while ((c = *String++) != '\0' && isdigit(c)) + { + a = a * 10.0 + (c - '0'); + } + if (c == '.') + { + while ((c = *String++) != '\0' && isdigit(c)) + { + a = a * 10.0 + (c - '0'); + e = e - 1; + } + } + if (c == 'e' || c == 'E') + { + int sign = 1; + int i = 0; + c = *String++; + if (c == '+') + c = *String++; + else if (c == '-') + { + c = *String++; + sign = -1; + } + while (isdigit(c)) + { + i = i * 10 + (c - '0'); + c = *String++; + } + e += i * sign; + } + while (e > 0) + { + a *= 10.0; + e--; + } + while (e < 0) + { + a *= 0.1; + e++; + } + return a; +} + +char *itoa(int Value, char *Buffer, int Base) +{ + if (Base < 2 || Base > 32) + return Buffer; + + int n = abs(Value); + int i = 0; + + while (n) + { + int r = n % Base; + if (r >= 10) + Buffer[i++] = 65 + (r - 10); + else + Buffer[i++] = 48 + r; + n = n / Base; + } + + if (i == 0) + Buffer[i++] = '0'; + + if (Value < 0 && Base == 10) + Buffer[i++] = '-'; + + Buffer[i] = '\0'; + return reverse(Buffer, 0, i - 1); +} diff --git a/Library/printf.c b/Library/printf.c index 09a777e..73c3c9e 100644 --- a/Library/printf.c +++ b/Library/printf.c @@ -37,21 +37,21 @@ * THE SOFTWARE. */ -#pragma GCC diagnostic ignored "-Wtype-limits" -#pragma GCC diagnostic ignored "-Wsign-compare" -#pragma GCC diagnostic ignored "-Wtautological-compare" -#pragma GCC diagnostic ignored "-Wsign-compare" - -// Define this globally (e.g. gcc -DPRINTF_INCLUDE_CONFIG_H ...) to include the +// Define this globally (e.g. gcc -DPRINTF_INCLUDE_CONFIG_H=1 ...) to include the // printf_config.h header file #if PRINTF_INCLUDE_CONFIG_H #include "printf_config.h" #endif +#include + +#ifdef __cplusplus +#include +#include +#else #include #include -#include -#include +#endif // __cplusplus #if PRINTF_ALIAS_STANDARD_FUNCTION_NAMES #define printf_ printf @@ -104,7 +104,7 @@ #endif // Support for the long long integral types (with the ll, z and t length modifiers for specifiers -// %d,%i,%o,%x,%X,%u, and with the %p specifier). Note: 'L' (long / *doubl e*/unsigned long) is not supported. +// %d,%i,%o,%x,%X,%u, and with the %p specifier). Note: 'L' (long double) is not supported. #ifndef PRINTF_SUPPORT_LONG_LONG #define PRINTF_SUPPORT_LONG_LONG 1 #endif @@ -120,6 +120,12 @@ #error "At least one non-constant Taylor expansion is necessary for the log10() calculation" #endif +// Be extra-safe, and don't assume format specifiers are completed correctly +// before the format string end. +#ifndef PRINTF_CHECK_FOR_NUL_IN_FORMAT_SPECIFIER +#define PRINTF_CHECK_FOR_NUL_IN_FORMAT_SPECIFIER 1 +#endif + #define PRINTF_PREFER_DECIMAL false #define PRINTF_PREFER_EXPONENTIAL true @@ -245,14 +251,14 @@ typedef uint64_t double_uint_t; #define DOUBLE_MAX_SUBNORMAL_POWER_OF_10 1e-308 #else -#error "Unsupported / *doubl e*/unsigned long type configuration" +#error "Unsupported double type configuration" #endif #define DOUBLE_STORED_MANTISSA_BITS (DBL_MANT_DIG - 1) typedef union { double_uint_t U; - /* double */ unsigned long F; + double F; } double_with_bit_access; // This is unnecessary in C99, since compound initializers can be used, @@ -260,14 +266,14 @@ typedef union // 1. Some compilers are finicky about this; // 2. Some people may want to convert this to C89; // 3. If you try to use it as C++, only C++20 supports compound literals -static inline double_with_bit_access get_bit_access(/* double */ unsigned long x) +static inline double_with_bit_access get_bit_access(double x) { double_with_bit_access dwba; dwba.F = x; return dwba; } -static inline int get_sign_bit(/* double */ unsigned long x) +static inline int get_sign_bit(double x) { // The sign is stored in the highest bit return (int)(get_bit_access(x).U >> (DOUBLE_SIZE_IN_BITS - 1)); @@ -356,7 +362,7 @@ static inline void putchar_wrapper(char c, void *unused) putchar(c); } -static inline output_gadget_t discarding_gadget() +static inline output_gadget_t discarding_gadget(void) { output_gadget_t gadget; gadget.function = NULL; @@ -388,7 +394,7 @@ static inline output_gadget_t function_gadget(void (*function)(char, void *), vo return result; } -static inline output_gadget_t extern_putchar_gadget() +static inline output_gadget_t extern_putchar_gadget(void) { return function_gadget(putchar_wrapper, NULL); } @@ -576,53 +582,50 @@ static void print_integer(output_gadget_t *output, printf_unsigned_value_t value #if (PRINTF_SUPPORT_DECIMAL_SPECIFIERS || PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS) -// Stores a fixed-precision representation of a / *doubl e*/unsigned long relative +// Stores a fixed-precision representation of a double relative // to a fixed precision (which cannot be determined by examining this structure) struct double_components { int_fast64_t integral; int_fast64_t fractional; - // ... truncation of the actual fractional part of the / *doubl e*/unsigned long value, scaled + // ... truncation of the actual fractional part of the double value, scaled // by the precision value bool is_negative; }; #define NUM_DECIMAL_DIGITS_IN_INT64_T 18 #define PRINTF_MAX_PRECOMPUTED_POWER_OF_10 NUM_DECIMAL_DIGITS_IN_INT64_T -static const /* double */ unsigned long powers_of_10[NUM_DECIMAL_DIGITS_IN_INT64_T] = { +static const double powers_of_10[NUM_DECIMAL_DIGITS_IN_INT64_T] = { 1e00, 1e01, 1e02, 1e03, 1e04, 1e05, 1e06, 1e07, 1e08, 1e09, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17}; #define PRINTF_MAX_SUPPORTED_PRECISION NUM_DECIMAL_DIGITS_IN_INT64_T - 1 -// Break up a / *doubl e*/unsigned long number - which is known to be a finite non-negative number - +// Break up a double number - which is known to be a finite non-negative number - // into its base-10 parts: integral - before the decimal point, and fractional - after it. // Taken the precision into account, but does not change it even internally. -static struct double_components get_components(/* double */ unsigned long number, printf_size_t precision) +static struct double_components get_components(double number, printf_size_t precision) { struct double_components number_; number_.is_negative = get_sign_bit(number); - /* double */ unsigned long abs_number = (number_.is_negative) ? -number : number; + double abs_number = (number_.is_negative) ? -number : number; number_.integral = (int_fast64_t)abs_number; - /* double */ unsigned long remainder = (abs_number - (/* double */ unsigned long)number_.integral) * powers_of_10[precision]; + double remainder = (abs_number - (double)number_.integral) * powers_of_10[precision]; number_.fractional = (int_fast64_t)remainder; - remainder -= (/* double */ unsigned long)number_.fractional; + remainder -= (double)number_.fractional; - // if (remainder > 0.5) - warn("SSE not supported."); - if (remainder > 1) + if (remainder > 0.5) { ++number_.fractional; // handle rollover, e.g. case 0.99 with precision 1 is 1.0 - if ((/* double */ unsigned long)number_.fractional >= powers_of_10[precision]) + if ((double)number_.fractional >= powers_of_10[precision]) { number_.fractional = 0; ++number_.integral; } } - // else if ((remainder == 0.5) && ((number_.fractional == 0U) || (number_.fractional & 1U))) - else if ((remainder == 1) && ((number_.fractional == 0U) || (number_.fractional & 1U))) + else if ((remainder == 0.5) && ((number_.fractional == 0U) || (number_.fractional & 1U))) { // if halfway, round up if odd OR if last digit is 0 ++number_.fractional; @@ -630,9 +633,8 @@ static struct double_components get_components(/* double */ unsigned long number if (precision == 0U) { - remainder = abs_number - (/* double */ unsigned long)number_.integral; - // if ((!(remainder < 0.5) || (remainder > 0.5)) && (number_.integral & 1)) - if ((!(remainder < 1) || (remainder > 1)) && (number_.integral & 1)) + remainder = abs_number - (double)number_.integral; + if ((!(remainder < 0.5) || (remainder > 0.5)) && (number_.integral & 1)) { // exactly 0.5 and ODD, then round up // 1.5 -> 2, but 2.5 -> 2 @@ -645,21 +647,29 @@ static struct double_components get_components(/* double */ unsigned long number #if PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS struct scaling_factor { - /* double */ unsigned long raw_factor; + double raw_factor; bool multiply; // if true, need to multiply by raw_factor; otherwise need to divide by it }; -static /* double */ unsigned long apply_scaling(/* double */ unsigned long num, struct scaling_factor normalization) +static double apply_scaling(double num, struct scaling_factor normalization) { return normalization.multiply ? num * normalization.raw_factor : num / normalization.raw_factor; } -static /* double */ unsigned long unapply_scaling(/* double */ unsigned long normalized, struct scaling_factor normalization) +static double unapply_scaling(double normalized, struct scaling_factor normalization) { +#ifdef __GNUC__ +// accounting for a static analysis bug in GCC 6.x and earlier +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#endif return normalization.multiply ? normalized / normalization.raw_factor : normalized * normalization.raw_factor; +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif } -static struct scaling_factor update_normalization(struct scaling_factor sf, /* double */ unsigned long extra_multiplicative_factor) +static struct scaling_factor update_normalization(struct scaling_factor sf, double extra_multiplicative_factor) { struct scaling_factor result; if (sf.multiply) @@ -687,11 +697,11 @@ static struct scaling_factor update_normalization(struct scaling_factor sf, /* d return result; } -static struct double_components get_normalized_components(bool negative, printf_size_t precision, /* double */ unsigned long non_normalized, struct scaling_factor normalization, int floored_exp10) +static struct double_components get_normalized_components(bool negative, printf_size_t precision, double non_normalized, struct scaling_factor normalization, int floored_exp10) { struct double_components components; components.is_negative = negative; - /* double */ unsigned long scaled = apply_scaling(non_normalized, normalization); + double scaled = apply_scaling(non_normalized, normalization); bool close_to_representation_extremum = ((-floored_exp10 + (int)precision) >= DBL_MAX_10_EXP - 1); if (close_to_representation_extremum) @@ -702,14 +712,14 @@ static struct double_components get_normalized_components(bool negative, printf_ return get_components(negative ? -scaled : scaled, precision); } components.integral = (int_fast64_t)scaled; - /* double */ unsigned long remainder = non_normalized - unapply_scaling((/* double */ unsigned long)components.integral, normalization); - /* double */ unsigned long prec_power_of_10 = powers_of_10[precision]; + double remainder = non_normalized - unapply_scaling((double)components.integral, normalization); + double prec_power_of_10 = powers_of_10[precision]; struct scaling_factor account_for_precision = update_normalization(normalization, prec_power_of_10); - /* double */ unsigned long scaled_remainder = apply_scaling(remainder, account_for_precision); - /* double */ unsigned long rounding_threshold = 1; // 0.5; + double scaled_remainder = apply_scaling(remainder, account_for_precision); + double rounding_threshold = 0.5; - components.fractional = (int_fast64_t)scaled_remainder; // when precision == 0, the assigned value should be 0 - scaled_remainder -= (/* double */ unsigned long)components.fractional; // when precision == 0, this will not change scaled_remainder + components.fractional = (int_fast64_t)scaled_remainder; // when precision == 0, the assigned value should be 0 + scaled_remainder -= (double)components.fractional; // when precision == 0, this will not change scaled_remainder components.fractional += (scaled_remainder >= rounding_threshold); if (scaled_remainder == rounding_threshold) @@ -722,7 +732,7 @@ static struct double_components get_normalized_components(bool negative, printf_ // Note: for precision = 0, this will "translate" the rounding effect from // the fractional part to the integral part where it should actually be // felt (as prec_power_of_10 is 1) - if ((/* double */ unsigned long)components.fractional >= prec_power_of_10) + if ((double)components.fractional >= prec_power_of_10) { components.fractional = 0; ++components.integral; @@ -833,7 +843,7 @@ static void print_broken_up_decimal( } // internal ftoa for fixed decimal floating point -static void print_decimal_number(output_gadget_t *output, /* double */ unsigned long number, printf_size_t precision, printf_size_t width, printf_flags_t flags, char *buf, printf_size_t len) +static void print_decimal_number(output_gadget_t *output, double number, printf_size_t precision, printf_size_t width, printf_flags_t flags, char *buf, printf_size_t len) { struct double_components value_ = get_components(number, precision); print_broken_up_decimal(value_, output, precision, width, flags, buf, len); @@ -843,19 +853,19 @@ static void print_decimal_number(output_gadget_t *output, /* double */ unsigned // A floor function - but one which only works for numbers whose // floor value is representable by an int. -static int bastardized_floor(/* double */ unsigned long x) +static int bastardized_floor(double x) { if (x >= 0) { return (int)x; } int n = (int)x; - return (((/* double */ unsigned long)n) == x) ? n : n - 1; + return (((double)n) == x) ? n : n - 1; } // Computes the base-10 logarithm of the input number - which must be an actual // positive number (not infinity or NaN, nor a sub-normal) -static /* double */ unsigned long log10_of_positive(/* double */ unsigned long positive_number) +static double log10_of_positive(double positive_number) { // The implementation follows David Gay (https://www.ampl.com/netlib/fp/dtoa.c). // @@ -871,36 +881,23 @@ static /* double */ unsigned long log10_of_positive(/* double */ unsigned long p // drop the exponent, so dwba.F comes into the range [1,2) dwba.U = (dwba.U & (((double_uint_t)(1) << DOUBLE_STORED_MANTISSA_BITS) - 1U)) | ((double_uint_t)DOUBLE_BASE_EXPONENT << DOUBLE_STORED_MANTISSA_BITS); - /* double */ unsigned long z = (dwba.F - 1 /* 1.5 */); - // return ( - // // Taylor expansion around 1.5: - // 0.1760912590556812420 // Expansion term 0: ln(1.5) / ln(10) - // + z * 0.2895296546021678851 // Expansion term 1: (M - 1.5) * 2/3 / ln(10) - // #if PRINTF_LOG10_TAYLOR_TERMS > 2 - // - z * z * 0.0965098848673892950 // Expansion term 2: (M - 1.5)^2 * 2/9 / ln(10) - // #if PRINTF_LOG10_TAYLOR_TERMS > 3 - // + z * z * z * 0.0428932821632841311 // Expansion term 2: (M - 1.5)^3 * 8/81 / ln(10) - // #endif - // #endif - // // exact log_2 of the exponent x, with logarithm base change - // + exp2 * 0.30102999566398119521 // = exp2 * log_10(2) = exp2 * ln(2)/ln(10) - // ); + double z = (dwba.F - 1.5); return ( // Taylor expansion around 1.5: - 0 // Expansion term 0: ln(1.5) / ln(10) - + z * 0 // Expansion term 1: (M - 1.5) * 2/3 / ln(10) + 0.1760912590556812420 // Expansion term 0: ln(1.5) / ln(10) + + z * 0.2895296546021678851 // Expansion term 1: (M - 1.5) * 2/3 / ln(10) #if PRINTF_LOG10_TAYLOR_TERMS > 2 - - z * z * 0 // Expansion term 2: (M - 1.5)^2 * 2/9 / ln(10) + - z * z * 0.0965098848673892950 // Expansion term 2: (M - 1.5)^2 * 2/9 / ln(10) #if PRINTF_LOG10_TAYLOR_TERMS > 3 - + z * z * z * 0 // Expansion term 2: (M - 1.5)^3 * 8/81 / ln(10) + + z * z * z * 0.0428932821632841311 // Expansion term 2: (M - 1.5)^3 * 8/81 / ln(10) #endif #endif // exact log_2 of the exponent x, with logarithm base change - + exp2 * 0 // = exp2 * log_10(2) = exp2 * ln(2)/ln(10) + + exp2 * 0.30102999566398119521 // = exp2 * log_10(2) = exp2 * ln(2)/ln(10) ); } -static /* double */ unsigned long pow10_of_int(int floored_exp10) +static double pow10_of_int(int floored_exp10) { // A crude hack for avoiding undesired behavior with barely-normal or slightly-subnormal values. if (floored_exp10 == DOUBLE_MAX_SUBNORMAL_EXPONENT_OF_10) @@ -909,11 +906,9 @@ static /* double */ unsigned long pow10_of_int(int floored_exp10) } // Compute 10^(floored_exp10) but (try to) make sure that doesn't overflow double_with_bit_access dwba; - // int exp2 = bastardized_floor(floored_exp10 * 3.321928094887362 + 0.5); - // const /* double */ unsigned long z = floored_exp10 * 2.302585092994046 - exp2 * 0.6931471805599453; - int exp2 = bastardized_floor(floored_exp10 * 3 + 1 /* 0.5 */); - const /* double */ unsigned long z = floored_exp10 * 2 - exp2 * 0; - const /* double */ unsigned long z2 = z * z; + int exp2 = bastardized_floor(floored_exp10 * 3.321928094887362 + 0.5); + const double z = floored_exp10 * 2.302585092994046 - exp2 * 0.6931471805599453; + const double z2 = z * z; dwba.U = ((double_uint_t)(exp2) + DOUBLE_BASE_EXPONENT) << DOUBLE_STORED_MANTISSA_BITS; // compute exp(z) using continued fractions, // see https://en.wikipedia.org/wiki/Exponential_function#Continued_fractions_for_ex @@ -921,28 +916,27 @@ static /* double */ unsigned long pow10_of_int(int floored_exp10) return dwba.F; } -static void print_exponential_number(output_gadget_t *output, /* double */ unsigned long number, printf_size_t precision, printf_size_t width, printf_flags_t flags, char *buf, printf_size_t len) +static void print_exponential_number(output_gadget_t *output, double number, printf_size_t precision, printf_size_t width, printf_flags_t flags, char *buf, printf_size_t len) { const bool negative = get_sign_bit(number); // This number will decrease gradually (by factors of 10) as we "extract" the exponent out of it - /* double */ unsigned long abs_number = negative ? -number : number; + double abs_number = negative ? -number : number; int floored_exp10; bool abs_exp10_covered_by_powers_table; struct scaling_factor normalization; // Determine the decimal exponent - // if (abs_number == 0.0) - if (abs_number == 0) + if (abs_number == 0.0) { // TODO: This is a special-case for 0.0 (and -0.0); but proper handling is required for denormals more generally. floored_exp10 = 0; // ... and no need to set a normalization factor or check the powers table } else { - /* double */ unsigned long exp10 = log10_of_positive(abs_number); + double exp10 = log10_of_positive(abs_number); floored_exp10 = bastardized_floor(exp10); - /* double */ unsigned long p10 = pow10_of_int(floored_exp10); + double p10 = pow10_of_int(floored_exp10); // correct for rounding errors if (abs_number < p10) { @@ -1001,7 +995,7 @@ static void print_exponential_number(output_gadget_t *output, /* double */ unsig } } - // the floored_exp10 format is "E%+03d" and largest possible floored_exp10 value for a 64-bit / *doubl e*/unsigned long + // the floored_exp10 format is "E%+03d" and largest possible floored_exp10 value for a 64-bit double // is "307" (for 2^1023), so we set aside 4-5 characters overall printf_size_t exp10_part_width = fall_back_to_decimal_only_mode ? 0U : (PRINTF_ABS(floored_exp10) < 100) ? 4U : 5U; @@ -1045,7 +1039,7 @@ static void print_exponential_number(output_gadget_t *output, /* double */ unsig } #endif // PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS -static void print_floating_point(output_gadget_t *output, /* double */ unsigned long value, printf_size_t precision, printf_size_t width, printf_flags_t flags, bool prefer_exponential) +static void print_floating_point(output_gadget_t *output, double value, printf_size_t precision, printf_size_t width, printf_flags_t flags, bool prefer_exponential) { char buf[PRINTF_DECIMAL_BUFFER_SIZE]; printf_size_t len = 0U; @@ -1056,22 +1050,19 @@ static void print_floating_point(output_gadget_t *output, /* double */ unsigned out_rev_(output, "nan", 3, width, flags); return; } - // if (value < -DBL_MAX) - if (value < -1) + if (value < -DBL_MAX) { out_rev_(output, "fni-", 4, width, flags); return; } - // if (value > DBL_MAX) - if (value > 1) + if (value > DBL_MAX) { out_rev_(output, (flags & FLAGS_PLUS) ? "fni+" : "fni", (flags & FLAGS_PLUS) ? 4U : 3U, width, flags); return; } if (!prefer_exponential && - // ((value > PRINTF_FLOAT_NOTATION_THRESHOLD) || (value < -PRINTF_FLOAT_NOTATION_THRESHOLD))) - ((value > 1) || (value < -1))) + ((value > PRINTF_FLOAT_NOTATION_THRESHOLD) || (value < -PRINTF_FLOAT_NOTATION_THRESHOLD))) { // The required behavior of standard printf is to print _every_ integral-part digit -- which could mean // printing hundreds of characters, overflowing any fixed internal buffer and necessitating a more complicated @@ -1140,29 +1131,31 @@ static printf_flags_t parse_flags(const char **format) } while (true); } -// internal vsnprintf - used for implementing _all library functions -// Note: We don't like the C standard's parameter names, so using more informative parameter names -// here instead. -static int _vsnprintf(output_gadget_t *output, const char *format, va_list args) +static inline void format_string_loop(output_gadget_t *output, const char *format, va_list args) { - // Note: The library only calls _vsnprintf() with output->pos being 0. However, it is - // possible to call this function with a non-zero pos value for some "remedial printing". +#if PRINTF_CHECK_FOR_NUL_IN_FORMAT_SPECIFIER +#define ADVANCE_IN_FORMAT_STRING(cptr_) \ + do \ + { \ + (cptr_)++; \ + if (!*(cptr_)) \ + return; \ + } while (0) +#else +#define ADVANCE_IN_FORMAT_STRING(cptr_) (cptr_)++ +#endif while (*format) { - // format specifier? %[flags][width][.precision][length] if (*format != '%') { - // no + // A regular content character putchar_via_gadget(output, *format); format++; continue; } - else - { - // yes, evaluate it - format++; - } + // We're parsing a format specifier: %[flags][width][.precision][length] + ADVANCE_IN_FORMAT_STRING(format); printf_flags_t flags = parse_flags(&format); @@ -1184,7 +1177,7 @@ static int _vsnprintf(output_gadget_t *output, const char *format, va_list args) { width = (printf_size_t)w; } - format++; + ADVANCE_IN_FORMAT_STRING(format); } // evaluate precision field @@ -1192,7 +1185,7 @@ static int _vsnprintf(output_gadget_t *output, const char *format, va_list args) if (*format == '.') { flags |= FLAGS_PRECISION; - format++; + ADVANCE_IN_FORMAT_STRING(format); if (is_digit_(*format)) { precision = (printf_size_t)atou_(&format); @@ -1201,7 +1194,7 @@ static int _vsnprintf(output_gadget_t *output, const char *format, va_list args) { const int precision_ = va_arg(args, int); precision = precision_ > 0 ? (printf_size_t)precision_ : 0U; - format++; + ADVANCE_IN_FORMAT_STRING(format); } } @@ -1211,16 +1204,16 @@ static int _vsnprintf(output_gadget_t *output, const char *format, va_list args) #ifdef PRINTF_SUPPORT_MSVC_STYLE_INTEGER_SPECIFIERS case 'I': { - format++; + ADVANCE_IN_FORMAT_STRING(format); // Greedily parse for size in bits: 8, 16, 32 or 64 switch (*format) { case '8': flags |= FLAGS_INT8; - format++; + ADVANCE_IN_FORMAT_STRING(format); break; case '1': - format++; + ADVANCE_IN_FORMAT_STRING(format); if (*format == '6') { format++; @@ -1228,18 +1221,18 @@ static int _vsnprintf(output_gadget_t *output, const char *format, va_list args) } break; case '3': - format++; + ADVANCE_IN_FORMAT_STRING(format); if (*format == '2') { - format++; + ADVANCE_IN_FORMAT_STRING(format); flags |= FLAGS_INT32; } break; case '6': - format++; + ADVANCE_IN_FORMAT_STRING(format); if (*format == '4') { - format++; + ADVANCE_IN_FORMAT_STRING(format); flags |= FLAGS_INT64; } break; @@ -1251,33 +1244,33 @@ static int _vsnprintf(output_gadget_t *output, const char *format, va_list args) #endif case 'l': flags |= FLAGS_LONG; - format++; + ADVANCE_IN_FORMAT_STRING(format); if (*format == 'l') { flags |= FLAGS_LONG_LONG; - format++; + ADVANCE_IN_FORMAT_STRING(format); } break; case 'h': flags |= FLAGS_SHORT; - format++; + ADVANCE_IN_FORMAT_STRING(format); if (*format == 'h') { flags |= FLAGS_CHAR; - format++; + ADVANCE_IN_FORMAT_STRING(format); } break; case 't': flags |= (sizeof(ptrdiff_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); - format++; + ADVANCE_IN_FORMAT_STRING(format); break; case 'j': flags |= (sizeof(intmax_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); - format++; + ADVANCE_IN_FORMAT_STRING(format); break; case 'z': flags |= (sizeof(size_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); - format++; + ADVANCE_IN_FORMAT_STRING(format); break; default: break; @@ -1390,7 +1383,7 @@ static int _vsnprintf(output_gadget_t *output, const char *format, va_list args) case 'F': if (*format == 'F') flags |= FLAGS_UPPERCASE; - print_floating_point(output, va_arg(args, /* double */ unsigned long), precision, width, flags, PRINTF_PREFER_DECIMAL); + print_floating_point(output, va_arg(args, double), precision, width, flags, PRINTF_PREFER_DECIMAL); format++; break; #endif @@ -1403,7 +1396,7 @@ static int _vsnprintf(output_gadget_t *output, const char *format, va_list args) flags |= FLAGS_ADAPT_EXP; if ((*format == 'E') || (*format == 'G')) flags |= FLAGS_UPPERCASE; - print_floating_point(output, va_arg(args, /* double */ unsigned long), precision, width, flags, PRINTF_PREFER_EXPONENTIAL); + print_floating_point(output, va_arg(args, double), precision, width, flags, PRINTF_PREFER_EXPONENTIAL); format++; break; #endif // PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS @@ -1517,6 +1510,14 @@ static int _vsnprintf(output_gadget_t *output, const char *format, va_list args) break; } } +} + +// internal vsnprintf - used for implementing _all library functions +static int vsnprintf_impl(output_gadget_t *output, const char *format, va_list args) +{ + // Note: The library only calls vsnprintf_impl() with output->pos being 0. However, it is + // possible to call this function with a non-zero pos value for some "remedial printing". + format_string_loop(output, format, args); // termination append_termination_with_gadget(output); @@ -1530,13 +1531,13 @@ static int _vsnprintf(output_gadget_t *output, const char *format, va_list args) int vprintf_(const char *format, va_list arg) { output_gadget_t gadget = extern_putchar_gadget(); - return _vsnprintf(&gadget, format, arg); + return vsnprintf_impl(&gadget, format, arg); } int vsnprintf_(char *s, size_t n, const char *format, va_list arg) { output_gadget_t gadget = buffer_gadget(s, n); - return _vsnprintf(&gadget, format, arg); + return vsnprintf_impl(&gadget, format, arg); } int vsprintf_(char *s, const char *format, va_list arg) @@ -1547,7 +1548,7 @@ int vsprintf_(char *s, const char *format, va_list arg) int vfctprintf(void (*out)(char c, void *extra_arg), void *extra_arg, const char *format, va_list arg) { output_gadget_t gadget = function_gadget(out, extra_arg); - return _vsnprintf(&gadget, format, arg); + return vsnprintf_impl(&gadget, format, arg); } int printf_(const char *format, ...) @@ -1585,7 +1586,3 @@ int fctprintf(void (*out)(char c, void *extra_arg), void *extra_arg, const char va_end(args); return ret; } - -#ifdef __cplusplus -} // extern "C" -#endif \ No newline at end of file diff --git a/include/string.h b/include/convert.h similarity index 83% rename from include/string.h rename to include/convert.h index aeeac0e..b37d96e 100644 --- a/include/string.h +++ b/include/convert.h @@ -9,6 +9,13 @@ extern "C" int isspace(int c); int isempty(char *str); unsigned int isdelim(char c, char *delim); + int abs(int i); + void swap(char *x, char *y); + char *reverse(char *Buffer, int i, int j); + + int atoi(const char *String); + double atof(const char *String); + char *itoa(int Value, char *Buffer, int Base); void *memcpy(void *dest, const void *src, size_t n); void *memset(void *dest, int c, size_t n); diff --git a/include/cstring b/include/cstring index 3e144e1..2817fcc 100644 --- a/include/cstring +++ b/include/cstring @@ -1,2 +1,2 @@ #pragma once -#include +#include diff --git a/include/memory.hpp b/include/memory.hpp index 49009e5..2fe6d43 100644 --- a/include/memory.hpp +++ b/include/memory.hpp @@ -1,11 +1,15 @@ #ifndef __FENNIX_KERNEL_INTERNAL_MEMORY_H__ #define __FENNIX_KERNEL_INTERNAL_MEMORY_H__ +#ifdef __cplusplus #include #include #include +#endif // __cplusplus #include +#ifdef __cplusplus + extern uint64_t _kernel_start, _kernel_end; extern uint64_t _kernel_text_end, _kernel_data_end, _kernel_rodata_end; @@ -51,6 +55,14 @@ extern uint64_t _kernel_text_end, _kernel_data_end, _kernel_rodata_end; namespace Memory { + enum MemoryAllocatorType + { + None, + Pages, + XallocV1, + liballoc11 + }; + /** * @brief https://wiki.osdev.org/images/4/41/64-bit_page_tables1.png * @brief https://wiki.osdev.org/images/6/6b/64-bit_page_tables2.png @@ -429,17 +441,19 @@ void operator delete[](void *Pointer); void operator delete(void *Pointer, long unsigned int Size); void operator delete[](void *Pointer, long unsigned int Size); -void *HeapMalloc(uint64_t Size); -void *HeapCalloc(uint64_t n, uint64_t Size); -void *HeapRealloc(void *Address, uint64_t Size); -void HeapFree(void *Address); +extern Memory::Physical KernelAllocator; +extern Memory::PageTable *KernelPageTable; + +#endif // __cplusplus + +EXTERNC void *HeapMalloc(uint64_t Size); +EXTERNC void *HeapCalloc(uint64_t n, uint64_t Size); +EXTERNC void *HeapRealloc(void *Address, uint64_t Size); +EXTERNC void HeapFree(void *Address); #define kmalloc(Size) HeapMalloc(Size) #define kcalloc(n, Size) HeapCalloc(n, Size) #define krealloc(Address, Size) HeapRealloc(Address, Size) #define kfree(Address) HeapFree(Address) -extern Memory::Physical KernelAllocator; -extern Memory::PageTable *KernelPageTable; - #endif // !__FENNIX_KERNEL_INTERNAL_MEMORY_H__