void setup_macro(struct macro_head *h, int arity, struct pnode *parms) { if (enforce_arity(arity, list_length(h->parms))) { /* push table for the marco parms */ state.stTopDefines = push_symbol_table(state.stTopDefines, state.case_insensitive); /* Now add the macro's declared parameter list to the new defines table. */ if (arity > 0) { struct pnode *pFrom, *pFromH; struct pnode *pTo, *pToH; struct symbol *sym; pTo = parms; for (pFrom = h->parms; pFrom; pFrom = TAIL(pFrom)) { pToH = HEAD(pTo); pFromH = HEAD(pFrom); assert(pFromH->tag == symbol); arg_index = 0; arg_buffer[0] = '\0'; node_to_string(pToH); sym = add_symbol(state.stTopDefines, pFromH->value.symbol); annotate_symbol(sym, strdup(arg_buffer)); pTo = TAIL(pTo); } } state.next_state = state_macro; state.next_buffer.macro = h; state.lst.line.linetype = none; } }
// expand partial ref (it is ensured to be leaf by toposort), and eliminate nil rules static void _expand_lex_def(struct ContextMap* context_map, Val name) { Val curr; bool found = ContextMap.find(context_map, name, &curr); assert(found); Val res = VAL_NIL; for (; curr != VAL_NIL; curr = TAIL(curr)) { if (IS_A(HEAD(curr), "RefPartialContext")) { Val ref_name = AT(HEAD(curr), 0); Val child_nodes; bool found = ContextMap.find(context_map, ref_name, &child_nodes); if (!found) { COMPILE_ERROR("partial context not found: %.*s", (int)nb_string_byte_size(ref_name), nb_string_ptr(ref_name)); } for (Val child_curr = child_nodes; child_curr != VAL_NIL; child_curr = TAIL(child_curr)) { if (child_curr != VAL_NIL) { res = nb_cons_new(child_curr, res); } } } } // yes it allocs more, but necessary to keep the order consistent ContextMap.insert(context_map, name, nb_cons_reverse(res)); }
void enqueue(queue q, int n) { node nd = malloc(sizeof(node_t)); nd->val = n; if (!HEAD(q)) HEAD(q) = nd; nd->prev = TAIL(q); if (nd->prev) nd->prev->next = nd; TAIL(q) = nd; nd->next = 0; }
int dequeue(queue q, int *val) { node tmp = HEAD(q); if (!tmp) return 0; *val = tmp->val; HEAD(q) = tmp->next; if (TAIL(q) == tmp) TAIL(q) = 0; free(tmp); return 1; }
void enqueue(queue q, ThrdCtlBlk n) { node nd = malloc(sizeof(node_t)); nd->block = n; if (!HEAD(q)){ HEAD(q) = nd; } nd->prev = TAIL(q); if (nd->prev){ nd->prev->next = nd; } TAIL(q) = nd; nd->next = 0; }
void setup_macro(struct macro_head *h, int arity, struct pnode *parms) { if (enforce_arity(arity, list_length(h->parms))) { /* push table for the marco parms */ state.stTopDefines = push_symbol_table(state.stTopDefines, state.case_insensitive); /* Now add the macro's declared parameter list to the new defines table. */ if (arity > 0) { struct pnode *pFrom, *pFromH; struct pnode *pTo, *pToH; struct symbol *sym; char buffer[BUFSIZ]; pTo = parms; for (pFrom = h->parms; pFrom; pFrom = TAIL(pFrom)) { pToH = HEAD(pTo); pFromH = HEAD(pFrom); assert(pFromH->tag == symbol); sym = add_symbol(state.stTopDefines, pFromH->value.symbol); /* must convert the parm to a plain string, this will allow subsitutions of labels and strings */ if (pToH->tag == symbol) { annotate_symbol(sym, strdup(pToH->value.symbol)); } else if (pToH->tag == string) { sprintf(buffer, "\"%s\"", pToH->value.string); annotate_symbol(sym, strdup(buffer)); } else { int value = maybe_evaluate(pToH); if (value < 0) sprintf(buffer, "-%#x", -value); else sprintf(buffer, "%#x", value); annotate_symbol(sym, strdup(buffer)); } pTo = TAIL(pTo); } } state.next_state = _macro; state.next_buffer.macro = h; state.lst.line.linetype = none; } }
int dequeue(queue q, ThrdCtlBlk *val) { node tmp = HEAD(q); if (!tmp){ return 0; } *val = tmp->block; HEAD(q) = tmp->next; if (TAIL(q) == tmp){ TAIL(q) = 0; } free(tmp); return 1; }
static int print_string(FILE* fp, const ETERM* ep) { int ch_written = 0; /* counter of written chars */ putc('"', fp); ch_written++; while (ERL_IS_CONS(ep)) { int c = ERL_INT_VALUE(HEAD(ep)); if (c >= ' ') { putc(c, fp); ch_written++; } else { switch (c) { case '\n': fputs("\\n", fp); ch_written += 2; break; case '\r': fputs("\\r", fp); ch_written += 2; break; case '\t': fputs("\\t", fp); ch_written += 2; break; case '\v': fputs("\\v", fp); ch_written += 2; break; case '\b': fputs("\\b", fp); ch_written += 2; break; case '\f': fputs("\\f", fp); ch_written += 2; break; break; default: ch_written += fprintf(fp, "\\%o", c); break; } } ep = TAIL(ep); } putc('"', fp); ch_written++; return ch_written; }
static int is_printable_list(const ETERM* term) { while (ERL_TYPE(term) == ERL_LIST) { ETERM* head = HEAD(term); if (!ERL_IS_BYTE(head)) { return 0; } if (ERL_INT_VALUE(head) < ' ') { switch (ERL_INT_VALUE(head)) { case '\n': case '\r': case '\t': case '\v': case '\b': case '\f': break; default: return 0; } } term = TAIL(term); } return ERL_IS_EMPTY_LIST(term); }
static void iolist_to_buf(const ETERM* term, char** bufp) { char* dest = *bufp; while (ERL_IS_CONS(term)) { ETERM* obj = HEAD(term); if (ERL_IS_BYTE(obj)) { *dest++ = ERL_INT_VALUE(obj); } else if (ERL_IS_CONS(obj)) { iolist_to_buf(obj, &dest); } else if (ERL_IS_BINARY(obj)) { memcpy(dest, ERL_BIN_PTR(obj), ERL_BIN_SIZE(obj)); dest += ERL_BIN_SIZE(obj); } else { /* * Types have been checked by caller. */ if (!ERL_IS_EMPTY_LIST(obj)) return; /* ASSERT(ERL_IS_EMPTY_LIST(obj)); */ } term = TAIL(term); } if (ERL_IS_BINARY(term)) { memcpy(dest, ERL_BIN_PTR(term), ERL_BIN_SIZE(term)); dest += ERL_BIN_SIZE(term); } else { /* * Types have been checked by caller. */ if (!ERL_IS_EMPTY_LIST(term)) return; /* ASSERT(ERL_IS_EMPTY_LIST(term));*/ } *bufp = dest; }
ETERM *erl_mk_estring(const char *s, int len) { ETERM *ep; int i; if ((!s) || (len < 0)) return NULL; /* * ASSERT(s != NULL); * ASSERT(len >= 0); */ ep = erl_mk_empty_list(); for (i = len-1; i >= 0; i--) { ETERM* integer; ETERM* cons; integer = erl_alloc_eterm(ERL_INTEGER); ERL_COUNT(integer) = 1; ERL_INT_VALUE(integer) = (unsigned char)s[i]; cons = erl_alloc_eterm(ERL_LIST); ERL_COUNT(cons) = 1; HEAD(cons) = integer; TAIL(cons) = ep; ep = cons; } return ep; }
int erl_iolist_length (const ETERM* term) { int len = 0; while (ERL_IS_CONS(term)) { ETERM* obj = HEAD(term); if (ERL_IS_BYTE(obj)) { len++; } else if (ERL_IS_CONS(obj)) { int i; if ((i = erl_iolist_length(obj)) < 0) return i; len += i; } else if (ERL_IS_BINARY(obj)) { len += ERL_BIN_SIZE(obj); } else if (!ERL_IS_EMPTY_LIST(obj)) { return(-1); } term = TAIL(term); } if (ERL_IS_EMPTY_LIST(term)) return len; else if (ERL_IS_BINARY(term)) return len + ERL_BIN_SIZE(term); else return -1; }
static void write_statements(tree *statements) { tree *list; tree *statement; list = statements; assert(list->tag == node_list); while(list) { statement = HEAD(list); switch(statement->tag) { case node_call: write_call(statement); break; case node_cond: write_cond(statement); break; case node_loop: write_loop(statement); break; default: write_expression(statement); } list = TAIL(list); } }
int extract(queue q, Tid val, ThrdCtlBlk *retval) { if(empty(q)) { return 0; } node tmp = HEAD(q); while(!tmp) //!(tmp->block == val) && tmp->next != 0) { ThrdCtlBlk tmpBlock = tmp->block; Tid tidval = tmpBlock.tid; if(tidval == val) { break; } tmp = tmp->next; } if(tmp) { if(tmp == HEAD(q)) { dequeue(q,retval); return 1; } if (TAIL(q) == tmp) { TAIL(q) = 0; node p = tmp->prev; p->next = TAIL(q); *retval = tmp->block; return 1; } else { node p = tmp->prev; node n = tmp->next; p->next = n; n->prev = p; retval = &tmp->block; return 1; } } else { return 0; } }
static int list_length(tree *L) { if (L == NULL) { return 0; } else { return 1 + list_length(TAIL(L)); } }
int list_length(struct pnode *L) { struct pnode *p = L; int n = 0; while (p && list == p->tag) { ++n; p = TAIL(p); } return (NULL != p) ? n + 1: n; }
/* * Extract the TAIL of a LIST. Bump the reference * counter on the tail object. */ ETERM *erl_tl (const ETERM *ep) { ETERM *tl; if (!ep) return NULL; /* ASSERT(ep != NULL); */ if (ERL_TYPE(ep) != ERL_LIST) { return (ETERM *) NULL; } tl = TAIL(ep); ERL_COUNT(tl)++; return tl; }
void cfree (void *ptr) { struct header *q = (struct header *)ptr-1; int qsize = q->size; char *qtail = TAIL(q); struct header *prev = freeList; struct header *p = prev->next; while (p && p->next<q){ prev = p; p = p->next; } char *prevtail = TAIL(prev); if (prevtail==(void *)q && qtail == (void *)p){ prev->size += (q->size+p->size); prev->next = p->next; return; } else if (prevtail == (void *)q){ prev->size += q->size; return; } else if (qtail == (void *)p){ q->size += p->size; q->next = p; prev->next = q; return; } else { q->next = p; prev->next = q; return; } }
/* * Return the LENGTH of a LIST. * At failure -1 is returned (this include non-proper lists like [a|b]). */ int erl_length(const ETERM *ep) { int n = 0; if (!ep) return -1; /* ASSERT(ep != NULL); */ while (ERL_TYPE(ep) == ERL_LIST) { n++; ep = TAIL(ep); } if (!ERL_IS_EMPTY_LIST(ep)) return -1; return n; }
static void extern_args(char *main_name, tree *list) { tree *decl; tree *symbol; while (list) { decl = HEAD(list); assert(decl->tag == node_decl); symbol = decl->value.decl.expr; assert(symbol->tag == node_symbol); extern_name(main_name, symbol->value.symbol, symbol); list = TAIL(list); } }
/* Insert a new element at the end; chan->lock must be held. * Returns 0 if data has been written or if data may be written * if 'data' is NULL. */ static int channel_write(sdb_channel_t *chan, const void *data) { assert(chan); if (chan->full || chan->shutdown) return -1; else if (! data) return 0; memcpy(TAIL(chan), data, chan->elem_size); chan->tail = NEXT_WRITE(chan); chan->full = chan->tail == chan->head; pthread_cond_broadcast(&chan->cond); return 0; } /* channel_write */
static void write_declarations(void) { entity *entity_list = NULL; tree *current = NULL; int first_time = 1; tree *list; tree *symbol; entity_list = state.list; while (entity_list != NULL) { current = entity_list->node; if ((current->tag == node_decl) && (current->value.decl.storage != EXTERN_STORAGE)) { if ((current->value.decl.type == CONST_TYPE) && (current->value.decl.storage != 0)) { gp_error("constants can't be public or volatile"); } /* FIXME: only bytes are supported so far */ assert(current->value.decl.size == BYTE_SIZE); if (first_time) { fprintf(state.output.f, "; declarations \n"); fprintf(state.output.f, " udata\n"); first_time = 0; } for (list = current->value.decl.expr; list; list = TAIL(list)) { symbol = HEAD(list); assert(symbol->tag == node_symbol); if (current->value.decl.type == VAR_TYPE) { fprintf(state.output.f, "%s res 1\n", symbol->value.symbol); if (current->value.decl.storage == PUBLIC_STORAGE) fprintf(state.output.f, " global %s\n", symbol->value.symbol); } add_global(symbol->value.symbol, symbol->value.symbol, current); } } entity_list = entity_list->next; } if (!first_time) fprintf(state.output.f, "\n"); }
/* * Return the CONTENT of a VARIABLE with NAME. * If the content is non-nil then bump its * reference counter. */ ETERM *erl_var_content (const ETERM *ep, const char *name) { int i; ETERM *vp; if ((!ep) || (!name)) return NULL; /* ASSERT(ep != NULL); */ switch(ERL_TYPE(ep)) { case ERL_VARIABLE: if (strcmp(ERL_VAR_NAME(ep), name) == 0) { if ((vp = ERL_VAR_VALUE(ep)) != NULL) { ERL_COUNT(vp)++; return vp; } } break; case ERL_LIST: while (ep && (ERL_TYPE(ep) != ERL_EMPTY_LIST)) { if ((vp = erl_var_content(HEAD(ep), name))) return vp; ep = TAIL(ep); } break; case ERL_TUPLE: for (i=0; i < ERL_TUPLE_SIZE(ep); i++) if ((vp = erl_var_content(ERL_TUPLE_ELEMENT(ep, i), name))) { return vp; } break; default: /* variables can't occur in other types */ break; } /* nothing found ! */ return NULL; }
/* * Construct a new list by CONS'ing a HEAD on * to the TAIL. Bump the reference counter on * the head and tail object. Note that we allow * non-well formed lists to be created. */ ETERM *erl_cons(ETERM *hd, ETERM *tl) { ETERM *ep; if ((!hd) || (!tl)) return NULL; /* * ASSERT(hd != NULL); * ASSERT(tl != NULL); */ ep = erl_alloc_eterm(ERL_LIST); ERL_COUNT(ep) = 1; HEAD(ep) = hd; TAIL(ep) = tl; ERL_COUNT(hd)++; ERL_COUNT(tl)++; return ep; }
void * cmalloc (int bytes) { if (bytes<0) die("bad mem length"); if (!memChunk){ // Use "malloc" instead of "brk" makes this // allocator portable. memChunk = malloc (MEM_SIZE); if (!memChunk) die ("out of memory"); freeList = &theHeader; assert ((void *)freeList < memChunk); freeList->next = (struct header *)memChunk; freeList = &theHeader; freeList->next->size = MEM_SIZE; freeList->next->next = 0; } // first time match struct header *prev = freeList; struct header *p = prev->next; while (p && p->size-HEADER_SIZE < bytes){ prev = p; p = p->next; } if (!p) die ("no memory chunk found"); if (p->size-HEADER_SIZE == bytes){ prev->next = p->next; return ++p; } // p->size-HEADER_SIZE > bytes struct header *q = (struct header *)(TAIL(p)-bytes-HEADER_SIZE); q->next = 0; q->size = bytes+HEADER_SIZE; p->size -= (bytes+HEADER_SIZE); return ++q; }
static void write_decl(tree *decl, char *name) { tree *list; tree *symbol; char alias[BUFSIZ]; assert(decl->tag == node_decl); list = decl->value.decl.expr; assert(list->tag == node_list); for (; list; list = TAIL(list)) { symbol = HEAD(list); assert(symbol->tag == node_symbol); sprintf(alias, "%s_%s", name, symbol->value.symbol); add_global(symbol->value.symbol, alias, symbol); if (decl->value.decl.type == VAR_TYPE) { fprintf(state.output.f, "%s res 1\n", alias); } } }
/* Links the named object files for dynamic loading, reads it in, and returns a "foreign_file" object which allows access to its symbols. If names is a non-empty list (of byte-strings), then make ld "undefine" these names so that they will show up in the linked version. */ obj_t load_c_file(obj_t /* list */ c_files, obj_t /* list */ names) { int i; obj_t retval = obj_False; struct shared_file *ret; shl_t handle; retval = alloc(obj_SharedFileClass, sizeof(struct shared_file) + ((length(c_files) - 1) * sizeof(shl_t))); ret = obj_ptr(struct shared_file *, retval); ret->file_count = length(c_files); for (i = 0; c_files != obj_Nil; i++, c_files = TAIL(c_files)) { handle = shl_load(string_chars(HEAD(c_files))); if (handle == NULL) { error("Can't load shared library %s.", HEAD(c_files)); }; ret->handles[i] = handle; ret->file_name = HEAD(c_files); } return retval; }
static inline isc_boolean_t task_shutdown(isc__task_t *task) { isc_boolean_t was_idle = ISC_FALSE; isc_event_t *event, *prev; /* * Caller must be holding the task's lock. */ XTRACE("task_shutdown"); if (! TASK_SHUTTINGDOWN(task)) { XTRACE(isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_SHUTTINGDOWN, "shutting down")); task->flags |= TASK_F_SHUTTINGDOWN; if (task->state == task_state_idle) { INSIST(EMPTY(task->events)); task->state = task_state_ready; was_idle = ISC_TRUE; } INSIST(task->state == task_state_ready || task->state == task_state_running); /* * Note that we post shutdown events LIFO. */ for (event = TAIL(task->on_shutdown); event != NULL; event = prev) { prev = PREV(event, ev_link); DEQUEUE(task->on_shutdown, event, ev_link); ENQUEUE(task->events, event, ev_link); } } return (was_idle); }
/** * Change setting 'name' to value specified by attribute 'attr_name' in LDAP * entry. Setting is un-set if specified value is missing in LDAP entry. * * @warning Multi-value attributes are no supported. * * @retval ISC_R_SUCCESS Setting was changed (set or unset). * @retval ISC_R_IGNORE Setting wasn't changed because value in settings set * and LDAP entry was same. * @retval ISC_R_NOTFOUND Required setting was not found in given set. * @retval Others Memory allocation or conversion errors. */ isc_result_t setting_update_from_ldap_entry(const char *name, settings_set_t *set, const char *attr_name, ldap_entry_t *entry) { isc_result_t result; setting_t *setting = NULL; ldap_valuelist_t values; CHECK(setting_find(name, set, ISC_FALSE, ISC_FALSE, &setting)); result = ldap_entry_getvalues(entry, attr_name, &values); if (result == ISC_R_NOTFOUND || HEAD(values) == NULL) { CHECK(setting_unset(name, set)); log_debug(2, "setting '%s' (%s) was deleted in object %s", name, attr_name, ldap_entry_logname(entry)); return ISC_R_SUCCESS; } else if (result != ISC_R_SUCCESS) { goto cleanup; } if (HEAD(values) != TAIL(values)) { log_bug("multi-value attributes are not supported: attribute " "'%s' in %s", attr_name, ldap_entry_logname(entry)); return ISC_R_NOTIMPLEMENTED; } CHECK(setting_set(name, set, HEAD(values)->value)); log_debug(2, "setting '%s' (%s) was changed to '%s' in %s", name, attr_name, HEAD(values)->value, ldap_entry_logname(entry)); cleanup: if (result == ISC_R_NOTFOUND) log_bug("setting '%s' was not found in settings set '%s'", name, set->name); return result; }
int erl_print_term(FILE *fp, const ETERM *ep) { int j,i,doquote; int ch_written = 0; /* counter of written chars */ if ((!fp) || (!ep)) return 0; /* ASSERT(ep != NULL); */ j = i = doquote = 0; switch(ERL_TYPE(ep)) { case ERL_ATOM: { char* adata = ERL_ATOM_PTR(ep); /* FIXME: what if some weird locale is in use? */ if (!islower(adata[0])) doquote = 1; for (i = 0; !doquote && i < ERL_ATOM_SIZE(ep); i++) { doquote = !(isalnum(adata[i]) || (adata[i] == '_')); } if (doquote) { putc('\'', fp); ch_written++; } fputs(adata, fp); ch_written += ERL_ATOM_SIZE(ep); if (doquote) { putc('\'', fp); ch_written++; } break; } case ERL_VARIABLE: if (!isupper((int)ERL_VAR_NAME(ep)[0])) { doquote = 1; putc('\'', fp); ch_written++; } fputs(ERL_VAR_NAME(ep), fp); ch_written += ERL_VAR_LEN(ep); if (doquote) { putc('\'', fp); ch_written++; } break; case ERL_PID: ch_written += fprintf(fp, "<%s.%d.%d>", ERL_PID_NODE(ep), ERL_PID_NUMBER(ep), ERL_PID_SERIAL(ep)); break; case ERL_PORT: ch_written += fprintf(fp, "#Port"); break; case ERL_REF: ch_written += fprintf(fp, "#Ref"); break; case ERL_EMPTY_LIST: ch_written += fprintf(fp, "[]"); break; case ERL_LIST: if (is_printable_list(ep)) { ch_written += print_string(fp, ep); } else { putc('[', fp); ch_written++; while (ERL_IS_CONS(ep)) { ch_written += erl_print_term(fp, HEAD(ep)); ep = TAIL(ep); if (ERL_IS_CONS(ep)) { putc(',', fp); ch_written++; } } if (!ERL_IS_EMPTY_LIST(ep)) { putc('|', fp); ch_written++; ch_written += erl_print_term(fp, ep); } putc(']', fp); ch_written++; } break; case ERL_TUPLE: putc('{', fp); ch_written++; for (i=0; i < ERL_TUPLE_SIZE(ep); i++) { ch_written += erl_print_term(fp, ERL_TUPLE_ELEMENT(ep, j++) ); if (i != ERL_TUPLE_SIZE(ep)-1) { putc(',', fp); ch_written++; } } putc('}', fp); ch_written++; break; case ERL_BINARY: { int sz = (ERL_BIN_SIZE(ep) > 20) ? 20 : ERL_BIN_SIZE(ep); unsigned char *ptr = ERL_BIN_PTR(ep); ch_written += fprintf(fp, "#Bin<"); for (i = 0; i < sz; i++) { putc(ptr[i], fp); ch_written++; } if (sz == 20) ch_written += fprintf(fp, "(%d)....>", ERL_BIN_SIZE(ep)-20); else ch_written += fprintf(fp, ">"); break; } case ERL_INTEGER: case ERL_SMALL_BIG: ch_written += fprintf(fp, "%d", ERL_INT_VALUE(ep)); break; case ERL_U_INTEGER: case ERL_U_SMALL_BIG: ch_written += fprintf(fp, "%d", ERL_INT_UVALUE(ep)); break; case ERL_LONGLONG: case ERL_U_LONGLONG: ch_written += fprintf(fp, "%lld", ERL_LL_UVALUE(ep)); break; case ERL_FLOAT: ch_written += fprintf(fp, "%f", ERL_FLOAT_VALUE(ep)); break; case ERL_FUNCTION: ch_written += fprintf(fp, "#Fun<"); ch_written += erl_print_term(fp, ERL_FUN_MODULE(ep)); putc('.', fp); ch_written++; ch_written += erl_print_term(fp, ERL_FUN_INDEX(ep)); putc('.', fp); ch_written++; ch_written += erl_print_term(fp, ERL_FUN_UNIQ(ep)); putc('>', fp); ch_written++; break; default: ch_written = -10000; erl_err_msg("<ERROR> erl_print_term: Bad type of term !"); } return ch_written; }