mirror of
https://github.com/pevans/erc-c.git
synced 2024-12-13 15:33:17 +00:00
First commit
This commit is contained in:
commit
237d5e3cb6
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
*.swp
|
||||
build
|
19
CMakeLists.txt
Normal file
19
CMakeLists.txt
Normal file
@ -0,0 +1,19 @@
|
||||
cmake_minimum_required(VERSION 3.9)
|
||||
|
||||
# it me
|
||||
project(emp)
|
||||
|
||||
include(sources.cmake)
|
||||
|
||||
foreach(src ${emp_sources})
|
||||
string(CONCAT relsrc src/ ${src})
|
||||
list(APPEND sources ${relsrc})
|
||||
endforeach(src)
|
||||
|
||||
# our header files
|
||||
include_directories(include /usr/local/include)
|
||||
|
||||
link_directories(/usr/local/lib)
|
||||
|
||||
# our bullshit
|
||||
add_executable(emp ${sources} src/main.c)
|
0
build/.gitkeep
Normal file
0
build/.gitkeep
Normal file
11
include/log.h
Normal file
11
include/log.h
Normal file
@ -0,0 +1,11 @@
|
||||
#ifndef _LOG_H_
|
||||
#define _LOG_H_
|
||||
|
||||
extern void log_write(int, const char *, ...);
|
||||
extern void log_close();
|
||||
extern void log_open();
|
||||
|
||||
#define log_critical(...) log_write(0, __VA_ARGS__)
|
||||
#define log_error(...) log_write(0, __VA_ARGS__)
|
||||
|
||||
#endif
|
18
include/vm_screen.h
Normal file
18
include/vm_screen.h
Normal file
@ -0,0 +1,18 @@
|
||||
#ifndef _VM_SCREEN_H_
|
||||
#define _VM_SCREEN_H_
|
||||
|
||||
typedef struct {
|
||||
int color_red;
|
||||
int color_green;
|
||||
int color_blue;
|
||||
int color_alpha;
|
||||
} vm_screen_context;
|
||||
|
||||
extern void vm_screen_draw_rect(vm_screen_context *, int, int, int, int);
|
||||
extern vm_screen_context *vm_screen_new_context();
|
||||
extern void vm_screen_set_color(vm_screen_context *, int, int, int, int);
|
||||
|
||||
#define vm_screen_draw_pixel(context, xpos, ypos) \
|
||||
vm_screen_draw_rect(context, xpos, ypos, 1, 1)
|
||||
|
||||
#endif
|
21
include/vm_segment.h
Normal file
21
include/vm_segment.h
Normal file
@ -0,0 +1,21 @@
|
||||
#ifndef _VM_SEGMENT_H_
|
||||
#define _VM_SEGMENT_H_
|
||||
|
||||
#define VM_SEGMENT_TABLE_MAX 16
|
||||
|
||||
typedef uint8_t vm_segment_byte;
|
||||
|
||||
typedef struct {
|
||||
size_t size;
|
||||
vm_segment_byte *memory;
|
||||
} vm_segment;
|
||||
|
||||
extern void vm_segment_copy(vm_segment *, vm_segment *, size_t, size_t, size_t);
|
||||
extern vm_segment *vm_segment_create(size_t);
|
||||
extern vm_segment_byte vm_segment_get(vm_segment *, size_t);
|
||||
extern void vm_segment_set(vm_segment *, size_t, vm_segment_byte);
|
||||
|
||||
#define vm_segment_bounds_check(segment, index) \
|
||||
(index == index % segment->size)
|
||||
|
||||
#endif
|
5
sources.cmake
Normal file
5
sources.cmake
Normal file
@ -0,0 +1,5 @@
|
||||
set(emp_sources
|
||||
log.c
|
||||
vm_screen.c
|
||||
vm_segment.c
|
||||
)
|
34
src/log.c
Normal file
34
src/log.c
Normal file
@ -0,0 +1,34 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
static FILE *log_stream = NULL;
|
||||
|
||||
void
|
||||
log_open()
|
||||
{
|
||||
log_stream = fopen("/tmp/emp.log", "w");
|
||||
if (log_stream == NULL) {
|
||||
perror("Couldn't open log file (/tmp/emp.log)");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
log_close()
|
||||
{
|
||||
if (log_stream != NULL) {
|
||||
fclose(log_stream);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
log_write(int level, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vfprintf(log_stream, fmt, ap);
|
||||
fprintf(log_stream, "\n");
|
||||
va_end(ap);
|
||||
}
|
27
src/main.c
Normal file
27
src/main.c
Normal file
@ -0,0 +1,27 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "log.h"
|
||||
|
||||
static void
|
||||
init()
|
||||
{
|
||||
log_open();
|
||||
}
|
||||
|
||||
static void
|
||||
finish()
|
||||
{
|
||||
log_close();
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
init();
|
||||
|
||||
// When we exit, we want to wrap up a few loose ends.
|
||||
atexit(finish);
|
||||
|
||||
printf("Hello, world\n");
|
||||
}
|
42
src/vm_screen.c
Normal file
42
src/vm_screen.c
Normal file
@ -0,0 +1,42 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "log.h"
|
||||
#include "vm_screen.h"
|
||||
|
||||
vm_screen_context *
|
||||
vm_screen_new_context()
|
||||
{
|
||||
vm_screen_context *context;
|
||||
|
||||
context = (vm_screen_context *)malloc(sizeof(vm_screen_context));
|
||||
if (context == NULL) {
|
||||
log_critical("Failed to allocate vm_screen_context");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
vm_screen_set_color(context, 0, 0, 0, 0);
|
||||
return context;
|
||||
}
|
||||
|
||||
void
|
||||
vm_screen_set_color(vm_screen_context *context,
|
||||
int red,
|
||||
int green,
|
||||
int blue,
|
||||
int alpha)
|
||||
{
|
||||
context->color_red = red;
|
||||
context->color_green = green;
|
||||
context->color_blue = blue;
|
||||
context->color_alpha = alpha;
|
||||
}
|
||||
|
||||
void
|
||||
vm_screen_draw_rect(vm_screen_context *context,
|
||||
int xpos,
|
||||
int ypos,
|
||||
int xsize,
|
||||
int ysize)
|
||||
{
|
||||
// FIXME: NOOP
|
||||
}
|
104
src/vm_segment.c
Normal file
104
src/vm_segment.c
Normal file
@ -0,0 +1,104 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "log.h"
|
||||
#include "vm_segment.h"
|
||||
|
||||
static vm_segment *seg_table[VM_SEGMENT_TABLE_MAX];
|
||||
static unsigned int seg_index = 0;
|
||||
|
||||
vm_segment *
|
||||
vm_segment_create(size_t size)
|
||||
{
|
||||
vm_segment *seg;
|
||||
|
||||
// Block us from attempting to allocate any memory beyond the
|
||||
// maximum defined blocks.
|
||||
if (seg_index >= VM_SEGMENT_TABLE_MAX) {
|
||||
log_error("Attempted to allocate more segments than we allow");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Allocate memory for the current memory segment.
|
||||
seg = seg_table[seg_index] =
|
||||
malloc(sizeof(vm_segment) * size);
|
||||
|
||||
// Ack! We couldn't get the memory we wanted. Let's bail.
|
||||
if (seg == NULL) {
|
||||
log_critical("Couldn't allocate enough space for vm_segment");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// We want to increment the current segment index only after a
|
||||
// _successful_ allocation.
|
||||
seg_index++;
|
||||
|
||||
return seg;
|
||||
}
|
||||
|
||||
void
|
||||
vm_segment_set(vm_segment *segment, size_t index, vm_segment_byte value)
|
||||
{
|
||||
// Some bounds checking.
|
||||
if (!vm_segment_bounds_check(segment, index)) {
|
||||
log_critical(
|
||||
"Attempt to set segment index (%d) greater than bounds (%d)",
|
||||
index,
|
||||
segment->size);
|
||||
|
||||
// We prefer to exit in this scenario, rather than try to
|
||||
// "handle" it with an overflow, because we would rather a crash
|
||||
// over ill-defined behavior.
|
||||
exit(1);
|
||||
}
|
||||
|
||||
segment->memory[index] = value;
|
||||
}
|
||||
|
||||
vm_segment_byte
|
||||
vm_segment_get(vm_segment *segment, size_t index)
|
||||
{
|
||||
if (!vm_segment_bounds_check(segment, index)) {
|
||||
log_critical(
|
||||
"Attempt to set segment index (%d) greater than bounds (%d)",
|
||||
index,
|
||||
segment->size);
|
||||
|
||||
// See vm_segment_set() for a justification of this behavior.
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return segment->memory[index];
|
||||
}
|
||||
|
||||
void
|
||||
vm_segment_copy(vm_segment *src,
|
||||
vm_segment *dest,
|
||||
size_t src_index,
|
||||
size_t dest_index,
|
||||
size_t length)
|
||||
{
|
||||
if (src_index + length >= src->size) {
|
||||
log_critical(
|
||||
"Attempt to copy beyond bounds of vm_segment (%d + %d >= %d)",
|
||||
src_index,
|
||||
length,
|
||||
src->size);
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (dest_index + length >= dest->size) {
|
||||
log_critical(
|
||||
"Attempt to copy beyond bounds of vm_segment (%d + %d >= %d)",
|
||||
dest_index,
|
||||
length,
|
||||
dest->size);
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memcpy(dest->memory + dest_index,
|
||||
src->memory + src_index,
|
||||
length * sizeof(src->memory[src_index]));
|
||||
}
|
18
tests/CMakeLists.txt
Normal file
18
tests/CMakeLists.txt
Normal file
@ -0,0 +1,18 @@
|
||||
cmake_minimum_required(VERSION 3.9)
|
||||
|
||||
project(emp-test)
|
||||
|
||||
include_directories(../include /usr/local/include)
|
||||
|
||||
link_directories(/usr/local/lib)
|
||||
|
||||
include(../sources.cmake)
|
||||
|
||||
foreach(src ${emp_sources})
|
||||
string(CONCAT relsrc ../src/ ${src})
|
||||
list(APPEND sources ${relsrc})
|
||||
endforeach(src)
|
||||
|
||||
add_executable(emp-test ${sources} ./main.c)
|
||||
|
||||
target_link_libraries(emp-test criterion)
|
0
tests/build/.gitkeep
Normal file
0
tests/build/.gitkeep
Normal file
5
tests/main.c
Normal file
5
tests/main.c
Normal file
@ -0,0 +1,5 @@
|
||||
#include <criterion/criterion.h>
|
||||
|
||||
Test(simple, test) {
|
||||
cr_assert(0, "Hello!");
|
||||
}
|
Loading…
Reference in New Issue
Block a user