Testing framework. Shader creation function. More dynstring functions
This commit is contained in:
39
meson.build
39
meson.build
@@ -1,20 +1,30 @@
|
|||||||
project('scuffedcraft', 'c')
|
project('scuffedcraft', 'c')
|
||||||
|
|
||||||
|
cc = meson.get_compiler('c')
|
||||||
|
vendor_dir_abs = meson.current_source_dir() + '/vendor/'
|
||||||
|
|
||||||
cargs = [
|
cargs = [
|
||||||
'-std=c99',
|
'-std=c99',
|
||||||
'-Og',
|
'-Og',
|
||||||
'-g',
|
'-g',
|
||||||
'-DBOUNDS_CHECK'
|
'-DBOUNDS_CHECK',
|
||||||
|
'-DSHADERS_PATH="../src/shaders/"'
|
||||||
]
|
]
|
||||||
|
|
||||||
dependencies = []
|
dependencies = [
|
||||||
|
]
|
||||||
|
|
||||||
link_args = []
|
link_args = []
|
||||||
|
test_link_args = []
|
||||||
|
|
||||||
include_dirs = [
|
include_dirs = [
|
||||||
'vendor/',
|
'vendor/',
|
||||||
'src/'
|
'src/'
|
||||||
]
|
]
|
||||||
|
test_include_dirs = [
|
||||||
|
'src/',
|
||||||
|
'vendor/'
|
||||||
|
]
|
||||||
|
|
||||||
if host_machine.system() == 'linux'
|
if host_machine.system() == 'linux'
|
||||||
dependencies += [
|
dependencies += [
|
||||||
@@ -24,6 +34,9 @@ elif host_machine.system() == 'windows'
|
|||||||
link_args += [
|
link_args += [
|
||||||
'-lopengl32'
|
'-lopengl32'
|
||||||
]
|
]
|
||||||
|
test_link_args += [
|
||||||
|
'-lwinpthread'
|
||||||
|
]
|
||||||
|
|
||||||
cargs += [
|
cargs += [
|
||||||
'-DUNICODE',
|
'-DUNICODE',
|
||||||
@@ -31,7 +44,7 @@ elif host_machine.system() == 'windows'
|
|||||||
'-municode'
|
'-municode'
|
||||||
]
|
]
|
||||||
|
|
||||||
if build_machine.system() == 'linux'
|
if meson.is_cross_build() and build_machine.system() == 'linux'
|
||||||
link_args += [
|
link_args += [
|
||||||
'-Lvendor/wine/',
|
'-Lvendor/wine/',
|
||||||
]
|
]
|
||||||
@@ -46,8 +59,26 @@ executable(
|
|||||||
'src/DynString.c',
|
'src/DynString.c',
|
||||||
'src/log.c',
|
'src/log.c',
|
||||||
'src/main.c',
|
'src/main.c',
|
||||||
|
'src/shader.c',
|
||||||
c_args: cargs,
|
c_args: cargs,
|
||||||
dependencies: dependencies,
|
dependencies: dependencies,
|
||||||
link_args: link_args,
|
link_args: link_args,
|
||||||
include_directories: include_directories(include_dirs)
|
include_directories: include_directories(include_dirs),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
executable(
|
||||||
|
'tests',
|
||||||
|
'tests/main.c',
|
||||||
|
'src/DynString.c',
|
||||||
|
'src/log.c',
|
||||||
|
c_args: cargs,
|
||||||
|
include_directories: include_directories(test_include_dirs),
|
||||||
|
link_args: test_link_args,
|
||||||
|
dependencies: [
|
||||||
|
cc.find_library(
|
||||||
|
'libcmocka',
|
||||||
|
dirs: [ vendor_dir_abs + 'cmocka/' ]
|
||||||
|
)
|
||||||
|
]
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
[binaries]
|
[binaries]
|
||||||
c = 'x86_64-w64-mingw32-clang'
|
c = 'x86_64-w64-mingw32-clang'
|
||||||
|
strip = 'x86_64-w64-mingw32-strip'
|
||||||
exe_wrapper = 'wine'
|
exe_wrapper = 'wine'
|
||||||
|
|
||||||
[host_machine]
|
[host_machine]
|
||||||
|
|||||||
@@ -1,19 +1,22 @@
|
|||||||
|
#include <errno.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
#include "DynString.h"
|
#include "DynString.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
DynString DynString_alloc(const char* str, const size_t len) {
|
DynString DynString_alloc(const char* str, const size_t len) {
|
||||||
DynString dstr = {
|
DynString dstr = {
|
||||||
.data = (char*) malloc(sizeof(char) * len),
|
.data = (char*) malloc(sizeof(char) * len + 1),
|
||||||
.len = len
|
.len = len,
|
||||||
|
.capacity = len
|
||||||
};
|
};
|
||||||
if (dstr.data == NULL) {
|
if (dstr.data == NULL) {
|
||||||
LOG_FATAL("Ran out of memory");
|
LOG_FATAL("Ran out of memory");
|
||||||
}
|
}
|
||||||
dstr.data = memcpy(dstr.data, str, len);
|
dstr.data = memcpy(dstr.data, str, len);
|
||||||
|
dstr.data[len] = '\0';
|
||||||
|
|
||||||
return dstr;
|
return dstr;
|
||||||
}
|
}
|
||||||
@@ -21,14 +24,20 @@ DynString DynString_alloc(const char* str, const size_t len) {
|
|||||||
void DynString_free(DynString* dstr) {
|
void DynString_free(DynString* dstr) {
|
||||||
if (dstr->data != NULL) {
|
if (dstr->data != NULL) {
|
||||||
free(dstr->data);
|
free(dstr->data);
|
||||||
|
dstr->data = NULL;
|
||||||
}
|
}
|
||||||
dstr->len = 0;
|
dstr->len = 0;
|
||||||
|
dstr->capacity = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DynString_is_null(const DynString* dstr) {
|
bool DynString_is_null(const DynString* dstr) {
|
||||||
return dstr->data == NULL;
|
return dstr->data == NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* DynString_c_str(const DynString* dstr) {
|
||||||
|
return dstr->data;
|
||||||
|
}
|
||||||
|
|
||||||
bool DynString_equal(const DynString* s1, const DynString* s2) {
|
bool DynString_equal(const DynString* s1, const DynString* s2) {
|
||||||
if (s1->len != s2->len) {
|
if (s1->len != s2->len) {
|
||||||
return false;
|
return false;
|
||||||
@@ -47,3 +56,41 @@ bool DynString_equal(const DynString* s1, const DynString* s2) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DynString_reserve(DynString* dstr, const size_t new_capacity) {
|
||||||
|
if (dstr->capacity >= new_capacity) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
dstr->data = realloc(dstr->data, new_capacity);
|
||||||
|
if (errno != 0) {
|
||||||
|
LOG_FATAL("Ran out of memory");
|
||||||
|
}
|
||||||
|
dstr->capacity = new_capacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DynString_concat_c_str(
|
||||||
|
DynString* dstr,
|
||||||
|
const char* str,
|
||||||
|
const size_t str_len
|
||||||
|
) {
|
||||||
|
const size_t new_len = dstr->len + str_len;
|
||||||
|
if (new_len > dstr->capacity) {
|
||||||
|
DynString_reserve(dstr, new_len + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
strncpy(dstr->data + dstr->len, str, str_len);
|
||||||
|
dstr->data[new_len] = '\0';
|
||||||
|
dstr->len = new_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
DynString DynString_alloc_concat_c_strs(
|
||||||
|
const char* s1,
|
||||||
|
const size_t s1_len,
|
||||||
|
const char* s2,
|
||||||
|
const size_t s2_len
|
||||||
|
) {
|
||||||
|
DynString dstr = DynString_alloc(s1, s1_len);
|
||||||
|
DynString_concat_c_str(&dstr, s2, s2_len);
|
||||||
|
return dstr;
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,11 +9,24 @@
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
char* data;
|
char* data;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
size_t capacity;
|
||||||
} DynString;
|
} DynString;
|
||||||
|
|
||||||
DynString DynString_alloc(const char* str, const size_t len);
|
DynString DynString_alloc(const char* str, const size_t len);
|
||||||
void DynString_free(DynString* dstr);
|
void DynString_free(DynString* dstr);
|
||||||
bool DynString_is_null(const DynString* dstr);
|
bool DynString_is_null(const DynString* dstr);
|
||||||
|
const char* DynString_c_str(const DynString* dstr);
|
||||||
bool DynString_equal(const DynString* s1, const DynString* s2);
|
bool DynString_equal(const DynString* s1, const DynString* s2);
|
||||||
|
void DynString_concat_c_str(
|
||||||
|
DynString* dstr,
|
||||||
|
const char* str,
|
||||||
|
const size_t str_len
|
||||||
|
);
|
||||||
|
DynString DynString_alloc_concat_c_strs(
|
||||||
|
const char* s1,
|
||||||
|
const size_t s1_len,
|
||||||
|
const char* s2,
|
||||||
|
const size_t s2_len
|
||||||
|
);
|
||||||
|
|
||||||
#endif // DYN_STRING_H_
|
#endif // DYN_STRING_H_
|
||||||
|
|||||||
70
src/main.c
70
src/main.c
@@ -15,6 +15,7 @@
|
|||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "pltf/gl_funcs.h"
|
#include "pltf/gl_funcs.h"
|
||||||
#include "pltf/pltf.h"
|
#include "pltf/pltf.h"
|
||||||
|
#include "shader.h"
|
||||||
|
|
||||||
// int _main() {
|
// int _main() {
|
||||||
// return 0;
|
// return 0;
|
||||||
@@ -396,69 +397,10 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pCmdLine,
|
|||||||
|
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
|
|
||||||
// clang-format off
|
const unsigned int shader = shader_create(
|
||||||
const char* vertex_shader_src =
|
"shader.vert",
|
||||||
"#version 460 core\n"
|
"shader.frag"
|
||||||
"layout (location = 0) in vec3 a_pos;\n"
|
);
|
||||||
"void main() {\n"
|
|
||||||
" gl_Position = vec4(a_pos, 1.0);\n"
|
|
||||||
"}\n"
|
|
||||||
;
|
|
||||||
|
|
||||||
const char* fragment_shader_src =
|
|
||||||
"#version 460 core\n"
|
|
||||||
"out vec4 frag_color;\n"
|
|
||||||
"void main() {\n"
|
|
||||||
" frag_color = vec4(0.0, 0.0, 0.0, 1.0);\n"
|
|
||||||
"}\n"
|
|
||||||
;
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
const unsigned int vert_shader = glCreateShader(GL_VERTEX_SHADER);
|
|
||||||
{
|
|
||||||
const int len = strlen(vertex_shader_src);
|
|
||||||
glShaderSource(vert_shader, 1, &vertex_shader_src, &len);
|
|
||||||
glCompileShader(vert_shader);
|
|
||||||
int compile_status = 0;
|
|
||||||
glGetShaderiv(vert_shader, GL_COMPILE_STATUS, &compile_status);
|
|
||||||
if (compile_status != GL_TRUE) {
|
|
||||||
int info_log_len = 0;
|
|
||||||
glGetShaderiv(vert_shader, GL_INFO_LOG_LENGTH, &info_log_len);
|
|
||||||
char* err_str = (char*) malloc(sizeof(char) * info_log_len);
|
|
||||||
glGetShaderInfoLog(vert_shader, info_log_len - 1, NULL, err_str);
|
|
||||||
LOG_FATALF("Failed to compile vertex shader: %s", err_str);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const unsigned int frag_shader = glCreateShader(GL_FRAGMENT_SHADER);
|
|
||||||
{
|
|
||||||
const int len = strlen(fragment_shader_src);
|
|
||||||
glShaderSource(frag_shader, 1, &fragment_shader_src, &len);
|
|
||||||
glCompileShader(frag_shader);
|
|
||||||
int compile_status = 0;
|
|
||||||
glGetShaderiv(frag_shader, GL_COMPILE_STATUS, &compile_status);
|
|
||||||
if (compile_status != GL_TRUE) {
|
|
||||||
int info_log_len = 0;
|
|
||||||
glGetShaderiv(frag_shader, GL_INFO_LOG_LENGTH, &info_log_len);
|
|
||||||
char* err_str = (char*) malloc(sizeof(char) * info_log_len);
|
|
||||||
glGetShaderInfoLog(frag_shader, info_log_len - 1, NULL, err_str);
|
|
||||||
LOG_FATALF("Failed to compile fragment shader: %s", err_str);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const unsigned int shader_program = glCreateProgram();
|
|
||||||
{
|
|
||||||
|
|
||||||
glAttachShader(shader_program, vert_shader);
|
|
||||||
glAttachShader(shader_program, frag_shader);
|
|
||||||
glLinkProgram(shader_program);
|
|
||||||
int compile_status = 0;
|
|
||||||
glGetProgramiv(shader_program, GL_LINK_STATUS, &compile_status);
|
|
||||||
if (compile_status != GL_TRUE) {
|
|
||||||
LOG_FATAL("Failed to link shader program.");
|
|
||||||
}
|
|
||||||
glDeleteShader(vert_shader);
|
|
||||||
glDeleteShader(frag_shader);
|
|
||||||
}
|
|
||||||
|
|
||||||
MSG msg = { 0 };
|
MSG msg = { 0 };
|
||||||
while (true) {
|
while (true) {
|
||||||
@@ -472,7 +414,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pCmdLine,
|
|||||||
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
glUseProgram(shader_program);
|
glUseProgram(shader);
|
||||||
glBindVertexArray(triangle_vao);
|
glBindVertexArray(triangle_vao);
|
||||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, triangle_vert_count);
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, triangle_vert_count);
|
||||||
|
|
||||||
|
|||||||
88
src/shader.c
Normal file
88
src/shader.c
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "DynString.h"
|
||||||
|
#include "pltf/gl_funcs.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
|
static char read_buf[512] = { 0 };
|
||||||
|
static const size_t read_buf_len = sizeof(read_buf) / sizeof(read_buf[0]);
|
||||||
|
|
||||||
|
static DynString read_shader_source(const char* path) {
|
||||||
|
const DynString full_path = DynString_alloc_concat_c_strs(
|
||||||
|
SHADERS_PATH,
|
||||||
|
strlen(SHADERS_PATH),
|
||||||
|
path,
|
||||||
|
strlen(path)
|
||||||
|
);
|
||||||
|
|
||||||
|
DynString source = DynString_alloc("", 0);
|
||||||
|
|
||||||
|
FILE* shader_file = fopen(DynString_c_str(&full_path), "r");
|
||||||
|
if (shader_file == NULL) {
|
||||||
|
LOG_ERRORF("Failed to open file %.*s. Errno: %d", DYN_STRING_FMT(full_path), errno);
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t bytes_read = 0;
|
||||||
|
do {
|
||||||
|
bytes_read = fread(read_buf, 1, read_buf_len - 1, shader_file);
|
||||||
|
read_buf[bytes_read] = '\0';
|
||||||
|
DynString_concat_c_str(&source, read_buf, bytes_read);
|
||||||
|
} while (bytes_read == read_buf_len - 1);
|
||||||
|
|
||||||
|
if (fclose(shader_file) == EOF) {
|
||||||
|
LOG_ERRORF("Failed to close file %s. Errno: %d", path, errno);
|
||||||
|
}
|
||||||
|
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int compile_shader(const DynString* shader_src, const GLenum shader_type) {
|
||||||
|
const unsigned int shader = glCreateShader(shader_type);
|
||||||
|
const char* shader_src_c_str = DynString_c_str(shader_src);
|
||||||
|
const int len = (int) shader_src->len;
|
||||||
|
glShaderSource(shader, 1, &shader_src_c_str, &len);
|
||||||
|
glCompileShader(shader);
|
||||||
|
int compile_status = 0;
|
||||||
|
glGetShaderiv(shader, GL_COMPILE_STATUS, &compile_status);
|
||||||
|
if (compile_status != GL_TRUE) {
|
||||||
|
int info_log_len = 0;
|
||||||
|
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &info_log_len);
|
||||||
|
char* err_str = (char*) malloc(sizeof(char) * info_log_len);
|
||||||
|
glGetShaderInfoLog(shader, info_log_len - 1, NULL, err_str);
|
||||||
|
LOG_FATALF("Failed to compile vertex shader: %s", err_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
return shader;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int shader_create(
|
||||||
|
const char* vertex_shader_path,
|
||||||
|
const char* fragment_shader_path
|
||||||
|
) {
|
||||||
|
DynString vert_source = read_shader_source(vertex_shader_path);
|
||||||
|
DynString frag_source = read_shader_source(fragment_shader_path);
|
||||||
|
|
||||||
|
const unsigned int vert_shader = compile_shader(&vert_source, GL_VERTEX_SHADER);
|
||||||
|
const unsigned int frag_shader = compile_shader(&frag_source, GL_FRAGMENT_SHADER);
|
||||||
|
|
||||||
|
DynString_free(&vert_source);
|
||||||
|
DynString_free(&frag_source);
|
||||||
|
|
||||||
|
const unsigned int shader_program = glCreateProgram();
|
||||||
|
glAttachShader(shader_program, vert_shader);
|
||||||
|
glAttachShader(shader_program, frag_shader);
|
||||||
|
glLinkProgram(shader_program);
|
||||||
|
int compile_status = 0;
|
||||||
|
glGetProgramiv(shader_program, GL_LINK_STATUS, &compile_status);
|
||||||
|
if (compile_status != GL_TRUE) {
|
||||||
|
LOG_FATAL("Failed to link shader program.");
|
||||||
|
}
|
||||||
|
|
||||||
|
glDeleteShader(vert_shader);
|
||||||
|
glDeleteShader(frag_shader);
|
||||||
|
|
||||||
|
return shader_program;
|
||||||
|
}
|
||||||
9
src/shader.h
Normal file
9
src/shader.h
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#ifndef SHADER_H_
|
||||||
|
#define SHADER_H_
|
||||||
|
|
||||||
|
unsigned int shader_create(
|
||||||
|
const char* vertex_shader_path,
|
||||||
|
const char* fragment_shader_path
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif // SHADER_H_
|
||||||
7
src/shaders/shader.frag
Normal file
7
src/shaders/shader.frag
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#version 460 core
|
||||||
|
|
||||||
|
out vec4 frag_color;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
frag_color = vec4(0.0, 0.0, 0.0, 1.0);
|
||||||
|
}
|
||||||
7
src/shaders/shader.vert
Normal file
7
src/shaders/shader.vert
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#version 460 core
|
||||||
|
|
||||||
|
layout (location = 0) in vec3 a_pos;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_Position = vec4(a_pos, 1.0);
|
||||||
|
}
|
||||||
80
tests/main.c
Normal file
80
tests/main.c
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "cmocka/cmocka.h"
|
||||||
|
#include "DynString.h"
|
||||||
|
|
||||||
|
void test_DynString_alloc(void** state) {
|
||||||
|
const char* c_str = "Hello";
|
||||||
|
const size_t c_str_len = strlen(c_str);
|
||||||
|
DynString dstr = DynString_alloc(c_str, c_str_len);
|
||||||
|
|
||||||
|
assert_memory_equal(dstr.data, c_str, c_str_len + 1);
|
||||||
|
assert_true(dstr.len == c_str_len);
|
||||||
|
assert_true(dstr.capacity == c_str_len);
|
||||||
|
|
||||||
|
free(dstr.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_DynString_free(void** state) {
|
||||||
|
DynString dstr = DynString_alloc("Hello", strlen("Hello"));
|
||||||
|
|
||||||
|
DynString_free(&dstr);
|
||||||
|
|
||||||
|
assert_null(dstr.data);
|
||||||
|
assert_true(dstr.len == 0);
|
||||||
|
assert_true(dstr.capacity == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_DynString_equal(void** state) {
|
||||||
|
DynString s1 = DynString_alloc("Hello", strlen("Hello"));
|
||||||
|
DynString s2 = DynString_alloc("Hello", strlen("Hello"));
|
||||||
|
assert_true(DynString_equal(&s1, &s2));
|
||||||
|
DynString_free(&s1);
|
||||||
|
DynString_free(&s2);
|
||||||
|
|
||||||
|
s1 = DynString_alloc("Hello", strlen("Hello"));
|
||||||
|
s2 = DynString_alloc("Hello", strlen("Hello"));
|
||||||
|
assert_true(DynString_equal(&s1, &s2));
|
||||||
|
DynString_free(&s1);
|
||||||
|
DynString_free(&s2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_DynString_concat_c_str(void** state) {
|
||||||
|
const char* dstr_c_str = "Hello";
|
||||||
|
const char* c_str = " World";
|
||||||
|
const size_t combined_length = strlen(dstr_c_str) + strlen(c_str);
|
||||||
|
|
||||||
|
DynString dstr = DynString_alloc(dstr_c_str, strlen("Hello"));
|
||||||
|
DynString_concat_c_str(&dstr, c_str, strlen(c_str));
|
||||||
|
|
||||||
|
assert_memory_equal(dstr.data, "Hello World", strlen("Hello World"));
|
||||||
|
assert_true(dstr.len == combined_length);
|
||||||
|
assert_true(dstr.capacity == combined_length + 1);
|
||||||
|
|
||||||
|
DynString_free(&dstr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_DynString_c_str(void** state) {
|
||||||
|
const char* c_str = "Hello";
|
||||||
|
DynString dstr = DynString_alloc(c_str, strlen(c_str));
|
||||||
|
|
||||||
|
assert_string_equal(c_str, DynString_c_str(&dstr));
|
||||||
|
|
||||||
|
DynString_concat_c_str(&dstr, " World", strlen(" World"));
|
||||||
|
|
||||||
|
assert_string_equal("Hello World", DynString_c_str(&dstr));
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
const struct CMUnitTest tests[] = {
|
||||||
|
cmocka_unit_test(test_DynString_alloc),
|
||||||
|
cmocka_unit_test(test_DynString_free),
|
||||||
|
cmocka_unit_test(test_DynString_equal),
|
||||||
|
cmocka_unit_test(test_DynString_concat_c_str),
|
||||||
|
cmocka_unit_test(test_DynString_c_str),
|
||||||
|
};
|
||||||
|
|
||||||
|
return cmocka_run_group_tests(tests, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
7092
vendor/cmocka/cmocka.h
vendored
Normal file
7092
vendor/cmocka/cmocka.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
BIN
vendor/cmocka/libcmocka.a
vendored
Normal file
BIN
vendor/cmocka/libcmocka.a
vendored
Normal file
Binary file not shown.
Reference in New Issue
Block a user