void release_node(node *o) { if ( nullp(o) ) { return; } if (symp(o)) { name_free(o->name); } else if (subrp(o) or fsubrp(o)) { name_free(o->fname); } node_free(o); }
data_t * _any_getattr(data_t *self, char _unused_ *func_name, arguments_t *args) { data_t *attrname = arguments_get_arg(args, 0); name_t *name = name_create(1, data_tostring(attrname)); data_t *ret; ret = data_get(self, name); name_free(name); return ret; }
data_t * _any_hasattr(data_t *self, char *func_name, arguments_t *args) { data_t *attrname = arguments_get_arg(args, 0); name_t *name = name_create(1, data_tostring(attrname)); data_t *r = data_resolve(self, name); data_t *ret = int_as_bool(r != NULL); (void) func_name; name_free(name); return ret; }
NameEntry* name_remove(char *name, NameEntry **entry) { if (!*entry || !name) return NULL; NameEntry *e = *entry, *b = *entry; while (e && e->name) { if (strcmp(name, e->name) == 0) { if (b == e) *entry = NULL; else b->next = e->next; break; } b = e; e = e->next; } name_free(e); return *entry; }
/* * declare_macro * * Common logic for parsing macro declarations. * * MACRO macro-name { (param,...) } { [param,...] } = {stuff} % {,...} * KEYWORDMACRO macro-name { (param{=defval},...) } = {stuff} % {,...} */ int declare_macro (expr_ctx_t ctx, scopectx_t scope, lextype_t curlt) { parse_ctx_t pctx = expr_parse_ctx(ctx); int skip_to_end = 0; lexeme_t *lex; lextype_t lt; strdesc_t *ltext; name_t *np; int is_kwdmacro = (curlt == LEXTYPE_DCL_KEYWORDMACRO); struct macrodecl_s *macro; textpos_t pos; namedef_t ndef; memset(&ndef, 0, sizeof(ndef)); ndef.lt = LEXTYPE_NAME_MACRO; ndef.flags = NAME_M_DECLARED; while (1) { if (!parse_decl_name(pctx, <ext, &pos)) { expr_signal(ctx, STC__NAMEEXP); skip_to_end = 1; } lt = parser_next(pctx, QL_NAME, 0); if (lt != LEXTYPE_DELIM_LPAR && lt != LEXTYPE_OP_ASSIGN && lt != LEXTYPE_DELIM_LBRACK) { expr_signal(ctx, STC__SYNTAXERR); skip_to_end = 1; } ndef.name = ltext->ptr; ndef.namelen = ltext->len; np = name_declare(scope, &ndef, pos, 0, 0, ¯o); macro->type = (is_kwdmacro ? MACRO_KWD : MACRO_UNK); // Parse the regular parameters if (lt == LEXTYPE_DELIM_LPAR) { if (macro_paramlist(ctx, scope, is_kwdmacro, 1, closers, 1, ¯o->ptable, ¯o->plist) < 0) { skip_to_end = 1; } if (namereflist_length(¯o->plist) == 0) { expr_signal(ctx, STC__NOMACPRMS); skip_to_end = 1; } lt = parser_next(pctx, QL_NAME, 0); if (!is_kwdmacro) { macro->type = MACRO_SIMPLE; } } // Parse the iterative parameters (or the empty bracket pair // for conditional macros) if (lt == LEXTYPE_DELIM_LBRACK) { if (is_kwdmacro) { expr_signal(ctx, STC__ITERKWMAC); skip_to_end = 1; } if (macro_paramlist(ctx, scope, 0, 1, &closers[1], 1, ¯o->ptable, ¯o->ilist) < 0) { skip_to_end = 1; } lt = parser_next(pctx, QL_NAME, 0); macro->type = (namereflist_length(¯o->ilist) == 0 ? MACRO_COND : MACRO_ITER); } if (lt == LEXTYPE_OP_ASSIGN) { // If the type is still unknown, there were no parameter // lists, so we know this is a simple, non-parameterized // macro if (macro->type == MACRO_UNK) { macro->type = MACRO_SIMPLE; } // Parse the macro body. It must be wholly contained within // the currently open file, so we set ERRONEOF to tell the // parser that. parser_incr_erroneof(pctx); parser_scope_begin(pctx); for (lt = parser_next(pctx, QL_MACRO, &lex); lt != LEXTYPE_LXF_DELIM_PERCENT; lt = parser_next(pctx, QL_MACRO, &lex)) { if (lt == LEXTYPE_END || lt == LEXTYPE_NONE) { expr_signal(ctx, STC__SYNTAXERR); skip_to_end = 1; break; } lexseq_instail(¯o->body, lex); } parser_scope_end(pctx); parser_decr_erroneof(pctx); } if (skip_to_end) { name_free(np); string_free(expr_strctx(ctx), ltext); break; } if (macro->ptable != 0) { scope_setparent(macro->ptable, 0); } string_free(expr_strctx(ctx), ltext); if (parser_expect(pctx, QL_NAME, LEXTYPE_DELIM_SEMI, 0, 1)) { break; } if (!parser_expect(pctx, QL_NAME, LEXTYPE_DELIM_COMMA, 0, 1)) { expr_signal(ctx, STC__DELIMEXP, ","); parser_skip_to_delim(pctx, LEXTYPE_DELIM_SEMI); break; } } /* while 1 */ return 1; } /* define_macro */
static tb_void_t tb_hash_map_itor_remove_range(tb_iterator_ref_t iterator, tb_size_t prev, tb_size_t next, tb_size_t size) { // check tb_hash_map_impl_t* impl = (tb_hash_map_impl_t*)iterator; tb_assert_return(impl && impl->hash_list && impl->hash_size); // no size tb_check_return(size); // the step tb_size_t step = impl->element_name.size + impl->element_data.size; tb_assert_return(step); // the first itor tb_size_t itor = prev? tb_hash_map_itor_next(iterator, prev) : tb_hash_map_itor_head(iterator); // the head buck and item tb_size_t buck_head = tb_hash_map_index_buck(itor); tb_size_t item_head = tb_hash_map_index_item(itor); tb_assert_return(buck_head && item_head); // compute index buck_head--; item_head--; tb_assert_return(buck_head < impl->hash_size && item_head < TB_HASH_MAP_BUCKET_ITEM_MAXN); // the last buck and the tail item tb_size_t buck_last; tb_size_t item_tail; if (next) { // next => buck and item buck_last = tb_hash_map_index_buck(next); item_tail = tb_hash_map_index_item(next); tb_assert_return(buck_last && item_tail); // compute index buck_last--; item_tail--; tb_assert_return(buck_last < impl->hash_size && item_tail < TB_HASH_MAP_BUCKET_ITEM_MAXN); } else { buck_last = impl->hash_size - 1; item_tail = -1; } // remove items: [itor, next) tb_size_t buck; tb_size_t item; tb_element_free_func_t name_free = impl->element_name.free; tb_element_free_func_t data_free = impl->element_data.free; for (buck = buck_head, item = item_head; buck <= buck_last; buck++, item = 0) { // the list tb_hash_map_item_list_t* list = impl->hash_list[buck]; tb_check_continue(list && list->size); // the tail tb_size_t tail = (buck == buck_last && next)? item_tail : list->size; tb_assert_abort(tail != -1); tb_check_continue(item < tail); // the data tb_byte_t* data = (tb_byte_t*)&list[1]; // free items tb_size_t i = 0; for (i = item; i < tail; i++) { if (name_free) name_free(&impl->element_name, data + i * step); if (data_free) data_free(&impl->element_data, data + i * step + impl->element_name.size); } // move items if (buck == buck_last && tail < list->size) tb_memmov(data + item * step, data + tail * step, (list->size - tail) * step); // update the list size list->size -= tail - item; // update the item size impl->item_size -= tail - item; } }