183 lines
4.6 KiB
C
183 lines
4.6 KiB
C
#include "string.h"
|
||
|
||
// Заполнить кусок памяти определенным байтом (очень нужно для очистки буферов)
|
||
void* memset(void* dest, int val, size_t count) {
|
||
uint8_t* temp = (uint8_t*)dest;
|
||
for (size_t i = 0; i < count; i++) {
|
||
temp[i] = (uint8_t)val;
|
||
}
|
||
return dest;
|
||
}
|
||
|
||
// Скопировать кусок памяти (будем использовать для скроллинга VGA экрана)
|
||
void* memcpy(void* dest, const void* src, size_t count) {
|
||
uint8_t* d = (uint8_t*)dest;
|
||
const uint8_t* s = (const uint8_t*)src;
|
||
for (size_t i = 0; i < count; i++) {
|
||
d[i] = s[i];
|
||
}
|
||
return dest;
|
||
}
|
||
|
||
// Скопировать кусок памяти с учетом возможного пересечения областей
|
||
void* memmove(void* dest, const void* src, size_t count) {
|
||
uint8_t* d = (uint8_t*)dest;
|
||
const uint8_t* s = (const uint8_t*)src;
|
||
|
||
if (d < s) {
|
||
for (size_t i = 0; i < count; i++) {
|
||
d[i] = s[i];
|
||
}
|
||
} else {
|
||
for (size_t i = count; i > 0; i--) {
|
||
d[i - 1] = s[i - 1];
|
||
}
|
||
}
|
||
return dest;
|
||
}
|
||
|
||
// Сравнение блоков памяти
|
||
int memcmp(const void* s1, const void* s2, size_t count) {
|
||
const uint8_t* p1 = (const uint8_t*)s1;
|
||
const uint8_t* p2 = (const uint8_t*)s2;
|
||
for (size_t i = 0; i < count; i++) {
|
||
if (p1[i] != p2[i]) {
|
||
return p1[i] - p2[i];
|
||
}
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
// Длина строки
|
||
size_t strlen(const char* str) {
|
||
size_t len = 0;
|
||
while (str[len] != '\0') {
|
||
len++;
|
||
}
|
||
return len;
|
||
}
|
||
|
||
// Копирование строки
|
||
char* strcpy(char* dest, const char* src) {
|
||
size_t i = 0;
|
||
while ((dest[i] = src[i]) != '\0') {
|
||
i++;
|
||
}
|
||
return dest;
|
||
}
|
||
|
||
// Конкатенация строк
|
||
char* strcat(char* dest, const char* src) {
|
||
size_t dest_len = strlen(dest);
|
||
size_t i = 0;
|
||
while ((dest[dest_len + i] = src[i]) != '\0') {
|
||
i++;
|
||
}
|
||
return dest;
|
||
}
|
||
|
||
// Сравнение строк (понадобится, когда будем парсить команды в терминале)
|
||
int strcmp(const char* s1, const char* s2) {
|
||
while (*s1 && (*s1 == *s2)) {
|
||
s1++;
|
||
s2++;
|
||
}
|
||
return *(const unsigned char*)s1 - *(const unsigned char*)s2;
|
||
}
|
||
|
||
// Строка в число
|
||
int atoi(const char* str) {
|
||
int res = 0;
|
||
int sign = 1;
|
||
int i = 0;
|
||
|
||
// Пропускаем пробелы, если они есть
|
||
while (str[i] == ' ' || str[i] == '\t') {
|
||
i++;
|
||
}
|
||
|
||
// Учитываем знак
|
||
if (str[i] == '-') {
|
||
sign = -1;
|
||
i++;
|
||
} else if (str[i] == '+') {
|
||
i++;
|
||
}
|
||
|
||
// Считаем само число
|
||
while (str[i] >= '0' && str[i] <= '9') {
|
||
res = res * 10 + (str[i] - '0');
|
||
i++;
|
||
}
|
||
|
||
return sign * res;
|
||
}
|
||
|
||
// Число в строку (поддерживает base = 10 и base = 2)
|
||
char* itoa(int value, char* str, int base) {
|
||
int i = 0;
|
||
int is_negative = 0;
|
||
|
||
// Защита от дурака
|
||
if (base < 2 || base > 36) {
|
||
str[0] = '\0';
|
||
return str;
|
||
}
|
||
|
||
// Обрабатываем 0
|
||
if (value == 0) {
|
||
str[i++] = '0';
|
||
str[i] = '\0';
|
||
return str;
|
||
}
|
||
|
||
// Отрицательные числа обрабатываем только для десятичной системы
|
||
if (value < 0 && base == 10) {
|
||
is_negative = 1;
|
||
value = -value;
|
||
}
|
||
|
||
// Переводим число в строку (но она получится задом наперед)
|
||
while (value != 0) {
|
||
int rem = value % base;
|
||
str[i++] = (rem > 9) ? (rem - 10) + 'a' : rem + '0';
|
||
value = value / base;
|
||
}
|
||
|
||
// Добавляем минус
|
||
if (is_negative) {
|
||
str[i++] = '-';
|
||
}
|
||
|
||
str[i] = '\0';
|
||
|
||
// Переворачиваем строку в нормальный вид
|
||
int start = 0;
|
||
int end = i - 1;
|
||
while (start < end) {
|
||
char temp = str[start];
|
||
str[start] = str[end];
|
||
str[end] = temp;
|
||
start++;
|
||
end--;
|
||
}
|
||
|
||
return str;
|
||
}
|
||
|
||
// Число в красивый Hex вид (например, 255 -> "0x000000ff")
|
||
char* itox(uint32_t value, char* str) {
|
||
char* hex_digits = "0123456789abcdef";
|
||
|
||
str[0] = '0';
|
||
str[1] = 'x';
|
||
str[10] = '\0'; // 2 символа на "0x" + 8 символов на 32-битное число
|
||
|
||
// Заполняем с конца
|
||
for (int i = 9; i >= 2; i--) {
|
||
str[i] = hex_digits[value & 0xF];
|
||
value >>= 4;
|
||
}
|
||
|
||
return str;
|
||
}
|