diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..61ce89f --- /dev/null +++ b/.clang-format @@ -0,0 +1,10 @@ +--- +DerivePointerAlignment: 'true' +SpaceBeforeParens: ControlStatements +UseTab: ForIndentation +IndentWidth: 2 +TabWidth: 2 +ColumnLimit: 120 +BreakBeforeBraces: Attach + +... diff --git a/arch/i386/tty.c b/arch/i386/tty.c old mode 100755 new mode 100644 index 94b9940..7774c35 --- a/arch/i386/tty.c +++ b/arch/i386/tty.c @@ -6,15 +6,15 @@ #include "kernel/tty.h" #include "kernel/utils.h" -static const size_t TERM_WIDTH=80; -static const size_t TERM_HEIGHT=25; +static const size_t TERM_WIDTH = 80; +static const size_t TERM_HEIGHT = 25; static size_t terminal_row; static size_t terminal_column; static uint8_t current_color; static uint16_t* term_buffer; -static uint16_t* const vga_buffer = (uint16_t*) 0xB8000; +static uint16_t* const vga_buffer = (uint16_t*)0xB8000; void screen_initialize(void) { @@ -24,18 +24,16 @@ void screen_initialize(void) { term_buffer = vga_buffer; for (size_t y = 0; y < TERM_HEIGHT; y++) { - for(size_t x = 0; x < TERM_WIDTH; x++) { + for (size_t x = 0; x < TERM_WIDTH; x++) { const size_t offset = y * TERM_WIDTH + x; term_buffer[offset] = vga_entry(' ', current_color); } } } -void term_setcolor(enum vga_colors color) { - current_color = color; -} +void term_setcolor(enum vga_colors color) { current_color = color; } -void term_putentryat (char c, uint8_t color, size_t x, size_t y) { +void term_putentryat(char c, uint8_t color, size_t x, size_t y) { const size_t offset = y * TERM_WIDTH + x; term_buffer[offset] = vga_entry(c, color); } @@ -43,38 +41,35 @@ void term_putentryat (char c, uint8_t color, size_t x, size_t y) { void term_putchar(char c) { unsigned char uc = c; - //Handle escaped characters, such as newline, and crtn. + // Handle escaped characters, such as newline, and crtn. switch (uc) { - case '\n': + case '\n': + terminal_column = 0; + terminal_row += 1; + break; + default: + term_putentryat(uc, current_color, terminal_column, terminal_row); + if (++terminal_column == TERM_WIDTH) { terminal_column = 0; - terminal_row += 1; - break; - default: - term_putentryat(uc, current_color, terminal_column, terminal_row); - if (++terminal_column == TERM_WIDTH) { - terminal_column = 0; - if (++terminal_row == TERM_HEIGHT) { - term_scroll(false); - terminal_row = 0; - } + if (++terminal_row == TERM_HEIGHT) { + term_scroll(false); + terminal_row = 0; } - break; + } + break; } - } struct csi_sequence parse_csi(const char* data, size_t size) { enum State { PARAMETER, INTERMEDIATE, FINAL, INVALID }; enum State state = PARAMETER; - struct csi_sequence sequence = { - .parameter = NULL, - .parameter_len = 0, - .intermediate = NULL, - .intermediate_len = 0, - .final = NULL, - .valid = false - }; + struct csi_sequence sequence = {.parameter = NULL, + .parameter_len = 0, + .intermediate = NULL, + .intermediate_len = 0, + .final = NULL, + .valid = false}; for (size_t j = 0; j < size; j++) { uint8_t c = data[j]; @@ -103,57 +98,56 @@ struct csi_sequence parse_csi(const char* data, size_t size) { } void term_write(const char* data, size_t size) { - for(size_t i = 0; i < size; i++) { - //Begin handling ANSI escape codes. - if(data[i] == 0x1b) { //The current character is ESC - the start of ANSI codes. - //term_writes("ANSI Code encountered: "); + for (size_t i = 0; i < size; i++) { + // Begin handling ANSI escape codes. + if (data[i] == 0x1b) { // The current character is ESC - the start of ANSI codes. + // term_writes("ANSI Code encountered: "); - bool string_terminated = false; //Flag used in some of the escape codes + bool string_terminated = false; // Flag used in some of the escape codes // TODO: Should only progress if we have at least 2 more bytes switch ((uint8_t)data[i + 1]) { - case '[': //CSI - Control Sequence Introducer (The most common one, hence it comes first) - { - struct csi_sequence sequence = parse_csi(data + i + 2, size - (i + 2)); - if (sequence.valid) { - // Send it off to our handler function to keep this part clean - handleControlSequence(sequence); - i += sequence.parameter_len + sequence.intermediate_len + 2; // Move past sequence - } - } - break; - //Single shifts are not handled, so just print them and exit - case 'N': //SS2 - Single Shift Two - term_writes("Single Shift Two\n"); - break; - case 'O': //SS3 - Single Shift Three - term_writes("Single Shift Three\n"); - break; + case '[': // CSI - Control Sequence Introducer (The most common one, hence it comes first) + { + struct csi_sequence sequence = parse_csi(data + i + 2, size - (i + 2)); + if (sequence.valid) { + // Send it off to our handler function to keep this part clean + handleControlSequence(sequence); + i += sequence.parameter_len + sequence.intermediate_len + 2; // Move past sequence + } + } break; + // Single shifts are not handled, so just print them and exit + case 'N': // SS2 - Single Shift Two + term_writes("Single Shift Two\n"); + break; + case 'O': // SS3 - Single Shift Three + term_writes("Single Shift Three\n"); + break; - //Control Strings - case 'P': //DCS - Device Control String - term_writes("Device Control String"); - string_terminated = false; - break; - case '\\': //ST - String Terminator - term_writes("String Terminator\n"); - string_terminated = true; - break; - case ']': //OSC - Operating System Command - term_writes("Operating System Command\n"); - string_terminated = false; - break; - case 'X': //SOS - Start Of String - term_writes("Start of String"); - string_terminated = false; - break; - case '^': //PM - Privacy Message - term_writes("Privacy Message\n"); - break; - case '_': //APC - Application Program Command - term_writes("Application Program Command\n"); - break; + // Control Strings + case 'P': // DCS - Device Control String + term_writes("Device Control String"); + string_terminated = false; + break; + case '\\': // ST - String Terminator + term_writes("String Terminator\n"); + string_terminated = true; + break; + case ']': // OSC - Operating System Command + term_writes("Operating System Command\n"); + string_terminated = false; + break; + case 'X': // SOS - Start Of String + term_writes("Start of String"); + string_terminated = false; + break; + case '^': // PM - Privacy Message + term_writes("Privacy Message\n"); + break; + case '_': // APC - Application Program Command + term_writes("Application Program Command\n"); + break; } } else { term_putchar(data[i]); @@ -161,9 +155,7 @@ void term_write(const char* data, size_t size) { } } -void term_writes(const char* data) { - term_write(data, strlen(data)); -} +void term_writes(const char* data) { term_write(data, strlen(data)); } void puts(const char* string) { term_write(string, strlen(string)); @@ -171,10 +163,10 @@ void puts(const char* string) { } void handleControlSequence(struct csi_sequence sequence) { - //Check for our failsafes + // Check for our failsafes if (sequence.valid) { - int n = 0; //Default of the flag used for a few items + int n = 0; // Default of the flag used for a few items // Parse parameters, we only care about a max 2 of number only parameters // for now @@ -184,7 +176,7 @@ void handleControlSequence(struct csi_sequence sequence) { for (size_t i = 0; i < sequence.parameter_len && param_count < 1; i++) { char c = sequence.parameter[i]; if (isDigit(c)) { - n = (n*10) + (sequence.parameter[i] - '0'); + n = (n * 10) + (sequence.parameter[i] - '0'); } else if (c == ';') { params[param_count++] = n; } @@ -193,96 +185,103 @@ void handleControlSequence(struct csi_sequence sequence) { } switch (*(sequence.final)) { - case 'H': case 'f': // CUP - Cursor Position - // TODO: Check to see if we have 2 paramaters - if (params[0]) params[0]--; - if (params[1]) params[1]--; - set_cursor(params[0], params[1]); - break; - case 'A': //CUU - Cursor Up - if (!params[0]) params[0] = 1; - set_cursor(terminal_column, terminal_row - params[0]); - break; - case 'B': //CUD - Cursor Down - if (!params[0]) params[0] = 1; - set_cursor(terminal_column, terminal_row + params[0]); - break; - case 'C': //CUF - Cursor Forward - if (!params[0]) params[0] = 1; - set_cursor(terminal_column + params[0], terminal_row); - break; - case 'D': //CUB - Cursor Back - if (!params[0]) params[0] = 1; - set_cursor(terminal_column - params[0], terminal_row); - break; - case 'E': //CNL - Cursor Next Line - if (!params[0]) params[0] = 1; - set_cursor(0, terminal_row + params[0]); - break; - case 'F': //CPL - Cursor Previous Line - if (!params[0]) params[0] = 1; - set_cursor(0, terminal_row - params[0]); - break; - case 'G': //CHA - Cursor Horizontal Absolute - if (params[0]) params[0]--; - set_cursor(params[0], terminal_row); - break; - case 'J': //ED - Erase in Display - //current cursor pos = y * width + x - { - int pos = terminal_row * 80 + terminal_column; - if (params[0] == 0) { // Clear from cursor to end of screen - for(; pos < (25 * 80); pos++) { - vga_buffer[pos] = '\0'; - } - } else if(params[0] == 1) { // Clear from cursor to beginning - for(; pos > 0; pos--) { - vga_buffer[pos] = '\0'; - } - } else if(params[0] == 2 || params[0] == 3) { // Clear entire screen - // TODO: Support scrollback buffer? (n = 3) - for(int i = 0; i < (25*80); i++) { - vga_buffer[0] = '\0'; - } - } + case 'H': + case 'f': // CUP - Cursor Position + // TODO: Check to see if we have 2 paramaters + if (params[0]) + params[0]--; + if (params[1]) + params[1]--; + set_cursor(params[0], params[1]); + break; + case 'A': // CUU - Cursor Up + if (!params[0]) + params[0] = 1; + set_cursor(terminal_column, terminal_row - params[0]); + break; + case 'B': // CUD - Cursor Down + if (!params[0]) + params[0] = 1; + set_cursor(terminal_column, terminal_row + params[0]); + break; + case 'C': // CUF - Cursor Forward + if (!params[0]) + params[0] = 1; + set_cursor(terminal_column + params[0], terminal_row); + break; + case 'D': // CUB - Cursor Back + if (!params[0]) + params[0] = 1; + set_cursor(terminal_column - params[0], terminal_row); + break; + case 'E': // CNL - Cursor Next Line + if (!params[0]) + params[0] = 1; + set_cursor(0, terminal_row + params[0]); + break; + case 'F': // CPL - Cursor Previous Line + if (!params[0]) + params[0] = 1; + set_cursor(0, terminal_row - params[0]); + break; + case 'G': // CHA - Cursor Horizontal Absolute + if (params[0]) + params[0]--; + set_cursor(params[0], terminal_row); + break; + case 'J': // ED - Erase in Display + { + // current cursor pos = y * width + x + int pos = terminal_row * 80 + terminal_column; + if (params[0] == 0) { // Clear from cursor to end of screen + for (; pos < (25 * 80); pos++) { + vga_buffer[pos] = '\0'; } - break; - case 'K': //EL - Erase in Line - { - int pos = terminal_row * 80 + terminal_column; - if(params[0] == 0) { // From cursor to end of line - int endPos = (terminal_row + 1) * 80 - 1; // End of line = current row + 25 columns = current row + 1 - for(; pos < endPos; pos++) { - vga_buffer[pos] = '\0'; - } - } else if (params[0] == 1) { // From cursor to start of line - int endPos = terminal_row * 80; // Start of line = end of previous line + 1 == current line - for(; pos > endPos; pos--) { - vga_buffer[pos] = '\0'; - } - } else if(params[0] == 2) { // Entire current line - pos = terminal_row * 80; - int endPos = (terminal_row + 1) * 80 - 1; - for(; pos < endPos; pos++) { - vga_buffer[pos] = '\0'; - } - } + } else if (params[0] == 1) { // Clear from cursor to beginning + for (; pos > 0; pos--) { + vga_buffer[pos] = '\0'; } - break; - case 'S': //SU - Scroll Up - term_scroll(true); - break; - case 'T': //SD - Scroll Down - term_scroll(false); - break; + } else if (params[0] == 2 || params[0] == 3) { // Clear entire screen + // TODO: Support scrollback buffer? (n = 3) + for (int i = 0; i < (25 * 80); i++) { + vga_buffer[0] = '\0'; + } + } + break; + } + case 'K': // EL - Erase in Line + { + int pos = terminal_row * 80 + terminal_column; + if (params[0] == 0) { // From cursor to end of line + int endPos = (terminal_row + 1) * 80 - 1; // End of line = current row + 25 columns = current row + 1 + for (; pos < endPos; pos++) { + vga_buffer[pos] = '\0'; + } + } else if (params[0] == 1) { // From cursor to start of line + int endPos = terminal_row * 80; // Start of line = end of previous line + 1 == current line + for (; pos > endPos; pos--) { + vga_buffer[pos] = '\0'; + } + } else if (params[0] == 2) { // Entire current line + pos = terminal_row * 80; + int endPos = (terminal_row + 1) * 80 - 1; + for (; pos < endPos; pos++) { + vga_buffer[pos] = '\0'; + } + } + break; + } + case 'S': // SU - Scroll Up + term_scroll(true); + break; + case 'T': // SD - Scroll Down + term_scroll(false); + break; } } - } -bool isDigit(char c) { - return c >= '0' && c <= '9'; -} +bool isDigit(char c) { return c >= '0' && c <= '9'; } void set_cursor(int n, int m) { terminal_column = n; @@ -292,41 +291,43 @@ void set_cursor(int n, int m) { void term_scroll(bool down) { int current_pos; - if(down) { - current_pos = 25 * 80; //Start of the last line. + if (down) { + current_pos = 25 * 80; // Start of the last line. } else { - current_pos = 160; //Start of the second line. + current_pos = 160; // Start of the second line. } - unsigned char* term_buffer = (unsigned char*) vga_buffer; + unsigned char* term_buffer = (unsigned char*)vga_buffer; - if(down) { //To scroll down, move every character into the one below it, or "pull" every character down - while(current_pos > 80) { + if (down) { // To scroll down, move every character into the one below it, or "pull" every character down + while (current_pos > 80) { term_buffer[current_pos + 160] = vga_buffer[current_pos]; term_buffer[current_pos + 159] = vga_buffer[current_pos - 1]; current_pos -= 2; } } else { while (current_pos <= 4000) { - term_buffer[current_pos - 160 /*The character immediately below it*/] = vga_buffer[current_pos]; //Move each character up a line - term_buffer[current_pos - 159 /*The color of the character below*/] = vga_buffer[current_pos + 1]; //As well as its color - current_pos += 2; //Move to next char + term_buffer[current_pos - 160 /*The character immediately below it*/] = + vga_buffer[current_pos]; // Move each character up a line + term_buffer[current_pos - 159 /*The color of the character below*/] = + vga_buffer[current_pos + 1]; // As well as its color + current_pos += 2; // Move to next char } } - - if(down) { - current_pos = 0; //Start of first line - for(; current_pos < 80; current_pos++) { + + if (down) { + current_pos = 0; // Start of first line + for (; current_pos < 80; current_pos++) { term_buffer[current_pos] = '\0'; current_pos += 2; } } else { - ; //Start of the last line - //Wipe out the bottom line - for(current_pos = 3840; current_pos <= 3920; current_pos += 2) { + ; // Start of the last line + // Wipe out the bottom line + for (current_pos = 3840; current_pos <= 3920; current_pos += 2) { term_buffer[current_pos] = 0; } } - terminal_row = 24; //Start writing on the last line + terminal_row = 24; // Start writing on the last line terminal_column = 0; } diff --git a/include/arch/i386/vga.h b/include/arch/i386/vga.h old mode 100755 new mode 100644 index 8dcf15a..e8f3fb7 --- a/include/arch/i386/vga.h +++ b/include/arch/i386/vga.h @@ -1,34 +1,29 @@ -#ifndef ARCH_I386_VGA_H -#define ARCH_I386_VGA_H - -#include - - -enum vga_colors { - BLACK = 0, - BLUE = 1, - GREEN = 2, - CYAN = 3, - RED = 4, - MAGENTA = 5, - BROWN = 6, - LIGHT_GREY = 7, - DARK_GREY = 8, - LIGHT_BLUE = 9, - LIGHT_GREEN = 10, - LIGHT_CYAN = 11, - LIGHT_RED = 12, - LIGHT_MAGENTA = 13, - LIGHT_BROWN = 14, - WHITE = 15 -}; - -static inline uint8_t vga_color_set(enum vga_colors fg, enum vga_colors bg) { - return fg | bg << 4; -} - -static inline uint16_t vga_entry(unsigned char uc, uint8_t color) { - return (uint16_t) uc | (uint16_t) color << 8; -} - +#ifndef ARCH_I386_VGA_H +#define ARCH_I386_VGA_H + +#include + +enum vga_colors { + BLACK = 0, + BLUE = 1, + GREEN = 2, + CYAN = 3, + RED = 4, + MAGENTA = 5, + BROWN = 6, + LIGHT_GREY = 7, + DARK_GREY = 8, + LIGHT_BLUE = 9, + LIGHT_GREEN = 10, + LIGHT_CYAN = 11, + LIGHT_RED = 12, + LIGHT_MAGENTA = 13, + LIGHT_BROWN = 14, + WHITE = 15 +}; + +static inline uint8_t vga_color_set(enum vga_colors fg, enum vga_colors bg) { return fg | bg << 4; } + +static inline uint16_t vga_entry(unsigned char uc, uint8_t color) { return (uint16_t)uc | (uint16_t)color << 8; } + #endif \ No newline at end of file diff --git a/include/kernel/tty.h b/include/kernel/tty.h old mode 100755 new mode 100644 index 503f424..46f62c2 --- a/include/kernel/tty.h +++ b/include/kernel/tty.h @@ -15,7 +15,6 @@ struct csi_sequence { bool valid; }; - void term_setcolor(enum vga_colors); void screen_initialize(void); void term_putentryat(char, uint8_t, size_t, size_t); diff --git a/include/kernel/utils.h b/include/kernel/utils.h index eb23480..7222974 100755 --- a/include/kernel/utils.h +++ b/include/kernel/utils.h @@ -1,5 +1,5 @@ -#include - -/* A temporary file, to get the system compiling. */ - +#include + +/* A temporary file, to get the system compiling. */ + size_t strlen(const char*); \ No newline at end of file diff --git a/include/vga.h b/include/vga.h old mode 100755 new mode 100644 index f69ba70..bdbe852 --- a/include/vga.h +++ b/include/vga.h @@ -1,31 +1,26 @@ -#pragma once - -#include - - -enum vga_colors { - BLACK = 0, - BLUE = 1, - GREEN = 2, - CYAN = 3, - RED = 4, - MAGENTA = 5, - BROWN = 6, - LIGHT_GREY = 7, - DARK_GREY = 8, - LIGHT_BLUE = 9, - LIGHT_GREEN = 10, - LIGHT_CYAN = 11, - LIGHT_RED = 12, - LIGHT_MAGENTA = 13, - LIGHT_BROWN = 14, - WHITE = 15 -}; - -static inline uint8_t vga_color_set(enum vga_colors fg, enum vga_colors bg) { - return fg | bg << 4; -} - -static inline uint16_t vga_entry(unsigned char uc, uint8_t color) { - return (uint16_t) uc | (uint16_t) color << 8; -} +#pragma once + +#include + +enum vga_colors { + BLACK = 0, + BLUE = 1, + GREEN = 2, + CYAN = 3, + RED = 4, + MAGENTA = 5, + BROWN = 6, + LIGHT_GREY = 7, + DARK_GREY = 8, + LIGHT_BLUE = 9, + LIGHT_GREEN = 10, + LIGHT_CYAN = 11, + LIGHT_RED = 12, + LIGHT_MAGENTA = 13, + LIGHT_BROWN = 14, + WHITE = 15 +}; + +static inline uint8_t vga_color_set(enum vga_colors fg, enum vga_colors bg) { return fg | bg << 4; } + +static inline uint16_t vga_entry(unsigned char uc, uint8_t color) { return (uint16_t)uc | (uint16_t)color << 8; } diff --git a/kernel/kernel.c b/kernel/kernel.c old mode 100755 new mode 100644 index 893c8b3..942601a --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -1,20 +1,21 @@ -//#include - -#include "kernel/tty.h" - -int kernel_main(void) { - //Prepare the screen, and blank it out. - screen_initialize(); - - //Print a copyright message. - term_writes("(c)"); - term_setcolor(GREEN); - term_writes(" Project"); - term_setcolor(RED); - term_writes("RED"); - term_setcolor(WHITE); - term_writes(", 2019\n"); - - for(;;) {} - return 0; -} \ No newline at end of file +//#include + +#include "kernel/tty.h" + +int kernel_main(void) { + // Prepare the screen, and blank it out. + screen_initialize(); + + // Print a copyright message. + term_writes("(c)"); + term_setcolor(GREEN); + term_writes(" Project"); + term_setcolor(RED); + term_writes("RED"); + term_setcolor(WHITE); + term_writes(", 2019\n"); + + for (;;) { + } + return 0; +} diff --git a/kernel/syscalls.c b/kernel/syscalls.c old mode 100755 new mode 100644 index cfa788c..b7c6994 --- a/kernel/syscalls.c +++ b/kernel/syscalls.c @@ -1,48 +1,48 @@ -/*#include -#include -#include -#include -#include -#include -#include - -//prototypes; these are the bare minimum for newlib to compile. - -void _exit(); - -int close(int file); - -char **environ; - -int execve(char *name, char **argv, char **env); - -int fork(); - -int fstat(int file, struct stat *st); - -int getpid(); - -int isatty(int file); - -int kill(int pid, int sig); - -int link(char *old, char *new); - -int lseek(int file, int ptr, int dir); - -int open(const char* name, int flags, ...); - -int read(int file, char* ptr, int len); - -caddr_t sbrk(int incr); - -int stat(const char* file, struct stat *st); - -clock_t times(struct tms* buf); - -int unlink(char* name); - -int wait(int file, char* ptr, int len); - -int gettimeofday(struct timeval* p, struct timezone* z); +/*#include +#include +#include +#include +#include +#include +#include + +//prototypes; these are the bare minimum for newlib to compile. + +void _exit(); + +int close(int file); + +char **environ; + +int execve(char *name, char **argv, char **env); + +int fork(); + +int fstat(int file, struct stat *st); + +int getpid(); + +int isatty(int file); + +int kill(int pid, int sig); + +int link(char *old, char *new); + +int lseek(int file, int ptr, int dir); + +int open(const char* name, int flags, ...); + +int read(int file, char* ptr, int len); + +caddr_t sbrk(int incr); + +int stat(const char* file, struct stat *st); + +clock_t times(struct tms* buf); + +int unlink(char* name); + +int wait(int file, char* ptr, int len); + +int gettimeofday(struct timeval* p, struct timezone* z); */ \ No newline at end of file diff --git a/kernel/utils.c b/kernel/utils.c old mode 100755 new mode 100644 index 739d608..818989b --- a/kernel/utils.c +++ b/kernel/utils.c @@ -1,8 +1,8 @@ -#include - -size_t strlen(const char* string) { - size_t size = 0; - while (string[size]) - size++; - return size; +#include + +size_t strlen(const char* string) { + size_t size = 0; + while (string[size]) + size++; + return size; } \ No newline at end of file diff --git a/libc/include/stdio.h b/libc/include/stdio.h index ba4721d..86d8480 100755 --- a/libc/include/stdio.h +++ b/libc/include/stdio.h @@ -1,19 +1,19 @@ -#ifndef _STDIO_H -#define _STDIO_H 1 - -#include - -#define EOF (-1) - -struct __sFile { - int unused; -}; - -typedef struct __sFile FILE; - -#define stderr (_impure_ptr->_stderr) - -int printf(const char* __restrict, ...); -int putchar(int); -int puts(const char*); +#ifndef _STDIO_H +#define _STDIO_H 1 + +#include + +#define EOF (-1) + +struct __sFile { + int unused; +}; + +typedef struct __sFile FILE; + +#define stderr (_impure_ptr->_stderr) + +int printf(const char* __restrict, ...); +int putchar(int); +int puts(const char*); #endif \ No newline at end of file diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h old mode 100755 new mode 100644 index 5a0bc70..f343d50 --- a/libc/include/stdlib.h +++ b/libc/include/stdlib.h @@ -1,601 +1,594 @@ -#ifndef _STDLIB_H -#define _STDLIB_H 1 - -#include - -__attribute__((__noreturn__)) -void abort(void); - -/* - Default header file for malloc-2.8.x, written by Doug Lea - and released to the public domain, as explained at - http://creativecommons.org/publicdomain/zero/1.0/ - - This header is for ANSI C/C++ only. You can set any of - the following #defines before including: - - * If USE_DL_PREFIX is defined, it is assumed that malloc.c - was also compiled with this option, so all routines - have names starting with "dl". - - * If HAVE_USR_INCLUDE_MALLOC_H is defined, it is assumed that this - file will be #included AFTER . This is needed only if - your system defines a struct mallinfo that is incompatible with the - standard one declared here. Otherwise, you can include this file - INSTEAD of your system system . At least on ANSI, all - declarations should be compatible with system versions - - * If MSPACES is defined, declarations for mspace versions are included. -*/ - -#ifdef __cplusplus -extern "C" { -#endif - -#include /* for size_t */ - -#ifndef ONLY_MSPACES -#define ONLY_MSPACES 0 /* define to a value */ -#elif ONLY_MSPACES != 0 -#define ONLY_MSPACES 1 -#endif /* ONLY_MSPACES */ -#ifndef NO_MALLINFO -#define NO_MALLINFO 0 -#endif /* NO_MALLINFO */ - -#ifndef MSPACES -#if ONLY_MSPACES -#define MSPACES 1 -#else /* ONLY_MSPACES */ -#define MSPACES 0 -#endif /* ONLY_MSPACES */ -#endif /* MSPACES */ - -#if !ONLY_MSPACES - -#if !NO_MALLINFO -#ifndef HAVE_USR_INCLUDE_MALLOC_H -#ifndef _MALLOC_H -#ifndef MALLINFO_FIELD_TYPE -#define MALLINFO_FIELD_TYPE size_t -#endif /* MALLINFO_FIELD_TYPE */ -#ifndef STRUCT_MALLINFO_DECLARED -#define STRUCT_MALLINFO_DECLARED 1 -struct mallinfo { - MALLINFO_FIELD_TYPE arena; /* non-mmapped space allocated from system */ - MALLINFO_FIELD_TYPE ordblks; /* number of free chunks */ - MALLINFO_FIELD_TYPE smblks; /* always 0 */ - MALLINFO_FIELD_TYPE hblks; /* always 0 */ - MALLINFO_FIELD_TYPE hblkhd; /* space in mmapped regions */ - MALLINFO_FIELD_TYPE usmblks; /* maximum total allocated space */ - MALLINFO_FIELD_TYPE fsmblks; /* always 0 */ - MALLINFO_FIELD_TYPE uordblks; /* total allocated space */ - MALLINFO_FIELD_TYPE fordblks; /* total free space */ - MALLINFO_FIELD_TYPE keepcost; /* releasable (via malloc_trim) space */ -}; -#endif /* STRUCT_MALLINFO_DECLARED */ -#endif /* _MALLOC_H */ -#endif /* HAVE_USR_INCLUDE_MALLOC_H */ -#endif /* !NO_MALLINFO */ - -/* - malloc(size_t n) - Returns a pointer to a newly allocated chunk of at least n bytes, or - null if no space is available, in which case errno is set to ENOMEM - on ANSI C systems. - - If n is zero, malloc returns a minimum-sized chunk. (The minimum - size is 16 bytes on most 32bit systems, and 32 bytes on 64bit - systems.) Note that size_t is an unsigned type, so calls with - arguments that would be negative if signed are interpreted as - requests for huge amounts of space, which will often fail. The - maximum supported value of n differs across systems, but is in all - cases less than the maximum representable value of a size_t. -*/ -void* malloc(size_t); - -/* - free(void* p) - Releases the chunk of memory pointed to by p, that had been previously - allocated using malloc or a related routine such as realloc. - It has no effect if p is null. If p was not malloced or already - freed, free(p) will by default cuase the current program to abort. -*/ -void free(void*); - -/* - calloc(size_t n_elements, size_t element_size); - Returns a pointer to n_elements * element_size bytes, with all locations - set to zero. -*/ -void* calloc(size_t, size_t); - -/* - realloc(void* p, size_t n) - Returns a pointer to a chunk of size n that contains the same data - as does chunk p up to the minimum of (n, p's size) bytes, or null - if no space is available. - - The returned pointer may or may not be the same as p. The algorithm - prefers extending p in most cases when possible, otherwise it - employs the equivalent of a malloc-copy-free sequence. - - If p is null, realloc is equivalent to malloc. - - If space is not available, realloc returns null, errno is set (if on - ANSI) and p is NOT freed. - - if n is for fewer bytes than already held by p, the newly unused - space is lopped off and freed if possible. realloc with a size - argument of zero (re)allocates a minimum-sized chunk. - - The old unix realloc convention of allowing the last-free'd chunk - to be used as an argument to realloc is not supported. -*/ -void* realloc(void*, size_t); - -/* - realloc_in_place(void* p, size_t n) - Resizes the space allocated for p to size n, only if this can be - done without moving p (i.e., only if there is adjacent space - available if n is greater than p's current allocated size, or n is - less than or equal to p's size). This may be used instead of plain - realloc if an alternative allocation strategy is needed upon failure - to expand space; for example, reallocation of a buffer that must be - memory-aligned or cleared. You can use realloc_in_place to trigger - these alternatives only when needed. - - Returns p if successful; otherwise null. -*/ -void* realloc_in_place(void*, size_t); - -/* - memalign(size_t alignment, size_t n); - Returns a pointer to a newly allocated chunk of n bytes, aligned - in accord with the alignment argument. - - The alignment argument should be a power of two. If the argument is - not a power of two, the nearest greater power is used. - 8-byte alignment is guaranteed by normal malloc calls, so don't - bother calling memalign with an argument of 8 or less. - - Overreliance on memalign is a sure way to fragment space. -*/ -void* memalign(size_t, size_t); - -/* - int posix_memalign(void** pp, size_t alignment, size_t n); - Allocates a chunk of n bytes, aligned in accord with the alignment - argument. Differs from memalign only in that it (1) assigns the - allocated memory to *pp rather than returning it, (2) fails and - returns EINVAL if the alignment is not a power of two (3) fails and - returns ENOMEM if memory cannot be allocated. -*/ -int posix_memalign(void**, size_t, size_t); - -/* - valloc(size_t n); - Equivalent to memalign(pagesize, n), where pagesize is the page - size of the system. If the pagesize is unknown, 4096 is used. -*/ -void* valloc(size_t); - -/* - mallopt(int parameter_number, int parameter_value) - Sets tunable parameters The format is to provide a - (parameter-number, parameter-value) pair. mallopt then sets the - corresponding parameter to the argument value if it can (i.e., so - long as the value is meaningful), and returns 1 if successful else - 0. SVID/XPG/ANSI defines four standard param numbers for mallopt, - normally defined in malloc.h. None of these are use in this malloc, - so setting them has no effect. But this malloc also supports other - options in mallopt: - - Symbol param # default allowed param values - M_TRIM_THRESHOLD -1 2*1024*1024 any (-1U disables trimming) - M_GRANULARITY -2 page size any power of 2 >= page size - M_MMAP_THRESHOLD -3 256*1024 any (or 0 if no MMAP support) -*/ -int mallopt(int, int); - -#define M_TRIM_THRESHOLD (-1) -#define M_GRANULARITY (-2) -#define M_MMAP_THRESHOLD (-3) - - -/* - malloc_footprint(); - Returns the number of bytes obtained from the system. The total - number of bytes allocated by malloc, realloc etc., is less than this - value. Unlike mallinfo, this function returns only a precomputed - result, so can be called frequently to monitor memory consumption. - Even if locks are otherwise defined, this function does not use them, - so results might not be up to date. -*/ -size_t malloc_footprint(void); - -/* - malloc_max_footprint(); - Returns the maximum number of bytes obtained from the system. This - value will be greater than current footprint if deallocated space - has been reclaimed by the system. The peak number of bytes allocated - by malloc, realloc etc., is less than this value. Unlike mallinfo, - this function returns only a precomputed result, so can be called - frequently to monitor memory consumption. Even if locks are - otherwise defined, this function does not use them, so results might - not be up to date. -*/ -size_t malloc_max_footprint(void); - -/* - malloc_footprint_limit(); - Returns the number of bytes that the heap is allowed to obtain from - the system, returning the last value returned by - malloc_set_footprint_limit, or the maximum size_t value if - never set. The returned value reflects a permission. There is no - guarantee that this number of bytes can actually be obtained from - the system. -*/ -size_t malloc_footprint_limit(void); - -/* - malloc_set_footprint_limit(); - Sets the maximum number of bytes to obtain from the system, causing - failure returns from malloc and related functions upon attempts to - exceed this value. The argument value may be subject to page - rounding to an enforceable limit; this actual value is returned. - Using an argument of the maximum possible size_t effectively - disables checks. If the argument is less than or equal to the - current malloc_footprint, then all future allocations that require - additional system memory will fail. However, invocation cannot - retroactively deallocate existing used memory. -*/ -size_t malloc_set_footprint_limit(size_t bytes); - -/* - malloc_inspect_all(void(*handler)(void *start, - void *end, - size_t used_bytes, - void* callback_arg), - void* arg); - Traverses the heap and calls the given handler for each managed - region, skipping all bytes that are (or may be) used for bookkeeping - purposes. Traversal does not include include chunks that have been - directly memory mapped. Each reported region begins at the start - address, and continues up to but not including the end address. The - first used_bytes of the region contain allocated data. If - used_bytes is zero, the region is unallocated. The handler is - invoked with the given callback argument. If locks are defined, they - are held during the entire traversal. It is a bad idea to invoke - other malloc functions from within the handler. - - For example, to count the number of in-use chunks with size greater - than 1000, you could write: - static int count = 0; - void count_chunks(void* start, void* end, size_t used, void* arg) { - if (used >= 1000) ++count; - } - then: - malloc_inspect_all(count_chunks, NULL); - - malloc_inspect_all is compiled only if MALLOC_INSPECT_ALL is defined. -*/ -void malloc_inspect_all(void(*handler)(void*, void *, size_t, void*), - void* arg); - -#if !NO_MALLINFO -/* - mallinfo() - Returns (by copy) a struct containing various summary statistics: - - arena: current total non-mmapped bytes allocated from system - ordblks: the number of free chunks - smblks: always zero. - hblks: current number of mmapped regions - hblkhd: total bytes held in mmapped regions - usmblks: the maximum total allocated space. This will be greater - than current total if trimming has occurred. - fsmblks: always zero - uordblks: current total allocated space (normal or mmapped) - fordblks: total free space - keepcost: the maximum number of bytes that could ideally be released - back to system via malloc_trim. ("ideally" means that - it ignores page restrictions etc.) - - Because these fields are ints, but internal bookkeeping may - be kept as longs, the reported values may wrap around zero and - thus be inaccurate. -*/ - -struct mallinfo mallinfo(void); -#endif /* NO_MALLINFO */ - -/* - independent_calloc(size_t n_elements, size_t element_size, void* chunks[]); - - independent_calloc is similar to calloc, but instead of returning a - single cleared space, it returns an array of pointers to n_elements - independent elements that can hold contents of size elem_size, each - of which starts out cleared, and can be independently freed, - realloc'ed etc. The elements are guaranteed to be adjacently - allocated (this is not guaranteed to occur with multiple callocs or - mallocs), which may also improve cache locality in some - applications. - - The "chunks" argument is optional (i.e., may be null, which is - probably the most typical usage). If it is null, the returned array - is itself dynamically allocated and should also be freed when it is - no longer needed. Otherwise, the chunks array must be of at least - n_elements in length. It is filled in with the pointers to the - chunks. - - In either case, independent_calloc returns this pointer array, or - null if the allocation failed. If n_elements is zero and "chunks" - is null, it returns a chunk representing an array with zero elements - (which should be freed if not wanted). - - Each element must be freed when it is no longer needed. This can be - done all at once using bulk_free. - - independent_calloc simplifies and speeds up implementations of many - kinds of pools. It may also be useful when constructing large data - structures that initially have a fixed number of fixed-sized nodes, - but the number is not known at compile time, and some of the nodes - may later need to be freed. For example: - - struct Node { int item; struct Node* next; }; - - struct Node* build_list() { - struct Node** pool; - int n = read_number_of_nodes_needed(); - if (n <= 0) return 0; - pool = (struct Node**)(independent_calloc(n, sizeof(struct Node), 0); - if (pool == 0) die(); - // organize into a linked list... - struct Node* first = pool[0]; - for (i = 0; i < n-1; ++i) - pool[i]->next = pool[i+1]; - free(pool); // Can now free the array (or not, if it is needed later) - return first; - } -*/ -void** independent_calloc(size_t, size_t, void**); - -/* - independent_comalloc(size_t n_elements, size_t sizes[], void* chunks[]); - - independent_comalloc allocates, all at once, a set of n_elements - chunks with sizes indicated in the "sizes" array. It returns - an array of pointers to these elements, each of which can be - independently freed, realloc'ed etc. The elements are guaranteed to - be adjacently allocated (this is not guaranteed to occur with - multiple callocs or mallocs), which may also improve cache locality - in some applications. - - The "chunks" argument is optional (i.e., may be null). If it is null - the returned array is itself dynamically allocated and should also - be freed when it is no longer needed. Otherwise, the chunks array - must be of at least n_elements in length. It is filled in with the - pointers to the chunks. - - In either case, independent_comalloc returns this pointer array, or - null if the allocation failed. If n_elements is zero and chunks is - null, it returns a chunk representing an array with zero elements - (which should be freed if not wanted). - - Each element must be freed when it is no longer needed. This can be - done all at once using bulk_free. - - independent_comallac differs from independent_calloc in that each - element may have a different size, and also that it does not - automatically clear elements. - - independent_comalloc can be used to speed up allocation in cases - where several structs or objects must always be allocated at the - same time. For example: - - struct Head { ... } - struct Foot { ... } - - void send_message(char* msg) { - int msglen = strlen(msg); - size_t sizes[3] = { sizeof(struct Head), msglen, sizeof(struct Foot) }; - void* chunks[3]; - if (independent_comalloc(3, sizes, chunks) == 0) - die(); - struct Head* head = (struct Head*)(chunks[0]); - char* body = (char*)(chunks[1]); - struct Foot* foot = (struct Foot*)(chunks[2]); - // ... - } - - In general though, independent_comalloc is worth using only for - larger values of n_elements. For small values, you probably won't - detect enough difference from series of malloc calls to bother. - - Overuse of independent_comalloc can increase overall memory usage, - since it cannot reuse existing noncontiguous small chunks that - might be available for some of the elements. -*/ -void** independent_comalloc(size_t, size_t*, void**); - -/* - bulk_free(void* array[], size_t n_elements) - Frees and clears (sets to null) each non-null pointer in the given - array. This is likely to be faster than freeing them one-by-one. - If footers are used, pointers that have been allocated in different - mspaces are not freed or cleared, and the count of all such pointers - is returned. For large arrays of pointers with poor locality, it - may be worthwhile to sort this array before calling bulk_free. -*/ -size_t bulk_free(void**, size_t n_elements); - -/* - pvalloc(size_t n); - Equivalent to valloc(minimum-page-that-holds(n)), that is, - round up n to nearest pagesize. - */ -void* pvalloc(size_t); - -/* - malloc_trim(size_t pad); - - If possible, gives memory back to the system (via negative arguments - to sbrk) if there is unused memory at the `high' end of the malloc - pool or in unused MMAP segments. You can call this after freeing - large blocks of memory to potentially reduce the system-level memory - requirements of a program. However, it cannot guarantee to reduce - memory. Under some allocation patterns, some large free blocks of - memory will be locked between two used chunks, so they cannot be - given back to the system. - - The `pad' argument to malloc_trim represents the amount of free - trailing space to leave untrimmed. If this argument is zero, only - the minimum amount of memory to maintain internal data structures - will be left. Non-zero arguments can be supplied to maintain enough - trailing space to service future expected allocations without having - to re-obtain memory from the system. - - Malloc_trim returns 1 if it actually released any memory, else 0. -*/ -int malloc_trim(size_t); - -/* - malloc_stats(); - Prints on stderr the amount of space obtained from the system (both - via sbrk and mmap), the maximum amount (which may be more than - current if malloc_trim and/or munmap got called), and the current - number of bytes allocated via malloc (or realloc, etc) but not yet - freed. Note that this is the number of bytes allocated, not the - number requested. It will be larger than the number requested - because of alignment and bookkeeping overhead. Because it includes - alignment wastage as being in use, this figure may be greater than - zero even when no user-level chunks are allocated. - - The reported current and maximum system memory can be inaccurate if - a program makes other calls to system memory allocation functions - (normally sbrk) outside of malloc. - - malloc_stats prints only the most commonly interesting statistics. - More information can be obtained by calling mallinfo. - - malloc_stats is not compiled if NO_MALLOC_STATS is defined. -*/ -void malloc_stats(void); - -#endif /* !ONLY_MSPACES */ - -/* - malloc_usable_size(void* p); - - Returns the number of bytes you can actually use in - an allocated chunk, which may be more than you requested (although - often not) due to alignment and minimum size constraints. - You can use this many bytes without worrying about - overwriting other allocated objects. This is not a particularly great - programming practice. malloc_usable_size can be more useful in - debugging and assertions, for example: - - p = malloc(n); - assert(malloc_usable_size(p) >= 256); -*/ -size_t malloc_usable_size(const void*); - -#if MSPACES - -/* - mspace is an opaque type representing an independent - region of space that supports mspace_malloc, etc. -*/ -typedef void* mspace; - -/* - create_mspace creates and returns a new independent space with the - given initial capacity, or, if 0, the default granularity size. It - returns null if there is no system memory available to create the - space. If argument locked is non-zero, the space uses a separate - lock to control access. The capacity of the space will grow - dynamically as needed to service mspace_malloc requests. You can - control the sizes of incremental increases of this space by - compiling with a different DEFAULT_GRANULARITY or dynamically - setting with mallopt(M_GRANULARITY, value). -*/ -mspace create_mspace(size_t capacity, int locked); - -/* - destroy_mspace destroys the given space, and attempts to return all - of its memory back to the system, returning the total number of - bytes freed. After destruction, the results of access to all memory - used by the space become undefined. -*/ -size_t destroy_mspace(mspace msp); - -/* - create_mspace_with_base uses the memory supplied as the initial base - of a new mspace. Part (less than 128*sizeof(size_t) bytes) of this - space is used for bookkeeping, so the capacity must be at least this - large. (Otherwise 0 is returned.) When this initial space is - exhausted, additional memory will be obtained from the system. - Destroying this space will deallocate all additionally allocated - space (if possible) but not the initial base. -*/ -mspace create_mspace_with_base(void* base, size_t capacity, int locked); - -/* - mspace_track_large_chunks controls whether requests for large chunks - are allocated in their own untracked mmapped regions, separate from - others in this mspace. By default large chunks are not tracked, - which reduces fragmentation. However, such chunks are not - necessarily released to the system upon destroy_mspace. Enabling - tracking by setting to true may increase fragmentation, but avoids - leakage when relying on destroy_mspace to release all memory - allocated using this space. The function returns the previous - setting. -*/ -int mspace_track_large_chunks(mspace msp, int enable); - -#if !NO_MALLINFO -/* - mspace_mallinfo behaves as mallinfo, but reports properties of - the given space. -*/ -struct mallinfo mspace_mallinfo(mspace msp); -#endif /* NO_MALLINFO */ - -/* - An alias for mallopt. -*/ -int mspace_mallopt(int, int); - -/* - The following operate identically to their malloc counterparts - but operate only for the given mspace argument -*/ -void* mspace_malloc(mspace msp, size_t bytes); -void mspace_free(mspace msp, void* mem); -void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size); -void* mspace_realloc(mspace msp, void* mem, size_t newsize); -void* mspace_realloc_in_place(mspace msp, void* mem, size_t newsize); -void* mspace_memalign(mspace msp, size_t alignment, size_t bytes); -void** mspace_independent_calloc(mspace msp, size_t n_elements, - size_t elem_size, void* chunks[]); -void** mspace_independent_comalloc(mspace msp, size_t n_elements, - size_t sizes[], void* chunks[]); -size_t mspace_bulk_free(mspace msp, void**, size_t n_elements); -size_t mspace_usable_size(const void* mem); -void mspace_malloc_stats(mspace msp); -int mspace_trim(mspace msp, size_t pad); -size_t mspace_footprint(mspace msp); -size_t mspace_max_footprint(mspace msp); -size_t mspace_footprint_limit(mspace msp); -size_t mspace_set_footprint_limit(mspace msp, size_t bytes); -void mspace_inspect_all(mspace msp, - void(*handler)(void *, void *, size_t, void*), - void* arg); -#endif /* MSPACES */ - -#ifdef __cplusplus -}; /* end of extern "C" */ -#endif - -#endif /* MALLOC_280_H */ +#ifndef _STDLIB_H +#define _STDLIB_H 1 + +#include + +__attribute__((__noreturn__)) void abort(void); + +/* + Default header file for malloc-2.8.x, written by Doug Lea + and released to the public domain, as explained at + http://creativecommons.org/publicdomain/zero/1.0/ + + This header is for ANSI C/C++ only. You can set any of + the following #defines before including: + + * If USE_DL_PREFIX is defined, it is assumed that malloc.c + was also compiled with this option, so all routines + have names starting with "dl". + + * If HAVE_USR_INCLUDE_MALLOC_H is defined, it is assumed that this + file will be #included AFTER . This is needed only if + your system defines a struct mallinfo that is incompatible with the + standard one declared here. Otherwise, you can include this file + INSTEAD of your system system . At least on ANSI, all + declarations should be compatible with system versions + + * If MSPACES is defined, declarations for mspace versions are included. +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#include /* for size_t */ + +#ifndef ONLY_MSPACES +#define ONLY_MSPACES 0 /* define to a value */ +#elif ONLY_MSPACES != 0 +#define ONLY_MSPACES 1 +#endif /* ONLY_MSPACES */ +#ifndef NO_MALLINFO +#define NO_MALLINFO 0 +#endif /* NO_MALLINFO */ + +#ifndef MSPACES +#if ONLY_MSPACES +#define MSPACES 1 +#else /* ONLY_MSPACES */ +#define MSPACES 0 +#endif /* ONLY_MSPACES */ +#endif /* MSPACES */ + +#if !ONLY_MSPACES + +#if !NO_MALLINFO +#ifndef HAVE_USR_INCLUDE_MALLOC_H +#ifndef _MALLOC_H +#ifndef MALLINFO_FIELD_TYPE +#define MALLINFO_FIELD_TYPE size_t +#endif /* MALLINFO_FIELD_TYPE */ +#ifndef STRUCT_MALLINFO_DECLARED +#define STRUCT_MALLINFO_DECLARED 1 +struct mallinfo { + MALLINFO_FIELD_TYPE arena; /* non-mmapped space allocated from system */ + MALLINFO_FIELD_TYPE ordblks; /* number of free chunks */ + MALLINFO_FIELD_TYPE smblks; /* always 0 */ + MALLINFO_FIELD_TYPE hblks; /* always 0 */ + MALLINFO_FIELD_TYPE hblkhd; /* space in mmapped regions */ + MALLINFO_FIELD_TYPE usmblks; /* maximum total allocated space */ + MALLINFO_FIELD_TYPE fsmblks; /* always 0 */ + MALLINFO_FIELD_TYPE uordblks; /* total allocated space */ + MALLINFO_FIELD_TYPE fordblks; /* total free space */ + MALLINFO_FIELD_TYPE keepcost; /* releasable (via malloc_trim) space */ +}; +#endif /* STRUCT_MALLINFO_DECLARED */ +#endif /* _MALLOC_H */ +#endif /* HAVE_USR_INCLUDE_MALLOC_H */ +#endif /* !NO_MALLINFO */ + +/* + malloc(size_t n) + Returns a pointer to a newly allocated chunk of at least n bytes, or + null if no space is available, in which case errno is set to ENOMEM + on ANSI C systems. + + If n is zero, malloc returns a minimum-sized chunk. (The minimum + size is 16 bytes on most 32bit systems, and 32 bytes on 64bit + systems.) Note that size_t is an unsigned type, so calls with + arguments that would be negative if signed are interpreted as + requests for huge amounts of space, which will often fail. The + maximum supported value of n differs across systems, but is in all + cases less than the maximum representable value of a size_t. +*/ +void* malloc(size_t); + +/* + free(void* p) + Releases the chunk of memory pointed to by p, that had been previously + allocated using malloc or a related routine such as realloc. + It has no effect if p is null. If p was not malloced or already + freed, free(p) will by default cuase the current program to abort. +*/ +void free(void*); + +/* + calloc(size_t n_elements, size_t element_size); + Returns a pointer to n_elements * element_size bytes, with all locations + set to zero. +*/ +void* calloc(size_t, size_t); + +/* + realloc(void* p, size_t n) + Returns a pointer to a chunk of size n that contains the same data + as does chunk p up to the minimum of (n, p's size) bytes, or null + if no space is available. + + The returned pointer may or may not be the same as p. The algorithm + prefers extending p in most cases when possible, otherwise it + employs the equivalent of a malloc-copy-free sequence. + + If p is null, realloc is equivalent to malloc. + + If space is not available, realloc returns null, errno is set (if on + ANSI) and p is NOT freed. + + if n is for fewer bytes than already held by p, the newly unused + space is lopped off and freed if possible. realloc with a size + argument of zero (re)allocates a minimum-sized chunk. + + The old unix realloc convention of allowing the last-free'd chunk + to be used as an argument to realloc is not supported. +*/ +void* realloc(void*, size_t); + +/* + realloc_in_place(void* p, size_t n) + Resizes the space allocated for p to size n, only if this can be + done without moving p (i.e., only if there is adjacent space + available if n is greater than p's current allocated size, or n is + less than or equal to p's size). This may be used instead of plain + realloc if an alternative allocation strategy is needed upon failure + to expand space; for example, reallocation of a buffer that must be + memory-aligned or cleared. You can use realloc_in_place to trigger + these alternatives only when needed. + + Returns p if successful; otherwise null. +*/ +void* realloc_in_place(void*, size_t); + +/* + memalign(size_t alignment, size_t n); + Returns a pointer to a newly allocated chunk of n bytes, aligned + in accord with the alignment argument. + + The alignment argument should be a power of two. If the argument is + not a power of two, the nearest greater power is used. + 8-byte alignment is guaranteed by normal malloc calls, so don't + bother calling memalign with an argument of 8 or less. + + Overreliance on memalign is a sure way to fragment space. +*/ +void* memalign(size_t, size_t); + +/* + int posix_memalign(void** pp, size_t alignment, size_t n); + Allocates a chunk of n bytes, aligned in accord with the alignment + argument. Differs from memalign only in that it (1) assigns the + allocated memory to *pp rather than returning it, (2) fails and + returns EINVAL if the alignment is not a power of two (3) fails and + returns ENOMEM if memory cannot be allocated. +*/ +int posix_memalign(void**, size_t, size_t); + +/* + valloc(size_t n); + Equivalent to memalign(pagesize, n), where pagesize is the page + size of the system. If the pagesize is unknown, 4096 is used. +*/ +void* valloc(size_t); + +/* + mallopt(int parameter_number, int parameter_value) + Sets tunable parameters The format is to provide a + (parameter-number, parameter-value) pair. mallopt then sets the + corresponding parameter to the argument value if it can (i.e., so + long as the value is meaningful), and returns 1 if successful else + 0. SVID/XPG/ANSI defines four standard param numbers for mallopt, + normally defined in malloc.h. None of these are use in this malloc, + so setting them has no effect. But this malloc also supports other + options in mallopt: + + Symbol param # default allowed param values + M_TRIM_THRESHOLD -1 2*1024*1024 any (-1U disables trimming) + M_GRANULARITY -2 page size any power of 2 >= page size + M_MMAP_THRESHOLD -3 256*1024 any (or 0 if no MMAP support) +*/ +int mallopt(int, int); + +#define M_TRIM_THRESHOLD (-1) +#define M_GRANULARITY (-2) +#define M_MMAP_THRESHOLD (-3) + +/* + malloc_footprint(); + Returns the number of bytes obtained from the system. The total + number of bytes allocated by malloc, realloc etc., is less than this + value. Unlike mallinfo, this function returns only a precomputed + result, so can be called frequently to monitor memory consumption. + Even if locks are otherwise defined, this function does not use them, + so results might not be up to date. +*/ +size_t malloc_footprint(void); + +/* + malloc_max_footprint(); + Returns the maximum number of bytes obtained from the system. This + value will be greater than current footprint if deallocated space + has been reclaimed by the system. The peak number of bytes allocated + by malloc, realloc etc., is less than this value. Unlike mallinfo, + this function returns only a precomputed result, so can be called + frequently to monitor memory consumption. Even if locks are + otherwise defined, this function does not use them, so results might + not be up to date. +*/ +size_t malloc_max_footprint(void); + +/* + malloc_footprint_limit(); + Returns the number of bytes that the heap is allowed to obtain from + the system, returning the last value returned by + malloc_set_footprint_limit, or the maximum size_t value if + never set. The returned value reflects a permission. There is no + guarantee that this number of bytes can actually be obtained from + the system. +*/ +size_t malloc_footprint_limit(void); + +/* + malloc_set_footprint_limit(); + Sets the maximum number of bytes to obtain from the system, causing + failure returns from malloc and related functions upon attempts to + exceed this value. The argument value may be subject to page + rounding to an enforceable limit; this actual value is returned. + Using an argument of the maximum possible size_t effectively + disables checks. If the argument is less than or equal to the + current malloc_footprint, then all future allocations that require + additional system memory will fail. However, invocation cannot + retroactively deallocate existing used memory. +*/ +size_t malloc_set_footprint_limit(size_t bytes); + +/* + malloc_inspect_all(void(*handler)(void *start, + void *end, + size_t used_bytes, + void* callback_arg), + void* arg); + Traverses the heap and calls the given handler for each managed + region, skipping all bytes that are (or may be) used for bookkeeping + purposes. Traversal does not include include chunks that have been + directly memory mapped. Each reported region begins at the start + address, and continues up to but not including the end address. The + first used_bytes of the region contain allocated data. If + used_bytes is zero, the region is unallocated. The handler is + invoked with the given callback argument. If locks are defined, they + are held during the entire traversal. It is a bad idea to invoke + other malloc functions from within the handler. + + For example, to count the number of in-use chunks with size greater + than 1000, you could write: + static int count = 0; + void count_chunks(void* start, void* end, size_t used, void* arg) { + if (used >= 1000) ++count; + } + then: + malloc_inspect_all(count_chunks, NULL); + + malloc_inspect_all is compiled only if MALLOC_INSPECT_ALL is defined. +*/ +void malloc_inspect_all(void (*handler)(void*, void*, size_t, void*), void* arg); + +#if !NO_MALLINFO +/* + mallinfo() + Returns (by copy) a struct containing various summary statistics: + + arena: current total non-mmapped bytes allocated from system + ordblks: the number of free chunks + smblks: always zero. + hblks: current number of mmapped regions + hblkhd: total bytes held in mmapped regions + usmblks: the maximum total allocated space. This will be greater + than current total if trimming has occurred. + fsmblks: always zero + uordblks: current total allocated space (normal or mmapped) + fordblks: total free space + keepcost: the maximum number of bytes that could ideally be released + back to system via malloc_trim. ("ideally" means that + it ignores page restrictions etc.) + + Because these fields are ints, but internal bookkeeping may + be kept as longs, the reported values may wrap around zero and + thus be inaccurate. +*/ + +struct mallinfo mallinfo(void); +#endif /* NO_MALLINFO */ + +/* + independent_calloc(size_t n_elements, size_t element_size, void* chunks[]); + + independent_calloc is similar to calloc, but instead of returning a + single cleared space, it returns an array of pointers to n_elements + independent elements that can hold contents of size elem_size, each + of which starts out cleared, and can be independently freed, + realloc'ed etc. The elements are guaranteed to be adjacently + allocated (this is not guaranteed to occur with multiple callocs or + mallocs), which may also improve cache locality in some + applications. + + The "chunks" argument is optional (i.e., may be null, which is + probably the most typical usage). If it is null, the returned array + is itself dynamically allocated and should also be freed when it is + no longer needed. Otherwise, the chunks array must be of at least + n_elements in length. It is filled in with the pointers to the + chunks. + + In either case, independent_calloc returns this pointer array, or + null if the allocation failed. If n_elements is zero and "chunks" + is null, it returns a chunk representing an array with zero elements + (which should be freed if not wanted). + + Each element must be freed when it is no longer needed. This can be + done all at once using bulk_free. + + independent_calloc simplifies and speeds up implementations of many + kinds of pools. It may also be useful when constructing large data + structures that initially have a fixed number of fixed-sized nodes, + but the number is not known at compile time, and some of the nodes + may later need to be freed. For example: + + struct Node { int item; struct Node* next; }; + + struct Node* build_list() { + struct Node** pool; + int n = read_number_of_nodes_needed(); + if (n <= 0) return 0; + pool = (struct Node**)(independent_calloc(n, sizeof(struct Node), 0); + if (pool == 0) die(); + // organize into a linked list... + struct Node* first = pool[0]; + for (i = 0; i < n-1; ++i) + pool[i]->next = pool[i+1]; + free(pool); // Can now free the array (or not, if it is needed later) + return first; + } +*/ +void** independent_calloc(size_t, size_t, void**); + +/* + independent_comalloc(size_t n_elements, size_t sizes[], void* chunks[]); + + independent_comalloc allocates, all at once, a set of n_elements + chunks with sizes indicated in the "sizes" array. It returns + an array of pointers to these elements, each of which can be + independently freed, realloc'ed etc. The elements are guaranteed to + be adjacently allocated (this is not guaranteed to occur with + multiple callocs or mallocs), which may also improve cache locality + in some applications. + + The "chunks" argument is optional (i.e., may be null). If it is null + the returned array is itself dynamically allocated and should also + be freed when it is no longer needed. Otherwise, the chunks array + must be of at least n_elements in length. It is filled in with the + pointers to the chunks. + + In either case, independent_comalloc returns this pointer array, or + null if the allocation failed. If n_elements is zero and chunks is + null, it returns a chunk representing an array with zero elements + (which should be freed if not wanted). + + Each element must be freed when it is no longer needed. This can be + done all at once using bulk_free. + + independent_comallac differs from independent_calloc in that each + element may have a different size, and also that it does not + automatically clear elements. + + independent_comalloc can be used to speed up allocation in cases + where several structs or objects must always be allocated at the + same time. For example: + + struct Head { ... } + struct Foot { ... } + + void send_message(char* msg) { + int msglen = strlen(msg); + size_t sizes[3] = { sizeof(struct Head), msglen, sizeof(struct Foot) }; + void* chunks[3]; + if (independent_comalloc(3, sizes, chunks) == 0) + die(); + struct Head* head = (struct Head*)(chunks[0]); + char* body = (char*)(chunks[1]); + struct Foot* foot = (struct Foot*)(chunks[2]); + // ... + } + + In general though, independent_comalloc is worth using only for + larger values of n_elements. For small values, you probably won't + detect enough difference from series of malloc calls to bother. + + Overuse of independent_comalloc can increase overall memory usage, + since it cannot reuse existing noncontiguous small chunks that + might be available for some of the elements. +*/ +void** independent_comalloc(size_t, size_t*, void**); + +/* + bulk_free(void* array[], size_t n_elements) + Frees and clears (sets to null) each non-null pointer in the given + array. This is likely to be faster than freeing them one-by-one. + If footers are used, pointers that have been allocated in different + mspaces are not freed or cleared, and the count of all such pointers + is returned. For large arrays of pointers with poor locality, it + may be worthwhile to sort this array before calling bulk_free. +*/ +size_t bulk_free(void**, size_t n_elements); + +/* + pvalloc(size_t n); + Equivalent to valloc(minimum-page-that-holds(n)), that is, + round up n to nearest pagesize. + */ +void* pvalloc(size_t); + +/* + malloc_trim(size_t pad); + + If possible, gives memory back to the system (via negative arguments + to sbrk) if there is unused memory at the `high' end of the malloc + pool or in unused MMAP segments. You can call this after freeing + large blocks of memory to potentially reduce the system-level memory + requirements of a program. However, it cannot guarantee to reduce + memory. Under some allocation patterns, some large free blocks of + memory will be locked between two used chunks, so they cannot be + given back to the system. + + The `pad' argument to malloc_trim represents the amount of free + trailing space to leave untrimmed. If this argument is zero, only + the minimum amount of memory to maintain internal data structures + will be left. Non-zero arguments can be supplied to maintain enough + trailing space to service future expected allocations without having + to re-obtain memory from the system. + + Malloc_trim returns 1 if it actually released any memory, else 0. +*/ +int malloc_trim(size_t); + +/* + malloc_stats(); + Prints on stderr the amount of space obtained from the system (both + via sbrk and mmap), the maximum amount (which may be more than + current if malloc_trim and/or munmap got called), and the current + number of bytes allocated via malloc (or realloc, etc) but not yet + freed. Note that this is the number of bytes allocated, not the + number requested. It will be larger than the number requested + because of alignment and bookkeeping overhead. Because it includes + alignment wastage as being in use, this figure may be greater than + zero even when no user-level chunks are allocated. + + The reported current and maximum system memory can be inaccurate if + a program makes other calls to system memory allocation functions + (normally sbrk) outside of malloc. + + malloc_stats prints only the most commonly interesting statistics. + More information can be obtained by calling mallinfo. + + malloc_stats is not compiled if NO_MALLOC_STATS is defined. +*/ +void malloc_stats(void); + +#endif /* !ONLY_MSPACES */ + +/* + malloc_usable_size(void* p); + + Returns the number of bytes you can actually use in + an allocated chunk, which may be more than you requested (although + often not) due to alignment and minimum size constraints. + You can use this many bytes without worrying about + overwriting other allocated objects. This is not a particularly great + programming practice. malloc_usable_size can be more useful in + debugging and assertions, for example: + + p = malloc(n); + assert(malloc_usable_size(p) >= 256); +*/ +size_t malloc_usable_size(const void*); + +#if MSPACES + +/* + mspace is an opaque type representing an independent + region of space that supports mspace_malloc, etc. +*/ +typedef void* mspace; + +/* + create_mspace creates and returns a new independent space with the + given initial capacity, or, if 0, the default granularity size. It + returns null if there is no system memory available to create the + space. If argument locked is non-zero, the space uses a separate + lock to control access. The capacity of the space will grow + dynamically as needed to service mspace_malloc requests. You can + control the sizes of incremental increases of this space by + compiling with a different DEFAULT_GRANULARITY or dynamically + setting with mallopt(M_GRANULARITY, value). +*/ +mspace create_mspace(size_t capacity, int locked); + +/* + destroy_mspace destroys the given space, and attempts to return all + of its memory back to the system, returning the total number of + bytes freed. After destruction, the results of access to all memory + used by the space become undefined. +*/ +size_t destroy_mspace(mspace msp); + +/* + create_mspace_with_base uses the memory supplied as the initial base + of a new mspace. Part (less than 128*sizeof(size_t) bytes) of this + space is used for bookkeeping, so the capacity must be at least this + large. (Otherwise 0 is returned.) When this initial space is + exhausted, additional memory will be obtained from the system. + Destroying this space will deallocate all additionally allocated + space (if possible) but not the initial base. +*/ +mspace create_mspace_with_base(void* base, size_t capacity, int locked); + +/* + mspace_track_large_chunks controls whether requests for large chunks + are allocated in their own untracked mmapped regions, separate from + others in this mspace. By default large chunks are not tracked, + which reduces fragmentation. However, such chunks are not + necessarily released to the system upon destroy_mspace. Enabling + tracking by setting to true may increase fragmentation, but avoids + leakage when relying on destroy_mspace to release all memory + allocated using this space. The function returns the previous + setting. +*/ +int mspace_track_large_chunks(mspace msp, int enable); + +#if !NO_MALLINFO +/* + mspace_mallinfo behaves as mallinfo, but reports properties of + the given space. +*/ +struct mallinfo mspace_mallinfo(mspace msp); +#endif /* NO_MALLINFO */ + +/* + An alias for mallopt. +*/ +int mspace_mallopt(int, int); + +/* + The following operate identically to their malloc counterparts + but operate only for the given mspace argument +*/ +void* mspace_malloc(mspace msp, size_t bytes); +void mspace_free(mspace msp, void* mem); +void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size); +void* mspace_realloc(mspace msp, void* mem, size_t newsize); +void* mspace_realloc_in_place(mspace msp, void* mem, size_t newsize); +void* mspace_memalign(mspace msp, size_t alignment, size_t bytes); +void** mspace_independent_calloc(mspace msp, size_t n_elements, size_t elem_size, void* chunks[]); +void** mspace_independent_comalloc(mspace msp, size_t n_elements, size_t sizes[], void* chunks[]); +size_t mspace_bulk_free(mspace msp, void**, size_t n_elements); +size_t mspace_usable_size(const void* mem); +void mspace_malloc_stats(mspace msp); +int mspace_trim(mspace msp, size_t pad); +size_t mspace_footprint(mspace msp); +size_t mspace_max_footprint(mspace msp); +size_t mspace_footprint_limit(mspace msp); +size_t mspace_set_footprint_limit(mspace msp, size_t bytes); +void mspace_inspect_all(mspace msp, void (*handler)(void*, void*, size_t, void*), void* arg); +#endif /* MSPACES */ + +#ifdef __cplusplus +}; /* end of extern "C" */ +#endif + +#endif /* MALLOC_280_H */ diff --git a/libc/include/string.h b/libc/include/string.h old mode 100755 new mode 100644 index e33fa44..5fde42f --- a/libc/include/string.h +++ b/libc/include/string.h @@ -1,13 +1,13 @@ -#ifndef _STRING_H -#define _STRING_H 1 - -#include -#include - -int memcmp(const void*, const void*, size_t); -void* memcpy(void* __restrict, const void* __restrict, size_t); -void* memmove(void*, const void*, size_t); -void* memset(void*, int, size_t); -size_t strlen(const char*); - +#ifndef _STRING_H +#define _STRING_H 1 + +#include +#include + +int memcmp(const void*, const void*, size_t); +void* memcpy(void* __restrict, const void* __restrict, size_t); +void* memmove(void*, const void*, size_t); +void* memset(void*, int, size_t); +size_t strlen(const char*); + #endif \ No newline at end of file diff --git a/libc/include/sys/cdefs.h b/libc/include/sys/cdefs.h index 2d557b4..4ef309d 100755 --- a/libc/include/sys/cdefs.h +++ b/libc/include/sys/cdefs.h @@ -1,5 +1,5 @@ -#ifndef _SYS_CDEFS_H -#define _SYS_CDEFS_H 1 - -#define __red_libc 1 +#ifndef _SYS_CDEFS_H +#define _SYS_CDEFS_H 1 + +#define __red_libc 1 #endif \ No newline at end of file diff --git a/libc/stdio/printf.c b/libc/stdio/printf.c old mode 100755 new mode 100644 index caee4b3..71d4ee8 --- a/libc/stdio/printf.c +++ b/libc/stdio/printf.c @@ -1,94 +1,93 @@ -#include -#include -#include -#include -#include - -static bool print(const char* data, size_t length) { - const unsigned char* bytes = (const unsigned char*) data; - for (size_t i = 0; i < length; i++) - if(putchar(bytes[i]) == EOF) - return false' - return true; -} - -int printf(const char* restrict format, ...) { - va_list parameters; - va_start(parameters, format); - - int written = 0; - - while(*format != '\0') { - size_t maxrem = INT_MAX - writen; - - if(format[0] != '%' || format[1] == '%') { - if(format[0] == '%') - format++; - size_t amount = 1; - - while (format[amount] && format[amount] != '%') - amount++; - - if(maxrem < amount) { - //TODO: Set an OVERFLOW error - return -1; - } - - if ((!print(format, amount)) - return -1; - - format += amount; - written += amount; - continue; - } - - const char* first_format = format++; - - switch(*format) { - case 'c': - format++; - char c = (char) va_arg(parameters, int); - if(!maxrem) { - //TODO: Set OVERFLOW - return -1; - } - - if(!print(&c, sizeof(c))) - return -1; - written++; - break; - case 's': - format++; - - const char* str = va_arg(parameters, const char*); - size_t len = strlen(str); - - if(maxrem < len) { - //TODO: Set OVERFLOW - return -1; - } - - if(!print(str, len)) - return -1; - - written += len; - break; - default: - format = first_format; - size_t len = strlen(format); - if(maxrem < len) { - //TODO: Set OVERFLOW - return -1; - } - - if(!print(format, len)) - return -1; - written += len; - format += len; - break; - } - } - - va_end(parameters); - return written; -} +#include +#include +#include +#include +#include + +static bool print(const char* data, size_t length) { + const unsigned char* bytes = (const unsigned char*)data; + for (size_t i = 0; i < length; i++) + if (putchar(bytes[i]) == EOF) + return false' return true; +} + +int printf(const char* restrict format, ...) { + va_list parameters; + va_start(parameters, format); + + int written = 0; + + while (*format != '\0') { + size_t maxrem = INT_MAX - writen; + + if (format[0] != '%' || format[1] == '%') { + if (format[0] == '%') + format++; + size_t amount = 1; + + while (format[amount] && format[amount] != '%') + amount++; + + if (maxrem < amount) { + // TODO: Set an OVERFLOW error + return -1; + } + + if ((!print(format, amount)) + return -1; + + format += amount; + written += amount; + continue; + } + + const char* first_format = format++; + + switch (*format) { + case 'c': + format++; + char c = (char)va_arg(parameters, int); + if (!maxrem) { + // TODO: Set OVERFLOW + return -1; + } + + if (!print(&c, sizeof(c))) + return -1; + written++; + break; + case 's': + format++; + + const char* str = va_arg(parameters, const char*); + size_t len = strlen(str); + + if (maxrem < len) { + // TODO: Set OVERFLOW + return -1; + } + + if (!print(str, len)) + return -1; + + written += len; + break; + default: + format = first_format; + size_t len = strlen(format); + if (maxrem < len) { + // TODO: Set OVERFLOW + return -1; + } + + if (!print(format, len)) + return -1; + written += len; + format += len; + break; + } + } + + va_end(parameters); + return written; +} diff --git a/libc/stdio/putchar.c b/libc/stdio/putchar.c old mode 100755 new mode 100644 index eba2d17..a969318 --- a/libc/stdio/putchar.c +++ b/libc/stdio/putchar.c @@ -1,15 +1,15 @@ -#include - -#if defined(__is_libk) -#include -#endif - -int putchar(int ic) { -#if defined(__is_libk) - char c = (char) ic; - term_write(&c, sizeof(c)); -#else - //TODO: Implement stdio & the write call -#endif - return ic; +#include + +#if defined(__is_libk) +#include +#endif + +int putchar(int ic) { +#if defined(__is_libk) + char c = (char)ic; + term_write(&c, sizeof(c)); +#else + // TODO: Implement stdio & the write call +#endif + return ic; } \ No newline at end of file diff --git a/libc/stdio/puts.c b/libc/stdio/puts.c index ea900cb..54a7185 100755 --- a/libc/stdio/puts.c +++ b/libc/stdio/puts.c @@ -1,5 +1,5 @@ -#include - -int puts(const char* string) { - return printf("%s\n"), string); +#include + +int puts(const char* string) { + return printf("%s\n"), string); } \ No newline at end of file diff --git a/libc/stdlib/abort.c b/libc/stdlib/abort.c old mode 100755 new mode 100644 index 8bf0f45..3537af8 --- a/libc/stdlib/abort.c +++ b/libc/stdlib/abort.c @@ -1,15 +1,15 @@ -#include -#include - -__attribute__((__noreturn__)) -void abort(void) { - -#if defined(__is_libk) - //TODO: Kernel panic. - printf(">>PANIC<<<\n abort() panicked!\n"); -#else - printf("abort() called\n"); -#endif - while(1) {} - __builtin_unreachable(); +#include +#include + +__attribute__((__noreturn__)) void abort(void) { + +#if defined(__is_libk) + // TODO: Kernel panic. + printf(">>PANIC<<<\n abort() panicked!\n"); +#else + printf("abort() called\n"); +#endif + while (1) { + } + __builtin_unreachable(); } \ No newline at end of file diff --git a/libc/string/memcmp.c b/libc/string/memcmp.c old mode 100755 new mode 100644 index b060501..dfb04f0 --- a/libc/string/memcmp.c +++ b/libc/string/memcmp.c @@ -1,13 +1,13 @@ -#include - -int memcmp(const void* aptr, const void* bptr, size_t size_ { - const unsigned char* a = (const unsigned char*) aptr; - const unsigned char* b = (const unsigned char*) bptr; - - for (size_t i = 0; i < size; i++) { - if(a[i] < b[i] - return -1 - else if(b[i] < a[i]) - return 1; - } +#include + +int memcmp(const void* aptr, const void* bptr, size_t size_ { + const unsigned char* a = (const unsigned char*)aptr; + const unsigned char* b = (const unsigned char*)bptr; + + for (size_t i = 0; i < size; i++) { + if(a[i] < b[i] + return -1 + else if(b[i] < a[i]) + return 1; + } return 0; \ No newline at end of file diff --git a/libc/string/memmove.c b/libc/string/memmove.c old mode 100755 new mode 100644 index 87c171f..7d3ea22 --- a/libc/string/memmove.c +++ b/libc/string/memmove.c @@ -1,14 +1,14 @@ -#include - -void* memmove(void* dstptr, const void* srcptr, size_t size) { - unsigned char* dst = (unsigned char*) dstptr; - const unsigned char* stc = (const unsigned char*) srcptr; - if(dst < src) { - for(size_t i = o; i < size; i++) - dst[i] = src[i]; - } else { - for(size_t i = size; i != 0; i--) - dst[i-1] = src[i-1]; - } - return dstptr; +#include + +void* memmove(void* dstptr, const void* srcptr, size_t size) { + unsigned char* dst = (unsigned char*)dstptr; + const unsigned char* stc = (const unsigned char*)srcptr; + if (dst < src) { + for (size_t i = o; i < size; i++) + dst[i] = src[i]; + } else { + for (size_t i = size; i != 0; i--) + dst[i - 1] = src[i - 1]; + } + return dstptr; } \ No newline at end of file diff --git a/libc/string/memset.c b/libc/string/memset.c old mode 100755 new mode 100644 index f16ce62..4481c30 --- a/libc/string/memset.c +++ b/libc/string/memset.c @@ -1,8 +1,8 @@ -#include - -void* memset(void* bufptr, int value, size_t size) { - unsigned char* buf = (unsigned char*) bufptr; - for(size_t i = 0; i < size; i++) - buf[i] = (unsigned char) value; - return bufptr; +#include + +void* memset(void* bufptr, int value, size_t size) { + unsigned char* buf = (unsigned char*)bufptr; + for (size_t i = 0; i < size; i++) + buf[i] = (unsigned char)value; + return bufptr; } \ No newline at end of file diff --git a/libc/string/strlen.c b/libc/string/strlen.c old mode 100755 new mode 100644 index 998b46d..dfc005c --- a/libc/string/strlen.c +++ b/libc/string/strlen.c @@ -1,8 +1,7 @@ -#include - -size_t strlen(const char* str) { - size_t len = 0; - while (str[len]) - len++ - return len; +#include + +size_t strlen(const char* str) { + size_t len = 0; + while (str[len]) + len++ return len; } \ No newline at end of file