2023-10-21 21:23:51 +03:00
|
|
|
|
/**
|
|
|
|
|
* tool.c
|
|
|
|
|
* Функции для упрощения разработки
|
|
|
|
|
*
|
|
|
|
|
* Данный файл содержит реализацию функций для упрощения написания кода
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
|
2023-10-21 20:27:23 +03:00
|
|
|
|
#include <stdarg.h>
|
2023-10-29 16:11:41 +03:00
|
|
|
|
#include <stdbool.h>
|
2023-10-21 20:27:23 +03:00
|
|
|
|
#include <stdint.h>
|
|
|
|
|
|
|
|
|
|
void tool_memcpy(void *dest, void *src, uint64_t n) {
|
|
|
|
|
char *d = (char *)dest;
|
|
|
|
|
const char *s = (const char *)src;
|
|
|
|
|
|
|
|
|
|
for (uint64_t i = 0; i < n; i++) { d[i] = s[i]; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void *tool_memset(void *ptr, uint8_t n, uint64_t size) {
|
|
|
|
|
uint8_t *p = (uint8_t *)ptr;
|
|
|
|
|
for (uint64_t i = 0; i < size; i++) { p[i] = n; }
|
|
|
|
|
return ptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint64_t tool_strlen(const char *str) {
|
|
|
|
|
uint64_t length = 0;
|
|
|
|
|
while (*str) {
|
|
|
|
|
length++;
|
|
|
|
|
str++;
|
|
|
|
|
}
|
|
|
|
|
return length;
|
|
|
|
|
}
|
|
|
|
|
|
2023-12-07 13:15:53 +03:00
|
|
|
|
void tool_strcpy(char *dest, char *src) {
|
|
|
|
|
uint64_t i = 0;
|
|
|
|
|
while (src[i] != '\0') {
|
|
|
|
|
dest[i] = src[i];
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
dest[i] = '\0';
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-21 20:27:23 +03:00
|
|
|
|
uint64_t tool_starts_with(const char *str, const char *prefix) {
|
|
|
|
|
uint64_t str_len = tool_strlen(str);
|
|
|
|
|
uint64_t prefix_len = tool_strlen(prefix);
|
|
|
|
|
|
|
|
|
|
if (prefix_len > str_len) { return 0; }
|
|
|
|
|
|
|
|
|
|
for (uint64_t i = 0; i < prefix_len; i++) {
|
|
|
|
|
if (str[i] != prefix[i]) { return 0; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-29 16:11:41 +03:00
|
|
|
|
// Функция для переворачивания строки
|
|
|
|
|
void tool_reverse_str(char *str) {
|
|
|
|
|
int len = 0;
|
|
|
|
|
while (str[len] != '\0') { len++; }
|
|
|
|
|
|
|
|
|
|
int start = 0;
|
|
|
|
|
int end = len - 1;
|
|
|
|
|
|
|
|
|
|
while (start < end) {
|
|
|
|
|
char temp = str[start];
|
|
|
|
|
str[start] = str[end];
|
|
|
|
|
str[end] = temp;
|
|
|
|
|
start++;
|
|
|
|
|
end--;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Преобразование целого числа "i" в системе счисления "base" в строку "buf"
|
|
|
|
|
void tool_int_to_str(int64_t i, uint8_t base, char *buf) {
|
|
|
|
|
bool negative = false;
|
|
|
|
|
|
|
|
|
|
// Проверяем, является ли число отрицательным
|
|
|
|
|
if (i < 0) {
|
|
|
|
|
negative = true;
|
|
|
|
|
i *= -1; // Если да, то умножаем на -1, чтобы сделать его положительным
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int64_t index = 0;
|
|
|
|
|
// Деление с остатком для преобразования числа в нужную систему счисления
|
|
|
|
|
do {
|
|
|
|
|
int64_t remainder = i % base;
|
|
|
|
|
// Преобразовываем остаток в символ и добавляем его в строку
|
|
|
|
|
buf[index++] =
|
2023-12-12 21:11:06 +03:00
|
|
|
|
(remainder > 9) ? (remainder - 10) + 'A' : remainder + '0'; // Если остаток > 9, добавляем заглавную букву А
|
2023-10-29 16:11:41 +03:00
|
|
|
|
i /= base;
|
|
|
|
|
} while (i > 0);
|
|
|
|
|
|
|
|
|
|
// Если число было отрицательным, добавляем знак минуса в конец строки
|
|
|
|
|
if (negative) { buf[index++] = '-'; }
|
|
|
|
|
|
|
|
|
|
// Добавляем нулевой символ в конец строки, чтобы завершить ее
|
|
|
|
|
buf[index] = '\0';
|
|
|
|
|
|
|
|
|
|
// Переворачиваем строку, чтобы цифры были в правильном порядке
|
|
|
|
|
tool_reverse_str(buf);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Преобразование неотрицательного целого числа "i" в системе счисления "base" в
|
|
|
|
|
// строку "buf"
|
|
|
|
|
void tool_uint_to_str(uint64_t i, uint8_t base, char *buf) {
|
|
|
|
|
uint64_t index = 0;
|
|
|
|
|
// Деление с остатком для преобразования числа в нужную систему счисления
|
|
|
|
|
do {
|
|
|
|
|
uint64_t remainder = i % base;
|
|
|
|
|
// Преобразовываем остаток в символ и добавляем его в строку
|
|
|
|
|
buf[index++] =
|
2023-12-12 21:11:06 +03:00
|
|
|
|
(remainder > 9) ? (remainder - 10) + 'A' : remainder + '0'; // Если остаток > 9, добавляем заглавную букву А
|
2023-10-29 16:11:41 +03:00
|
|
|
|
i /= base;
|
|
|
|
|
} while (i > 0);
|
|
|
|
|
|
|
|
|
|
// Добавляем нулевой символ в конец строки, чтобы завершить ее
|
|
|
|
|
buf[index] = '\0';
|
|
|
|
|
|
|
|
|
|
// Переворачиваем строку, чтобы цифры были в правильном порядке
|
|
|
|
|
tool_reverse_str(buf);
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-21 20:27:23 +03:00
|
|
|
|
// Функция для форматированного вывода
|
2023-12-12 21:11:06 +03:00
|
|
|
|
void tool_format(void (*putc)(char c), const char *format_string, va_list args) {
|
2023-10-21 20:27:23 +03:00
|
|
|
|
while (*format_string != '\0') {
|
|
|
|
|
if (*format_string == '%') {
|
2023-10-29 16:11:41 +03:00
|
|
|
|
char buf[48];
|
|
|
|
|
uint64_t point = 0;
|
|
|
|
|
const char *arg_s;
|
|
|
|
|
int64_t arg_d = 0;
|
|
|
|
|
uint64_t arg_u = 0;
|
2023-10-21 20:27:23 +03:00
|
|
|
|
format_string++;
|
2023-10-29 16:11:41 +03:00
|
|
|
|
|
2023-10-21 20:27:23 +03:00
|
|
|
|
if (*format_string == '\0') {
|
|
|
|
|
break; // Неожиданный конец строки формата
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-29 16:11:41 +03:00
|
|
|
|
switch (*format_string) {
|
|
|
|
|
case '%': putc('%'); break;
|
|
|
|
|
case 'c': putc(va_arg(args, int)); break;
|
|
|
|
|
case 's':
|
|
|
|
|
arg_s = va_arg(args, const char *);
|
|
|
|
|
// Вывод каждого символа строки
|
|
|
|
|
while (*arg_s != '\0') {
|
|
|
|
|
putc(*arg_s);
|
|
|
|
|
arg_s++;
|
2023-10-21 20:27:23 +03:00
|
|
|
|
}
|
2023-10-29 16:11:41 +03:00
|
|
|
|
break;
|
|
|
|
|
case 'd':
|
|
|
|
|
arg_d = va_arg(args, int64_t);
|
|
|
|
|
tool_int_to_str(arg_d, 10, buf);
|
|
|
|
|
while (buf[point] != '\0') {
|
|
|
|
|
putc(buf[point]);
|
|
|
|
|
point++;
|
2023-10-21 20:27:23 +03:00
|
|
|
|
}
|
|
|
|
|
|
2023-10-29 16:11:41 +03:00
|
|
|
|
break;
|
|
|
|
|
case 'u':
|
|
|
|
|
arg_u = va_arg(args, uint64_t);
|
|
|
|
|
tool_uint_to_str(arg_u, 10, buf);
|
|
|
|
|
while (buf[point] != '\0') {
|
|
|
|
|
putc(buf[point]);
|
|
|
|
|
point++;
|
2023-10-21 20:27:23 +03:00
|
|
|
|
}
|
2023-10-29 16:11:41 +03:00
|
|
|
|
break;
|
|
|
|
|
case 'x':
|
|
|
|
|
arg_u = va_arg(args, uint64_t);
|
|
|
|
|
tool_uint_to_str(arg_u, 16, buf);
|
|
|
|
|
while (buf[point] != '\0') {
|
|
|
|
|
putc(buf[point]);
|
|
|
|
|
point++;
|
2023-10-21 20:27:23 +03:00
|
|
|
|
}
|
2023-10-29 16:11:41 +03:00
|
|
|
|
break;
|
|
|
|
|
case 'l':
|
|
|
|
|
arg_u = va_arg(args, uint64_t);
|
|
|
|
|
tool_uint_to_str(arg_u, 16, buf);
|
|
|
|
|
while (buf[point] != '\0') {
|
|
|
|
|
putc(buf[point]);
|
|
|
|
|
point++;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default: putc('?'); break;
|
2023-10-21 20:27:23 +03:00
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
putc(*format_string);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
format_string++;
|
|
|
|
|
}
|
|
|
|
|
}
|