/* * 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; }
/* * Create an empty VARIABLE. */ ETERM *erl_mk_var(const char *s) { ETERM *ep; if (!s) return NULL; /* ASSERT(s != NULL); */ ep = erl_alloc_eterm(ERL_VARIABLE); ERL_COUNT(ep) = 1; ERL_VAR_LEN(ep) = strlen(s); if ((ERL_VAR_NAME(ep) = strsave(s)) == NULL) { erl_free_term(ep); erl_errno = ENOMEM; return NULL; } ERL_VAR_VALUE(ep) = (ETERM *) NULL; return ep; }
/* * Dump (print for debugging) a term. Useful if/when things go wrong. */ void dump_term (FILE *fp, ETERM *t) { if (fp == NULL) return; fprintf(fp, "#<%p ", t); if(t != NULL) { fprintf(fp, "count:%d, type:%d", ERL_COUNT(t), ERL_TYPE(t)); switch(ERL_TYPE(t)) { case ERL_UNDEF: fprintf(fp, "==undef"); break; case ERL_INTEGER: fprintf(fp, "==int, val:%d", ERL_INT_VALUE(t)); break; case ERL_U_INTEGER: fprintf(fp, "==uint, val:%u", ERL_INT_UVALUE(t)); break; case ERL_FLOAT: fprintf(fp, "==float, val:%g", ERL_FLOAT_VALUE(t)); break; case ERL_ATOM: fprintf(fp, "==atom, name:%p \"%s\"", ERL_ATOM_PTR(t), ERL_ATOM_PTR(t)); break; case ERL_BINARY: fprintf(fp, "==binary, data:%p,%u", ERL_BIN_PTR(t), ERL_BIN_SIZE(t)); break; case ERL_PID: fprintf(fp, "==pid, node:%p \"%s\"", ERL_PID_NODE(t), ERL_PID_NODE(t)); break; case ERL_PORT: fprintf(fp, "==port, node:%p \"%s\"", ERL_PORT_NODE(t), ERL_PORT_NODE(t)); break; case ERL_REF: fprintf(fp, "==ref, node:%p \"%s\"", ERL_REF_NODE(t), ERL_REF_NODE(t)); break; case ERL_CONS: fprintf(fp, "==cons"); fprintf(fp, ", car:"); dump_term(fp, ERL_CONS_HEAD(t)); fprintf(fp, ", cdr:"); dump_term(fp, ERL_CONS_TAIL(t)); break; case ERL_NIL: fprintf(fp, "==nil"); break; case ERL_TUPLE: fprintf(fp, "==tuple, elems:%p,%u", ERL_TUPLE_ELEMS(t), ERL_TUPLE_SIZE(t)); { size_t i; for(i = 0; i < ERL_TUPLE_SIZE(t); i++) { fprintf(fp, "elem[%u]:", i); dump_term(fp, ERL_TUPLE_ELEMENT(t, i)); } } break; case ERL_VARIABLE: fprintf(fp, "==variable, name:%p \"%s\"", ERL_VAR_NAME(t), ERL_VAR_NAME(t)); fprintf(fp, ", value:"); dump_term(fp, ERL_VAR_VALUE(t)); break; default: break; } } fprintf(fp, ">"); }