Compare commits

...

3 Commits

7 changed files with 144 additions and 95 deletions

2
build-config/modules.txt Normal file
View File

@ -0,0 +1,2 @@
core
platform

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -0,0 +1 @@
core/exports/

View File

@ -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

View File

@ -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;
}