int main(int argc, char **argv) { if(argc < 2) { fprintf(stderr, "Please specify the file to parse.\n"); return 1; } ast *t; position p; const char *err; if((err = mmap_open(argv[1], &p))) { fprintf(stderr, "mmap_open failed on file \"%s\": %s\n", argv[1], err); return 1; } t = alloc_ast(); if(!t) { fprintf(stderr, "alloc_ast could not allocate memory.\n"); mmap_close(&p); return 1; } if((err = start_parser(t, &p))) { log_err(err, p); mmap_close(&p); } else { mmap_close(&p); ast_callback(t, argc - 2, argv + 2); } delete_ast(t); }
int parse_hex2(ast *t, position *p){//TODO: Make all builtin parse/read functions that are '<' rules respect the merge_ast rule. Ugh OMG. position s = *p; ast *c = alloc_ast(); if(read_string("x", NULL, p) && (read_setrange('0', '9', c, p) || read_setrange('a', 'f', c, p) || read_setrange('A', 'F', c, p)) && (read_setrange('0', '9', c, p) || read_setrange('a', 'f', c, p) || read_setrange('A', 'F', c, p))){ unsigned x, f; f = sscanf(c->text, "%2x", &x); delete_ast(c); if(!f){ *p = s; return 0; } add_text(t, (char*)&x, 1); return 1; } delete_ast(c); return 0; }
void clear_ast(ast *t){ for(size_t i = 0; i < t->size; ++i){ delete_ast(t->children[i]); } free(t->children); t->children = NULL; t->size = 0; free((char*)t->text); t->text = NULL; t->length = 0; }
int parse_hex4(ast *t, position *p){ position s = *p; ast *c = alloc_ast(); if(read_string("X", NULL, p) && (read_setrange('0', '9', c, p) || read_setrange('a', 'f', c, p) || read_setrange('A', 'F', c, p)) && (read_setrange('0', '9', c, p) || read_setrange('a', 'f', c, p) || read_setrange('A', 'F', c, p)) && (read_setrange('0', '9', c, p) || read_setrange('a', 'f', c, p) || read_setrange('A', 'F', c, p)) && (read_setrange('0', '9', c, p) || read_setrange('a', 'f', c, p) || read_setrange('A', 'F', c, p))){ unsigned x, f; f = sscanf(c->text, "%4x", &x); delete_ast(c); if(!f){ *p = s; return 0; } add_text(t, (char*)&x, 1); return 1; } delete_ast(c); return 0; }
void append_ast(ast *t, ast *c){ if(!t){ delete_ast(c); return; } size_t size = t->size; ast **tmp = realloc(t->children, (size + 1)*sizeof(ast*)); if(!tmp){ //TODO: Handle error return; } t->children = tmp; t->children[size] = c; ++t->size; }
int delete_task(struct task *self) { if (!self) return -1; assert(self->refs == 0); xfree(self->name); xfree(self->actions); (void) delete_ast(self->expr, (ast_item_dtor) task_decref); xfree(self); return 0; }
int delete_ast(ast_t self, ast_item_dtor dtor) { int i, status; if (!self) return -1; if (self->item && dtor) { status = dtor(self->item); assert(status == 0); } for (i = 0; i < AST_MAX_CHILDREN; i++) delete_ast(self->children[i], dtor); xfree(self); return 0; }
void merge_ast(ast *t, ast *c){ if(!t){ delete_ast(c); return; } if(t->size){ size_t size = t->size + c->size; void *tmp = realloc(t->children, size*sizeof(ast*)); if(!tmp){ //TODO: Handle error return; } t->children = tmp; memcpy(t->children + t->size, c->children, c->size*sizeof(ast*)); t->size = size; free(c->children); }else{ t->children = c->children; t->size = c->size; } if(t->length){ size_t length = t->length + c->length; void *tmp = realloc((void*)t->text, length*sizeof(char)); if(!tmp){ t->children = realloc(t->children, t->size*sizeof(ast*)); return; } t->text = tmp; memcpy((void*)t->text + t->length, c->text, c->length*sizeof(char)); t->length = length; free((char*)c->text);//discard const qualifier }else{ t->text = c->text; t->length = c->length; } free_ast(c); }
void delete_mj_new_object(mj_new_object *no) { delete_ast((ast *) no->class_id); jrv_free(&no); }
void delete_mj_binary_operation(mj_binary_operation *op) { delete_ast(op->left_operand); delete_ast(op->right_operand); jrv_free(&op); }