Example #1
0
/* 
 * 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;
}
Example #2
0
/* 
 * 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;
}
Example #3
0
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;
}
Example #4
0
int erl_sprint_term(char *buf, const ETERM *ep)
{
    int j,i,doquote;
    int ch_written = 0; /* counter of written chars */

    if ((!buf) || (!ep)) return 0;
    /* ASSERT(ep != NULL); */

    j = i = doquote = 0;
    switch(ERL_TYPE(ep)) 
    {
    case ERL_ATOM:
	/* FIXME: what if some weird locale is in use? */
	if (!islower((int)ERL_ATOM_PTR(ep)[0]))
	    doquote = 1;

	for (i = 0; !doquote && i < ERL_ATOM_SIZE(ep); i++) 
	{
	    doquote = !(isalnum((int)ERL_ATOM_PTR(ep)[i]) 
			|| (ERL_ATOM_PTR(ep)[i] == '_'));
	}

	if (doquote) {
	    *buf++ = '\'';
	    ch_written++; 
	}
	{
	    int len = ERL_ATOM_SIZE(ep);
	    strncpy(buf, ERL_ATOM_PTR(ep), len);
	    buf += len;
	    ch_written += len;	
	}
	if (doquote) {
	    *buf++ = '\'';
	    ch_written++;
	}
	break;

    case ERL_VARIABLE:
	if (!isupper((int)ERL_VAR_NAME(ep)[0])) {
	    doquote = 1;
	    *buf++ = '\'';
	    ch_written++;
	}
	len = ERL_VAR_LEN(ep);
	strncpy(buf, ERL_VAR_NAME(ep), len);
	buf += len;
	ch_written += len;
	
	if (doquote) {
	    *buf++ = '\'';
	    ch_written++;
	}
	break;

    case ERL_PID:
	len = sprintf(buf, "<%s.%d.%d>", 
		      ERL_PID_NODE(ep), 
		      ERL_PID_NUMBER(ep), ERL_PID_SERIAL(ep));
        buf += len;
        ch_written += len;
	break;
    case ERL_PORT:
	len = sprintf(buf , "#Port");
        buf += len;
        ch_written += len;
	break;
    case ERL_REF:
	len = sprintf(buf , "#Ref");
        buf += len;
        ch_written += len;
	break;
    case ERL_EMPTY_LIST:
	len = sprintf(buf , "[]");
        buf += len;
        ch_written += len;
	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_sprint_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_sprint_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_sprint_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:
	len = sprintf(buf , "#Bin");
        buf += len;
        ch_written += len;
	break;
    case ERL_INTEGER:
    case ERL_SMALL_BIG:
	len = sprintf(buf , "%d", ERL_INT_VALUE(ep));
        buf += len;
        ch_written += len;
	break;
    case ERL_U_INTEGER:
    case ERL_U_SMALL_BIG:
	len = sprintf(buf , "%d", ERL_INT_UVALUE(ep));
        buf += len;
        ch_written += len;
	break;
    case ERL_FLOAT:
	len = sprintf(buf , "%f", ERL_FLOAT_VALUE(ep));
        buf += len;
        ch_written += len;
	break;
    case ERL_FUNCTION:
	len = sprintf(buf , "#Fun<");
        buf += len;
        ch_written += len;
	ch_written += erl_sprint_term(fp, ERL_FUN_MODULE(ep));
	putc('.', fp);
	ch_written++;
	ch_written += erl_sprint_term(fp, ERL_FUN_INDEX(ep));
	putc('.', fp);
	ch_written++;
	ch_written += erl_sprint_term(fp, ERL_FUN_UNIQ(ep));
	putc('>', fp);
	ch_written++;
	break;
    default:
	ch_written = -10000;
	erl_err_msg("<ERROR> erl_sprint_term: Bad type of term !");
    }
    return ch_written;
}
Example #5
0
/*
 * 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, ">");
}