Ejemplo n.º 1
0
int
symexpand(struct idl *idl, struct sym *sym)
{
	char *key;
	struct sym *mem;
	iter_t iter;

	if (IS_EXPANDED(sym)) {
		return 0;
	}
	sym->flags |= FLAGS_EXPANDED;
	sym->orig = sym;

	if (IS_INTERFACE(sym)) {
		const char *pd = hashmap_get(&sym->attrs, "pointer_default");
		idl->ptr_default = PTR_TYPE_UNIQUE;
		if (pd) {
			if (strcmp(pd, "ptr") == 0) {
				idl->ptr_default = PTR_TYPE_PTR;
			} else if (strcmp(pd, "ref") == 0) {
				idl->ptr_default = PTR_TYPE_REF;
			}
		}
	} else if (IS_ENUM(sym)) {
		char buf[16];
		int val = 0;

		linkedlist_iterate(&sym->mems, &iter);
		while ((mem = linkedlist_next(&sym->mems, &iter))) {
			mem->flags = FLAGS_CONST | FLAGS_PRIMATIVE;
			if (mem->value) {
				val = strtoul(mem->value, NULL, 0);
			}
			sprintf(buf, "%d", val++);
			mem->value = dupstr(buf, idl->al);
		}
	} else if (sym->ptr) {
		if (hashmap_get(&sym->attrs, "unique")) {
			sym->ptr_type = PTR_TYPE_UNIQUE;
		} else if (hashmap_get(&sym->attrs, "ptr")) {
			sym->ptr_type = PTR_TYPE_PTR;
		} else if (hashmap_get(&sym->attrs, "ref")) {
			sym->ptr_type = PTR_TYPE_REF;
		} else if (IS_PARAMETER(sym) || IS_OPERATION(sym)) {
			sym->ptr_type = PTR_TYPE_REF;
		} else {
			sym->ptr_type = idl->ptr_default;
		}
	}

	/* If the symbol is typedef'd add it to the table using the
	 * typedef'd name too
	 */
	if (IS_TYPEDEFD(sym) && sym->name) {
		if (IS_ENUM(sym) && (mem = hashmap_get(idl->syms, sym->idl_type))) {
			mem->noemit = 1; /* supress redundant enum */
		}
		key = sym->name;
	} else {
		key = sym->idl_type;
	}
	if (hashmap_get(idl->syms, key) == NULL) {
		if (hashmap_put(idl->syms, key, sym) == -1) {
			AMSG("");
		}
	}

	/* If the symbol has members it is already expanded
	 */
	if (linkedlist_size(&sym->mems) == 0) {
		struct sym *s = symlook(idl, sym->idl_type);
		if (s) {
			sym->interface = s->interface;
			linkedlist_iterate(&s->mems, &iter);
			while ((mem = linkedlist_next(&s->mems, &iter))) {
				struct sym *cpy = symnew(idl->al);
				symcopy(mem, cpy, idl->al);
				linkedlist_add(&sym->mems, cpy);
			}
		} else {
			AMSG("");
			return -1;
		}
	}

	sym->id = idl->symid++;

	/* Perform expansion recursively on all symbols
	 */
	linkedlist_iterate(&sym->mems, &iter);
	while ((mem = linkedlist_next(&sym->mems, &iter))) {
		symexpand(idl, mem);
		mem->parent = sym;
	}

	return 0;
}
Ejemplo n.º 2
0
static void
tre_do_print(FILE *stream, tre_ast_node_t *ast, int indent)
{
  int code_min, code_max, pos;
  int num_tags = ast->num_tags;
  tre_literal_t *lit;
  tre_iteration_t *iter;

  tre_findent(stream, indent);
  switch (ast->type)
    {
    case LITERAL:
      lit = ast->obj;
      code_min = lit->code_min;
      code_max = lit->code_max;
      pos = lit->position;
      if (IS_EMPTY(lit))
	{
	  fprintf(stream, "literal empty\n");
	}
      else if (IS_ASSERTION(lit))
	{
	  int i;
	  char *assertions[] = { "bol", "eol", "bracket",
				 "bow", "eow", "wb", "!wb", "backref" };
	  if (code_max >= ASSERT_LAST << 1)
	    assert(0);
	  fprintf(stream, "assertions: ");
	  for (i = 0; (1 << i) <= ASSERT_LAST; i++)
	    if (code_max & (1 << i))
	      fprintf(stream, "%s ", assertions[i]);
	  fprintf(stream, "\n");
	}
      else if (IS_TAG(lit))
	{
	  fprintf(stream, "tag %d\n", code_max);
	}
      else if (IS_BACKREF(lit))
	{
	  fprintf(stream, "backref %d, pos %d\n", code_max, pos);
	}
      else if (IS_PARAMETER(lit))
	{
	  tre_print_params(lit->u.params);
	  fprintf(stream, "\n");
	}
      else
	{
	  fprintf(stream, "literal (%c, %c) (%d, %d), pos %d, sub %d, "
		  "%d tags\n", code_min, code_max, code_min, code_max, pos,
		  ast->submatch_id, num_tags);
	}
      break;
    case ITERATION:
      iter = ast->obj;
      fprintf(stream, "iteration {%d, %d}, sub %d, %d tags, %s\n",
	      iter->min, iter->max, ast->submatch_id, num_tags,
	      iter->minimal ? "minimal" : "greedy");
      tre_do_print(stream, iter->arg, indent + 2);
      break;
    case UNION:
      fprintf(stream, "union, sub %d, %d tags\n", ast->submatch_id, num_tags);
      tre_do_print(stream, ((tre_union_t *)ast->obj)->left, indent + 2);
      tre_do_print(stream, ((tre_union_t *)ast->obj)->right, indent + 2);
      break;
    case CATENATION:
      fprintf(stream, "catenation, sub %d, %d tags\n", ast->submatch_id,
	      num_tags);
      tre_do_print(stream, ((tre_catenation_t *)ast->obj)->left, indent + 2);
      tre_do_print(stream, ((tre_catenation_t *)ast->obj)->right, indent + 2);
      break;
    default:
      assert(0);
      break;
    }
}