Updated copy function to work properly with larger parsers
This commit is contained in:
65
mpc.c
65
mpc.c
@@ -1365,14 +1365,77 @@ mpc_parser_t *mpc_new(const char *name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mpc_parser_t *mpc_copy(mpc_parser_t *a) {
|
mpc_parser_t *mpc_copy(mpc_parser_t *a) {
|
||||||
mpc_parser_t *p = mpc_undefined();
|
int i = 0;
|
||||||
|
mpc_parser_t *p;
|
||||||
|
|
||||||
|
if (a->retained) { return a; }
|
||||||
|
|
||||||
|
p = mpc_undefined();
|
||||||
p->retained = a->retained;
|
p->retained = a->retained;
|
||||||
p->type = a->type;
|
p->type = a->type;
|
||||||
p->data = a->data;
|
p->data = a->data;
|
||||||
|
|
||||||
if (a->name) {
|
if (a->name) {
|
||||||
p->name = malloc(strlen(a->name)+1);
|
p->name = malloc(strlen(a->name)+1);
|
||||||
strcpy(p->name, a->name);
|
strcpy(p->name, a->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (a->type) {
|
||||||
|
|
||||||
|
case MPC_TYPE_FAIL:
|
||||||
|
p->data.fail.m = malloc(strlen(a->data.fail.m)+1);
|
||||||
|
strcpy(p->data.fail.m, a->data.fail.m);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MPC_TYPE_ONEOF:
|
||||||
|
case MPC_TYPE_NONEOF:
|
||||||
|
case MPC_TYPE_STRING:
|
||||||
|
p->data.string.x = malloc(strlen(a->data.string.x)+1);
|
||||||
|
strcpy(p->data.string.x, a->data.string.x);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MPC_TYPE_APPLY: p->data.apply.x = mpc_copy(a->data.apply.x); break;
|
||||||
|
case MPC_TYPE_APPLY_TO: p->data.apply_to.x = mpc_copy(a->data.apply_to.x); break;
|
||||||
|
case MPC_TYPE_PREDICT: p->data.predict.x = mpc_copy(a->data.predict.x); break;
|
||||||
|
|
||||||
|
case MPC_TYPE_MAYBE:
|
||||||
|
case MPC_TYPE_NOT:
|
||||||
|
p->data.not.x = mpc_copy(a->data.not.x);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MPC_TYPE_EXPECT:
|
||||||
|
p->data.expect.x = mpc_copy(a->data.expect.x);
|
||||||
|
p->data.expect.m = malloc(strlen(a->data.expect.m)+1);
|
||||||
|
strcpy(p->data.expect.m, a->data.expect.m);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MPC_TYPE_MANY:
|
||||||
|
case MPC_TYPE_MANY1:
|
||||||
|
case MPC_TYPE_COUNT:
|
||||||
|
p->data.repeat.x = mpc_copy(a->data.repeat.x);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MPC_TYPE_OR:
|
||||||
|
p->data.or.xs = malloc(a->data.or.n * sizeof(mpc_parser_t*));
|
||||||
|
for (i = 0; i < a->data.or.n; i++) {
|
||||||
|
p->data.or.xs[i] = mpc_copy(a->data.or.xs[i]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MPC_TYPE_AND:
|
||||||
|
p->data.and.xs = malloc(a->data.and.n * sizeof(mpc_parser_t*));
|
||||||
|
for (i = 0; i < a->data.and.n; i++) {
|
||||||
|
p->data.and.xs[i] = mpc_copy(a->data.and.xs[i]);
|
||||||
|
}
|
||||||
|
p->data.and.dxs = malloc((a->data.and.n-1) * sizeof(mpc_dtor_t));
|
||||||
|
for (i = 0; i < a->data.and.n-1; i++) {
|
||||||
|
p->data.and.dxs[i] = a->data.and.dxs[i];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
39
tests/core.c
39
tests/core.c
@@ -114,9 +114,48 @@ void test_repeat(void) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_copy(void) {
|
||||||
|
|
||||||
|
int success;
|
||||||
|
mpc_result_t r;
|
||||||
|
mpc_parser_t* p = mpc_or(2, mpc_char('a'), mpc_char('b'));
|
||||||
|
mpc_parser_t* q = mpc_and(2, mpcf_strfold, p, mpc_copy(p), free);
|
||||||
|
|
||||||
|
success = mpc_parse("test", "aa", q, &r);
|
||||||
|
PT_ASSERT(success);
|
||||||
|
PT_ASSERT_STR_EQ(r.output, "aa");
|
||||||
|
free(r.output);
|
||||||
|
|
||||||
|
success = mpc_parse("test", "bb", q, &r);
|
||||||
|
PT_ASSERT(success);
|
||||||
|
PT_ASSERT_STR_EQ(r.output, "bb");
|
||||||
|
free(r.output);
|
||||||
|
|
||||||
|
success = mpc_parse("test", "ab", q, &r);
|
||||||
|
PT_ASSERT(success);
|
||||||
|
PT_ASSERT_STR_EQ(r.output, "ab");
|
||||||
|
free(r.output);
|
||||||
|
|
||||||
|
success = mpc_parse("test", "ba", q, &r);
|
||||||
|
PT_ASSERT(success);
|
||||||
|
PT_ASSERT_STR_EQ(r.output, "ba");
|
||||||
|
free(r.output);
|
||||||
|
|
||||||
|
success = mpc_parse("test", "c", p, &r);
|
||||||
|
PT_ASSERT(!success);
|
||||||
|
mpc_err_delete(r.error);
|
||||||
|
|
||||||
|
mpc_delete(mpc_copy(p));
|
||||||
|
mpc_delete(mpc_copy(q));
|
||||||
|
|
||||||
|
mpc_delete(q);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void suite_core(void) {
|
void suite_core(void) {
|
||||||
pt_add_test(test_ident, "Test Ident", "Suite Core");
|
pt_add_test(test_ident, "Test Ident", "Suite Core");
|
||||||
pt_add_test(test_maths, "Test Maths", "Suite Core");
|
pt_add_test(test_maths, "Test Maths", "Suite Core");
|
||||||
pt_add_test(test_strip, "Test Strip", "Suite Core");
|
pt_add_test(test_strip, "Test Strip", "Suite Core");
|
||||||
pt_add_test(test_repeat, "Test Repeat", "Suite Core");
|
pt_add_test(test_repeat, "Test Repeat", "Suite Core");
|
||||||
|
pt_add_test(test_copy, "Test Copy", "Suite Core");
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user