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

6 Commits

Author SHA1 Message Date
f1a729c418 chore(release): 1.2.0 [skip ci] 2023-01-07 18:43:17 +00:00
bd85171e2d refactor: include only in header files 2023-01-07 19:41:04 +01:00
886038a0ac feat: add array_list data structure
fixes #2
2023-01-07 19:40:16 +01:00
821c27c6a9 chore: minor improvements 2023-01-07 18:57:14 +01:00
e844600214 chore(release): 1.1.2 [skip ci] 2023-01-06 17:09:41 +00:00
ba5dddcf2f fix: exclude release tools in documentation 2023-01-06 18:08:34 +01:00
48 changed files with 233 additions and 131 deletions

View File

@ -12,6 +12,7 @@ jobs:
with:
fetch-depth: 0
persist-credentials: false
submodules: recursive
- name: 'Import GPG key'
uses: 'crazy-max/ghaction-import-gpg@v4'

View File

@ -1,6 +1,6 @@
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = libcproject
PROJECT_BRIEF = "C static library easier to use than $(libc) (C standard library)."
PROJECT_BRIEF = "C static library easier to use than libc (C standard library)."
OUTPUT_DIRECTORY = documentation
OUTPUT_LANGUAGE = English
OPTIMIZE_OUTPUT_FOR_C = YES
@ -12,7 +12,7 @@ FILE_PATTERNS = *.h \
HTML_EXTRA_STYLESHEET = doxygen-awesome-css/doxygen-awesome.css
RECURSIVE = YES
EXCLUDE = test doxygen-awesome-css
EXCLUDE = test doxygen-awesome-css node_modules
GENERATE_LATEX = NO
GENERATE_TREEVIEW = YES
EXAMPLE_PATTERNS = *

View File

@ -12,14 +12,22 @@ MAIN_EXECUTABLE = bin/main.exe
SET_VERSION_EXECUTABLE = bin/set_version.exe
TEST_EXECUTABLE = bin/test.exe
build/%.o: %.c
mkdir --parents ./build/lib ./build/test
${CC} ${CC_FLAGS} -c $< -o $@
${LIB}: $(addprefix build/, ${LIB_OBJECTS})
rm --force ${LIB}
ar -rcs ${LIB} $(addprefix build/, ${LIB_OBJECTS})
build/lib:
mkdir --parents ./build/lib
build/test:
mkdir --parents ./build/test
build/lib/%.o: lib/%.c ${HEADER_FILES} | build/lib
${CC} ${CC_FLAGS} -c $< -o $@
build/test/%.o: test/%.c ${HEADER_FILES} | build/test
${CC} ${CC_FLAGS} -c $< -o $@
.PHONY: run
run: ${LIB} ./main.c
mkdir --parents ./bin
@ -35,7 +43,7 @@ set_version: ${LIB} ./set_version.c
test: ${LIB} $(addprefix build/, ${TEST_OBJECTS})
mkdir --parents ./bin
${CC} ${CC_FLAGS} -o ${TEST_EXECUTABLE} $(addprefix build/, ${TEST_OBJECTS}) ${LIB_CC_FLAGS}
./${TEST_EXECUTABLE}
./${TEST_EXECUTABLE} ${ARGS}
.PHONY: lint
lint:

View File

@ -30,7 +30,7 @@ C is a low-level programming language and we often end up reinventing the wheel
- [GNU binutils](https://www.gnu.org/software/binutils/)
- [GNU gcc](https://gcc.gnu.org/)
- [GNU make](https://www.gnu.org/software/make/)
- [clang-format](https://clang.llvm.org/docs/ClangFormat.html)
- [ClangFormat](https://clang.llvm.org/docs/ClangFormat.html)
- [Doxygen](https://www.doxygen.nl/)
For example on GNU/Linux Ubuntu:
@ -55,9 +55,16 @@ nm ./build/libcproject.a # to see the symbols
Steps to create a new C project that uses `libcproject`:
### Step 1: Compile `libcproject`
### Step 1: Install and Compile `libcproject`
```sh
# Clone the repository
git clone https://github.com/Divlo/libcproject.git
# Go to libcproject directory
cd libcproject
# Compile the library
make
```

39
lib/array_list.c Normal file
View File

@ -0,0 +1,39 @@
#include "array_list.h"
struct array_list* array_list_initialization() {
struct array_list* list = malloc(sizeof(struct array_list));
list->data = malloc(sizeof(void*) * ARRAY_LIST_INITIAL_CAPACITY);
list->size = 0;
list->capacity = ARRAY_LIST_INITIAL_CAPACITY;
return list;
}
void array_list_add(struct array_list* list, void* element) {
if (list->size >= list->capacity) {
size_t previous_capacity = list->capacity;
list->capacity += ARRAY_LIST_INITIAL_CAPACITY;
list->data = realloc(list->data, sizeof(void*) * list->capacity);
for (size_t index = previous_capacity; index < list->capacity; index++) {
list->data[index] = NULL;
}
}
list->data[list->size] = element;
list->size++;
}
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];
}
list->size--;
}
void* array_list_get(struct array_list* list, size_t index) {
if (index >= list->size) {
return NULL;
}
return list->data[index];
}

23
lib/array_list.h Normal file
View File

@ -0,0 +1,23 @@
#ifndef __ARRAY_LIST__
#define __ARRAY_LIST__
#include <stdbool.h>
#include <stdlib.h>
#define ARRAY_LIST_INITIAL_CAPACITY 10
struct array_list {
void** data;
size_t size;
size_t capacity;
};
struct array_list* array_list_initialization();
void array_list_add(struct array_list* list, void* element);
void array_list_remove(struct array_list* list, size_t index);
void* array_list_get(struct array_list* list, size_t index);
#endif

View File

@ -1,10 +1,5 @@
#include "character.h"
#include <stdbool.h>
#include <stdlib.h>
#include "string.h"
void character_append(char* string, const char character) {
size_t length = string_get_length(string);
character_append_at(string, character, length);

View File

@ -4,6 +4,8 @@
#include <stdbool.h>
#include <stdlib.h>
#include "string.h"
/**
* @brief Append a character to a string, assuming string points to an array
* with enough space.

View File

@ -1,13 +1,5 @@
#include "convert.h"
#include <stdio.h>
#include <stdlib.h>
#include "character.h"
#include "mathematics.h"
#include "stdbool.h"
#include "string.h"
char* convert_character_to_string(const char character) {
char* string = malloc(sizeof(char*) * 2);
if (string == NULL) {

View File

@ -1,6 +1,14 @@
#ifndef __CONVERT__
#define __CONVERT__
#include <stdio.h>
#include <stdlib.h>
#include "character.h"
#include "mathematics.h"
#include "stdbool.h"
#include "string.h"
char* convert_character_to_string(const char character);
char convert_character_to_digit(const char character);

View File

@ -1,9 +1,5 @@
#include "dictionary.h"
#include <stdlib.h>
#include "string.h"
struct dictionary *dictionary_initialization() {
struct dictionary *dictionary = malloc(sizeof(struct dictionary));
dictionary->items = malloc(sizeof(struct dictionary_item *) * DICTIONARY_INITIAL_CAPACITY);

View File

@ -4,7 +4,7 @@
#include <stdbool.h>
#include <stdlib.h>
#include "linked_list.h"
#include "string.h"
#define DICTIONARY_INITIAL_CAPACITY 10

View File

@ -1,16 +1,5 @@
#include "filesystem.h"
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <pwd.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "string.h"
int filesystem_read(char *path, char **file_content, off_t *file_size) {
int file_descriptor = open(path, O_RDONLY);
if (file_descriptor == -1) {

View File

@ -1,7 +1,16 @@
#ifndef __FILESYSTEM__
#define __FILESYSTEM__
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <pwd.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "string.h"
/**
* @brief Read the content of a file.

View File

@ -1,10 +1,5 @@
#include "linked_list.h"
#include <stdbool.h>
#include <stdlib.h>
#include "stack.h"
struct linked_list *linked_list_initialization() {
struct linked_list *list = malloc(sizeof(*list));
if (list == NULL) {

View File

@ -1,10 +1,12 @@
#ifndef __LINKED_LIST__
#define __LINKED_LIST__
#include <stdbool.h>
#include <stdlib.h>
#include "stack.h"
struct linked_list {
// first node of the list
struct linked_list_node *head;
size_t length;

View File

@ -1,7 +1,5 @@
#include "mathematics.h"
#include <stdbool.h>
bool mathematics_equals(const float number1, const float number2) {
return (number1 - number2) < MATHEMATICS_FLOAT_PRECISION;
}

View File

@ -1,8 +1,5 @@
#include "queue.h"
#include <stdio.h>
#include <stdlib.h>
struct queue *queue_initialization() {
struct queue *queue = malloc(sizeof(*queue));
if (queue == NULL) {

View File

@ -1,6 +1,7 @@
#ifndef __QUEUE__
#define __QUEUE__
#include <stdio.h>
#include <stdlib.h>
// FIFO = First In First Out

View File

@ -1,8 +1,5 @@
#include "stack.h"
#include <stdio.h>
#include <stdlib.h>
struct stack *stack_initialization() {
struct stack *stack = malloc(sizeof(*stack));
if (stack == NULL) {

View File

@ -1,6 +1,7 @@
#ifndef __STACK__
#define __STACK__
#include <stdio.h>
#include <stdlib.h>
// LIFO = Last In First Out

View File

@ -1,13 +1,5 @@
#include "string.h"
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include "character.h"
#include "convert.h"
#include "dictionary.h"
size_t string_get_length(const char* string) {
size_t length = 0;
while (string[length] != '\0') {

View File

@ -2,8 +2,13 @@
#define __STRING__
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include "character.h"
#include "convert.h"
#include "dictionary.h"
/**
* @brief Return the length of a string (excluding '\0').
*
@ -100,7 +105,7 @@ char* string_reverse(const char* string);
*
* @param string1
* @param string2
* @return true if the strings are equals, false otherwise
* @return true if the strings are equals, false otherwise.
*/
bool string_equals(const char* string1, const char* string2);
@ -108,7 +113,7 @@ bool string_equals(const char* string1, const char* string2);
* @brief Check if the string is a integer.
*
* @param string
* @return true if the string is a integer, false otherwise
* @return true if the string is a integer, false otherwise.
*/
bool string_get_is_integer(const char* string);
@ -143,7 +148,7 @@ char* string_concatenate(char* string1, char* string2);
* @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, false otherwise.
*/
bool string_get_has_unique_characters(const char* string);
@ -162,7 +167,7 @@ char* string_substring(const char* string, size_t index_start, size_t index_end)
*
* @param string
* @param substring
* @return true if the string contains the substring, false otherwise
* @return true if the string contains the substring, false otherwise.
*/
bool string_get_is_substring(const char* string, const char* substring);
@ -188,7 +193,7 @@ char* string_get_last_occurence_of_character(const char* string, char character)
*
* @param string
* @param prefix
* @return true if the string starts with the substring, false otherwise
* @return true if the string starts with the substring, false otherwise.
*/
bool string_starts_with(const char* string, const char* prefix);
@ -197,7 +202,7 @@ bool string_starts_with(const char* string, const char* prefix);
*
* @param string
* @param prefix
* @return true if the string ends with the substring, false otherwise
* @return true if the string ends with the substring, false otherwise.
*/
bool string_ends_with(const char* string, const char* prefix);

View File

@ -1,16 +1,5 @@
#include "terminal.h"
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include "character.h"
#include "dictionary.h"
#include "linked_list.h"
#include "queue.h"
#include "stack.h"
char* terminal_input() {
char character;
size_t length = 1;

View File

@ -1,8 +1,12 @@
#ifndef __TERMINAL__
#define __TERMINAL__
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include "character.h"
#include "dictionary.h"
#include "linked_list.h"
#include "queue.h"

View File

@ -1,6 +1,7 @@
#ifndef __LIBCPROJECT__
#define __LIBCPROJECT__
#include "lib/array_list.h"
#include "lib/character.h"
#include "lib/convert.h"
#include "lib/dictionary.h"
@ -11,5 +12,6 @@
#include "lib/stack.h"
#include "lib/string.h"
#include "lib/terminal.h"
#include "version.h"
#endif

35
test/array_list_test.c Normal file
View File

@ -0,0 +1,35 @@
#include "array_list_test.h"
void array_list_test() {
struct array_list *list = array_list_initialization();
assert(list->size == 0);
array_list_add(list, (void *)'a');
array_list_add(list, (void *)'b');
array_list_add(list, (void *)'c');
array_list_add(list, (void *)'d');
array_list_add(list, (void *)'e');
array_list_add(list, (void *)'f');
assert(list->size == 6);
assert(array_list_get(list, 0) == (void *)'a');
assert(array_list_get(list, 1) == (void *)'b');
assert(array_list_get(list, 2) == (void *)'c');
assert(array_list_get(list, 3) == (void *)'d');
assert(array_list_get(list, 4) == (void *)'e');
assert(array_list_get(list, 5) == (void *)'f');
array_list_add(list, (void *)'a');
assert(array_list_get(list, 6) == (void *)'a');
assert(list->size == 7);
array_list_remove(list, 6);
assert(list->size == 6);
assert(array_list_get(list, 6) == NULL);
for (size_t index = 0; index < 100; index++) {
array_list_add(list, (void *)index);
}
assert(list->size == 106);
assert(array_list_get(list, 100) == (void *)94);
assert(array_list_get(list, 101) == (void *)95);
array_list_remove(list, 100);
assert(list->size == 105);
assert(array_list_get(list, 100) == (void *)95);
}

13
test/array_list_test.h Normal file
View File

@ -0,0 +1,13 @@
#ifndef __ARRAY_LIST_TEST__
#define __ARRAY_LIST_TEST__
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include "libcproject.h"
void array_list_test();
#endif

View File

@ -1,12 +1,5 @@
#include "character_test.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include "libcproject.h"
#include "test.h"
void character_test() {
character_append_test();
character_append_at_test();

View File

@ -1,6 +1,13 @@
#ifndef __CHARACTER_TEST__
#define __CHARACTER_TEST__
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include "libcproject.h"
#include "test.h"
void character_test();
void character_append_test();

View File

@ -1,12 +1,5 @@
#include "convert_test.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include "libcproject.h"
#include "test.h"
void convert_test() {
convert_character_to_string_test();
convert_character_to_digit_test();

View File

@ -1,6 +1,13 @@
#ifndef __CONVERT_TEST__
#define __CONVERT_TEST__
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include "libcproject.h"
#include "test.h"
void convert_test();
void convert_character_to_string_test();

View File

@ -1,11 +1,5 @@
#include "dictionary_test.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include "libcproject.h"
void dictionary_test() {
struct dictionary *dictionary = dictionary_initialization();
assert(dictionary->length == 0);

View File

@ -1,6 +1,12 @@
#ifndef __DICTIONARY_TEST__
#define __DICTIONARY_TEST__
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include "libcproject.h"
void dictionary_test();
#endif

View File

@ -1,12 +1,5 @@
#include "linked_list_test.h"
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include "libcproject.h"
void linked_list_test() {
linked_list_initialization_test();
linked_list_add_in_head_test();

View File

@ -1,6 +1,13 @@
#ifndef __LINKED_LIST_TEST__
#define __LINKED_LIST_TEST__
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include "libcproject.h"
void linked_list_test();
void linked_list_initialization_test();

View File

@ -1,6 +1,7 @@
#include <stdio.h>
#include <stdlib.h>
#include "array_list_test.h"
#include "character_test.h"
#include "convert_test.h"
#include "dictionary_test.h"
@ -11,6 +12,7 @@
#include "string_test.h"
int main() {
array_list_test();
character_test();
convert_test();
dictionary_test();

View File

@ -1,9 +1,5 @@
#include "mathematics_test.h"
#include <assert.h>
#include "libcproject.h"
void mathematics_test() {
mathematics_absolute_value_test();
mathematics_pow_test();

View File

@ -1,6 +1,10 @@
#ifndef __MATHEMATICS_TEST__
#define __MATHEMATICS_TEST__
#include <assert.h>
#include "libcproject.h"
void mathematics_test();
void mathematics_absolute_value_test();

View File

@ -1,11 +1,5 @@
#include "queue_test.h"
#include <assert.h>
#include <stdint.h>
#include <stdlib.h>
#include "libcproject.h"
void queue_test() {
queue_initialization_test();
queue_push_test();

View File

@ -1,6 +1,12 @@
#ifndef __QUEUE_TEST__
#define __QUEUE_TEST__
#include <assert.h>
#include <stdint.h>
#include <stdlib.h>
#include "libcproject.h"
void queue_test();
void queue_initialization_test();

View File

@ -1,11 +1,5 @@
#include "stack_test.h"
#include <assert.h>
#include <stdint.h>
#include <stdlib.h>
#include "libcproject.h"
void stack_test() {
stack_initialization_test();
stack_push_test();

View File

@ -1,6 +1,12 @@
#ifndef __STACK_TEST__
#define __STACK_TEST__
#include <assert.h>
#include <stdint.h>
#include <stdlib.h>
#include "libcproject.h"
void stack_test();
void stack_initialization_test();

View File

@ -1,12 +1,5 @@
#include "string_test.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include "libcproject.h"
#include "test.h"
void string_test() {
string_get_length_test();
string_to_uppercase_test();

View File

@ -1,6 +1,13 @@
#ifndef __STRING_TEST__
#define __STRING_TEST__
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include "libcproject.h"
#include "test.h"
void string_test();
void string_get_length_test();

View File

@ -1,6 +1,4 @@
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include "test.h"
bool assert_string_equal(const char *actual, const char *expected) {
if (strcmp(expected, actual) != 0) {

View File

@ -2,6 +2,8 @@
#define __TEST__
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
bool assert_string_equal(const char *actual, const char *expected);

View File

@ -1,4 +1,4 @@
#ifndef __LIBCPROJECT_VERSION__
#define __LIBCPROJECT_VERSION__ "1.1.1"
#define __LIBCPROJECT_VERSION__ "1.2.0"
#endif