strictly ansi C now
This commit is contained in:
2
Makefile
2
Makefile
@@ -1,5 +1,5 @@
|
||||
CC = gcc
|
||||
CFLAGS = -ansi -Wall -Werror -Wno-unused -g
|
||||
CFLAGS = -ansi -Wall -Wpedantic -Werror -Wno-unused -g
|
||||
|
||||
TESTS = $(wildcard tests/*.c)
|
||||
|
||||
|
25
mpc.h
25
mpc.h
@@ -1,16 +1,19 @@
|
||||
/*
|
||||
** mpc - Micro Parser Combinator library for C
|
||||
**
|
||||
** https://github.com/orangeduck/mpc
|
||||
**
|
||||
** Daniel Holden - contact@daniel-holden.com
|
||||
** Licensed under BSD3
|
||||
*/
|
||||
|
||||
#ifndef mpc_h
|
||||
#define mpc_h
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
** Error Type
|
||||
@@ -45,9 +48,9 @@ typedef union {
|
||||
struct mpc_parser_t;
|
||||
typedef struct mpc_parser_t mpc_parser_t;
|
||||
|
||||
bool mpc_parse(const char* filename, const char* s, mpc_parser_t* p, mpc_result_t* r);
|
||||
bool mpc_parse_file(const char* filename, FILE* f, mpc_parser_t* p, mpc_result_t* r);
|
||||
bool mpc_parse_filename(const char* filename, mpc_parser_t* p, mpc_result_t* r);
|
||||
int mpc_parse(const char* filename, const char* s, mpc_parser_t* p, mpc_result_t* r);
|
||||
int mpc_parse_file(const char* filename, FILE* f, mpc_parser_t* p, mpc_result_t* r);
|
||||
int mpc_parse_filename(const char* filename, mpc_parser_t* p, mpc_result_t* r);
|
||||
|
||||
/*
|
||||
** Function Types
|
||||
@@ -88,7 +91,7 @@ mpc_parser_t* mpc_char(char c);
|
||||
mpc_parser_t* mpc_range(char s, char e);
|
||||
mpc_parser_t* mpc_oneof(const char* s);
|
||||
mpc_parser_t* mpc_noneof(const char* s);
|
||||
mpc_parser_t* mpc_satisfy(bool(*f)(char));
|
||||
mpc_parser_t* mpc_satisfy(int(*f)(char));
|
||||
mpc_parser_t* mpc_string(const char* s);
|
||||
|
||||
/*
|
||||
@@ -247,7 +250,7 @@ mpc_ast_t* mpc_ast_insert_root(mpc_ast_t* a);
|
||||
void mpc_ast_add_child(mpc_ast_t* r, mpc_ast_t* a);
|
||||
void mpc_ast_tag(mpc_ast_t* a, const char* t);
|
||||
void mpc_ast_print(mpc_ast_t* a);
|
||||
bool mpc_ast_eq(mpc_ast_t* a, mpc_ast_t* b);
|
||||
int mpc_ast_eq(mpc_ast_t* a, mpc_ast_t* b);
|
||||
|
||||
mpc_val_t* mpcf_fold_ast(mpc_val_t* a, mpc_val_t* b);
|
||||
mpc_val_t* mpcf_afold_ast(int n, mpc_val_t** as);
|
||||
@@ -274,13 +277,13 @@ mpc_err_t* mpca_lang_file(const char* filename, ...);
|
||||
** Testing
|
||||
*/
|
||||
|
||||
bool mpc_unmatch(mpc_parser_t* p, const char* s, void* d,
|
||||
bool(*tester)(void*, void*),
|
||||
int mpc_unmatch(mpc_parser_t* p, const char* s, void* d,
|
||||
int(*tester)(void*, void*),
|
||||
mpc_dtor_t destructor,
|
||||
void(*printer)(void*));
|
||||
|
||||
bool mpc_match(mpc_parser_t* p, const char* s, void* d,
|
||||
bool(*tester)(void*, void*),
|
||||
int mpc_match(mpc_parser_t* p, const char* s, void* d,
|
||||
int(*tester)(void*, void*),
|
||||
mpc_dtor_t destructor,
|
||||
void(*printer)(void*));
|
||||
|
||||
|
31
tests/core.c
31
tests/core.c
@@ -4,9 +4,9 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static bool int_eq(void* x, void* y) { return (*(int*)x == *(int*)y); }
|
||||
static int int_eq(void* x, void* y) { return (*(int*)x == *(int*)y); }
|
||||
static void int_print(void* x) { printf("'%i'", *((int*)x)); }
|
||||
static bool string_eq(void* x, void* y) { return (strcmp(x, y) == 0); }
|
||||
static int string_eq(void* x, void* y) { return (strcmp(x, y) == 0); }
|
||||
static void string_print(void* x) { printf("'%s'", (char*)x); }
|
||||
|
||||
void test_ident(void) {
|
||||
@@ -34,11 +34,18 @@ void test_ident(void) {
|
||||
}
|
||||
|
||||
void test_maths(void) {
|
||||
|
||||
mpc_parser_t* Expr = mpc_new("expr");
|
||||
mpc_parser_t* Factor = mpc_new("factor");
|
||||
mpc_parser_t* Term = mpc_new("term");
|
||||
mpc_parser_t* Maths = mpc_new("maths");
|
||||
|
||||
mpc_parser_t *Expr, *Factor, *Term, *Maths;
|
||||
int r0 = 1;
|
||||
int r1 = 5;
|
||||
int r2 = 13;
|
||||
int r3 = 0;
|
||||
int r4 = 2;
|
||||
|
||||
Expr = mpc_new("expr");
|
||||
Factor = mpc_new("factor");
|
||||
Term = mpc_new("term");
|
||||
Maths = mpc_new("maths");
|
||||
|
||||
mpc_define(Expr, mpc_else(
|
||||
mpc_and(3, mpcf_maths, Factor, mpc_oneof("*/"), Factor, free, free),
|
||||
@@ -57,11 +64,11 @@ void test_maths(void) {
|
||||
|
||||
mpc_define(Maths, mpc_enclose(Expr, free));
|
||||
|
||||
PT_ASSERT(mpc_match(Maths, "1", (int[]){ 1 }, int_eq, free, int_print));
|
||||
PT_ASSERT(mpc_match(Maths, "(5)", (int[]){ 5 }, int_eq, free, int_print));
|
||||
PT_ASSERT(mpc_match(Maths, "(4*2)+5", (int[]){ 13 }, int_eq, free, int_print));
|
||||
PT_ASSERT(mpc_unmatch(Maths, "a", (int[]){ 0 }, int_eq, free, int_print));
|
||||
PT_ASSERT(mpc_unmatch(Maths, "2b+4", (int[]){ 2 }, int_eq, free, int_print));
|
||||
PT_ASSERT(mpc_match(Maths, "1", &r0, int_eq, free, int_print));
|
||||
PT_ASSERT(mpc_match(Maths, "(5)", &r1, int_eq, free, int_print));
|
||||
PT_ASSERT(mpc_match(Maths, "(4*2)+5", &r2, int_eq, free, int_print));
|
||||
PT_ASSERT(mpc_unmatch(Maths, "a", &r3, int_eq, free, int_print));
|
||||
PT_ASSERT(mpc_unmatch(Maths, "2b+4", &r4, int_eq, free, int_print));
|
||||
|
||||
mpc_cleanup(4, Expr, Factor, Term, Maths);
|
||||
}
|
||||
|
@@ -3,24 +3,27 @@
|
||||
|
||||
void test_grammar(void) {
|
||||
|
||||
mpc_parser_t* Expr = mpc_new("expression");
|
||||
mpc_parser_t* Prod = mpc_new("product");
|
||||
mpc_parser_t* Value = mpc_new("value");
|
||||
mpc_parser_t* Maths = mpc_new("maths");
|
||||
mpc_parser_t *Expr, *Prod, *Value, *Maths;
|
||||
mpc_ast_t *t0, *t1, *t2;
|
||||
|
||||
Expr = mpc_new("expression");
|
||||
Prod = mpc_new("product");
|
||||
Value = mpc_new("value");
|
||||
Maths = mpc_new("maths");
|
||||
|
||||
mpc_define(Expr, mpca_grammar(" <product> (('+' | '-') <product>)* ", Prod));
|
||||
mpc_define(Prod, mpca_grammar(" <value> (('*' | '/') <value>)* ", Value));
|
||||
mpc_define(Value, mpca_grammar(" /[0-9]+/ | '(' <expression> ')' ", Expr));
|
||||
mpc_define(Maths, mpca_total(Expr));
|
||||
|
||||
mpc_ast_t* t0 = mpc_ast_build(1, "root", mpc_ast_new("value", "24"));
|
||||
mpc_ast_t* t1 = mpc_ast_build(1, "root",
|
||||
t0 = mpc_ast_build(1, "root", mpc_ast_new("value", "24"));
|
||||
t1 = mpc_ast_build(1, "root",
|
||||
mpc_ast_build(3, "value",
|
||||
mpc_ast_new("char", "("),
|
||||
mpc_ast_new("value", "5"),
|
||||
mpc_ast_new("char", ")")));
|
||||
|
||||
mpc_ast_t* t2 = mpc_ast_build(3, "root",
|
||||
t2 = mpc_ast_build(3, "root",
|
||||
|
||||
mpc_ast_build(3, "value",
|
||||
mpc_ast_new("char", "("),
|
||||
@@ -39,12 +42,12 @@ void test_grammar(void) {
|
||||
|
||||
mpc_ast_new("char", "+"),
|
||||
mpc_ast_new("value", "5"));
|
||||
|
||||
PT_ASSERT(mpc_match(Maths, " 24 ", t0, (bool(*)(void*,void*))mpc_ast_eq, (mpc_dtor_t)mpc_ast_delete, (void(*)(void*))mpc_ast_print));
|
||||
PT_ASSERT(mpc_match(Maths, "(5)", t1, (bool(*)(void*,void*))mpc_ast_eq, (mpc_dtor_t)mpc_ast_delete, (void(*)(void*))mpc_ast_print));
|
||||
PT_ASSERT(mpc_match(Maths, "(4 * 2 * 11 + 2) + 5", t2, (bool(*)(void*,void*))mpc_ast_eq, (mpc_dtor_t)mpc_ast_delete, (void(*)(void*))mpc_ast_print));
|
||||
PT_ASSERT(mpc_unmatch(Maths, "a", t0, (bool(*)(void*,void*))mpc_ast_eq, (mpc_dtor_t)mpc_ast_delete, (void(*)(void*))mpc_ast_print));
|
||||
PT_ASSERT(mpc_unmatch(Maths, "2b+4", t0, (bool(*)(void*,void*))mpc_ast_eq, (mpc_dtor_t)mpc_ast_delete, (void(*)(void*))mpc_ast_print));
|
||||
|
||||
PT_ASSERT(mpc_match(Maths, " 24 ", t0, (int(*)(void*,void*))mpc_ast_eq, (mpc_dtor_t)mpc_ast_delete, (void(*)(void*))mpc_ast_print));
|
||||
PT_ASSERT(mpc_match(Maths, "(5)", t1, (int(*)(void*,void*))mpc_ast_eq, (mpc_dtor_t)mpc_ast_delete, (void(*)(void*))mpc_ast_print));
|
||||
PT_ASSERT(mpc_match(Maths, "(4 * 2 * 11 + 2) + 5", t2, (int(*)(void*,void*))mpc_ast_eq, (mpc_dtor_t)mpc_ast_delete, (void(*)(void*))mpc_ast_print));
|
||||
PT_ASSERT(mpc_unmatch(Maths, "a", t0, (int(*)(void*,void*))mpc_ast_eq, (mpc_dtor_t)mpc_ast_delete, (void(*)(void*))mpc_ast_print));
|
||||
PT_ASSERT(mpc_unmatch(Maths, "2b+4", t0, (int(*)(void*,void*))mpc_ast_eq, (mpc_dtor_t)mpc_ast_delete, (void(*)(void*))mpc_ast_print));
|
||||
|
||||
mpc_ast_delete(t0);
|
||||
mpc_ast_delete(t1);
|
||||
@@ -56,10 +59,12 @@ void test_grammar(void) {
|
||||
|
||||
void test_language(void) {
|
||||
|
||||
mpc_parser_t* Expr = mpc_new("expression");
|
||||
mpc_parser_t* Prod = mpc_new("product");
|
||||
mpc_parser_t* Value = mpc_new("value");
|
||||
mpc_parser_t* Maths = mpc_new("maths");
|
||||
mpc_parser_t *Expr, *Prod, *Value, *Maths;
|
||||
|
||||
Expr = mpc_new("expression");
|
||||
Prod = mpc_new("product");
|
||||
Value = mpc_new("value");
|
||||
Maths = mpc_new("maths");
|
||||
|
||||
mpca_lang(
|
||||
" \
|
||||
@@ -75,10 +80,12 @@ void test_language(void) {
|
||||
|
||||
void test_language_file(void) {
|
||||
|
||||
mpc_parser_t* Expr = mpc_new("expression");
|
||||
mpc_parser_t* Prod = mpc_new("product");
|
||||
mpc_parser_t* Value = mpc_new("value");
|
||||
mpc_parser_t* Maths = mpc_new("maths");
|
||||
mpc_parser_t *Expr, *Prod, *Value, *Maths;
|
||||
|
||||
Expr = mpc_new("expression");
|
||||
Prod = mpc_new("product");
|
||||
Value = mpc_new("value");
|
||||
Maths = mpc_new("maths");
|
||||
|
||||
mpca_lang_file("./tests/maths.grammar", Expr, Prod, Value, Maths);
|
||||
|
||||
|
@@ -8,12 +8,20 @@
|
||||
|
||||
/* Globals */
|
||||
|
||||
#define MAX_NAME 512
|
||||
#define MAX_ERROR 2048
|
||||
#define MAX_TESTS 2048
|
||||
enum {
|
||||
MAX_NAME = 512
|
||||
};
|
||||
|
||||
static bool test_passing = false;
|
||||
static bool suite_passing = false;
|
||||
enum {
|
||||
MAX_ERROR = 2048
|
||||
};
|
||||
|
||||
enum {
|
||||
MAX_TESTS = 2048
|
||||
};
|
||||
|
||||
static int test_passing = 0;
|
||||
static int suite_passing = 0;
|
||||
|
||||
/* Colors */
|
||||
|
||||
@@ -33,7 +41,7 @@ enum {
|
||||
LIGHT_RED = 0xC,
|
||||
LIGHT_PURPLE = 0xD,
|
||||
LIGHT_YELLOW = 0xE,
|
||||
LIGHT_WHITE = 0xF,
|
||||
LIGHT_WHITE = 0xF
|
||||
};
|
||||
|
||||
#ifdef _WIN32
|
||||
@@ -84,7 +92,7 @@ static char assert_err[MAX_ERROR];
|
||||
static char assert_err_buff[MAX_ERROR];
|
||||
static int assert_err_num = 0;
|
||||
|
||||
void pt_assert_run(bool result, const char* expr, const char* func, const char* file, int line) {
|
||||
void pt_assert_run(int result, const char* expr, const char* func, const char* file, int line) {
|
||||
|
||||
num_asserts++;
|
||||
test_passing = test_passing && result;
|
||||
@@ -102,7 +110,7 @@ void pt_assert_run(bool result, const char* expr, const char* func, const char*
|
||||
|
||||
static void ptest_signal(int sig) {
|
||||
|
||||
test_passing = false;
|
||||
test_passing = 0;
|
||||
|
||||
switch( sig ) {
|
||||
case SIGFPE: sprintf(assert_err_buff, " %i. Division by Zero\n", assert_err_num+1); break;
|
||||
@@ -125,15 +133,15 @@ static void ptest_signal(int sig) {
|
||||
|
||||
static void pt_title_case(char* output, const char* input) {
|
||||
|
||||
bool space = true;
|
||||
int space = 1;
|
||||
unsigned int i;
|
||||
|
||||
strcpy(output, input);
|
||||
|
||||
unsigned int i;
|
||||
for(i = 0; i < strlen(output); i++) {
|
||||
|
||||
if (output[i] == '_' || output[i] == ' ') {
|
||||
space = true;
|
||||
space = 1;
|
||||
output[i] = ' ';
|
||||
continue;
|
||||
}
|
||||
@@ -143,7 +151,7 @@ static void pt_title_case(char* output, const char* input) {
|
||||
continue;
|
||||
}
|
||||
|
||||
space = false;
|
||||
space = 0;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -162,6 +170,8 @@ static int num_tests_fails = 0;
|
||||
|
||||
void pt_add_test(void (*func)(void), const char* name, const char* suite) {
|
||||
|
||||
test_t test;
|
||||
|
||||
if (num_tests == MAX_TESTS) {
|
||||
printf("ERROR: Exceeded maximum test count of %i!\n", MAX_TESTS); abort();
|
||||
}
|
||||
@@ -174,7 +184,6 @@ void pt_add_test(void (*func)(void), const char* name, const char* suite) {
|
||||
printf("ERROR: Test suite '%s' too long (Maximum is %i characters)\n", suite, MAX_NAME); abort();
|
||||
}
|
||||
|
||||
test_t test;
|
||||
test.func = func;
|
||||
pt_title_case(test.name, name);
|
||||
pt_title_case(test.suite, suite);
|
||||
@@ -202,6 +211,9 @@ static char current_suite[MAX_NAME];
|
||||
|
||||
int pt_run(void) {
|
||||
|
||||
unsigned int i;
|
||||
double total;
|
||||
|
||||
printf(" \n");
|
||||
printf(" +-------------------------------------------+\n");
|
||||
printf(" | ptest MicroTesting Magic for C |\n");
|
||||
@@ -218,7 +230,6 @@ int pt_run(void) {
|
||||
start = clock();
|
||||
strcpy(current_suite, "");
|
||||
|
||||
unsigned int i;
|
||||
for(i = 0; i < num_tests; i++) {
|
||||
|
||||
test_t test = tests[i];
|
||||
@@ -235,14 +246,14 @@ int pt_run(void) {
|
||||
}
|
||||
}
|
||||
|
||||
suite_passing = true;
|
||||
suite_passing = 1;
|
||||
strcpy(current_suite, test.suite);
|
||||
printf("\n\n ===== %s =====\n\n", current_suite);
|
||||
}
|
||||
|
||||
/* Run Test */
|
||||
|
||||
test_passing = true;
|
||||
test_passing = 1;
|
||||
strcpy(assert_err, "");
|
||||
strcpy(assert_err_buff, "");
|
||||
assert_err_num = 0;
|
||||
@@ -293,7 +304,7 @@ int pt_run(void) {
|
||||
printf(" +---------++------------+-------------+-------------+\n");
|
||||
printf(" \n");
|
||||
|
||||
double total = (double)(end - start) / CLOCKS_PER_SEC;
|
||||
total = (double)(end - start) / CLOCKS_PER_SEC;
|
||||
|
||||
printf(" Total Running Time: %0.3fs\n\n", total);
|
||||
|
||||
|
@@ -1,16 +1,15 @@
|
||||
#ifndef ptest_h
|
||||
#define ptest_h
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#define PT_SUITE(name) void name(void)
|
||||
#define PT_TEST(name) auto void name(void); pt_add_test(name, #name, __func__); void name(void)
|
||||
|
||||
#define PT_ASSERT(expr) pt_assert_run((bool)(expr), #expr, __func__, __FILE__, __LINE__)
|
||||
#define PT_ASSERT(expr) pt_assert_run((int)(expr), #expr, __func__, __FILE__, __LINE__)
|
||||
#define PT_ASSERT_STR_EQ(fst, snd) pt_assert_run(strcmp(fst, snd) == 0, "strcmp( " #fst ", " #snd " ) == 0", __func__, __FILE__, __LINE__)
|
||||
|
||||
void pt_assert_run(bool result, const char* expr, const char* func, const char* file, int line);
|
||||
void pt_assert_run(int result, const char* expr, const char* func, const char* file, int line);
|
||||
|
||||
void pt_add_test(void (*func)(void), const char* name, const char* suite);
|
||||
void pt_add_suite(void (*func)(void));
|
||||
|
@@ -4,17 +4,19 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static bool string_eq(void* x, void* y) { return (strcmp(x, y) == 0); }
|
||||
static int string_eq(void* x, void* y) { return (strcmp(x, y) == 0); }
|
||||
static void string_print(void* x) { printf("'%s'", (char*)x); }
|
||||
|
||||
void test_regex_basic(void) {
|
||||
|
||||
mpc_parser_t* re0 = mpc_re("abc|bcd");
|
||||
mpc_parser_t* re1 = mpc_re("abc|bcd|e");
|
||||
mpc_parser_t* re2 = mpc_re("ab()c(ab)*");
|
||||
mpc_parser_t* re3 = mpc_re("abc(abdd)?");
|
||||
mpc_parser_t* re4 = mpc_re("ab|c(abdd)?");
|
||||
mpc_parser_t* re5 = mpc_re("abc(ab|dd)+g$");
|
||||
mpc_parser_t *re0, *re1, *re2, *re3, *re4, *re5;
|
||||
|
||||
re0 = mpc_re("abc|bcd");
|
||||
re1 = mpc_re("abc|bcd|e");
|
||||
re2 = mpc_re("ab()c(ab)*");
|
||||
re3 = mpc_re("abc(abdd)?");
|
||||
re4 = mpc_re("ab|c(abdd)?");
|
||||
re5 = mpc_re("abc(ab|dd)+g$");
|
||||
|
||||
PT_ASSERT(mpc_match(re0, "abc", "abc", string_eq, free, string_print));
|
||||
PT_ASSERT(mpc_match(re0, "bcd", "bcd", string_eq, free, string_print));
|
||||
@@ -36,10 +38,12 @@ void test_regex_basic(void) {
|
||||
|
||||
void test_regex_range(void) {
|
||||
|
||||
mpc_parser_t* re0 = mpc_re("abg[abcdef]");
|
||||
mpc_parser_t* re1 = mpc_re("y*[a-z]");
|
||||
mpc_parser_t* re2 = mpc_re("zz(p+)?[A-Z_0\\]123]*");
|
||||
mpc_parser_t* re3 = mpc_re("^[^56hy].*$");
|
||||
mpc_parser_t *re0, *re1, *re2, *re3, *re4;
|
||||
|
||||
re0 = mpc_re("abg[abcdef]");
|
||||
re1 = mpc_re("y*[a-z]");
|
||||
re2 = mpc_re("zz(p+)?[A-Z_0\\]123]*");
|
||||
re3 = mpc_re("^[^56hy].*$");
|
||||
|
||||
/* TODO: Testing */
|
||||
|
||||
|
Reference in New Issue
Block a user