Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ast alloc dealloc #62

Merged
merged 2 commits into from
Jun 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions include/ast.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#ifndef REGEX_AST_H

Check notice on line 1 in include/ast.h

View workflow job for this annotation

GitHub Actions / linter

Run clang-format on include/ast.h

File include/ast.h does not conform to Custom style guidelines. (lines 2, 8, 9, 10, 11, 12, 13, 15, 28, 29, 30, 31, 33, 34, 35, 36, 38, 39, 40, 41, 42, 43, 45, 46, 48, 53, 59, 70, 78)
#define REGEX_AST_H


Expand Down Expand Up @@ -47,4 +47,34 @@
} extra;
} ASTNode;


/**
* Allocate a new AST Node, and initialize it with the given type
*
* @param type The type of the AST Node
*
* @return A pointer to a heap allocated AST Node on success,
* NULL on failure
*/
ASTNode* ast_node_create(ASTNodeType type);


/**
* Initialize an AST Node
*
* @param node A Pointer to the AST Node to initialize
* @param type The type of the AST Node
*
* @return 0 on success, -1 on failure
*/
int ast_node_init(ASTNode* node, ASTNodeType type);


/**
* Release memory allocated for the given AST Node
*
* @param node The AST Node to free
*/
void ast_node_free(ASTNode* node);

#endif // REGEX_AST
53 changes: 53 additions & 0 deletions src/ast.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#include <stdlib.h>

Check notice on line 1 in src/ast.c

View workflow job for this annotation

GitHub Actions / linter

Run clang-format on src/ast.c

File src/ast.c does not conform to Custom style guidelines. (lines 6, 7, 9, 10, 11, 12, 13, 16, 20, 21, 22, 23, 25, 26, 27, 28, 29, 32, 36, 37, 38, 39, 41, 42, 43, 44, 46, 48, 49, 50)

#include "ast.h"

Check failure on line 3 in src/ast.c

View workflow job for this annotation

GitHub Actions / linter

src/ast.c:3:10 [clang-diagnostic-error]

'ast.h' file not found

// Allocate a new AST Node, and initialize it with the given type
ASTNode* ast_node_create(ASTNodeType type) {
ASTNode* node = malloc(sizeof(ASTNode));

// Initialize the created node, this implicitly checks for NULL
if (ast_node_init(node, type) != 0) {
free(node); // free of NULL is a no-op
return NULL;
}

return node;
}


// Initialize an AST Node
int ast_node_init(ASTNode* node, ASTNodeType type) {
if (node == NULL) {
return -1;
}

*node = (ASTNode){
.type = type,
.child1 = NULL,
.extra = {0},
};

return 0;
}


// Release memory allocated for the given AST Node
void ast_node_free(ASTNode* node) {
if (node == NULL) {
return;
}

if (node->type == CHAR_NODE) {
free(node);
return;
}

ast_node_free(node->child1);

if (node->type == OR_NODE || node->type == CONCAT_NODE) {
ast_node_free(node->extra.child2);
}

free(node);
}
72 changes: 72 additions & 0 deletions tests/test_ast.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#include "testlib/asserts.h"

Check notice on line 1 in tests/test_ast.c

View workflow job for this annotation

GitHub Actions / linter

Run clang-format on tests/test_ast.c

File tests/test_ast.c does not conform to Custom style guidelines. (lines 1, 6, 7, 8, 9, 10, 11, 13, 15, 16, 18, 19, 20, 21, 25, 26, 27, 28, 29, 30, 32, 34, 35, 36, 38, 39, 40, 42, 43, 46, 50, 51, 52, 53, 56, 57, 58, 59, 60, 61, 62, 64, 66, 68, 69)
#include "testlib/tests.h"
#include "ast.h"

Check failure on line 3 in tests/test_ast.c

View workflow job for this annotation

GitHub Actions / linter

tests/test_ast.c:3:10 [clang-diagnostic-error]

'ast.h' file not found

// Test creating AST dynamically
int test_ast_create() {
TEST_BEGIN;
ASTNodeType types[] = {
CHAR_NODE, STAR_NODE, PLUS_NODE,
OR_NODE, QUESTION_NODE, CONCAT_NODE,
};

size_t n_types = sizeof(types) / sizeof(ASTNodeType);

Check warning on line 13 in tests/test_ast.c

View workflow job for this annotation

GitHub Actions / linter

tests/test_ast.c:13:12 [cppcoreguidelines-init-variables]

variable 'n_types' is not initialized

for (size_t i = 0; i < n_types; i++) {
ASTNode* node = ast_node_create(types[i]);

assert_is_not_null(node);
assert_equals_int(node->type, types[i]);
ast_node_free(node);
}
TEST_END;
}

int test_ast_init() {
TEST_BEGIN;
ASTNodeType types[] = {
CHAR_NODE, STAR_NODE, PLUS_NODE,
OR_NODE, QUESTION_NODE, CONCAT_NODE,
};

size_t n_types = sizeof(types) / sizeof(ASTNodeType);

Check warning on line 32 in tests/test_ast.c

View workflow job for this annotation

GitHub Actions / linter

tests/test_ast.c:32:12 [cppcoreguidelines-init-variables]

variable 'n_types' is not initialized

ASTNode node;
for (size_t i = 0; i < n_types; i++) {
int ret = ast_node_init(&node, types[i]);

Check warning on line 36 in tests/test_ast.c

View workflow job for this annotation

GitHub Actions / linter

tests/test_ast.c:36:13 [cppcoreguidelines-init-variables]

variable 'ret' is not initialized

assert_equals_int(ret, 0);
assert_equals_int(node.type, types[i]);
}

int ret = ast_node_init(NULL, *types);

Check warning on line 42 in tests/test_ast.c

View workflow job for this annotation

GitHub Actions / linter

tests/test_ast.c:42:9 [cppcoreguidelines-init-variables]

variable 'ret' is not initialized
assert_equals_int(ret, -1);

TEST_END;
}


Test tests[] = {

Check warning on line 49 in tests/test_ast.c

View workflow job for this annotation

GitHub Actions / linter

tests/test_ast.c:49:6 [cppcoreguidelines-avoid-non-const-global-variables]

variable 'tests' is non-const and globally accessible, consider making it const
{.name="test_ast_create", .func=test_ast_create},
{.name="test_ast_init", .func=test_ast_init},
{.name=NULL},
};


int main(int argc, char* argv[]) {
TestOpts opts;
int ret = parse_test_opts(&opts, &argv[1], argc - 1);
if (ret != 0) {
printf("%s\n", str_parse_error(ret));
exit(1);
}

const TestSuite* suite = create_test_suite(&opts);

int n_failures = run_test_suite(suite);

free_opts(&opts);
free_test_suite(suite);

return n_failures;
}
Loading