Compare commits
3 Commits
dd80cb179e
...
dcbd9555d5
Author | SHA1 | Date |
---|---|---|
Eric-Paul Ickhorn | dcbd9555d5 | |
Eric-Paul Ickhorn | eab3989878 | |
Eric-Paul Ickhorn | 8b65c5ddb3 |
|
@ -0,0 +1,2 @@
|
||||||
|
core
|
||||||
|
platform
|
84
build.bash
84
build.bash
|
@ -1,34 +1,71 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Get the absolute repository root path and go there
|
||||||
|
cd $(dirname "$(pwd)/$0")
|
||||||
|
REPOSITORY_FOLDER=$(pwd)
|
||||||
|
|
||||||
|
|
||||||
|
# Configuration Values start here
|
||||||
|
|
||||||
PROJECT_NAME="librr"
|
PROJECT_NAME="librr"
|
||||||
PROJECT_ROOT=`pwd`
|
|
||||||
GCC_ARGUMENTS="-std=c11 -Wall"
|
GCC_ARGUMENTS="-std=c11 -Wall"
|
||||||
|
|
||||||
MODULES=(
|
MAIN_OBJECTS_FOLDER="$REPOSITORY_FOLDER/.build/objects"
|
||||||
"core"
|
|
||||||
"platform"
|
# End of configuration values
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
|
# Constants not meant for configuration
|
||||||
|
|
||||||
|
CONFIG_FILE_INCLUDE_PATHS="build-config/include_paths.txt"
|
||||||
|
MODULE_LIST_PATH="build-config/modules.txt"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function get_include_path_configuration {
|
||||||
|
MODULE_NAME=$1
|
||||||
|
|
||||||
|
INCLUDE_CONFIG_PATH="$REPOSITORY_FOLDER/$MODULE_NAME/$CONFIG_FILE_INCLUDE_PATHS"
|
||||||
|
INCLUDE_STATEMENTS="-I $REPOSITORY_FOLDER/$MODULE_NAME/inc-c/ -I $REPOSITORY_FOLDER/$MODULE_NAME/exports/"
|
||||||
|
if [[ ! -f $INCLUDE_CONFIG_PATH ]]
|
||||||
|
then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
for LINE in $(cat $INCLUDE_CONFIG_PATH)
|
||||||
|
do
|
||||||
|
INCLUDE_STATEMENTS="$INCLUDE_STATEMENTS -I $REPOSITORY_FOLDER/$LINE"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
# Arguments:
|
# Arguments:
|
||||||
# 1) Path to the module
|
# 1) Module name / folder name in project root (May not include slashes)
|
||||||
# 2) Include Statements
|
function compile_single_module() {
|
||||||
function compile_folder() {
|
MODULE_NAME=$1
|
||||||
|
|
||||||
OBJECTS_FOLDER="$PROJECT_ROOT/.build/objects/$1"
|
ENTRY_WORKING_DIR=$(pwd)
|
||||||
mkdir -p $OBJECTS_FOLDER
|
printf "\n\n\n"
|
||||||
cd $PROJECT_ROOT/$1
|
echo "|================> Module Separator <================|"
|
||||||
|
echo "> Name: $MODULE_NAME "
|
||||||
|
echo "> Path: $REPOSITORY_FOLDER/$MODULE_NAME"
|
||||||
|
echo " "
|
||||||
|
get_include_path_configuration $MODULE_NAME
|
||||||
|
|
||||||
|
MODULE_OBJECTS_FOLDER="$MAIN_OBJECTS_FOLDER/$MODULE_NAME"
|
||||||
|
mkdir -p $MODULE_OBJECTS_FOLDER
|
||||||
|
cd $REPOSITORY_FOLDER/$1
|
||||||
|
|
||||||
cd src-c/
|
cd src-c/
|
||||||
for SOURCE_FILE in $(find .)
|
for SOURCE_FILE in $(find . -mindepth 1)
|
||||||
do
|
do
|
||||||
# Create every folder except of the source root folder (src-c/).
|
# Create all subfolders of this module's source folder
|
||||||
if [[ $SOURCE_FILE != "." ]] then
|
|
||||||
if [[ -d $SOURCE_FILE ]] then
|
if [[ -d $SOURCE_FILE ]] then
|
||||||
mkdir $SOURCE_FILE
|
mkdir -p $MODULE_OBJECTS_FOLDER/$SOURCE_FILE
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
fi
|
|
||||||
|
|
||||||
|
# If this is not a regular file, quietly ignore it.
|
||||||
if [[ ! -f $SOURCE_FILE ]] then
|
if [[ ! -f $SOURCE_FILE ]] then
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
|
@ -36,17 +73,20 @@ function compile_folder() {
|
||||||
# Cut out the ./ at the front of the path
|
# Cut out the ./ at the front of the path
|
||||||
SOURCE_FILE=$(echo $SOURCE_FILE | cut -c 3-)
|
SOURCE_FILE=$(echo $SOURCE_FILE | cut -c 3-)
|
||||||
|
|
||||||
echo "==== Building '$SOURCE_FILE' ===="
|
echo "==> File: $SOURCE_FILE"
|
||||||
gcc -c $GCC_ARGUMENTS -o $OBJECTS_FOLDER/$SOURCE_FILE.o $SOURCE_FILE $2
|
gcc -c $GCC_ARGUMENTS -o $MODULE_OBJECTS_FOLDER/$SOURCE_FILE.o $SOURCE_FILE $INCLUDE_STATEMENTS
|
||||||
done
|
done
|
||||||
|
|
||||||
ar -rvs $PROJECT_ROOT/.build/$PROJECT_NAME-$1.a $OBJECTS_FOLDER/*.o
|
OBJECT_FILES=$(find $MODULE_OBJECTS_FOLDER -mindepth 1 -type f)
|
||||||
cd $PROJECT_ROOT
|
ar -rvs $REPOSITORY_FOLDER/.build/$PROJECT_NAME-$MODULE_NAME.a $OBJECT_FILES
|
||||||
|
cd $ENTRY_WORKING_DIR
|
||||||
}
|
}
|
||||||
|
|
||||||
function compile_all_modules() {
|
function compile_all_modules() {
|
||||||
compile_folder "core" "-I $PROJECT_ROOT/core/exports/"
|
for MODULE_PATH in $(cat $MODULE_LIST_PATH)
|
||||||
compile_folder "platform" "-I $PROJECT_ROOT/core/exports/ -I $PROJECT_ROOT/platform/exports/"
|
do
|
||||||
|
compile_single_module $MODULE_PATH
|
||||||
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
case $1 in
|
case $1 in
|
||||||
|
|
|
@ -4,15 +4,6 @@
|
||||||
|
|
||||||
#include <librr/types.h>
|
#include <librr/types.h>
|
||||||
|
|
||||||
typedef struct rr_arena rr_arena_s;
|
|
||||||
|
|
||||||
struct rr_arena
|
|
||||||
{
|
|
||||||
usz_t capacity;
|
|
||||||
usz_t offset;
|
|
||||||
char *allocation;
|
|
||||||
};
|
|
||||||
|
|
||||||
/// @brief Tests if two memory regions overlap partially or completely.
|
/// @brief Tests if two memory regions overlap partially or completely.
|
||||||
/// @param block1 Block to check for overlapping with block2.
|
/// @param block1 Block to check for overlapping with block2.
|
||||||
// If the address of this block is higher than that of block2, the blocks will be swapped internally.
|
// If the address of this block is higher than that of block2, the blocks will be swapped internally.
|
||||||
|
@ -20,7 +11,7 @@ struct rr_arena
|
||||||
/// @param block2 The second block to check for overlapping.
|
/// @param block2 The second block to check for overlapping.
|
||||||
/// @param length2 The length of the second block.
|
/// @param length2 The length of the second block.
|
||||||
/// @return Whether the two blocks overlap.
|
/// @return Whether the two blocks overlap.
|
||||||
bool_t rr_mem_overlap(void *block1, usz_t length1, void *block2, usz_t length2);
|
bool_t rr_mem_overlap(const void *block1, usz_t length1, const void *block2, usz_t length2);
|
||||||
|
|
||||||
/// @brief Checks if two memory blocks contain the equal data.
|
/// @brief Checks if two memory blocks contain the equal data.
|
||||||
/// @param block1 Address of the data to be checked for equality with 'block2'
|
/// @param block1 Address of the data to be checked for equality with 'block2'
|
||||||
|
@ -28,7 +19,7 @@ bool_t rr_mem_overlap(void *block1, usz_t length1, void *block2, usz_t length2);
|
||||||
/// this should be the correct data to be checked against.
|
/// this should be the correct data to be checked against.
|
||||||
/// @param count How many bytes will be checked.
|
/// @param count How many bytes will be checked.
|
||||||
/// @return Whether the two memory regions are equal.
|
/// @return Whether the two memory regions are equal.
|
||||||
bool_t rr_memequ(void *block1, void *block2, usz_t count);
|
bool_t rr_memequ(const void *block1, const void *block2, usz_t count);
|
||||||
|
|
||||||
/// @brief Sets all bytes in a memory region all to one byte.
|
/// @brief Sets all bytes in a memory region all to one byte.
|
||||||
/// @param destination Address to the memory region to fill with one byte.
|
/// @param destination Address to the memory region to fill with one byte.
|
||||||
|
@ -43,19 +34,13 @@ void rr_memset(void *destination, usz_t count, u8_t value);
|
||||||
/// @param sequence Sequence of bytes which will be written to destination.
|
/// @param sequence Sequence of bytes which will be written to destination.
|
||||||
/// @param len_sequence Length of 'sequence'.
|
/// @param len_sequence Length of 'sequence'.
|
||||||
/// @return The number of attempted or partial repetitions which have been performed.
|
/// @return The number of attempted or partial repetitions which have been performed.
|
||||||
usz_t rr_memrep(void *destination, usz_t num_bytes, void *sequence, usz_t len_sequence);
|
usz_t rr_memrep(void *destination, usz_t num_bytes, const void *sequence, usz_t len_sequence);
|
||||||
|
|
||||||
/// @brief Copies a given number of bytes from a source memory region to a destination memory region.
|
/// @brief Copies a given number of bytes from a source memory region to a destination memory region.
|
||||||
/// @attention The source and the destination cannot overlap!
|
/// @attention The source and the destination cannot overlap!
|
||||||
/// @param destination Memory region to which to write.
|
/// @param destination Memory region to which to write.
|
||||||
/// @param source Memory region from which to read the bytes to write into the destination.
|
/// @param source Memory region from which to read the bytes to write into the destination.
|
||||||
/// @param num_bytes Number of bytes to copy from the source to the destination.
|
/// @param num_bytes Number of bytes to copy from the source to the destination.
|
||||||
void rr_memcopy(void *destination, void *source, usz_t num_bytes);
|
void rr_memcopy(void *destination, const void *source, usz_t num_bytes);
|
||||||
|
|
||||||
rr_arena_s rr_new_arena(usz_t capacity);
|
|
||||||
void rr_delete_arena(rr_arena_s *arena);
|
|
||||||
|
|
||||||
void * rr_arena_alloc(rr_arena_s *arena, usz_t length);
|
|
||||||
char * rr_arena_clone_string(rr_arena_s *arena, char *string);
|
|
||||||
|
|
||||||
#endif // RR_MEMORY_H
|
#endif // RR_MEMORY_H
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
#include <librr/memory.h>
|
#include <librr/memory.h>
|
||||||
#include <librr/strutil.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
bool_t rr_mem_overlap(void *block1, usz_t length1, void *block2, usz_t length2)
|
bool_t rr_mem_overlap(const void *block1, usz_t length1, const void *block2, usz_t length2)
|
||||||
{
|
{
|
||||||
// Make block1 always be before block2
|
// Make block1 always be before block2
|
||||||
if(block1 > block2)
|
if(block1 > block2)
|
||||||
{
|
{
|
||||||
void *block_backup = block2;
|
const void *block_backup = block2;
|
||||||
usz_t length_backup = length2;
|
usz_t length_backup = length2;
|
||||||
block2 = block1;
|
block2 = block1;
|
||||||
length2 = length1;
|
length2 = length1;
|
||||||
|
@ -27,10 +25,10 @@ bool_t rr_mem_overlap(void *block1, usz_t length1, void *block2, usz_t length2)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool_t rr_memequ(void *block1, void *block2, usz_t count)
|
bool_t rr_memequ(const void *block1, const void *block2, usz_t count)
|
||||||
{
|
{
|
||||||
u8_t *block1_8 = block1;
|
const u8_t *block1_8 = block1;
|
||||||
u8_t *block2_8 = block2;
|
const u8_t *block2_8 = block2;
|
||||||
for(usz_t index = 0; index < count; ++index)
|
for(usz_t index = 0; index < count; ++index)
|
||||||
if(block1_8[index] != block2_8[index]) return FALSE;
|
if(block1_8[index] != block2_8[index]) return FALSE;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -43,62 +41,22 @@ void rr_memset(void *destination, usz_t count, u8_t value)
|
||||||
destination_8[index] = value;
|
destination_8[index] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
usz_t rr_memrep(void *destination, usz_t num_bytes, void *sequence, usz_t len_sequence)
|
usz_t rr_memrep(void *destination, usz_t num_bytes, const void *sequence, usz_t len_sequence)
|
||||||
{
|
{
|
||||||
if(rr_mem_overlap(destination, num_bytes, sequence, len_sequence)) return 0;
|
if(rr_mem_overlap(destination, num_bytes, sequence, len_sequence)) return 0;
|
||||||
u8_t *destination_8 = destination;
|
u8_t *destination_8 = destination;
|
||||||
u8_t *sequence_8 = sequence;
|
const u8_t *sequence_8 = sequence;
|
||||||
for(usz_t index = 0; index < num_bytes; ++index)
|
for(usz_t index = 0; index < num_bytes; ++index)
|
||||||
destination_8[index] = sequence_8[index % len_sequence];
|
destination_8[index] = sequence_8[index % len_sequence];
|
||||||
return (num_bytes / len_sequence) // How many full repetitions are performed
|
return (num_bytes / len_sequence) // How many full repetitions are performed
|
||||||
+ ((num_bytes % len_sequence) != 0); // One more if a partial repetiton is done
|
+ ((num_bytes % len_sequence) != 0); // One more if a partial repetiton is done
|
||||||
}
|
}
|
||||||
|
|
||||||
void rr_memcopy(void *destination, void *source, usz_t num_bytes)
|
void rr_memcopy(void *destination, const void *source, usz_t num_bytes)
|
||||||
{
|
{
|
||||||
if(rr_mem_overlap(destination, num_bytes, source, num_bytes)) return;
|
if(rr_mem_overlap(destination, num_bytes, source, num_bytes)) return;
|
||||||
u8_t *destination_8 = destination;
|
u8_t *destination_8 = destination;
|
||||||
u8_t *source_8 = source;
|
const u8_t *source_8 = source;
|
||||||
for(usz_t index = 0; index < num_bytes; ++index)
|
for(usz_t index = 0; index < num_bytes; ++index)
|
||||||
destination_8[index] = source_8[index];
|
destination_8[index] = source_8[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
rr_arena_s rr_new_arena(usz_t capacity)
|
|
||||||
{
|
|
||||||
rr_arena_s arena;
|
|
||||||
arena.capacity = capacity;
|
|
||||||
arena.offset = 0;
|
|
||||||
arena.allocation = malloc(capacity);
|
|
||||||
return arena;
|
|
||||||
}
|
|
||||||
|
|
||||||
void rr_delete_arena(rr_arena_s *arena)
|
|
||||||
{
|
|
||||||
if(arena->allocation == NULL) return;
|
|
||||||
free(arena->allocation);
|
|
||||||
arena->allocation = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void * rr_arena_alloc(rr_arena_s *arena, usz_t length)
|
|
||||||
{
|
|
||||||
if((arena->offset + length) > arena->capacity)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
void *block = &arena->allocation[arena->offset];
|
|
||||||
arena->offset += length;
|
|
||||||
return block;
|
|
||||||
}
|
|
||||||
|
|
||||||
char * rr_arena_clone_string(rr_arena_s *arena, char *string)
|
|
||||||
{
|
|
||||||
usz_t len_string = rr_measure_string(string);
|
|
||||||
char *cloned_string = rr_arena_alloc(arena, len_string+1);
|
|
||||||
rr_memcopy(cloned_string, string, len_string);
|
|
||||||
cloned_string[len_string] = 0x00;
|
|
||||||
|
|
||||||
return cloned_string;
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
core/exports/
|
|
@ -0,0 +1,22 @@
|
||||||
|
|
||||||
|
#ifndef RR_ARENA_ALLOCATOR_H
|
||||||
|
#define RR_ARENA_ALLOCATOR_H
|
||||||
|
|
||||||
|
#include <librr/types.h>
|
||||||
|
|
||||||
|
typedef struct rr_arena rr_arena_s;
|
||||||
|
|
||||||
|
struct rr_arena
|
||||||
|
{
|
||||||
|
usz_t capacity;
|
||||||
|
usz_t offset;
|
||||||
|
char *allocation;
|
||||||
|
};
|
||||||
|
|
||||||
|
rr_arena_s rr_new_arena(usz_t capacity);
|
||||||
|
void rr_delete_arena(rr_arena_s *arena);
|
||||||
|
|
||||||
|
void * rr_arena_alloc(rr_arena_s *arena, usz_t length);
|
||||||
|
char * rr_arena_clone_string(rr_arena_s *arena, const char *string);
|
||||||
|
|
||||||
|
#endif // RR_ARENA_ALLOCATOR_H
|
|
@ -0,0 +1,41 @@
|
||||||
|
#include <alloc/arena.h>
|
||||||
|
|
||||||
|
rr_arena_s rr_new_arena(usz_t capacity)
|
||||||
|
{
|
||||||
|
rr_arena_s arena;
|
||||||
|
arena.capacity = capacity;
|
||||||
|
arena.offset = 0;
|
||||||
|
arena.allocation = malloc(capacity);
|
||||||
|
return arena;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rr_delete_arena(rr_arena_s *arena)
|
||||||
|
{
|
||||||
|
if(arena->allocation == NULL) return;
|
||||||
|
free(arena->allocation);
|
||||||
|
arena->allocation = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void * rr_arena_alloc(rr_arena_s *arena, usz_t length)
|
||||||
|
{
|
||||||
|
if((arena->offset + length) > arena->capacity)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
void *block = &arena->allocation[arena->offset];
|
||||||
|
arena->offset += length;
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
|
||||||
|
char * rr_arena_clone_string(rr_arena_s *arena, char *string)
|
||||||
|
{
|
||||||
|
usz_t len_string = rr_measure_string(string);
|
||||||
|
char *cloned_string = rr_arena_alloc(arena, len_string+1);
|
||||||
|
if(cloned_string == NULL)
|
||||||
|
return NULL;
|
||||||
|
rr_memcopy(cloned_string, string, len_string);
|
||||||
|
cloned_string[len_string] = 0x00;
|
||||||
|
|
||||||
|
return cloned_string;
|
||||||
|
}
|
Loading…
Reference in New Issue