-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
83061e8
commit b540e29
Showing
12 changed files
with
248 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
/* | ||
* string.h | ||
* | ||
* Created on: 16/12/2021 | ||
* Author: Paulo Almeida | ||
*/ | ||
|
||
#ifndef INCLUDE_LIBC_STRING_H_ | ||
#define INCLUDE_LIBC_STRING_H_ | ||
|
||
#include "libc/compiler/freestanding.h" | ||
|
||
void* memcpy(void *dst, const void *src, size_t size); | ||
void* memset(void *buf, char value, size_t size); | ||
void* memmove(void *dst, void *src, size_t size); | ||
size_t strlen(const char *buf); | ||
void strrev(char *str, size_t length); | ||
|
||
#endif /* INCLUDE_LIBC_STRING_H_ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
/* | ||
* abs.c | ||
* | ||
* Created on: 16/12/2021 | ||
* Author: Paulo Almeida | ||
*/ | ||
|
||
#include "libc/stdlib.h" | ||
|
||
int abs(int value) { | ||
/* | ||
* C99 abs:"if the result cannot be represented, the behavior is undefined." | ||
* So I decided not to handle 2-complement's edge case such as -2147483648 | ||
*/ | ||
int const mask = value >> (sizeof(int) * CHAR_BIT - 1); | ||
return (value + mask) ^ mask; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
/* | ||
* ltoa.c | ||
* | ||
* Created on: 16/12/2021 | ||
* Author: Paulo Almeida | ||
*/ | ||
|
||
#include "libc/stdlib.h" | ||
#include "libc/string.h" | ||
|
||
char* ltoa(long value, char *str, int radix) { | ||
// Check for supported base. | ||
if (radix != 8 && radix != 10 && radix != 16) { | ||
*str = '\0'; | ||
return str; | ||
} | ||
|
||
int i = 0; | ||
bool is_negative = false; | ||
|
||
/* handle edge case */ | ||
if (value == 0) { | ||
str[i++] = '0'; | ||
str[i] = '\0'; | ||
return str; | ||
} | ||
|
||
/* negative numbers are handled only with base 10 */ | ||
if (value < 0 && radix == 10) { | ||
is_negative = true; | ||
value = abs(value); | ||
} | ||
|
||
while (value != 0) { | ||
int rem = value % radix; | ||
str[i++] = (rem > 9) ? (rem - 10) + 'a' : rem + '0'; | ||
value = value / radix; | ||
} | ||
|
||
if (is_negative) | ||
str[i++] = '-'; | ||
|
||
str[i] = '\0'; | ||
strrev(str, i); | ||
|
||
return str; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
#---------------------------------------------------------------------------- | ||
# AlmeidaOS libc/string makefile | ||
#---------------------------------------------------------------------------- | ||
|
||
DIR_ROOT := $(CURDIR)/../../../ | ||
|
||
include $(DIR_ROOT)/scripts/config.mk | ||
|
||
# override AS flags from $(DIR_ROOT)/scripts/config.mk | ||
ASFLAGS := -f elf64 | ||
|
||
DIR_SRC_SUBSYSTEMS := $(shell find $(CURDIR)/* -maxdepth 1 -type d) | ||
DIR_TARGET := $(DIR_BUILD)/libc/string | ||
|
||
SRC_C_FILES := $(wildcard *.c) | ||
BIN_C_FILES := $(SRC_C_FILES:%.c=$(DIR_TARGET)/%.o) | ||
|
||
SRC_ASM_FILES := $(wildcard *.asm) | ||
BIN_ASM_FILES := $(SRC_ASM_FILES:%.asm=$(DIR_TARGET)/%.o) | ||
|
||
TAG := [libc/string] | ||
|
||
all: mkdir compile | ||
@echo "$(TAG) Compiled successfully" | ||
|
||
.PHONY: mkdir | ||
mkdir: | ||
@mkdir -p $(DIR_TARGET) | ||
|
||
.PHONY: clean | ||
clean: | ||
@rm -f $(BIN_C_FILES) | ||
|
||
.PHONY: compile | ||
compile: $(BIN_C_FILES) $(BIN_ASM_FILES) $(DIR_SRC_SUBSYSTEMS) | ||
|
||
$(BIN_C_FILES): $(DIR_TARGET)/%.o: %.c | ||
@echo "$(TAG) Compiling $<" | ||
@$(CC) $(CCFLAGS) -I$(DIR_INCLUDE) -c $< -o $@ | ||
|
||
$(BIN_ASM_FILES): $(DIR_TARGET)/%.o: %.asm | ||
@echo "$(TAG) Assembling $<" | ||
@$(AS) $(ASFLAGS) $< -o $@ | ||
|
||
.PHONY: $(DIR_SRC_SUBSYSTEMS) | ||
$(DIR_SRC_SUBSYSTEMS): | ||
@$(MAKE) $(MAKE_FLAGS) --directory=$@ | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
/* | ||
* memcpy.c | ||
* | ||
* Created on: 16/12/2021 | ||
* Author: Paulo Almeida | ||
*/ | ||
|
||
#include "libc/string.h" | ||
|
||
void* memcpy(void *dst, const void *src, size_t size) { | ||
|
||
long d0, d1, d2; | ||
asm volatile( | ||
"rep movsq \n\t" | ||
"movq rcx, %[remainder] \n\t" | ||
"rep movsb \n\t" | ||
: "=&c" (d0), "=&D" (d1), "=&S" (d2) | ||
: "0" (size >> 3), [remainder] "g" (size & 7), "1" (dst), "2" (src) | ||
: "memory" | ||
); | ||
|
||
return dst; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
/* | ||
* memmove.c | ||
* | ||
* Created on: 16/12/2021 | ||
* Author: Paulo Almeida | ||
*/ | ||
|
||
#include "libc/string.h" | ||
|
||
void* memmove(void *dst, void *src, size_t size) { | ||
char *t_dst = dst; | ||
char *t_src = src; | ||
|
||
/* sanity check */ | ||
if (t_src == t_dst) | ||
return dst; | ||
|
||
memcpy(t_dst, t_src, size); | ||
|
||
if ((t_dst > t_src && (t_src + size) < t_dst) || (t_src > t_dst && (t_dst + size) < t_src)) { | ||
/* they don't interset */ | ||
memset(t_src, 0, size); | ||
} else if (t_dst > t_src) { | ||
memset(t_src, 0, size - (t_dst - t_src)); | ||
} else { | ||
memset(t_src + ((t_src + size) - (t_dst + size)), 0, (t_src + size) - (t_dst + size)); | ||
} | ||
|
||
return dst; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
/* | ||
* memset.c | ||
* | ||
* Created on: 16/12/2021 | ||
* Author: Paulo Almeida | ||
*/ | ||
|
||
#include "libc/string.h" | ||
|
||
void* memset(void *buf, char value, size_t size) { | ||
asm volatile( | ||
"rep stosb \n\t" | ||
: "=&D" (buf) | ||
: "a" (value), "c"(size) | ||
: "memory" | ||
); | ||
return buf; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
/* | ||
* strlen.c | ||
* | ||
* Created on: 16/12/2021 | ||
* Author: Paulo Almeida | ||
*/ | ||
|
||
#include "libc/string.h" | ||
|
||
size_t strlen(const char *buf) { | ||
/* we don't count NUL-terminator */ | ||
size_t len = 0; | ||
for (; *(buf + len) != '\0'; len++) | ||
/* nothing */ ; | ||
return len; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
/* | ||
* strrev.c | ||
* | ||
* Created on: 16/12/2021 | ||
* Author: Paulo Almeida | ||
*/ | ||
|
||
#include "libc/string.h" | ||
|
||
void strrev(char *str, size_t length) { | ||
/* str is expected to be NUL-terminated */ | ||
if (length < 2) | ||
return; | ||
|
||
for (size_t start = 0, end = length - 1; start < length / 2; start++, end--) { | ||
char tmp = *(str + start); | ||
*(str + start) = *(str + end); | ||
*(str + end) = tmp; | ||
} | ||
} |