1
1
mirror of https://github.com/theoludwig/libcproject.git synced 2025-05-21 23:21:15 +02:00

32 Commits

Author SHA1 Message Date
2fd8d102e9 feat: add mathematics_max, mathematics_min
Also add `mathematics_max_values` and
`mathematics_min_values` to check in array.
2024-09-13 15:35:19 +02:00
85ce5228ef feat: add mathematics_opposite 2024-09-13 14:44:26 +02:00
c49d5f5421 feat: add string_zero_pad 2024-09-12 12:31:58 +02:00
35b868d0c1 feat: add string_pad_start 2024-09-12 12:22:53 +02:00
7683aa1db7 docs(license): add email address 2024-01-30 01:25:17 +01:00
6eee39fffb chore(release): 4.2.1 [skip ci] 2023-12-26 20:20:38 +00:00
ab9860e969 fix: markdownlint in LICENSE 2023-12-26 21:19:20 +01:00
a50773e058 chore(release): 4.2.0 [skip ci] 2023-12-26 19:47:09 +00:00
1e0bf99ef6 feat: add string_last_position_of 2023-12-26 20:40:46 +01:00
ec6e748d24 feat: add string_position_of 2023-12-26 20:30:54 +01:00
9bb21e070f build(deps): update latest 2023-12-26 19:42:12 +01:00
bb9c7a1668 Merge branch 'master' of github.com:theoludwig/libcproject 2023-10-23 23:02:35 +02:00
211648d29f chore: better Prettier config for easier reviews 2023-10-23 23:02:29 +02:00
574aeb414e chore(release): 4.1.1 [skip ci] 2023-10-13 09:07:49 +00:00
e0115dd7d9 fix: error in array_list_remove (always removed the last index and not the index given) (#6)
Co-authored-by: Maxime Rumpler <mrumpler68@gmail.com>
2023-10-13 11:04:38 +02:00
269b1f7451 chore(release): 4.1.0 [skip ci] 2023-08-10 09:06:44 +00:00
c6df05e634 refactor: avoid usage of char*, instead use string_t 2023-08-10 00:32:49 +02:00
07e2f4db45 fix: convert numbers base to another only accept unsigned integers 2023-08-09 23:29:58 +02:00
b9ba3fbff4 docs: consistency improvements 2023-08-09 21:08:15 +02:00
7ef38fa993 chore: always use apt instead of apt-get 2023-08-09 20:29:19 +02:00
f99e4941e4 fix: correct usage of malloc and sizeof for structs 2023-08-09 20:25:03 +02:00
6505e3ba49 feat: add string_remove_character 2023-08-09 20:21:33 +02:00
f0716c2e12 docs: invalid @param for character_append 2023-08-09 20:17:54 +02:00
78fe9ff404 chore(release): 4.0.0 [skip ci] 2023-08-08 12:24:43 +00:00
e5190818c4 perf: mutate destination string for string_concatenate
BREAKING CHANGE: Function signature changed
2023-08-07 00:42:11 +02:00
b922fd9cd3 fix: handle EXIT_FAILURE by printing error message with perror 2023-08-07 00:11:07 +02:00
72645da4b2 perf: mutate strings instead of copy when possible
BREAKING CHANGE: Most of string functions mutates the string instead of copying now.
This allows better performance when copy is not needed.
It also allows more granual control.
If copy is wanted, simply use `string_copy` before calling the function.

Impacted functions are:
`string_to_uppercase`, `string_to_lowercase`, `string_replace`,
`string_trim_start`, `string_trim_end`, `string_trim`,
`string_capitalize`, `string_reverse`
2023-08-06 23:17:07 +02:00
01e9b71402 chore(release): 3.1.0 [skip ci] 2023-08-06 14:43:01 +00:00
5c6f4d8192 feat: improvements to filesystem_get_mimetype 2023-08-06 16:39:33 +02:00
d604288365 docs: improve usage explanations 2023-08-06 16:12:10 +02:00
dff2836bfc feat: add filesystem_remove 2023-08-06 12:14:13 +02:00
ad0a460923 feat: add filesystem_exists 2023-08-06 12:06:43 +02:00
43 changed files with 1127 additions and 443 deletions

View File

@ -1,2 +1,2 @@
BasedOnStyle: 'Google'
BasedOnStyle: "Google"
ColumnLimit: 0

View File

@ -1,8 +1,8 @@
---
name: '🐛 Bug Report'
about: 'Report an unexpected problem or unintended behavior.'
title: '[Bug]'
labels: 'bug'
name: "🐛 Bug Report"
about: "Report an unexpected problem or unintended behavior."
title: "[Bug]"
labels: "bug"
---
<!--

View File

@ -1,8 +1,8 @@
---
name: '📜 Documentation'
about: 'Correct spelling errors, improvements or additions to documentation files (README, CONTRIBUTING...).'
title: '[Documentation]'
labels: 'documentation'
name: "📜 Documentation"
about: "Correct spelling errors, improvements or additions to documentation files (README, CONTRIBUTING...)."
title: "[Documentation]"
labels: "documentation"
---
<!-- Please make sure your issue has not already been fixed. -->

View File

@ -1,8 +1,8 @@
---
name: '✨ Feature Request'
about: 'Suggest a new feature idea.'
title: '[Feature]'
labels: 'feature request'
name: "✨ Feature Request"
about: "Suggest a new feature idea."
title: "[Feature]"
labels: "feature request"
---
<!-- Please make sure your issue has not already been fixed. -->

View File

@ -1,8 +1,8 @@
---
name: '🔧 Improvement'
about: 'Improve structure/format/performance/refactor/tests of the code.'
title: '[Improvement]'
labels: 'improvement'
name: "🔧 Improvement"
about: "Improve structure/format/performance/refactor/tests of the code."
title: "[Improvement]"
labels: "improvement"
---
<!-- Please make sure your issue has not already been fixed. -->

View File

@ -1,8 +1,8 @@
---
name: '🙋 Question'
about: 'Further information is requested.'
title: '[Question]'
labels: 'question'
name: "🙋 Question"
about: "Further information is requested."
title: "[Question]"
labels: "question"
---
### Question

View File

@ -1,4 +1,4 @@
name: 'CI'
name: "CI"
on:
push:
@ -8,33 +8,33 @@ on:
jobs:
ci:
runs-on: 'ubuntu-latest'
runs-on: "ubuntu-latest"
steps:
- uses: 'actions/checkout@v3.5.3'
- uses: "actions/checkout@v4.1.1"
- run: 'sudo apt update'
- run: "sudo apt update"
- name: 'Install Build Tools'
run: 'sudo apt-get install --yes build-essential gcc make clang-format'
- name: "Install Build Tools"
run: "sudo apt install --yes build-essential gcc make clang-format"
- name: 'Install Documentation Tools'
run: 'sudo apt-get install --yes doxygen doxygen-gui doxygen-doc graphviz'
- name: "Install Documentation Tools"
run: "sudo apt install --yes doxygen doxygen-gui doxygen-doc graphviz"
- run: 'gcc --version'
- run: "gcc --version"
- run: 'make'
- run: 'make run'
- run: 'make test'
- run: 'make lint'
- run: 'make documentation'
- run: 'make set_version'
- run: 'make clean'
- run: "make"
- run: "make run"
- run: "make test"
- run: "make lint"
- run: "make documentation"
- run: "make set_version"
- run: "make clean"
lint-commit:
runs-on: 'ubuntu-latest'
steps:
- uses: 'actions/checkout@v3.5.3'
with:
fetch-depth: 0
runs-on: "ubuntu-latest"
steps:
- uses: "actions/checkout@v4.1.1"
with:
fetch-depth: 0
- uses: 'wagoid/commitlint-github-action@v5.4.1'
- uses: "wagoid/commitlint-github-action@v5.4.4"

View File

@ -1,4 +1,4 @@
name: 'Release'
name: "Release"
on:
push:
@ -6,52 +6,52 @@ on:
jobs:
release:
runs-on: 'ubuntu-latest'
runs-on: "ubuntu-latest"
steps:
- uses: 'actions/checkout@v3.5.3'
- uses: "actions/checkout@v4.1.1"
with:
fetch-depth: 0
persist-credentials: false
submodules: recursive
submodules: "recursive"
- name: 'Import GPG key'
uses: 'crazy-max/ghaction-import-gpg@v5.3.0'
- name: "Import GPG key"
uses: "crazy-max/ghaction-import-gpg@v6.1.0"
with:
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
git_user_signingkey: true
git_commit_gpgsign: true
- run: 'sudo apt update'
- run: "sudo apt update"
- name: 'Install Build Tools'
run: 'sudo apt-get install --yes build-essential gcc make clang-format'
- name: "Install Build Tools"
run: "sudo apt install --yes build-essential gcc make clang-format"
- name: 'Install Documentation Tools'
run: 'sudo apt-get install --yes doxygen doxygen-gui doxygen-doc graphviz'
- name: "Install Documentation Tools"
run: "sudo apt install --yes doxygen doxygen-gui doxygen-doc graphviz"
- run: 'make set_version'
- run: "make set_version"
- name: 'Use Node.js'
uses: 'actions/setup-node@v3.7.0'
- name: "Use Node.js"
uses: "actions/setup-node@v4.0.1"
with:
node-version: '18.17.0'
node-version: "20.10.0"
- name: 'Install Release Tools'
run: 'npm install --save-dev semantic-release@21.0.7 @commitlint/cli@17.6.7 @commitlint/config-conventional@17.6.7 @semantic-release/git@10.0.1 @semantic-release/exec@6.0.3 @saithodev/semantic-release-backmerge@3.2.0 vercel@31.2.2'
- name: "Install Release Tools"
run: "npm install --save-dev semantic-release@22.0.12 @commitlint/cli@18.4.3 @commitlint/config-conventional@18.4.3 @semantic-release/git@10.0.1 @semantic-release/exec@6.0.3 @saithodev/semantic-release-backmerge@4.0.1 vercel@33.0.1"
- run: 'rm --force package.json package-lock.json'
- run: "rm --force package.json package-lock.json"
- name: 'Release'
run: 'npx semantic-release'
- name: "Release"
run: "npx semantic-release"
env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
GIT_COMMITTER_NAME: ${{ secrets.GIT_NAME }}
GIT_COMMITTER_EMAIL: ${{ secrets.GIT_EMAIL }}
- name: 'Generate Documentation'
run: 'make documentation'
- name: "Generate Documentation"
run: "make documentation"
- name: 'Deploy to Vercel'
- name: "Deploy to Vercel"
run: 'npx vercel ./documentation/html --token="${VERCEL_TOKEN}" --prod'
env:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}

View File

@ -12,7 +12,7 @@ FILE_PATTERNS = *.h \
CODE_OF_CONDUCT.md \
CONTRIBUTING.md \
LICENSE
HTML_EXTRA_STYLESHEET = doxygen-awesome-css/doxygen-awesome.css
HTML_EXTRA_STYLESHEET = doxygen-awesome-css/doxygen-awesome.css
RECURSIVE = YES
EXCLUDE = test doxygen-awesome-css node_modules

View File

@ -1,6 +1,6 @@
MIT License
# MIT License
Copyright (c) Théo LUDWIG
Copyright (c) Théo LUDWIG <contact@theoludwig.fr>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -32,13 +32,13 @@ build/test/%.o: test/%.c ${HEADER_FILES} | build/test
.PHONY: run
run: ${LIB} ./main.c
mkdir --parents ./bin
${CC} ${CC_FLAGS} -o ${MAIN_EXECUTABLE} ./main.c ${LIB_CC_FLAGS}
${CC} ${CC_FLAGS} ${CC_SANITIZER_FLAGS} -o ${MAIN_EXECUTABLE} ./main.c ${LIB_CC_FLAGS}
./${MAIN_EXECUTABLE} ${ARGS}
.PHONY: set_version
set_version: ${LIB} ./set_version.c
mkdir --parents ./bin
${CC} ${CC_FLAGS} -o ${SET_VERSION_EXECUTABLE} ./set_version.c ${LIB_CC_FLAGS}
${CC} ${CC_FLAGS} ${CC_SANITIZER_FLAGS} -o ${SET_VERSION_EXECUTABLE} ./set_version.c ${LIB_CC_FLAGS}
.PHONY: test
test: ${LIB} $(addprefix build/, ${TEST_OBJECTS})

View File

@ -5,11 +5,11 @@
</p>
<p align="center">
<a href="./CONTRIBUTING.md"><img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat" /></a>
<a href="./CONTRIBUTING.md"><img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat" alt="Contributing" /></a>
<a href="./LICENSE"><img src="https://img.shields.io/badge/licence-MIT-blue.svg" alt="Licence MIT"/></a>
<a href="./CODE_OF_CONDUCT.md"><img src="https://img.shields.io/badge/Contributor%20Covenant-v2.0%20adopted-ff69b4.svg" alt="Contributor Covenant" /></a>
<br />
<a href="https://github.com/theoludwig/libcproject/actions/workflows/ci.yml"><img src="https://github.com/theoludwig/libcproject/actions/workflows/ci.yml/badge.svg?branch=develop" /></a>
<a href="https://github.com/theoludwig/libcproject/actions/workflows/ci.yml"><img src="https://github.com/theoludwig/libcproject/actions/workflows/ci.yml/badge.svg?branch=develop" alt="CI" /></a>
<a href="https://conventionalcommits.org"><img src="https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg" alt="Conventional Commits" /></a>
<a href="https://github.com/semantic-release/semantic-release"><img src="https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg" alt="semantic-release" /></a>
</p>
@ -20,7 +20,7 @@
C is a low-level programming language and we often end up reinventing the wheel as the C standard library (`libc`) is quite small and in my humble opinion, not well designed.
**libcproject** solve this by providing common functions or data structures (`hash_map`, `array_list`, `linked_list`, `queue`, `stack`, etc.) we might need in our C projects.
**libcproject** solve this by providing common functions or data structures (`hash_map`, `array_list`, `linked_list`, `queue`, `stack`, etc.), we might need in our C projects.
[Online documentation](https://libcproject.vercel.app/).
@ -36,8 +36,11 @@ C is a low-level programming language and we often end up reinventing the wheel
For example on GNU/Linux Ubuntu:
```sh
sudo apt-get install build-essential gcc make clang-format
sudo apt-get install doxygen doxygen-gui doxygen-doc graphviz
# Install Build Tools
sudo apt install build-essential gcc make clang-format
# Install Documentation Tools
sudo apt install doxygen doxygen-gui doxygen-doc graphviz
```
## Usage
@ -55,7 +58,14 @@ nm ./build/libcproject.a # to see the symbols
Steps to create a new C project that uses `libcproject`:
### Step 1: Install and Compile `libcproject`
### Step 1: Create a new project
```sh
mkdir my-project
cd my-project
```
### Step 2: Install and Compile `libcproject` in the project
```sh
# Clone the repository
@ -68,25 +78,10 @@ cd libcproject
make
```
### Step 2: Create a new project
```sh
mkdir my-project
cd my-project
```
### Step 3: Install `libcproject` in the project
```sh
mkdir libcproject
cp --recursive <path-to-libcproject> ./ # copy
# or
ln -s <path-to-libcproject> ./ # symbolic link
```
### Step 4: Create a new C file
### Step 3: Create a new C file
```sh
cd ..
touch main.c
```
@ -97,14 +92,14 @@ touch main.c
#include "libcproject/libcproject.h"
int main() {
string_t string_value = "Hello, world!"; // `string_t` is a typedef from `libcproject`
printf("%s\n", string_value);
printf("string_length = %ld\n", string_get_length(string_value)); // `string_get_length` is a function from `libcproject`
string_t string = "Hello, world!"; // `string_t` is a typedef from `libcproject`
printf("%s\n", string);
printf("string_length = %ld\n", string_get_length(string)); // `string_get_length` is a function from `libcproject`
return EXIT_SUCCESS;
}
```
### Step 5: Compile your project and link it with the library
### Step 4: Compile your project and link it with the library
```sh
gcc -o ./main ./main.c -L. -l:./libcproject/build/libcproject.a

View File

@ -25,8 +25,8 @@ void array_list_remove(struct array_list* list, size_t index) {
if (index >= list->size) {
return;
}
for (size_t i = index + 1; i < list->size - 1; i++) {
list->data[i - 1] = list->data[i];
for (size_t i = index; i < list->size - 1; i++) {
list->data[i] = list->data[i + 1];
}
list->size--;
}

View File

@ -1,6 +1,7 @@
#ifndef __LIBCPROJECT_ARRAY_LIST__
#define __LIBCPROJECT_ARRAY_LIST__
#include <errno.h>
#include <stdbool.h>
#include <stdlib.h>
@ -26,24 +27,36 @@ struct array_list* array_list_initialization();
/**
* @brief Adds an element to the end of the array list.
*
* @param list
* @param element
* @since v1.2.0
*/
void array_list_add(struct array_list* list, void* element);
/**
* @brief Removes an element from the array list.
*
* @param list
* @param index
* @since v1.2.0
*/
void array_list_remove(struct array_list* list, size_t index);
/**
* @brief Gets an element from the array list.
*
* @param list
* @param index
* @return void*
* @since v1.2.0
*/
void* array_list_get(struct array_list* list, size_t index);
/**
* @brief Frees the array list.
*
* @param list
* @since v3.0.0
*/
void array_list_free(struct array_list* list);

View File

@ -1,17 +1,17 @@
#include "character.h"
void character_append(string_t string_value, const char character) {
size_t length = string_get_length(string_value);
character_append_at(string_value, character, length);
void character_append(string_t string, const char character) {
size_t length = string_get_length(string);
character_append_at(string, character, length);
}
void character_append_at(string_t string_value, const char character, const size_t index) {
size_t length = string_get_length(string_value);
void character_append_at(string_t string, const char character, const size_t index) {
size_t length = string_get_length(string);
for (size_t index_string = length; index_string > index; index_string--) {
string_value[index_string] = string_value[index_string - 1];
string[index_string] = string[index_string - 1];
}
string_value[index] = character;
string_value[length + 1] = '\0';
string[index] = character;
string[length + 1] = '\0';
}
char character_to_upper(const char character) {

View File

@ -1,6 +1,7 @@
#ifndef __LIBCPROJECT_CHARACTER__
#define __LIBCPROJECT_CHARACTER__
#include <errno.h>
#include <stdbool.h>
#include <stdlib.h>
@ -11,21 +12,21 @@
* @brief Append a character to a string, assuming string points to an array
* with enough space.
*
* @param string_value
* @param string
* @param character
* @since v1.0.0
*/
void character_append(string_t string_value, char character);
void character_append(string_t string, char character);
/**
* @brief Append a character to a string at a specific index, assuming string points to an array with enough space.
*
* @param string_value
* @param string
* @param character
* @param index
* @since v1.0.0
*/
void character_append_at(string_t string_value, const char character, const size_t index);
void character_append_at(string_t string, const char character, const size_t index);
/**
* @brief Converts the character to uppercase.
@ -46,7 +47,9 @@ char character_to_lower(const char character);
/**
* @brief Check if the character is a digit ('0', '1', '2', '3', '4', '5', '6', '7, '8' or '9').
*
* @return true if the character is a digit, false otherwise
* @param character
* @return true
* @return false
* @since v1.0.0
*/
bool character_get_is_digit(const char character);
@ -56,6 +59,7 @@ bool character_get_is_digit(const char character);
* Return 0 if the character is not a letter.
*
* @param character
* @return unsigned char
* @since v1.0.0
*/
unsigned char character_get_alphabet_position(const char character);

View File

@ -3,6 +3,7 @@
string_t convert_character_to_string(const char character) {
string_t string = malloc(sizeof(char) * 2);
if (string == NULL) {
perror("Error (convert_character_to_string)");
exit(EXIT_FAILURE);
}
string[0] = character;
@ -18,12 +19,12 @@ char convert_digit_to_character(const char digit) {
return digit + '0';
}
long long convert_string_to_number(const string_t string_value) {
bool is_negative = string_value[0] == '-';
long long convert_string_to_number(const string_t string) {
bool is_negative = string[0] == '-';
long long integer = 0;
size_t length = string_get_length(string_value);
size_t length = string_get_length(string);
for (size_t index = is_negative ? 1 : 0; index < length; index++) {
integer = integer * 10 + convert_character_to_digit(string_value[index]);
integer = integer * 10 + convert_character_to_digit(string[index]);
}
return is_negative ? integer * -1 : integer;
}
@ -42,26 +43,26 @@ string_t convert_number_to_string(const long long integer) {
if (is_negative) {
length++;
}
string_t string_value = malloc(sizeof(char) * length);
if (string_value == NULL) {
string_t string = malloc(sizeof(char) * length);
if (string == NULL) {
perror("Error (convert_number_to_string)");
exit(EXIT_FAILURE);
}
current = mathematics_absolute_value(integer);
size_t index = 0;
while (current != 0) {
string_value[index++] = convert_digit_to_character(current % 10);
string[index++] = convert_digit_to_character(current % 10);
current = current / 10;
}
if (is_negative) {
string_value[index++] = '-';
string[index++] = '-';
}
string_value[index] = '\0';
char* result = string_reverse(string_value);
free(string_value);
return result;
string[index] = '\0';
string_reverse(string);
return string;
}
string_t convert_number_from_base_10_to_base(unsigned long long number, unsigned int base) {
string_t convert_number_from_base_10_to_base(unsigned long long number, unsigned long base) {
if (number == 0) {
return "0";
}
@ -87,10 +88,10 @@ string_t convert_number_from_base_10_to_base(unsigned long long number, unsigned
return result;
}
int convert_number_from_base_to_base_10(string_t number, unsigned int base) {
int length = string_get_length(number);
unsigned long convert_number_from_base_to_base_10(string_t number, unsigned long base) {
size_t length = string_get_length(number);
int exponent = length - 1;
int result = 0;
unsigned long result = 0;
int index = 0;
while (exponent >= 0) {
int current_number = (int)(number[index] - '0');
@ -106,6 +107,6 @@ int convert_number_from_base_to_base_10(string_t number, unsigned int base) {
return result;
}
string_t convert_number_from_base_to_another(string_t number, int base_from, int base_target) {
string_t convert_number_from_base_to_another(string_t number, unsigned long base_from, unsigned long base_target) {
return convert_number_from_base_10_to_base(convert_number_from_base_to_base_10(number, base_from), base_target);
}

View File

@ -1,6 +1,7 @@
#ifndef __LIBCPROJECT_CONVERT__
#define __LIBCPROJECT_CONVERT__
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
@ -14,6 +15,7 @@
* @brief Convert a character to a string.
*
* @param character
* @return string_t
* @since v1.0.0
*/
string_t convert_character_to_string(const char character);
@ -22,6 +24,7 @@ string_t convert_character_to_string(const char character);
* @brief Convert a character to a digit.
*
* @param character
* @return char
* @since v1.0.0
*/
char convert_character_to_digit(const char character);
@ -30,6 +33,7 @@ char convert_character_to_digit(const char character);
* @brief Convert a digit to a character.
*
* @param digit
* @return char
* @since v1.0.0
*/
char convert_digit_to_character(const char digit);
@ -37,15 +41,17 @@ char convert_digit_to_character(const char digit);
/**
* @brief Convert a string to a number.
*
* @param string_value
* @param string
* @return long long
* @since v1.0.0
*/
long long convert_string_to_number(const string_t string_value);
long long convert_string_to_number(const string_t string);
/**
* @brief Convert a number to a string.
*
* @param integer
* @return string_t
* @since v1.0.0
*/
string_t convert_number_to_string(const long long integer);
@ -55,18 +61,20 @@ string_t convert_number_to_string(const long long integer);
*
* @param number
* @param base
* @return string_t
* @since v1.0.0
*/
string_t convert_number_from_base_10_to_base(unsigned long long number, unsigned int base);
string_t convert_number_from_base_10_to_base(unsigned long long number, unsigned long base);
/**
* @brief Convert a number with a specific base to a number base 10.
*
* @param number
* @param base
* @return int
* @since v1.0.0
*/
int convert_number_from_base_to_base_10(string_t number, unsigned int base);
unsigned long convert_number_from_base_to_base_10(string_t number, unsigned long base);
/**
* @brief Convert a number with a specific base to a number of specific base.
@ -74,8 +82,9 @@ int convert_number_from_base_to_base_10(string_t number, unsigned int base);
* @param number
* @param base_from
* @param base_target
* @return string_t
* @since v1.0.0
*/
string_t convert_number_from_base_to_another(string_t number, int base_from, int base_target);
string_t convert_number_from_base_to_another(string_t number, unsigned long base_from, unsigned long base_target);
#endif

View File

@ -27,63 +27,224 @@ int filesystem_write(string_t path, byte_t *file_content, off_t file_size) {
return 0;
}
bool filesystem_exists(string_t path) {
return access(path, F_OK) == 0;
}
int filesystem_remove(string_t path) {
return remove(path);
}
string_t filesystem_get_mimetype(string_t path) {
if (string_ends_with(path, ".html")) {
return "text/html";
if (string_ends_with(path, ".aac")) {
return "audio/aac";
}
if (string_ends_with(path, ".css")) {
return "text/css";
if (string_ends_with(path, ".abw")) {
return "application/x-abiword";
}
if (string_ends_with(path, ".js")) {
return "text/javascript";
if (string_ends_with(path, ".arc")) {
return "application/x-freearc";
}
if (string_ends_with(path, ".png")) {
return "image/png";
if (string_ends_with(path, ".avif")) {
return "image/avif";
}
if (string_ends_with(path, ".jpg") || string_ends_with(path, ".jpeg")) {
return "image/jpeg";
if (string_ends_with(path, ".avi")) {
return "video/x-msvideo";
}
if (string_ends_with(path, ".gif")) {
return "image/gif";
}
if (string_ends_with(path, ".ico")) {
return "image/x-icon";
}
if (string_ends_with(path, ".svg")) {
return "image/svg+xml";
}
if (string_ends_with(path, ".json")) {
return "application/json";
}
if (string_ends_with(path, ".pdf")) {
return "application/pdf";
}
if (string_ends_with(path, ".xml")) {
return "application/xml";
}
if (string_ends_with(path, ".csv")) {
return "text/csv";
}
if (string_ends_with(path, ".zip")) {
return "application/zip";
}
if (string_ends_with(path, ".tar")) {
return "application/x-tar";
}
if (string_ends_with(path, ".gz")) {
return "application/x-gzip";
}
if (string_ends_with(path, ".mp3")) {
return "audio/mpeg";
}
if (string_ends_with(path, ".wav")) {
return "audio/wav";
}
if (string_ends_with(path, ".mp4")) {
return "video/mp4";
if (string_ends_with(path, ".azw")) {
return "application/vnd.amazon.ebook";
}
if (string_ends_with(path, ".bin")) {
return "application/octet-stream";
}
return "text/plain";
if (string_ends_with(path, ".bmp")) {
return "image/bmp";
}
if (string_ends_with(path, ".bz")) {
return "application/x-bzip";
}
if (string_ends_with(path, ".bz2")) {
return "application/x-bzip2";
}
if (string_ends_with(path, ".cda")) {
return "application/x-cdf";
}
if (string_ends_with(path, ".csh")) {
return "application/x-csh";
}
if (string_ends_with(path, ".css")) {
return "text/css";
}
if (string_ends_with(path, ".csv")) {
return "text/csv";
}
if (string_ends_with(path, ".doc")) {
return "application/msword";
}
if (string_ends_with(path, ".docx")) {
return "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
}
if (string_ends_with(path, ".eot")) {
return "application/vnd.ms-fontobject";
}
if (string_ends_with(path, ".epub")) {
return "application/epub+zip";
}
if (string_ends_with(path, ".gz")) {
return "application/gzip";
}
if (string_ends_with(path, ".gif")) {
return "image/gif";
}
if (string_ends_with(path, ".htm") || string_ends_with(path, ".html")) {
return "text/html";
}
if (string_ends_with(path, ".ico")) {
return "image/vnd.microsoft.icon";
}
if (string_ends_with(path, ".ics")) {
return "text/calendar";
}
if (string_ends_with(path, ".jar")) {
return "application/java-archive";
}
if (string_ends_with(path, ".jpg") || string_ends_with(path, ".jpeg") || string_ends_with(path, ".jpe") || string_ends_with(path, ".jif") || string_ends_with(path, ".jfif") || string_ends_with(path, ".jfi")) {
return "image/jpeg";
}
if (string_ends_with(path, ".js") || string_ends_with(path, ".mjs") || string_ends_with(path, ".cjs")) {
return "text/javascript";
}
if (string_ends_with(path, ".json")) {
return "application/json";
}
if (string_ends_with(path, ".jsonld")) {
return "application/ld+json";
}
if (string_ends_with(path, ".mid") || string_ends_with(path, ".midi")) {
return "audio/midi";
}
if (string_ends_with(path, ".mp3")) {
return "audio/mpeg";
}
if (string_ends_with(path, ".mp4")) {
return "video/mp4";
}
if (string_ends_with(path, ".mpeg")) {
return "video/mpeg";
}
if (string_ends_with(path, ".mpkg")) {
return "application/vnd.apple.installer+xml";
}
if (string_ends_with(path, ".odp")) {
return "application/vnd.oasis.opendocument.presentation";
}
if (string_ends_with(path, ".ods")) {
return "application/vnd.oasis.opendocument.spreadsheet";
}
if (string_ends_with(path, ".odt")) {
return "application/vnd.oasis.opendocument.text";
}
if (string_ends_with(path, ".oga")) {
return "audio/ogg";
}
if (string_ends_with(path, ".ogv")) {
return "video/ogg";
}
if (string_ends_with(path, ".ogx")) {
return "application/ogg";
}
if (string_ends_with(path, ".opus")) {
return "audio/opus";
}
if (string_ends_with(path, ".otf")) {
return "font/otf";
}
if (string_ends_with(path, ".png")) {
return "image/png";
}
if (string_ends_with(path, ".pdf")) {
return "application/pdf";
}
if (string_ends_with(path, ".php")) {
return "application/x-httpd-php";
}
if (string_ends_with(path, ".ppt")) {
return "application/vnd.ms-powerpoint";
}
if (string_ends_with(path, ".pptx")) {
return "application/vnd.openxmlformats-officedocument.presentationml.presentation";
}
if (string_ends_with(path, ".rar")) {
return "application/vnd.rar";
}
if (string_ends_with(path, ".rtf")) {
return "application/rtf";
}
if (string_ends_with(path, ".sh")) {
return "application/x-sh";
}
if (string_ends_with(path, ".svg")) {
return "image/svg+xml";
}
if (string_ends_with(path, ".tar")) {
return "application/x-tar";
}
if (string_ends_with(path, ".tif") || string_ends_with(path, ".tiff")) {
return "image/tiff";
}
if (string_ends_with(path, ".ts")) {
return "application/typescript";
}
if (string_ends_with(path, ".ttf")) {
return "font/ttf";
}
if (string_ends_with(path, ".txt")) {
return "text/plain";
}
if (string_ends_with(path, ".vsd")) {
return "application/vnd.visio";
}
if (string_ends_with(path, ".wav")) {
return "audio/wav";
}
if (string_ends_with(path, ".weba") || string_ends_with(path, ".webm")) {
return "audio/webm";
}
if (string_ends_with(path, ".webp")) {
return "image/webp";
}
if (string_ends_with(path, ".woff")) {
return "font/woff";
}
if (string_ends_with(path, ".woff2")) {
return "font/woff2";
}
if (string_ends_with(path, ".xhtml")) {
return "application/xhtml+xml";
}
if (string_ends_with(path, ".xls")) {
return "application/vnd.ms-excel";
}
if (string_ends_with(path, ".xlsx")) {
return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
}
if (string_ends_with(path, ".xml")) {
return "application/xml";
}
if (string_ends_with(path, ".xul")) {
return "application/vnd.mozilla.xul+xml";
}
if (string_ends_with(path, ".zip")) {
return "application/zip";
}
if (string_ends_with(path, ".3gp")) {
return "video/3gpp";
}
if (string_ends_with(path, ".3g2")) {
return "video/3gpp2";
}
if (string_ends_with(path, ".7z")) {
return "application/x-7z-compressed";
}
return "application/octet-stream";
}

View File

@ -18,9 +18,10 @@
*
* @param path
* @param file_content
* @param file_size
* @param file_size The size of the file that was read (mutated by the function).
* @retval -1 if the file does not exist or if there is an error.
* @retval 0 for success.
* @return int
* @since v1.0.0
*/
int filesystem_read(string_t path, byte_t **file_content, off_t *file_size);
@ -33,14 +34,40 @@ int filesystem_read(string_t path, byte_t **file_content, off_t *file_size);
* @param file_size
* @retval -1 if there is an error.
* @retval 0 for success.
* @return int
* @since v1.0.0
*/
int filesystem_write(string_t path, byte_t *file_content, off_t file_size);
/**
* @brief Get the mimetype of a file.
* @brief Check if a path exists.
*
* @param path
* @return true
* @return false
* @since v3.1.0
*/
bool filesystem_exists(string_t path);
/**
* @brief Removes a path.
*
* @param path
* @return int
* @retval -1 if there is an error.
* @retval 0 for success.
* @return int
* @since v3.1.0
*/
int filesystem_remove(string_t path);
/**
* @brief Get the mimetype of a file based on its extension.
*
* @param path
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types
* @see https://www.iana.org/assignments/media-types/media-types.xhtml
* @return string_t
* @since v1.0.0
*/
string_t filesystem_get_mimetype(string_t path);

View File

@ -1,6 +1,7 @@
#ifndef __LIBCPROJECT_HASH_MAP__
#define __LIBCPROJECT_HASH_MAP__
#include <errno.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
@ -34,22 +35,27 @@ struct hash_map_item {
/**
* @brief Hash function (using SipHash 1-3 algorithm).
* @param key
* @param capacity
* @see https://en.wikipedia.org/wiki/SipHash
* @see https://github.com/veorq/SipHash
*
* @param key
* @param capacity
* @return uint64_t
* @since v2.0.0
*/
uint64_t hash(string_t key, size_t capacity);
/**
* @brief Hash map initialization.
*
* @return struct hash_map*
* @since v2.0.0
*/
struct hash_map *hash_map_initialization();
/**
* @brief Add an item to the hash map.
*
* @param hash_map
* @param key
* @param data
@ -69,14 +75,18 @@ void hash_map_remove(struct hash_map *hash_map, string_t key);
* @brief Get an item from the hash map.
* @param hash_map
* @param key
* @return void*
* @since v2.0.0
*/
void *hash_map_get(struct hash_map *hash_map, string_t key);
/**
* @brief Check if the hash map contains a key.
*
* @param hash_map
* @param key
* @return true
* @return false
* @since v2.0.0
*/
bool hash_map_contains_key(struct hash_map *hash_map, string_t key);
@ -85,12 +95,15 @@ bool hash_map_contains_key(struct hash_map *hash_map, string_t key);
* @brief Get the hash map keys.
*
* @param hash_map
* @return string_t*
* @since v2.0.0
*/
string_t *hash_map_get_keys(struct hash_map *hash_map);
/**
* @brief Frees the hash map.
*
* @param hash_map
* @since v3.0.0
*/
void hash_map_free(struct hash_map *hash_map);

View File

@ -1,8 +1,9 @@
#include "linked_list.h"
struct linked_list *linked_list_initialization() {
struct linked_list *list = malloc(sizeof(*list));
struct linked_list *list = malloc(sizeof(struct linked_list));
if (list == NULL) {
perror("Error (linked_list_initialization)");
exit(EXIT_FAILURE);
}
list->head = NULL;
@ -11,8 +12,14 @@ struct linked_list *linked_list_initialization() {
}
struct linked_list_node *linked_list_add_in_head(struct linked_list *list, void *new_data) {
struct linked_list_node *node_new = malloc(sizeof(*node_new));
if (list == NULL || node_new == NULL) {
if (list == NULL) {
errno = EINVAL;
perror("Error (linked_list_add_in_head)");
exit(EXIT_FAILURE);
}
struct linked_list_node *node_new = malloc(sizeof(struct linked_list_node));
if (node_new == NULL) {
perror("Error (linked_list_add_in_head)");
exit(EXIT_FAILURE);
}
node_new->data = new_data;
@ -24,6 +31,8 @@ struct linked_list_node *linked_list_add_in_head(struct linked_list *list, void
void linked_list_delete_in_head(struct linked_list *list) {
if (list == NULL) {
errno = EINVAL;
perror("Error (linked_list_delete_in_head)");
exit(EXIT_FAILURE);
}
if (list->head != NULL) {
@ -35,11 +44,17 @@ void linked_list_delete_in_head(struct linked_list *list) {
}
struct linked_list_node *linked_list_add_after_last(struct linked_list *list, void *new_data) {
if (list == NULL) {
errno = EINVAL;
perror("Error (linked_list_add_after_last)");
exit(EXIT_FAILURE);
}
if (list->head == NULL) {
return linked_list_add_in_head(list, new_data);
}
struct linked_list_node *node_new = malloc(sizeof(*node_new));
if (list == NULL || node_new == NULL) {
struct linked_list_node *node_new = malloc(sizeof(struct linked_list_node));
if (node_new == NULL) {
perror("Error (linked_list_add_after_last)");
exit(EXIT_FAILURE);
}
node_new->data = new_data;

View File

@ -1,6 +1,7 @@
#ifndef __LIBCPROJECT_LINKED_LIST__
#define __LIBCPROJECT_LINKED_LIST__
#include <errno.h>
#include <stdbool.h>
#include <stdlib.h>
@ -13,7 +14,6 @@
*/
struct linked_list {
struct linked_list_node *head;
size_t length;
};
@ -28,42 +28,61 @@ struct linked_list_node {
/**
* @brief Linked list initialization.
*
* @return struct linked_list*
* @since v1.0.0
*/
struct linked_list *linked_list_initialization();
/**
* @brief Add a new node in the head of the linked list.
*
* @param list
* @param new_value
* @return struct linked_list_node*
* @since v1.0.0
*/
struct linked_list_node *linked_list_add_in_head(struct linked_list *list, void *new_value);
/**
* @brief Delete node in the head of the linked list.
*
* @param list
* @since v1.0.0
*/
void linked_list_delete_in_head(struct linked_list *list);
/**
* @brief Add a new node in the tail of the linked list.
*
* @param list
* @param new_data
* @return struct linked_list_node*
* @since v1.0.0
*/
struct linked_list_node *linked_list_add_after_last(struct linked_list *list, void *new_data);
/**
* @brief Reverse the linked list by creating a new one.
*
* @param list
* @return struct linked_list*
* @since v1.0.0
*/
struct linked_list *linked_list_reverse(struct linked_list *list);
/**
* @brief Reverse the linked list by mutating it.
*
* @param list
* @since v1.0.0
*/
void linked_list_reverse_mutate(struct linked_list *list);
/**
* @brief Frees the linked list.
*
* @param list
* @since v3.0.0
*/
void linked_list_free(struct linked_list *list);

View File

@ -32,3 +32,39 @@ float mathematics_square_root(float number) {
unsigned long long mathematics_factorial(unsigned long long number) {
return number == 0 ? 1 : number * mathematics_factorial(number - 1);
}
int64_t mathematics_opposite(int64_t number) {
return number * -1;
}
int64_t mathematics_max(int64_t number1, int64_t number2) {
return number1 > number2 ? number1 : number2;
}
int64_t mathematics_max_values(int64_t *values, size_t values_length) {
int64_t max = 0;
if (values_length <= 0) {
return max;
}
max = values[0];
for (size_t index = 1; index < values_length; index++) {
max = mathematics_max(max, values[index]);
}
return max;
}
int64_t mathematics_min(int64_t number1, int64_t number2) {
return number1 > number2 ? number2 : number1;
}
int64_t mathematics_min_values(int64_t *values, size_t values_length) {
int64_t min = 0;
if (values_length <= 0) {
return min;
}
min = values[0];
for (size_t index = 1; index < values_length; index++) {
min = mathematics_min(min, values[index]);
}
return min;
}

View File

@ -3,7 +3,9 @@
#define MATHEMATICS_FLOAT_PRECISION 0.00000001
#include <errno.h>
#include <stdbool.h>
#include <stdlib.h>
#include "types.h"
@ -12,6 +14,8 @@
*
* @param number1
* @param number2
* @return true
* @return false
* @since v1.0.0
*/
bool mathematics_equals(const float number1, const float number2);
@ -20,6 +24,7 @@ bool mathematics_equals(const float number1, const float number2);
* @brief Get the absolute value of a number.
*
* @param number
* @return unsigned long long
* @since v1.0.0
*/
unsigned long long mathematics_absolute_value(const long long number);
@ -29,15 +34,17 @@ unsigned long long mathematics_absolute_value(const long long number);
*
* @param base
* @param exponent
* @return unsigned long long
* @since v1.0.0
*/
unsigned long long mathematics_pow(unsigned long long base, unsigned long long exponent);
/**
* @brief Calculates the nth root of a number using Heron's method.
* @brief Calculates the nth root of a number.
*
* @param number
* @param nth_root
* @return float
* @since v1.0.0
*/
float mathematics_root(float number, unsigned int nth_root);
@ -46,6 +53,7 @@ float mathematics_root(float number, unsigned int nth_root);
* @brief Calculates the square root of a number using Heron's method.
*
* @param number
* @return float
* @since v1.0.0
*/
float mathematics_square_root(float number);
@ -54,8 +62,64 @@ float mathematics_square_root(float number);
* @brief Calculates the factorial of a number.
*
* @param number
* @return unsigned long long
* @since v1.0.0
*/
unsigned long long mathematics_factorial(unsigned long long number);
/**
* @brief Calulcates the opposite number (additive inverse).
*
* @param number
* @return int64_t
*
* @code
* mathematics_opposite(7) // -7
*
* mathematics_opposite(-7) // 7
* @endcode
* @since vTODO
*/
int64_t mathematics_opposite(int64_t number);
/**
* @brief Returns the largest number between 2 numbers.
*
* @param number1
* @param number2
* @return int64_t
* @since vTODO
*/
int64_t mathematics_max(int64_t number1, int64_t number2);
/**
* @brief Returns the largest number between multiple numbers. If the array is empty, returns 0.
*
* @param values
* @param values_length
* @return int64_t
* @since vTODO
*/
int64_t mathematics_max_values(int64_t *values, size_t values_length);
/**
* @brief Returns the smallest number between 2 numbers.
*
* @param number1
* @param number2
* @return int64_t
* @since vTODO
*/
int64_t mathematics_min(int64_t number1, int64_t number2);
/**
* @brief Returns the smallest number between multiple numbers. If the array is empty, returns 0.
*
* @param values
* @param values_length
* @return int64_t
* @since vTODO
*/
int64_t mathematics_min_values(int64_t *values, size_t values_length);
#endif

View File

@ -1,8 +1,9 @@
#include "queue.h"
struct queue *queue_initialization() {
struct queue *queue = malloc(sizeof(*queue));
struct queue *queue = malloc(sizeof(struct queue));
if (queue == NULL) {
perror("Error (queue_initialization)");
exit(EXIT_FAILURE);
}
queue->first = NULL;
@ -11,8 +12,14 @@ struct queue *queue_initialization() {
}
void queue_push(struct queue *queue, void *data) {
struct queue_node *node_new = malloc(sizeof(*node_new));
if (queue == NULL || node_new == NULL) {
if (queue == NULL) {
errno = EINVAL;
perror("Error (queue_push)");
exit(EXIT_FAILURE);
}
struct queue_node *node_new = malloc(sizeof(struct queue_node));
if (node_new == NULL) {
perror("Error (queue_push)");
exit(EXIT_FAILURE);
}
node_new->data = data;
@ -31,6 +38,8 @@ void queue_push(struct queue *queue, void *data) {
void *queue_pop(struct queue *queue) {
if (queue == NULL) {
errno = EINVAL;
perror("Error (queue_pop)");
exit(EXIT_FAILURE);
}
struct queue_node *node = queue->first;
@ -46,6 +55,8 @@ void *queue_pop(struct queue *queue) {
void queue_free(struct queue *queue) {
if (queue == NULL) {
errno = EINVAL;
perror("Error (queue_free)");
exit(EXIT_FAILURE);
}
struct queue_node *node = queue->first;

View File

@ -1,6 +1,7 @@
#ifndef __LIBCPROJECT_QUEUE__
#define __LIBCPROJECT_QUEUE__
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
@ -26,24 +27,34 @@ struct queue_node {
/**
* @brief Queue initialization.
*
* @return struct queue*
* @since v1.0.0
*/
struct queue *queue_initialization();
/**
* @brief Push data to queue.
*
* @param queue
* @param data
* @since v1.0.0
*/
void queue_push(struct queue *queue, void *data);
/**
* @brief Pop data from queue.
*
* @param queue
* @return void*
* @since v1.0.0
*/
void *queue_pop(struct queue *queue);
/**
* @brief Frees the queue.
*
* @param queue
* @since v3.0.0
*/
void queue_free(struct queue *queue);

View File

@ -1,8 +1,9 @@
#include "stack.h"
struct stack *stack_initialization() {
struct stack *stack = malloc(sizeof(*stack));
struct stack *stack = malloc(sizeof(struct stack));
if (stack == NULL) {
perror("Error (stack_initialization)");
exit(EXIT_FAILURE);
}
stack->first = NULL;
@ -11,8 +12,14 @@ struct stack *stack_initialization() {
}
void stack_push(struct stack *stack, void *data) {
struct stack_node *node_new = malloc(sizeof(*node_new));
if (stack == NULL || data == NULL) {
if (stack == NULL) {
errno = EINVAL;
perror("Error (stack_push)");
exit(EXIT_FAILURE);
}
struct stack_node *node_new = malloc(sizeof(struct stack_node));
if (data == NULL) {
perror("Error (stack_push)");
exit(EXIT_FAILURE);
}
node_new->data = data;
@ -23,6 +30,8 @@ void stack_push(struct stack *stack, void *data) {
void *stack_pop(struct stack *stack) {
if (stack == NULL) {
errno = EINVAL;
perror("Error (stack_pop)");
exit(EXIT_FAILURE);
}
struct stack_node *node = stack->first;
@ -38,6 +47,8 @@ void *stack_pop(struct stack *stack) {
void stack_free(struct stack *stack) {
if (stack == NULL) {
errno = EINVAL;
perror("Error (stack_free)");
exit(EXIT_FAILURE);
}
struct stack_node *node = stack->first;

View File

@ -1,6 +1,7 @@
#ifndef __LIBCPROJECT_STACK__
#define __LIBCPROJECT_STACK__
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
@ -26,24 +27,34 @@ struct stack_node {
/**
* @brief Stack initialization.
*
* @return struct stack*
* @since v1.0.0
*/
struct stack *stack_initialization();
/**
* @brief Push data to stack.
*
* @param stack
* @param data
* @since v1.0.0
*/
void stack_push(struct stack *stack, void *data);
/**
* @brief Pop data from stack.
*
* @param stack
* @return void*
* @since v1.0.0
*/
void *stack_pop(struct stack *stack);
/**
* @brief Frees the stack.
*
* @param stack
* @since v3.0.0
*/
void stack_free(struct stack *stack);

View File

@ -1,135 +1,110 @@
#include "string.h"
size_t string_get_length(const string_t string_value) {
size_t string_get_length(const string_t string) {
size_t length = 0;
while (string_value[length] != '\0') {
while (string[length] != '\0') {
length++;
}
return length;
}
string_t string_to_uppercase(string_t string_value) {
size_t string_length = string_get_length(string_value);
string_t result = malloc(sizeof(char) * (string_length + 1));
if (result == NULL) {
exit(EXIT_FAILURE);
}
void string_to_uppercase(string_t string) {
size_t string_length = string_get_length(string);
for (size_t index = 0; index < string_length; index++) {
result[index] = character_to_upper(string_value[index]);
string[index] = character_to_upper(string[index]);
}
result[string_length] = '\0';
return result;
string[string_length] = '\0';
}
string_t string_to_lowercase(string_t string_value) {
size_t string_length = string_get_length(string_value);
string_t result = malloc(sizeof(char) * (string_length + 1));
if (result == NULL) {
exit(EXIT_FAILURE);
}
void string_to_lowercase(string_t string) {
size_t string_length = string_get_length(string);
for (size_t index = 0; index < string_length; index++) {
result[index] = character_to_lower(string_value[index]);
string[index] = character_to_lower(string[index]);
}
result[string_length] = '\0';
return result;
string[string_length] = '\0';
}
string_t string_replace(string_t string_value, char search, char replace) {
size_t string_length = string_get_length(string_value);
string_t result = malloc(sizeof(char) * (string_length + 1));
if (result == NULL) {
exit(EXIT_FAILURE);
}
void string_replace(string_t string, char search, char replace) {
size_t string_length = string_get_length(string);
for (size_t index = 0; index < string_length; index++) {
bool is_search_value = search == string_value[index];
bool is_search_value = search == string[index];
if (is_search_value) {
result[index] = replace;
string[index] = replace;
} else {
result[index] = string_value[index];
string[index] = string[index];
}
}
result[string_length] = '\0';
return result;
string[string_length] = '\0';
}
string_t string_trim_start(string_t string_value, char character) {
size_t string_length = string_get_length(string_value);
string_t result = malloc(sizeof(char) * (string_length + 1));
if (result == NULL) {
exit(EXIT_FAILURE);
void string_remove_character(string_t string, char search) {
size_t string_length = string_get_length(string);
for (size_t index = 0; index < string_length; index++) {
if (string[index] == search) {
for (size_t index_string = index; index_string < string_length; index_string++) {
string[index_string] = string[index_string + 1];
}
string_length--;
index--;
}
}
string[string_length] = '\0';
}
void string_trim_start(string_t string, char character) {
size_t string_length = string_get_length(string);
size_t index_space = 0;
while (string_value[index_space] == character) {
while (string[index_space] == character) {
index_space++;
}
for (size_t index = index_space; index < string_length; index++) {
result[index - index_space] = string_value[index];
for (size_t index = 0; index < string_length - index_space; index++) {
string[index] = string[index + index_space];
}
result[string_length - index_space] = '\0';
return result;
string[string_length - index_space] = '\0';
}
string_t string_trim_end(string_t string_value, char character) {
size_t string_length = string_get_length(string_value);
string_t result = malloc(sizeof(char) * (string_length + 1));
if (result == NULL) {
exit(EXIT_FAILURE);
}
void string_trim_end(string_t string, char character) {
size_t string_length = string_get_length(string);
size_t index_space = string_length - 1;
while (string_value[index_space] == character) {
while (string[index_space] == character) {
index_space--;
}
for (size_t index = 0; index < index_space + 1; index++) {
result[index] = string_value[index];
}
result[index_space + 1] = '\0';
return result;
string[index_space + 1] = '\0';
}
string_t string_trim(string_t string_value, char character) {
string_t result_start = string_trim_start(string_value, character);
string_t result = string_trim_end(result_start, character);
free(result_start);
return result;
void string_trim(string_t string, char character) {
string_trim_start(string, character);
string_trim_end(string, character);
}
string_t string_copy(const string_t source) {
size_t source_length = string_get_length(source);
string_t string_copy(const string_t string) {
size_t source_length = string_get_length(string);
string_t copy = malloc(sizeof(char) * (source_length + 1));
if (copy == NULL) {
perror("Error (string_copy)");
exit(EXIT_FAILURE);
}
size_t index;
for (index = 0; index < source_length; index++) {
copy[index] = source[index];
copy[index] = string[index];
}
copy[index] = '\0';
return copy;
}
string_t string_capitalize(string_t string_value) {
size_t string_length = string_get_length(string_value);
string_t result = malloc(sizeof(char) * (string_length + 1));
if (result == NULL) {
exit(EXIT_FAILURE);
void string_capitalize(string_t string) {
size_t string_length = string_get_length(string);
if (string_length == 0) {
return;
}
for (size_t index = 0; index < string_length; index++) {
bool is_first_character = index == 0;
if (is_first_character) {
result[index] = character_to_upper(string_value[index]);
} else {
result[index] = string_value[index];
}
}
result[string_length] = '\0';
return result;
string[0] = character_to_upper(string[0]);
}
size_t string_total_occurrences_of_character(string_t string_value, char character) {
size_t string_total_occurrences_of_character(string_t string, char character) {
size_t result = 0;
size_t string_length = string_get_length(string_value);
size_t string_length = string_get_length(string);
for (size_t index = 0; index < string_length; index++) {
char current_character = string_value[index];
char current_character = string[index];
if (current_character == character) {
result += 1;
}
@ -137,21 +112,17 @@ size_t string_total_occurrences_of_character(string_t string_value, char charact
return result;
}
string_t string_reverse(const string_t string_value) {
size_t string_length = string_get_length(string_value);
size_t index = 0;
string_t result = malloc(sizeof(char) * (string_length + 1));
if (result == NULL) {
exit(EXIT_FAILURE);
void string_reverse(const string_t string) {
size_t string_length = string_get_length(string);
size_t index_start = 0;
size_t index_end = string_length - 1;
while (index_start < index_end) {
char temporary = string[index_start];
string[index_start] = string[index_end];
string[index_end] = temporary;
index_start++;
index_end--;
}
size_t result_index = 0;
for (index = string_length - 1; index > 0; index--) {
result[result_index] = string_value[index];
result_index++;
}
result[result_index] = string_value[index];
result[string_length] = '\0';
return result;
}
bool string_equals(const string_t string1, const string_t string2) {
@ -166,11 +137,11 @@ bool string_equals(const string_t string1, const string_t string2) {
return is_equal;
}
bool string_get_is_integer(const string_t string_value) {
bool string_get_is_integer(const string_t string) {
size_t index = 0;
size_t string_length = string_get_length(string_value);
size_t string_length = string_get_length(string);
bool is_integer = string_length >= 1;
if (is_integer && string_value[0] == '-') {
if (is_integer && string[0] == '-') {
if (string_length == 1) {
is_integer = false;
} else {
@ -178,7 +149,7 @@ bool string_get_is_integer(const string_t string_value) {
}
}
while (index < string_length && is_integer) {
if (!character_get_is_digit(string_value[index])) {
if (!character_get_is_digit(string[index])) {
is_integer = false;
}
index++;
@ -186,36 +157,38 @@ bool string_get_is_integer(const string_t string_value) {
return is_integer;
}
string_t* string_split(const string_t string_value, char separator, size_t* result_size) {
size_t string_length = string_get_length(string_value);
string_t* string_split(const string_t string, char separator, size_t* result_size) {
size_t string_length = string_get_length(string);
size_t index_string = 0;
size_t index_current = 0;
size_t index_result = 0;
string_t current = malloc(sizeof(char) * (string_length + 1));
string_t* result = NULL;
if (current == NULL) {
perror("Error (string_split)");
exit(EXIT_FAILURE);
}
while (index_string < string_length) {
if (string_value[index_string] == separator) {
if (string[index_string] == separator) {
current[index_current] = '\0';
result = realloc(result, sizeof(string_t) * (index_result + 1));
if (result == NULL) {
perror("Error (string_split)");
exit(EXIT_FAILURE);
}
result[index_result] = string_copy(current);
index_result++;
index_current = 0;
} else {
current[index_current] = string_value[index_string];
current[index_current] = string[index_string];
index_current++;
}
index_string++;
}
current[index_current] = '\0';
result = realloc(result, sizeof(string_t) * (index_result + 1));
if (result == NULL) {
perror("Error (string_split)");
exit(EXIT_FAILURE);
}
result[index_result] = string_copy(current);
@ -230,8 +203,9 @@ string_t string_join(string_t* array, const char separator, size_t array_length)
total_length += string_get_length(array[index_array]);
}
size_t string_length = total_length + (array_length - 1);
string_t string_value = malloc(sizeof(char) * (string_length + 1));
if (string_value == NULL) {
string_t string = malloc(sizeof(char) * (string_length + 1));
if (string == NULL) {
perror("Error (string_join)");
exit(EXIT_FAILURE);
}
size_t current_index = 0;
@ -239,48 +213,45 @@ string_t string_join(string_t* array, const char separator, size_t array_length)
string_t substring = array[index_array];
size_t substring_length = string_get_length(substring);
for (size_t index_substring = 0; index_substring < substring_length; index_substring++) {
string_value[current_index] = substring[index_substring];
string[current_index] = substring[index_substring];
current_index++;
}
bool is_last_character = index_array == (array_length - 1);
if (!is_last_character) {
string_value[current_index] = separator;
string[current_index] = separator;
current_index++;
}
}
string_value[string_length] = '\0';
return string_value;
string[string_length] = '\0';
return string;
}
string_t string_concatenate(string_t string1, string_t string2) {
size_t string1_length = string_get_length(string1);
size_t string2_length = string_get_length(string2);
size_t result_length = string1_length + string2_length;
string_t result = malloc(sizeof(char) * (result_length + 1));
if (result == NULL) {
void string_concatenate(string_t* destination, string_t source) {
size_t destination_length = string_get_length(*destination);
size_t source_length = string_get_length(source);
size_t new_length = destination_length + source_length;
*destination = realloc(*destination, sizeof(char) * (new_length + 1));
if (*destination == NULL) {
perror("Error (string_concatenate)");
exit(EXIT_FAILURE);
}
size_t index_string1 = 0;
for (; index_string1 < string1_length; index_string1++) {
result[index_string1] = string1[index_string1];
size_t index_destination = destination_length;
for (size_t index_source = 0; index_source < source_length; index_source++) {
(*destination)[index_destination++] = source[index_source];
}
for (size_t index_string2 = 0; index_string2 < string2_length; index_string2++) {
result[index_string1 + index_string2] = string2[index_string2];
}
result[result_length] = '\0';
return result;
(*destination)[index_destination] = '\0';
}
bool string_get_has_unique_characters(const string_t string_value) {
bool string_get_has_unique_characters(const string_t string) {
bool has_unique = true;
size_t string_length = string_get_length(string_value);
size_t string_length = string_get_length(string);
struct hash_map* characters_already_seen = hash_map_initialization();
string_t* keys = malloc(sizeof(string_t) * string_length);
for (size_t index = 0; index < string_length; index++) {
keys[index] = NULL;
}
for (size_t index = 0; index < string_length && has_unique; index++) {
char character = string_value[index];
char character = string[index];
keys[index] = convert_character_to_string(character);
string_t key = keys[index];
if (hash_map_contains_key(characters_already_seen, key)) {
@ -299,24 +270,24 @@ bool string_get_has_unique_characters(const string_t string_value) {
return has_unique;
}
string_t string_substring(const string_t string_value, size_t index_start, size_t index_end) {
string_t string_substring(const string_t string, size_t index_start, size_t index_end) {
size_t substring_length = index_end - index_start + 1;
string_t result = malloc(sizeof(char) * (substring_length + 1));
for (size_t index = 0; index < substring_length; index++) {
result[index] = string_value[index_start + index];
result[index] = string[index_start + index];
}
result[substring_length] = '\0';
return result;
}
bool string_get_is_substring(const string_t string_value, const string_t substring) {
bool string_get_is_substring(const string_t string, const string_t substring) {
bool is_substring = false;
size_t string_length = string_get_length(string_value);
size_t string_length = string_get_length(string);
size_t substring_length = string_get_length(substring);
for (size_t index_string = 0; index_string < string_length && !is_substring; index_string++) {
size_t index_substring = 0;
size_t index_considered = index_string;
while (index_substring < substring_length && string_value[index_considered] == substring[index_substring]) {
while (index_substring < substring_length && string[index_considered] == substring[index_substring]) {
index_substring++;
index_considered++;
}
@ -337,6 +308,7 @@ string_t string_get_formatted_number(const long long number, string_t separator)
size_t formatted_length = number_string_length + (number_string_length - 1) / 3;
string_t result = malloc(sizeof(char) * (formatted_length + 1));
if (result == NULL) {
perror("Error (string_get_formatted_number)");
exit(EXIT_FAILURE);
}
size_t count = 0;
@ -356,23 +328,21 @@ string_t string_get_formatted_number(const long long number, string_t separator)
}
free(number_string);
result[formatted_length] = '\0';
string_t new_result = string_reverse(result);
free(result);
string_reverse(result);
if (is_negative) {
string_t dash = convert_character_to_string('-');
string_t negative_result = string_concatenate(dash, new_result);
free(new_result);
free(dash);
string_t negative_result = convert_character_to_string('-');
string_concatenate(&negative_result, result);
free(result);
return negative_result;
}
return new_result;
return result;
}
string_t string_get_last_occurence_of_character(const string_t string_value, char character) {
size_t string_length = string_get_length(string_value);
string_t string_get_last_occurence_of_character(const string_t string, char character) {
size_t string_length = string_get_length(string);
size_t index_last_occurrence = SIZE_MAX;
for (size_t index = 0; index < string_length; index++) {
if (string_value[index] == character) {
if (string[index] == character) {
index_last_occurrence = index;
}
}
@ -381,35 +351,92 @@ string_t string_get_last_occurence_of_character(const string_t string_value, cha
}
string_t result = malloc(sizeof(char) * (string_length - index_last_occurrence + 1));
if (result == NULL) {
perror("Error (string_get_last_occurence_of_character)");
exit(EXIT_FAILURE);
}
size_t index_result = 0;
for (size_t index = index_last_occurrence; index < string_length; index++) {
result[index_result++] = string_value[index];
result[index_result++] = string[index];
}
result[index_result] = '\0';
return result;
}
bool string_starts_with(const string_t string_value, const string_t prefix) {
bool string_starts_with(const string_t string, const string_t prefix) {
bool starts_with = true;
size_t prefix_length = string_get_length(prefix);
for (size_t index = 0; index < prefix_length && starts_with; index++) {
starts_with = string_value[index] == prefix[index];
starts_with = string[index] == prefix[index];
}
return starts_with;
}
bool string_ends_with(const string_t string_value, const string_t prefix) {
bool string_ends_with(const string_t string, const string_t prefix) {
bool ends_with = true;
size_t string_length = string_get_length(string_value);
size_t string_length = string_get_length(string);
size_t prefix_length = string_get_length(prefix);
size_t index_string = string_length - 1;
size_t index_prefix = prefix_length - 1;
while (index_prefix > 0 && ends_with) {
ends_with = string_value[index_string] == prefix[index_prefix];
ends_with = string[index_string] == prefix[index_prefix];
index_string--;
index_prefix--;
}
return ends_with;
}
size_t string_position_of(const string_t string, const char character) {
size_t position_found = 0;
size_t string_length = string_get_length(string);
for (size_t index = 0; index < string_length && position_found == 0; index++) {
if (string[index] == character) {
position_found = index + 1;
}
}
return position_found;
}
size_t string_last_position_of(const string_t string, const char character) {
size_t position_found = 0;
size_t string_length = string_get_length(string);
while (string_length > 0 && position_found == 0) {
if (string[string_length - 1] == character) {
position_found = string_length;
}
string_length--;
}
return position_found;
}
string_t string_pad_start(const string_t string, const string_t pad_string, size_t target_length) {
string_t result = malloc(sizeof(char) * (target_length + 1));
size_t initial_length = string_get_length(string);
size_t left_length = target_length - initial_length;
if (target_length <= initial_length) {
left_length = 0;
}
size_t pad_length = string_get_length(pad_string);
size_t count_pad_string = 0;
size_t index_initial_string = 0;
for (size_t index = 0; index < target_length; index++) {
if (index < left_length) {
size_t index_pad_string = count_pad_string % pad_length;
result[index] = pad_string[index_pad_string];
count_pad_string += 1;
} else {
result[index] = string[index_initial_string];
index_initial_string += 1;
}
}
result[target_length] = '\0';
return result;
}
string_t string_zero_pad(uint64_t number, size_t places) {
string_t number_string = convert_number_to_string((long long)number);
string_t pad_string = string_copy("0");
string_t result = string_pad_start(number_string, pad_string, places);
free(pad_string);
free(number_string);
return result;
}

View File

@ -1,6 +1,7 @@
#ifndef __LIBCPROJECT_STRING__
#define __LIBCPROJECT_STRING__
#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
@ -13,122 +14,155 @@
/**
* @brief Return the length of a string (excluding '\0').
*
* @param string_value
* @param string
* @return size_t
* @since v1.0.0
*/
size_t string_get_length(const string_t string_value);
size_t string_get_length(const string_t string);
/**
* @brief Converts all the alphabetic characters in a string to uppercase.
*
* @param string_value
* NOTE: Mutates the string.
*
* @param string
* @since v1.0.0
*/
string_t string_to_uppercase(string_t string_value);
void string_to_uppercase(string_t string);
/**
* @brief Converts all the alphabetic characters in a string to lowercase.
*
* @param string_value
* NOTE: Mutates the string.
*
* @param string
* @since v1.0.0
*/
string_t string_to_lowercase(string_t string_value);
void string_to_lowercase(string_t string);
/**
* @brief Replace all the occurrences of search value into replace value in the string.
*
* @param string_value
* NOTE: Mutates the string.
*
* @param string
* @param search A character search value.
* @param replace A character containing the text to replace for match.
* @since v1.0.0
*/
string_t string_replace(string_t string_value, char search, char replace);
void string_replace(string_t string, char search, char replace);
/**
* @brief Removes all the occurrences of a character in a string.
*
* NOTE: Mutates the string.
*
* @param string
* @param search A character search value.
* @since v4.1.0
*/
void string_remove_character(string_t string, char search);
/**
* @brief Removes all `character` from the start of a string.
*
* @param string_value
* NOTE: Mutates the string.
*
* @param string
* @since v1.0.0
*/
string_t string_trim_start(string_t string_value, char character);
void string_trim_start(string_t string, char character);
/**
* @brief Removes all `character` from the end of a string.
*
* @param string_value
* NOTE: Mutates the string.
*
* @param string
* @since v1.0.0
*/
string_t string_trim_end(string_t string_value, char character);
void string_trim_end(string_t string, char character);
/**
* @brief Removes all `character` from the start and end of a string.
*
* @param string_value
* NOTE: Mutates the string.
*
* @param string
* @since v1.0.0
*/
string_t string_trim(string_t string_value, char character);
void string_trim(string_t string, char character);
/**
* @brief Return the copy of a string.
*
* @param string_value
* @param string
* @return string_t
* @since v1.0.0
*/
string_t string_copy(const string_t string_value);
string_t string_copy(const string_t string);
/**
* @brief Capitalizes the string.
*
* @param string_value
* NOTE: Mutates the string.
*
* @param string
* @since v1.0.0
*/
string_t string_capitalize(string_t string_value);
void string_capitalize(string_t string);
/**
* @brief Returns the total number of occurrences of the given character in the string.
*
* @param string_value
* @param string
* @param character
* @return size_t
* @since v1.0.0
*/
size_t string_total_occurrences_of_character(string_t string_value, char character);
size_t string_total_occurrences_of_character(string_t string, char character);
/**
* @brief Reverse the characters in an array.
* @brief Reverse the characters in a string.
*
* @param string_value
* NOTE: Mutates the string.
*
* @param string
* @since v1.0.0
*/
string_t string_reverse(const string_t string_value);
void string_reverse(const string_t string);
/**
* @brief Check if two strings are equals.
*
* @param string1
* @param string2
* @return true if the strings are equals, false otherwise.
* @return true if the strings are equals.
* @return false if the strings are not equals.
* @since v1.0.0
*/
bool string_equals(const string_t string1, const string_t string2);
/**
* @brief Check if the string is a integer.
* @brief Check if the string is an integer.
*
* @param string_value
* @return true if the string is a integer, false otherwise.
* @param string
* @return true if the string is an integer.
* @return false if the string is not an integer.
* @since v1.0.0
*/
bool string_get_is_integer(const string_t string_value);
bool string_get_is_integer(const string_t string);
/**
* @brief Split a string into substrings using the specified separator and return them as an array and update the pointer `result_size` to the resulting size of the created array.
*
* @param string_value
* @param string
* @param separator
* @param result_size
* @return string_t*
* @since v1.0.0
*/
string_t* string_split(const string_t string_value, char separator, size_t* result_size);
string_t* string_split(const string_t string, char separator, size_t* result_size);
/**
* @brief Adds all the elements of an array into a string, separated by the specified separator string.
@ -136,6 +170,7 @@ string_t* string_split(const string_t string_value, char separator, size_t* resu
* @param array
* @param separator
* @param array_length
* @return string_t
* @since v1.0.0
*/
string_t string_join(string_t* array, const char separator, size_t array_length);
@ -143,17 +178,20 @@ string_t string_join(string_t* array, const char separator, size_t array_length)
/**
* @brief Concatenate two strings.
*
* @param string1
* @param string2
* NOTE: Mutates the string `destination`.
*
* @param destination
* @param source
* @since v1.0.0
*/
string_t string_concatenate(string_t string1, string_t string2);
void string_concatenate(string_t* destination, string_t source);
/**
* @brief Check if a string contains only unique characters.
*
* @param string
* @return true if string contains only unique characters, false otherwise.
* @return true if string contains only unique characters.
* @return false if string contains duplicate characters.
* @since v1.0.0
*/
bool string_get_has_unique_characters(const string_t string);
@ -161,63 +199,129 @@ bool string_get_has_unique_characters(const string_t string);
/**
* @brief Returns the part of the string between the start and end indexes (both included).
*
* @param string_value
* @param string
* @param index_start
* @param index_end
* @return string_t
* @since v1.0.0
*/
string_t string_substring(const string_t string_value, size_t index_start, size_t index_end);
string_t string_substring(const string_t string, size_t index_start, size_t index_end);
/**
* @brief Check if a string contains a substring.
*
* @param string_value
* @param string
* @param substring
* @return true if the string contains the substring, false otherwise.
* @return true if the string contains the substring.
* @return false if the string does not contain the substring.
* @since v1.0.0
*/
bool string_get_is_substring(const string_t string_value, const string_t substring);
bool string_get_is_substring(const string_t string, const string_t substring);
/**
* @brief Format a number to a string with specified separator.
*
* @param number
* @param separator
* @since v1.0.0
* @return string_t
*
* @code
* string_get_formatted_number(1000, " ") // "1 000"
* string_get_formatted_number(1000, ",") // "1,000"
* @endcode
* @since v1.0.0
*/
string_t string_get_formatted_number(const long long number, string_t separator);
/**
* @brief Returns a pointer to the last occurrence of character in the string.
*
* @param string_value
* @param string
* @param character
* @return string_t
* @since v1.0.0
*/
string_t string_get_last_occurence_of_character(const string_t string_value, char character);
string_t string_get_last_occurence_of_character(const string_t string, char character);
/**
* @brief Check if a string starts with a substring.
*
* @param string_value
* @param string
* @param prefix
* @return true if the string starts with the substring, false otherwise.
* @return true if the string starts with the substring.
* @return false if the string does not start with the substring.
* @since v1.0.0
*/
bool string_starts_with(const string_t string_value, const string_t prefix);
bool string_starts_with(const string_t string, const string_t prefix);
/**
* @brief Check if a string ends with a substring.
*
* @param string_value
* @param string
* @param prefix
* @return true if the string ends with the substring, false otherwise.
* @return true if the string ends with the substring.
* @return false if the string does not end with the substring.
* @since v1.0.0
*/
bool string_ends_with(const string_t string_value, const string_t prefix);
bool string_ends_with(const string_t string, const string_t prefix);
/**
* @brief Returns the position (index + 1) within the string of the first occurrence of the specified substring (0 if not found).
*
* @param string
* @param substring
* @return size_t
*
* @code
* string_position_of("hello world", 'e') // 2
* @endcode
* @since v4.2.0
*/
size_t string_position_of(const string_t string, const char character);
/**
* @brief Returns the position (index + 1) within the string of the last occurrence of the specified substring (0 if not found).
*
* @param string
* @param character
* @return size_t
*
* @code
* string_last_position_of("hello world", 'o') // 8
* @endcode
* @since v4.2.0
*/
size_t string_last_position_of(const string_t string, const char character);
/**
* @brief Pads a `string` with another `pad_string` (multiple times, if needed) until the resulting string reaches the `target_length`. The padding is applied from the start (left) of the string.
*
* @param string The string to pad.
* @param pad_string The string to pad the current string with, to the left.
* @param target_length
* @return string_t
*
* @code
* string_pad_start("hello", " ", 10) // " hello"
* @endcode
* @since vTODO
*/
string_t string_pad_start(const string_t string, const string_t pad_string, size_t target_length);
/**
* @brief Pad a number with zeros.
*
* @param number
* @param places
* @return string_t
*
* @code
* string_zero_pad(1, 2) // "01"
*
* string_zero_pad(10, 2) // "10"
* @endcode
* @since vTODO
*/
string_t string_zero_pad(uint64_t number, size_t places);
#endif

View File

@ -3,26 +3,28 @@
string_t terminal_input() {
char character;
size_t length = 1;
string_t string_value = malloc(length * sizeof(char));
if (string_value == NULL) {
string_t string = malloc(length * sizeof(char));
if (string == NULL) {
perror("Error (terminal_input)");
exit(EXIT_FAILURE);
}
*string_value = '\0';
*string = '\0';
while ((character = getchar()) != '\n' && character != EOF) {
length++;
string_value = realloc(string_value, length * sizeof(char));
if (string_value == NULL) {
string = realloc(string, length * sizeof(char));
if (string == NULL) {
perror("Error (terminal_input)");
exit(EXIT_FAILURE);
}
character_append(string_value, character);
character_append(string, character);
}
return string_value;
return string;
}
void terminal_print_array(void* array, size_t array_size, size_t element_size, void (*print_element)(void*)) {
printf("[");
for (size_t index = 0; index < array_size; index++) {
void* element = (char*)array + index * element_size;
void* element = (string_t)array + index * element_size;
print_element(element);
bool is_last = index == array_size - 1;
if (!is_last) {
@ -45,21 +47,23 @@ void terminal_print_unsigned_long(void* value) {
}
void terminal_print_char(void* value) {
printf("%c", *(char*)value);
printf("%c", *(string_t)value);
}
void terminal_print_string(void* value) {
printf("%s", (char*)value);
printf("%s", (string_t)value);
}
void terminal_print_stack(struct stack* stack, void (*print_element)(void*)) {
if (stack == NULL) {
errno = EINVAL;
perror("Error (terminal_print_stack)");
exit(EXIT_FAILURE);
}
struct stack_node* node_current = stack->first;
while (node_current != NULL) {
printf("|\t");
void* element = (char*)node_current->data;
void* element = node_current->data;
print_element(&element);
node_current = node_current->next;
printf("\t|\n");
@ -68,12 +72,14 @@ void terminal_print_stack(struct stack* stack, void (*print_element)(void*)) {
void terminal_print_queue(struct queue* queue, void (*print_element)(void*)) {
if (queue == NULL) {
errno = EINVAL;
perror("Error (terminal_print_queue)");
exit(EXIT_FAILURE);
}
struct queue_node* node_current = queue->first;
while (node_current != NULL) {
printf("|\t");
void* element = (char*)node_current->data;
void* element = node_current->data;
print_element(&element);
node_current = node_current->next;
printf("\t|\n");
@ -82,11 +88,13 @@ void terminal_print_queue(struct queue* queue, void (*print_element)(void*)) {
void terminal_print_linked_list(struct linked_list* linked_list, void (*print_element)(void*)) {
if (linked_list == NULL) {
errno = EINVAL;
perror("Error (terminal_print_linked_list)");
exit(EXIT_FAILURE);
}
struct linked_list_node* node_current = linked_list->head;
while (node_current != NULL) {
void* element = (char*)node_current->data;
void* element = (string_t)node_current->data;
node_current = node_current->next;
print_element(&element);
printf(" -> ");
@ -96,6 +104,8 @@ void terminal_print_linked_list(struct linked_list* linked_list, void (*print_el
void terminal_print_hash_map(struct hash_map* hash_map, void (*print_element)(void*)) {
if (hash_map == NULL) {
errno = EINVAL;
perror("Error (terminal_print_hash_map)");
exit(EXIT_FAILURE);
}
printf("{\n");

View File

@ -1,6 +1,7 @@
#ifndef __LIBCPROJECT_TERMINAL__
#define __LIBCPROJECT_TERMINAL__
#include <errno.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
@ -16,6 +17,8 @@
/**
* @brief Read a line from stdin.
*
* @return string_t
* @since v1.0.0
*/
string_t terminal_input();
@ -110,7 +113,7 @@ void terminal_print_hash_map(struct hash_map* hash_map, void (*print_element)(vo
/**
* @brief Print an array list.
*
* @param array_list
* @param list
* @param print_element
* @since v3.0.0
*/

6
main.c
View File

@ -4,8 +4,8 @@
#include "libcproject.h"
int main() {
string_t string_value = "Hello, world!";
printf("%s\n", string_value);
printf("string_length = %ld\n", string_get_length(string_value));
string_t string = "Hello, world!";
printf("%s\n", string);
printf("string_length = %ld\n", string_get_length(string));
return EXIT_SUCCESS;
}

View File

@ -8,14 +8,15 @@ int main(int argc, string_t* argv) {
fprintf(stderr, "Usage: %s <version>\n", argv[0]);
return EXIT_FAILURE;
}
string_t content = "#ifndef __LIBCPROJECT_VERSION__\n";
content = string_concatenate(content, "#define __LIBCPROJECT_VERSION__ \"");
content = string_concatenate(content, argv[1]);
content = string_concatenate(content, "\"\n\n");
content = string_concatenate(content, "#endif\n");
string_t content = string_copy("#ifndef __LIBCPROJECT_VERSION__\n");
string_concatenate(&content, "#define __LIBCPROJECT_VERSION__ \"");
string_concatenate(&content, argv[1]);
string_concatenate(&content, "\"\n\n");
string_concatenate(&content, "#endif\n");
int result = filesystem_write("./version.h", (byte_t*)content, string_get_length(content));
if (result == -1) {
fprintf(stderr, "Error: Could not write to file.\n");
perror("Error (set_version)");
return EXIT_FAILURE;
}
printf("Success: Version set to %s.\n", argv[1]);

View File

@ -34,4 +34,15 @@ void array_list_test() {
assert(array_list_get(list, 100) == (void *)95);
array_list_free(list);
list = array_list_initialization();
array_list_add(list, (void *)'a');
array_list_add(list, (void *)'b');
array_list_add(list, (void *)'c');
array_list_remove(list, 1);
assert(array_list_get(list, 0) == (void *)'a');
assert(array_list_get(list, 1) == (void *)'c');
assert(list->size == 2);
array_list_free(list);
}

View File

@ -10,7 +10,7 @@ void convert_test() {
}
void convert_character_to_string_test() {
char* result = convert_character_to_string('a');
string_t result = convert_character_to_string('a');
assert(assert_string_equal(result, "a"));
free(result);
@ -77,7 +77,7 @@ void convert_string_to_number_test() {
}
void convert_number_to_string_test() {
char* result = convert_number_to_string(0);
string_t result = convert_number_to_string(0);
assert(assert_string_equal(result, "0"));
free(result);
@ -143,7 +143,7 @@ void convert_number_to_string_test() {
}
void convert_number_from_base_to_another_test() {
char* result = convert_number_from_base_to_another("15", 10, 16);
string_t result = convert_number_from_base_to_another("15", 10, 16);
assert(assert_string_equal(result, "F"));
free(result);

View File

@ -6,6 +6,11 @@ void mathematics_test() {
mathematics_root_test();
mathematics_square_root_test();
mathematics_factorial_test();
mathematics_opposite_test();
mathematics_max_test();
mathematics_max_values_test();
mathematics_min_test();
mathematics_min_values_test();
}
void mathematics_absolute_value_test() {
@ -56,3 +61,38 @@ void mathematics_factorial_test() {
assert(mathematics_factorial(9) == 362880);
assert(mathematics_factorial(10) == 3628800);
}
void mathematics_opposite_test() {
assert(mathematics_opposite(-7) == 7);
assert(mathematics_opposite(7) == -7);
}
void mathematics_max_test() {
assert(mathematics_max(0, 0) == 0);
assert(mathematics_max(0, 1) == 1);
assert(mathematics_max(2, 0) == 2);
assert(mathematics_max(54, 37) == 54);
}
void mathematics_max_values_test() {
int64_t values[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
assert(mathematics_max_values(values, 10) == 9);
int64_t values2[] = {8, 6, 4, 7};
assert(mathematics_max_values(values2, 4) == 8);
}
void mathematics_min_test() {
assert(mathematics_min(0, 0) == 0);
assert(mathematics_min(3, 5) == 3);
assert(mathematics_min(2, 1) == 1);
assert(mathematics_min(54, 37) == 37);
}
void mathematics_min_values_test() {
int64_t values[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
assert(mathematics_min_values(values, 10) == 0);
int64_t values2[] = {9, 6, 8, 7};
assert(mathematics_min_values(values2, 4) == 6);
}

View File

@ -17,4 +17,14 @@ void mathematics_square_root_test();
void mathematics_factorial_test();
void mathematics_opposite_test();
void mathematics_max_test();
void mathematics_max_values_test();
void mathematics_min_test();
void mathematics_min_values_test();
#endif

View File

@ -5,6 +5,7 @@ void string_test() {
string_to_uppercase_test();
string_to_lowercase_test();
string_replace_test();
string_remove_character_test();
string_trim_start_test();
string_trim_end_test();
string_trim_test();
@ -24,52 +25,64 @@ void string_test() {
string_get_last_occurence_of_character_test();
string_starts_with_test();
string_ends_with_test();
string_position_of_test();
string_last_position_of_test();
string_pad_start_test();
string_zero_pad_test();
}
void string_get_length_test() {
string_t string = "Hello World!";
size_t string_length = string_get_length(string);
assert(string_length == 12);
assert(strlen(string) == string_length);
}
void string_to_uppercase_test() {
string_t string = "heLlO world";
string = string_to_uppercase(string);
string_t string = string_copy("heLlO world");
string_to_uppercase(string);
assert(assert_string_equal(string, "HELLO WORLD"));
free(string);
}
void string_to_lowercase_test() {
string_t string = "HellO WoRLd";
string = string_to_lowercase(string);
string_t string = string_copy("HellO WoRLd");
string_to_lowercase(string);
assert(assert_string_equal(string, "hello world"));
free(string);
}
void string_replace_test() {
string_t string = "hello world";
string = string_replace(string, 'l', 'z');
string_t string = string_copy("hello world");
string_replace(string, 'l', 'z');
assert(assert_string_equal(string, "hezzo worzd"));
free(string);
}
void string_remove_character_test() {
string_t string = string_copy("hello world");
string_remove_character(string, 'l');
assert(assert_string_equal(string, "heo word"));
free(string);
}
void string_trim_start_test() {
string_t string = " hello world ";
string = string_trim_start(string, ' ');
string_t string = string_copy(" hello world ");
string_trim_start(string, ' ');
assert(assert_string_equal(string, "hello world "));
free(string);
}
void string_trim_end_test() {
string_t string = " hello world ";
string = string_trim_end(string, ' ');
string_t string = string_copy(" hello world ");
string_trim_end(string, ' ');
assert(assert_string_equal(string, " hello world"));
free(string);
}
void string_trim_test() {
string_t string = " hello world ";
string = string_trim(string, ' ');
string_t string = string_copy(" hello world ");
string_trim(string, ' ');
assert(assert_string_equal(string, "hello world"));
free(string);
}
@ -86,8 +99,8 @@ void string_copy_test() {
}
void string_capitalize_test() {
string_t string = "hello world";
string = string_capitalize(string);
string_t string = string_copy("hello world");
string_capitalize(string);
assert(assert_string_equal(string, "Hello world"));
free(string);
}
@ -98,8 +111,8 @@ void string_total_occurrences_of_character_test() {
}
void string_reverse_test() {
string_t string = "hello world";
string = string_reverse(string);
string_t string = string_copy("hello world");
string_reverse(string);
assert(assert_string_equal(string, "dlrow olleh"));
free(string);
}
@ -157,12 +170,14 @@ void string_join_test() {
}
void string_concatenate_test() {
char* result = string_concatenate("abc", "def");
string_t result = string_copy("abc");
string_concatenate(&result, "def");
assert(assert_string_equal(result, "abcdef"));
free(result);
result = string_concatenate("abc", " defghi");
assert(assert_string_equal(result, "abc defghi"));
result = string_copy("abcz");
string_concatenate(&result, " defghi");
assert(assert_string_equal(result, "abcz defghi"));
free(result);
}
@ -192,7 +207,7 @@ void string_get_is_substring_test() {
}
void string_get_formatted_number_test() {
char* result = string_get_formatted_number(1000, " ");
string_t result = string_get_formatted_number(1000, " ");
assert(assert_string_equal(result, "1 000"));
free(result);
@ -224,7 +239,7 @@ void string_get_formatted_number_test() {
void string_get_last_occurence_of_character_test() {
string_t string = "abcdef";
char* result = string_get_last_occurence_of_character(string, 'a');
string_t result = string_get_last_occurence_of_character(string, 'a');
assert(assert_string_equal(result, "abcdef"));
free(result);
@ -266,3 +281,55 @@ void string_ends_with_test() {
assert(!string_ends_with("abcdef", "bcd"));
assert(!string_ends_with("abcdef", "abcdefg"));
}
void string_position_of_test() {
assert(string_position_of("hello world", 'e') == 2);
assert(string_position_of("hello world", 'o') == 5);
assert(string_position_of("abcdef", 'a') == 1);
assert(string_position_of("abcdef", 'b') == 2);
assert(string_position_of("abcdef", 'c') == 3);
assert(string_position_of("abcdef", 'd') == 4);
assert(string_position_of("abcdef", 'e') == 5);
assert(string_position_of("abcdef", 'f') == 6);
assert(string_position_of("abcdef", 'g') == 0);
}
void string_last_position_of_test() {
assert(string_last_position_of("hello world", 'e') == 2);
assert(string_last_position_of("hello world", 'o') == 8);
assert(string_last_position_of("abcdef", 'a') == 1);
assert(string_last_position_of("abcdef", 'b') == 2);
assert(string_last_position_of("abcdef", 'c') == 3);
assert(string_last_position_of("abcdef", 'd') == 4);
assert(string_last_position_of("abcdef", 'e') == 5);
assert(string_last_position_of("abcdef", 'f') == 6);
assert(string_last_position_of("abcdef", 'g') == 0);
}
void string_pad_start_test() {
string_t result = string_pad_start("hello", "ab", 10);
assert(assert_string_equal(result, "ababahello"));
free(result);
result = string_pad_start("hello", "ab", 4);
assert(assert_string_equal(result, "hell"));
free(result);
result = string_pad_start("hello", "ab", 5);
assert(assert_string_equal(result, "hello"));
free(result);
result = string_pad_start("hello", "ab", 6);
assert(assert_string_equal(result, "ahello"));
free(result);
}
void string_zero_pad_test() {
string_t result = string_zero_pad(1, 2);
assert(assert_string_equal(result, "01"));
free(result);
result = string_zero_pad(10, 2);
assert(assert_string_equal(result, "10"));
free(result);
}

View File

@ -18,6 +18,8 @@ void string_to_lowercase_test();
void string_replace_test();
void string_remove_character_test();
void string_trim_start_test();
void string_trim_end_test();
@ -56,4 +58,12 @@ void string_starts_with_test();
void string_ends_with_test();
void string_position_of_test();
void string_last_position_of_test();
void string_pad_start_test();
void string_zero_pad_test();
#endif

View File

@ -1,4 +1,4 @@
#ifndef __LIBCPROJECT_VERSION__
#define __LIBCPROJECT_VERSION__ "3.0.0"
#define __LIBCPROJECT_VERSION__ "4.2.1"
#endif