int				put_stones(t_env *env)
{
	int				type_rate[2];
	int				quantity;
	int				x;
	int				y;
	int				c;
	static int		base_rate[NB_STONE + 1] = {

	RATE_FOOD, RATE_LINEMATE, RATE_DERAUMERE, RATE_SIBUR, RATE_MENDIANE,
	RATE_PHIRAS, RATE_THYSTAME};
	type_rate[0] = -1;
	while (++type_rate[0] < NB_STONE + 1)
	{
		quantity = get_quantity_by_type(env, type_rate[0]) + 1;
		c = 1;
		while (quantity-- && (type_rate[1] = base_rate[type_rate[0]]) >= 0)
		{
			x = rand_int(0, env->opt.x);
			y = rand_int(0, env->opt.y);
			env->map[y][x].ground[type_rate[0]] = 1;
			c += put_one(env, type_rate, x, y);
		}
		printf("%d %s ont ete poses.\n", c, type_to_str(type_rate[0]));
	}
	return (0);
}
Exemple #2
0
    std::vector<Section*> get_executable_section(std::ifstream &file) const
    {
        std::vector<Section*> exec_sections;

        for(iter_elf_phdr it = elfProgramHeaders.begin(); it != elfProgramHeaders.end(); ++it)
        {
            if((*it)->p_flags & 1)
            {
                Section *sec = new (std::nothrow) Section(
                    type_to_str((*it)->p_type).c_str(),
                    (*it)->p_offset,
                    (*it)->p_vaddr,
                    (*it)->p_filesz
                );

                if(sec == NULL)
                    RAISE_EXCEPTION("Cannot alocate a section");
                
                sec->dump(file);
                sec->set_props(Section::Executable);

                exec_sections.push_back(sec);
            }
        }

        return exec_sections;
    }
Exemple #3
0
static void test_read_xmldeclaration(void)
{
    IXmlReader *reader;
    IStream *stream;
    HRESULT hr;
    XmlNodeType type;
    UINT count = 0;

    hr = pCreateXmlReader(&IID_IXmlReader, (LPVOID*)&reader, NULL);
    ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);

    /* position methods with Null args */
    hr = IXmlReader_GetLineNumber(reader, NULL);
    ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);

    hr = IXmlReader_GetLinePosition(reader, NULL);
    ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr);

    stream = create_stream_on_data(xmldecl_full, sizeof(xmldecl_full));

    hr = IXmlReader_SetInput(reader, (IUnknown*)stream);
    ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);

    ok_pos(reader, 0, 0, -1, -1, FALSE);

    type = -1;
    hr = IXmlReader_Read(reader, &type);
todo_wine {
    ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
    ok(type == XmlNodeType_XmlDeclaration,
                     "Expected XmlNodeType_XmlDeclaration, got %s\n", type_to_str(type));
}
    /* new version 1.2.x and 1.3.x properly update postition for <?xml ?> */
    ok_pos(reader, 1, 3, -1, 55, TRUE);

    /* check attributes */
    hr = IXmlReader_MoveToNextAttribute(reader);
    todo_wine ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
    ok_pos(reader, 1, 7, -1, 55, TRUE);

    hr = IXmlReader_MoveToFirstAttribute(reader);
    todo_wine ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
    ok_pos(reader, 1, 7, -1, 55, TRUE);

    hr = IXmlReader_GetAttributeCount(reader, &count);
todo_wine {
    ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
    ok(count == 3, "Expected 3, got %d\n", count);
}
    hr = IXmlReader_GetDepth(reader, &count);
todo_wine {
    ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
    ok(count == 1, "Expected 1, got %d\n", count);
}

    IStream_Release(stream);
    IXmlReader_Release(reader);
}
Exemple #4
0
static void
private_array_resolve_symbols (type_t * tself, container_t * context, logger_t * log)
{
  estring_t * tmp = NULL;
  t_array_t * self = &(tself->t_array);

  // We need to resolve array bounds.
  boundspair_t * bp = self->bounds;
  expression_t * hi = boundspair_hi (bp);
  expression_t * lo = boundspair_lo (bp);

  // symbols in bounds are resolved with use of parental
  // symtab.  The following is illegal:
  //  'begin' 'integer' y; 'integer' 'array' z[1:y]; 'end';
  expr_resolve_symbols (lo, container_parent (context), log);
  expr_resolve_symbols (hi, container_parent (context), log);
  type_resolve_symbols (self->host, context, log);

  type_t * lot = expr_type (lo);
  type_t * hit = expr_type (hi);

  // Type of `unknown' means that appropriate reporting action has
  // already been taken.  Type of `implicit' means the symbol is yet
  // to be resolved.

  if (!type_is_unknown (lot) && !type_is_implicit (lot)
      && !types_match (lot, type_int ()))
    {
      log_printfc (log, ll_error, expr_cursor (lo),
		  "invalid type %s in lower boundary",
		  estr_cstr (tmp = type_to_str (lot, tmp)));
      boundspair_set_lo (bp, expr_primitive_for_type (type_int ()));
    }

  if (!type_is_unknown (hit) && !type_is_implicit (hit)
      && !types_match (hit, type_int ()))
    {
      log_printfc (log, ll_error, expr_cursor (hi),
		  "invalid type %s in upper boundary",
		  estr_cstr (tmp = type_to_str (hit, tmp)));
      boundspair_set_hi (bp, expr_primitive_for_type (type_int ()));
    }

  delete_estring (tmp);
}
/* this complies with system.methodSignature as defined at 
 * http://xmlrpc.usefulinc.com/doc/sysmethodsig.html 
 */
static XMLRPC_VALUE xi_system_method_signature_cb(XMLRPC_SERVER server, XMLRPC_REQUEST input, void* userData) {
   const char* method = XMLRPC_GetValueString(XMLRPC_VectorRewind(XMLRPC_RequestGetData(input)));
   XMLRPC_VALUE xResponse = NULL;

   /* lazy loading of introspection data */
   check_docs_loaded(server, userData);

   if(method) {
      server_method* sm = find_method(server, method);
      if(sm && sm->desc) {
         XMLRPC_VALUE xTypesArray = XMLRPC_CreateVector(NULL, xmlrpc_vector_array);
         XMLRPC_VALUE xIter, xParams, xSig, xSigIter;
         const char* type;

         /* array of possible signatures.  */
         xResponse = XMLRPC_CreateVector(NULL, xmlrpc_vector_array);

         /* find first signature */
         xSig = XMLRPC_VectorGetValueWithID(sm->desc, xi_token_signatures);
         xSigIter = XMLRPC_VectorRewind( xSig );

         /* iterate through sigs */
         while(xSigIter) {
            /* first type is the return value */
            type = XMLRPC_VectorGetStringWithID(XMLRPC_VectorRewind(
                                                 XMLRPC_VectorGetValueWithID(xSigIter, xi_token_returns)), 
                                                xi_token_type);
            XMLRPC_AddValueToVector(xTypesArray, 
                                    XMLRPC_CreateValueString(NULL, 
                                                             type ? type : type_to_str(xmlrpc_none, 0), 
                                    0));

            /* the rest are parameters */
            xParams = XMLRPC_VectorGetValueWithID(xSigIter, xi_token_params);
            xIter = XMLRPC_VectorRewind(xParams);

            /* iter through params, adding to types array */
            while(xIter) {
               XMLRPC_AddValueToVector(xTypesArray,
                                       XMLRPC_CreateValueString(NULL, 
                                                                XMLRPC_VectorGetStringWithID(xIter, xi_token_type),
                                                                0));
               xIter = XMLRPC_VectorNext(xParams);
            }

            /* add types for this signature */
            XMLRPC_AddValueToVector(xResponse, xTypesArray);

            xSigIter = XMLRPC_VectorNext( xSig );
         }
      }
   }

   return xResponse;
}
Exemple #6
0
/** 
 * renders a card to a space separated string like 
 * Ace Clubs, or 2 Spades 
 */
void card_to_str_long(int card, char* buffer)
{
  assert(card >= 0 && card < NSUITS*NTYPES);

  char type_buffer[16];
  char suit_buffer[16];
  type_to_str(get_type(card), type_buffer);
  suit_to_str(get_suit(card), suit_buffer);  

  sprintf(buffer, "%s %s", type_buffer, suit_buffer);
}
Exemple #7
0
static void dump_type(dump *ctx, type *ty)
{
	struct_union_enum_st *sue;
	dump_printf_indent(ctx, 0, " %s'%s'%s",
			maybe_colour(ctx->fout, col_type),
			type_to_str(ty),
			maybe_colour(ctx->fout, col_off));

	if((sue = type_is_s_or_u_or_e(ty)) && !sue_is_complete(sue))
		dump_printf_indent(ctx, 0, " (incomplete)");
}
Exemple #8
0
void heap_dump() {
    //HEAP_VALIDATE;

    size_t offset = 0;
    consout("Address   Type  Size Mark  CID           Next\n");
    consout("=============================================\n");
    int usedElements = 0;
    int freeElements = 0;
    int protElement = 0;
    size_t usedSize = 0;
    size_t freeSize = 0;
    size_t protSize = 0;
    while (offset < heap_size) {
        header_t* h = offset_header(heap, offset);

        if (get_type(h) == HT_USED) {
            usedElements++;
            usedSize += h->e.size;
        }
        if (get_type(h) == HT_FREE) {
            freeElements++;
            freeSize += h->e.size;
        }
        if (get_type(h) == HT_PROTECTED) {
            protElement++;
            protSize += h->e.size;
        }
        consout("%p %s %4d   %2d %4d  ->%10p\n", h, type_to_str(get_type(h)), h->e.size, h->e.mark,
                h->e.classId, h->e.next);
        if (get_type(h) == HT_PROTECTED || get_type(h) == HT_USED) {
            sDumpObject(h);
        }

        offset += h->e.size;
    }
    consout("\n");
    consout("Total %s: %d/%d\n", type_to_str(HT_USED), usedSize, usedElements);
    consout("Total %s: %d/%d\n", type_to_str(HT_FREE), freeSize, freeElements);
    consout("Total %s: %d/%d\n", type_to_str(HT_PROTECTED), protSize, protElement);
}
static void sentinel_check(where *w, expr *e, expr **args,
		const int variadic, const int nstdargs, symtable *stab)
{
#define ATTR_WARN_RET(w, ...) \
	do{ cc1_warn_at(w, attr_sentinel, __VA_ARGS__); return; }while(0)

	attribute *attr = func_or_builtin_attr_present(e, attr_sentinel);
	int i, nvs;
	expr *sentinel;

	if(!attr)
		return;

	if(!variadic)
		return; /* warning emitted elsewhere, on the decl */

	if(attr->bits.sentinel){
		consty k;

		FOLD_EXPR(attr->bits.sentinel, stab);
		const_fold(attr->bits.sentinel, &k);

		if(k.type != CONST_NUM || !K_INTEGRAL(k.bits.num))
			die_at(&attr->where, "sentinel attribute not reducible to integer constant");

		i = k.bits.num.val.i;
	}else{
		i = 0;
	}

	nvs = dynarray_count(args) - nstdargs;

	if(nvs == 0)
		ATTR_WARN_RET(w, "not enough variadic arguments for a sentinel");

	UCC_ASSERT(nvs >= 0, "too few args");

	if(i >= nvs)
		ATTR_WARN_RET(w, "sentinel index is not a variadic argument");

	sentinel = args[(nstdargs + nvs - 1) - i];

	/* must be of a pointer type, printf("%p\n", 0) is undefined */
	if(!expr_is_null_ptr(sentinel, NULL_STRICT_ANY_PTR))
		ATTR_WARN_RET(&sentinel->where, "sentinel argument expected (got %s)",
				type_to_str(sentinel->tree_type));

#undef ATTR_WARN_RET
}
Exemple #10
0
void fold_expr_addr(expr *e, symtable *stab)
{
	if(e->bits.lbl.spel){
		decl *in_func = symtab_func(stab);

		if(!in_func)
			die_at(&e->where, "address-of-label outside a function");

		if(e->bits.lbl.static_ctx)
			in_func->bits.func.contains_static_label_addr = 1;

		(e->bits.lbl.label =
		 symtab_label_find_or_new(
			 stab, e->bits.lbl.spel, &e->where))
			->uses++;

		/* address of label - void * */
		e->tree_type = type_ptr_to(type_nav_btype(cc1_type_nav, type_void));

	}else{
		/* if it's an identifier, act as a read */
		fold_inc_writes_if_sym(e->lhs, stab);

		fold_expr_nodecay(e->lhs, stab);

		e->tree_type = type_ptr_to(e->lhs->tree_type);

		/* can address: lvalues, arrays and functions */
		if(!expr_is_addressable(e->lhs)){
			warn_at_print_error(&e->where, "can't take the address of %s (%s)",
					expr_str_friendly(e->lhs), type_to_str(e->lhs->tree_type));
			fold_had_error = 1;
			return;
		}

		if(expr_kind(e->lhs, identifier)){
			sym *sym = e->lhs->bits.ident.bits.ident.sym;
			if(sym){
				decl *d = sym->decl;

				if((d->store & STORE_MASK_STORE) == store_register)
					die_at(&e->lhs->where, "can't take the address of register");
			}
		}

		fold_check_expr(e->lhs, FOLD_CHK_ALLOW_VOID | FOLD_CHK_NO_BITFIELD,
				"address-of");
	}
}
Exemple #11
0
void Codegen_C::write( Inst *inst ) {
    // reg decl
    std::map<String,Vec<CppOutReg *> > by_type;
    for( CppOutReg *r : inst->reg_to_decl )
        by_type[ type_to_str( r->type ) ] << r;
    for( auto it : by_type ) {
        on.write_beg() << it.first;
        for( int i = 0; i < it.second.size(); ++i )
            *os << ( i ? ", R" : " R" ) << it.second[ i ]->num;
        on.write_end( ";" );
    }

    // instruction
    inst->write( this );
}
Exemple #12
0
int expr_must_lvalue(expr *e, const char *desc)
{
	int lval = (expr_is_lval(e) == LVALUE_USER_ASSIGNABLE);

	if(!lval || type_is_array(e->tree_type)){
		fold_had_error = 1;
		warn_at_print_error(&e->where, "%s to %s - %s",
				desc, type_to_str(e->tree_type),
				lval ? "arrays not assignable" : "not an lvalue");

		return 0;
	}

	return 1;
}
Exemple #13
0
    void display(VerbosityLevel lvl = VERBOSE_LEVEL_1) const
    {
        w_yel_lf("-> Elf_Phdr64:"); 
        std::cout << "    " << type_to_str(p_type) << " " << flags_to_str(p_flags) << std::endl;

        if(lvl > VERBOSE_LEVEL_1)
        {
            display_short_hex_2fields_lf(p_vaddr, p_filesz);
        }

        if(lvl > VERBOSE_LEVEL_2)
        {
            display_short_hex_2fields_lf(p_align, p_flags);
        }

        display_short_hex_2fields_lf(p_offset, p_paddr);
    }
static void check_arg_types(
		funcargs *args_from_decl,
		expr **exprargs, symtable *stab,
		char *sp, where *const exprloc)
{
	if(exprargs && args_from_decl->arglist){
		int i;
		char buf[64];
		int finished_expr_args = 0;

		for(i = 0; ; i++){
			decl *decl_arg = args_from_decl->arglist[i];

			if(!decl_arg)
				break;

			if(!type_is_complete(decl_arg->ref)){
				warn_at_print_error(&decl_arg->where,
						"incomplete parameter type '%s'",
						type_to_str(decl_arg->ref));
				fold_had_error = 1;

				note_at(exprloc, "in call here");
			}

			/* exprargs[i] may be NULL - old style function */
			if(finished_expr_args || !exprargs[i]){
				finished_expr_args = 1;
				continue;
			}

			ARG_BUF(buf, i, sp);

			fold_type_chk_and_cast_ty(
					decl_arg->ref, &exprargs[i],
					stab, &exprargs[i]->where,
					buf);

			/* f(int [static 5]) check */
			static_array_check(decl_arg, exprargs[i]);
		}
	}
}
Exemple #15
0
static const out_val *vla_cached_size(type *const qual_t, out_ctx *octx)
{
	type *t = type_skip_all(qual_t);
	struct cc1_out_ctx **cc1_octx = cc1_out_ctx(octx);
	dynmap *vlamap;

	if(*cc1_octx && (vlamap = (*cc1_octx)->vlamap)){
		const out_val *stack_off = dynmap_get(type *, const out_val *, vlamap, t);

		if(stack_off){
			out_comment(octx, "vla saved size for %s", type_to_str(qual_t));

			out_val_retain(octx, stack_off);
			return out_deref(octx, stack_off);
		}
	}

	return NULL;
}
Exemple #16
0
void lgdb_log(log_type type, const char *format, ...)
{
	va_list args;
	struct timeval tv;
	struct tm ts;
	char buf[80];

        if (!log_type_enabled[type])
		return;

	gettimeofday(&tv, NULL);
	ts = *localtime(&tv.tv_sec);
	strftime(buf, sizeof(buf), "%b %d %H:%M:%S", &ts);
	fprintf(log_file, "%s %s : [%lu.%lu] ", buf, type_to_str(type), tv.tv_sec, tv.tv_usec / 1000);
	va_start(args, format);
	vfprintf(log_file, format, args);
	va_end(args);
	fflush(log_file);
}
void dump_expr_assign_compound(const expr *e, dump *ctx)
{
	dump_desc_expr_newline(ctx, "compound assignment", e, 0);

	dump_printf_indent(ctx, 0, " %s%s=",
			e->assign_is_post ? "post-assignment " : "",
			op_to_str(e->bits.compoundop.op));

	if(e->bits.compoundop.upcast_ty){
		dump_printf_indent(ctx, 0, " upcast='%s'",
				type_to_str(e->bits.compoundop.upcast_ty));
	}

	dump_printf_indent(ctx, 0, "\n");

	dump_inc(ctx);
	dump_expr(e->lhs, ctx);
	dump_expr(e->rhs, ctx);
	dump_dec(ctx);
}
Exemple #18
0
static void try_pointer_propagate(
		expr *e, enum type_cmp cmp,
		type *const tt_l, type *const tt_r)
{
	/* 6.5.15 p6 */
	int l_ptr = !!type_is_ptr_or_block(tt_l);
	int r_ptr = !!type_is_ptr_or_block(tt_r);

	/* if both the second and third operands are pointers */
	if(l_ptr && r_ptr){
		int allowed = TYPE_EQUAL_ANY
				| TYPE_QUAL_ADD
				| TYPE_QUAL_SUB
				| TYPE_QUAL_POINTED_ADD
				| TYPE_QUAL_POINTED_SUB;

		if(cmp & allowed){
			e->tree_type = pointer_to_qualified(type_next(tt_l), tt_l, tt_r);
		}
	}

	if(!e->tree_type && (l_ptr || r_ptr)){
		/* or one is a null pointer constant and the other is a pointer */
		int l_ptr_null = expr_is_null_ptr(
				e->lhs ? e->lhs : e->expr, NULL_STRICT_INT);

		int r_ptr_null = expr_is_null_ptr(e->rhs, NULL_STRICT_INT);

		/* both may still be pointers here */
		if((l_ptr && r_ptr_null) || (r_ptr && l_ptr_null)){
			type *pointed_to;

			if(l_ptr_null != r_ptr_null){
				/* only one is an int - pick the other side */
				pointed_to = type_next(l_ptr_null ? tt_r : tt_l);
			}else{
				/* both are pointers, pick either side */
				pointed_to = type_next(l_ptr ? tt_l : tt_r);
			}

			e->tree_type = pointer_to_qualified(
					pointed_to,
					l_ptr ? tt_l : NULL,
					r_ptr ? tt_r : NULL);
		}
	}

	if(!e->tree_type && l_ptr && r_ptr){
		e->tree_type = pointer_to_qualified(
					type_nav_btype(cc1_type_nav, type_void),
					tt_l, tt_r);

		/* gcc/clang relax the rule here.
		 * 0 ? (A *)0 : (B *)0
		 * becomes a void pointer too */
		if(!type_is_void_ptr(tt_l) && !type_is_void_ptr(tt_r)){
			char buf[TYPE_STATIC_BUFSIZ];

			cc1_warn_at(&e->where,
					mismatch_conditional,
					"conditional type mismatch (%s vs %s)",
					type_to_str(tt_l), type_to_str_r(buf, tt_r));
		}
	}

	if(!e->tree_type){
		char buf[TYPE_STATIC_BUFSIZ];

		warn_at_print_error(&e->where, "conditional type mismatch (%s vs %s)",
				type_to_str(tt_l), type_to_str_r(buf, tt_r));

		fold_had_error = 1;

		e->tree_type = type_nav_btype(cc1_type_nav, type_void);
	}
}
Exemple #19
0
void fold_expr_if(expr *e, symtable *stab)
{
	consty konst;
	type *tt_l, *tt_r;

	FOLD_EXPR(e->expr, stab);
	const_fold(e->expr, &konst);

	fold_check_expr(e->expr, FOLD_CHK_NO_ST_UN, "if-expr");

	if(e->lhs){
		FOLD_EXPR(e->lhs, stab);
		fold_check_expr(e->lhs,
				FOLD_CHK_NO_ST_UN | FOLD_CHK_ALLOW_VOID,
				"if-lhs");
	}

	FOLD_EXPR(e->rhs, stab);
	fold_check_expr(e->rhs,
			FOLD_CHK_NO_ST_UN | FOLD_CHK_ALLOW_VOID,
			"if-rhs");


	/*

	Arithmetic                             Arithmetic                           Arithmetic type after usual arithmetic conversions
	// Structure or union type                Compatible structure or union type   Structure or union type with all the qualifiers on both operands
	void                                   void                                 void
	Pointer to compatible type             Pointer to compatible type           Pointer to type with all the qualifiers specified for the type
	Pointer to type                        NULL pointer (the constant 0)        Pointer to type
	Pointer to object or incomplete type   Pointer to void                      Pointer to void with all the qualifiers specified for the type

	GCC and Clang seem to relax the last rule:
		a) resolve if either is any pointer, not just (void *)
	  b) resolve to a pointer to the incomplete-type
	*/

	tt_l = (e->lhs ? e->lhs : e->expr)->tree_type;
	tt_r = e->rhs->tree_type;

	if(type_is_integral(tt_l) && type_is_integral(tt_r)){
		expr **middle_op = e->lhs ? &e->lhs : &e->expr;

		expr_check_sign("?:", *middle_op, e->rhs, &e->where);

		e->tree_type = op_promote_types(
				op_unknown,
				middle_op, &e->rhs, &e->where, stab);

	}else if(type_is_void(tt_l) || type_is_void(tt_r)){
		e->tree_type = type_nav_btype(cc1_type_nav, type_void);

	}else if(type_cmp(tt_l, tt_r, 0) & TYPE_EQUAL_ANY){
		/* pointer to 'compatible' type */
		e->tree_type = type_qualify(tt_l,
				type_qual(tt_l) | type_qual(tt_r));

	}else{
		/* brace yourself. */
		int l_ptr_null = expr_is_null_ptr(
				e->lhs ? e->lhs : e->expr, NULL_STRICT_VOID_PTR);

		int r_ptr_null = expr_is_null_ptr(e->rhs, NULL_STRICT_VOID_PTR);

		int l_complete = !l_ptr_null && type_is_complete(tt_l);
		int r_complete = !r_ptr_null && type_is_complete(tt_r);

		if((l_complete && r_ptr_null) || (r_complete && l_ptr_null)){
			e->tree_type = l_ptr_null ? tt_r : tt_l;

		}else{
			int l_ptr = l_ptr_null || type_is(tt_l, type_ptr);
			int r_ptr = r_ptr_null || type_is(tt_r, type_ptr);

			if(l_ptr || r_ptr){
				fold_type_chk_warn(
						tt_l, tt_r, &e->where, "?: pointer type mismatch");

				/* qualified void * */
				e->tree_type = type_qualify(
						type_ptr_to(type_nav_btype(cc1_type_nav, type_void)),
						type_qual(tt_l) | type_qual(tt_r));

			}else{
				char buf[TYPE_STATIC_BUFSIZ];

				warn_at(&e->where, "conditional type mismatch (%s vs %s)",
						type_to_str(tt_l), type_to_str_r(buf, tt_r));

				e->tree_type = type_nav_btype(cc1_type_nav, type_void);
			}
		}
	}

	e->freestanding = (e->lhs ? e->lhs : e->expr)->freestanding || e->rhs->freestanding;
}
/******************************************************************************
 *
 * \par Function Name: ui_print_table
 *
 * \par Purpose: Prints a table to stdout.
 *
 * \par
 * COL HDR: Name (Type), Name (Type), Name (Type)...
 * ROW   0: Value1, Value2, Value3...
 * ROW   1: Value1, Value2, Value3...
 *
 * \param[in]  table  The table to be printed
 *
 * Modification History:
 *  MM/DD/YY  AUTHOR         DESCRIPTION
 *  --------  ------------   ---------------------------------------------
 *  06/8/16  E. Birrane     Initial implementation,
 *****************************************************************************/
void ui_print_table(table_t *table)
{
	int32_t i = 0;
	uint32_t row_num = 1;
	int8_t first = 0;

	LystElt elt;
	LystElt elt2;

	char *temp = NULL;
	blob_t *cur_blob = NULL;
	table_row_t *cur_row = NULL;

	if(table == NULL)
	{
		printf("NULL");
		return;
	}

	printf("COL HDR: ");
	for(elt = lyst_first(table->hdr.names); elt; elt = lyst_next(elt))
	{
		cur_blob = (blob_t*) lyst_data(elt);

		if(first == 0)
		{
			first = 1;
		}
		else
		{
			printf(", ");
		}
		printf(" %s (%s)", (char *)cur_blob->value, type_to_str(table->hdr.types.value[i]));
		i++;
	}
	printf("\n");

	for(elt = lyst_first(table->rows); elt; elt = lyst_next(elt))
	{
		cur_row = (table_row_t*) lyst_data(elt);

		printf("ROW %3d: ", row_num++);

		if(cur_row == NULL)
		{
			printf("NULL");
		}
		else
		{
			first = 0;
			i = 0;

			for(elt2 = lyst_first(cur_row->cels); elt2; elt2 = lyst_next(elt2))
			{
				cur_blob = (blob_t *) lyst_data(elt2);
				value_t  val = val_from_blob(cur_blob, table->hdr.types.value[i]);

				if(first == 0)
				{
					first = 1;
				}
				else
				{
					printf(", ");
				}

				temp = val_to_string(val);
				printf("%s", temp);
				SRELEASE(temp);
				val_release(&val, 0);
				i++;
			}
			printf("\n");
		}
	}

}
Exemple #21
0
const out_val *gen_expr_style_compound_lit(const expr *e, out_ctx *octx)
{
	stylef("(%s)", type_to_str(e->bits.complit.decl->ref));
	gen_style_dinit(e->bits.complit.decl->bits.var.init.dinit);
	UNUSED_OCTX();
}
void fold_expr_struct(expr *e, symtable *stab)
{
	/*
	 * lhs = any ptr-to-struct expr
	 * rhs = struct member ident
	 */
	const int ptr_expect = !e->expr_is_st_dot;
	struct_union_enum_st *sue;
	char *spel;

	fold_expr_no_decay(e->lhs, stab);
	/* don't fold the rhs - just a member name */

	if(e->rhs){
		UCC_ASSERT(expr_kind(e->rhs, identifier),
				"struct/union member not identifier (%s)", e->rhs->f_str());

		UCC_ASSERT(!e->bits.struct_mem.d, "already have a struct-member");

		spel = e->rhs->bits.ident.spel;
	}else{
		UCC_ASSERT(e->bits.struct_mem.d, "no member specified already?");
		spel = NULL;
	}

	/* we access a struct, of the right ptr depth */
	{
		type *r = e->lhs->tree_type;

		if(ptr_expect){
			type *rtest = type_is(r, type_ptr);

			if(!rtest && !(rtest = type_is(r, type_array)))
				goto err;

			r = rtest->ref; /* safe - rtest is an array */
		}

		if(!(sue = type_is_s_or_u(r))){
err:
			die_at(&e->lhs->where, "'%s' (%s-expr) is not a %sstruct or union (member %s)",
					type_to_str(e->lhs->tree_type),
					e->lhs->f_str(),
					ptr_expect ? "pointer to " : "",
					spel);
		}
	}

	if(!sue_complete(sue)){
		char wbuf[WHERE_BUF_SIZ];

		die_at(&e->lhs->where, "%s incomplete type (%s)\n"
				"%s: note: forward declared here",
				ptr_expect
					? "dereferencing pointer to"
					: "accessing member of",
				type_to_str(e->lhs->tree_type),
				where_str_r(wbuf, &sue->where));
	}

	if(spel){
		/* found the struct, find the member */
		decl *d_mem = struct_union_member_find(sue, spel,
				&e->bits.struct_mem.extra_off, NULL);

		if(!d_mem)
			die_at(&e->where, "%s %s has no member named \"%s\"",
					sue_str(sue), sue->spel, spel);

		e->rhs->tree_type = (e->bits.struct_mem.d = d_mem)->ref;
	}/* else already have the member */

	/*
	 * if it's a.b, convert to (&a)->b for asm gen
	 * e = { lhs = "a", rhs = "b", type = dot }
	 * e = {
	 *   type = ptr,
	 *   lhs = { cast<void *>, expr = { expr = "a", type = addr } },
	 *   rhs = "b",
	 * }
	 */
	if(!ptr_expect){
		expr *cast, *addr;

		addr = expr_new_addr(e->lhs);
		cast = expr_new_cast(addr,
				type_ptr_to(type_nav_btype(cc1_type_nav, type_void)),
				1);

		e->lhs = cast;
		e->expr_is_st_dot = 0;

		FOLD_EXPR(e->lhs, stab);
	}

	/* pull qualifiers from the struct to the member */
	e->tree_type = type_qualify(
			e->bits.struct_mem.d->ref,
			type_qual(e->lhs->tree_type));
}
Exemple #23
0
static void asm_declare_init(enum section_type sec, decl_init *init, type *tfor)
{
	type *r;

	if(init == DYNARRAY_NULL)
		init = NULL;

	if(!init){
		/* don't initialise flex-arrays */
		if(!type_is_incomplete_array(tfor)){
			asm_declare_pad(sec, type_size(tfor, NULL),
					"null init"/*, type_to_str(tfor)*/);
		}else{
			asm_out_section(sec, ASM_COMMENT " flex array init skipped\n");
		}

	}else if((r = type_is_primitive(tfor, type_struct))){
		/* array of stmts for each member
		 * assumes the ->bits.inits order is member order
		 */
		struct_union_enum_st *const sue = r->bits.type->sue;
		sue_member **mem;
		decl_init **i;
		unsigned end_of_last = 0;
		struct bitfield_val *bitfields = NULL;
		unsigned nbitfields = 0;
		decl *first_bf = NULL;
		expr *copy_from_exp;

		UCC_ASSERT(init->type == decl_init_brace, "unbraced struct");

#define DEBUG(s, ...) /*fprintf(f, "\033[35m" s "\033[m\n", __VA_ARGS__)*/

		i = init->bits.ar.inits;

		/* check for compound-literal copy-init */
		if((copy_from_exp = decl_init_is_struct_copy(init, sue))){
			decl_init *copy_from_init;

			copy_from_exp = expr_skip_lval2rval(copy_from_exp);

			/* the only struct-expression that's possible
			 * in static context is a compound literal */
			assert(expr_kind(copy_from_exp, compound_lit)
					&& "unhandled expression init");

			copy_from_init = copy_from_exp->bits.complit.decl->bits.var.init.dinit;
			assert(copy_from_init->type == decl_init_brace);

			i = copy_from_init->bits.ar.inits;
		}

		/* iterate using members, not inits */
		for(mem = sue->members;
				mem && *mem;
				mem++)
		{
			decl *d_mem = (*mem)->struct_member;
			decl_init *di_to_use = NULL;

			if(i){
				int inc = 1;

				if(*i == NULL)
					inc = 0;
				else if(*i != DYNARRAY_NULL)
					di_to_use = *i;

				if(inc){
					i++;
					if(!*i)
						i = NULL; /* reached end */
				}
			}

			DEBUG("init for %ld/%s, %s",
					mem - sue->members, d_mem->spel,
					di_to_use ? di_to_use->bits.expr->f_str() : NULL);

			/* only pad if we're not on a bitfield or we're on the first bitfield */
			if(!d_mem->bits.var.field_width || !first_bf){
				DEBUG("prev padding, offset=%d, end_of_last=%d",
						d_mem->struct_offset, end_of_last);

				UCC_ASSERT(
						d_mem->bits.var.struct_offset >= end_of_last,
						"negative struct pad, sue %s, member %s "
						"offset %u, end_of_last %u",
						sue->spel, decl_to_str(d_mem),
						d_mem->bits.var.struct_offset, end_of_last);

				asm_declare_pad(sec,
						d_mem->bits.var.struct_offset - end_of_last,
						"prev struct padding");
			}

			if(d_mem->bits.var.field_width){
				if(!first_bf || d_mem->bits.var.first_bitfield){
					if(first_bf){
						DEBUG("new bitfield group (%s is new boundary), old:",
								d_mem->spel);
						/* next bitfield group - store the current */
						bitfields_out(sec, bitfields, &nbitfields, first_bf->ref);
					}
					first_bf = d_mem;
				}

				bitfields = bitfields_add(
						bitfields, &nbitfields,
						d_mem, di_to_use);

			}else{
				if(nbitfields){
					DEBUG("at non-bitfield, prev-bitfield out:", 0);
					bitfields_out(sec, bitfields, &nbitfields, first_bf->ref);
					first_bf = NULL;
				}

				DEBUG("normal init for %s:", d_mem->spel);
				asm_declare_init(sec, di_to_use, d_mem->ref);
			}

			if(type_is_incomplete_array(d_mem->ref)){
				UCC_ASSERT(!mem[1], "flex-arr not at end");
			}else if(!d_mem->bits.var.field_width || d_mem->bits.var.first_bitfield){
				unsigned last_sz = type_size(d_mem->ref, NULL);

				end_of_last = d_mem->bits.var.struct_offset + last_sz;
				DEBUG("done with member \"%s\", end_of_last = %d",
						d_mem->spel, end_of_last);
			}
		}

		if(nbitfields)
			bitfields_out(sec, bitfields, &nbitfields, first_bf->ref);
		free(bitfields);

		/* need to pad to struct size */
		asm_declare_pad(sec,
				sue_size(sue, NULL) - end_of_last,
				"struct tail");

	}else if((r = type_is(tfor, type_array))){
		size_t i, len;
		decl_init **p;
		type *next = type_next(tfor);

		UCC_ASSERT(init->type == decl_init_brace, "unbraced struct");

		if(type_is_incomplete_array(tfor)){
			len = dynarray_count(init->bits.ar.inits);
		}else{
			UCC_ASSERT(type_is_complete(tfor), "incomplete array/type init");
			len = type_array_len(tfor);
		}

		for(i = len, p = init->bits.ar.inits;
				i > 0;
				i--)
		{
			decl_init *this = NULL;
			if(*p){
				this = *p++;

				if(this != DYNARRAY_NULL && this->type == decl_init_copy){
					/*fprintf(f, "# copy from %lu\n", DECL_INIT_COPY_IDX(this, init));*/
					struct init_cpy *icpy = *this->bits.range_copy;
					/* resolve the copy */
					this = icpy->range_init;
				}
			}

			asm_declare_init(sec, this, next);
		}

	}else if((r = type_is_primitive(tfor, type_union))){
		/* union inits are decl_init_brace with spaces up to the first union init,
		 * then NULL/end of the init-array */
		struct_union_enum_st *sue = type_is_s_or_u(r);
		unsigned i, sub = 0;
		decl_init *u_init;

		UCC_ASSERT(init->type == decl_init_brace, "brace init expected");

		/* skip the empties until we get to one */
		for(i = 0; init->bits.ar.inits[i] == DYNARRAY_NULL; i++);

		if((u_init = init->bits.ar.inits[i])){
			decl *mem = sue->members[i]->struct_member;
			type *mem_r = mem->ref;

			/* union init, member at index `i' */
			if(mem->bits.var.field_width){
				/* we know it's integral */
				struct bitfield_val bfv;

				ASSERT_SCALAR(u_init);

				bitfield_val_set(&bfv, u_init->bits.expr, mem->bits.var.field_width);

				asm_declare_init_bitfields(sec, &bfv, 1, mem_r);
			}else{
				asm_declare_init(sec, u_init, mem_r);
			}

			sub = type_size(mem_r, NULL);
		} /* else null union init */

		asm_declare_pad(sec,
				type_size(r, NULL) - sub,
				"union extra");

	}else{
		/* scalar */
		expr *exp = init->bits.expr;

		UCC_ASSERT(init->type == decl_init_scalar, "scalar init expected");

		/* exp->tree_type should match tfor */
		{
			char buf[TYPE_STATIC_BUFSIZ];

			UCC_ASSERT(
					type_cmp(exp->tree_type, tfor, TYPE_CMP_ALLOW_TENATIVE_ARRAY) != TYPE_NOT_EQUAL,
					"mismatching init types: %s and %s",
					type_to_str_r(buf, exp->tree_type),
					type_to_str(tfor));
		}

		/* use tfor, since "abc" has type (char[]){(int)'a', (int)'b', ...} */
		DEBUG("  scalar init for %s:", type_to_str(tfor));
		static_val(sec, tfor, exp);
	}
}
void
TrexRpcCommand::check_field_type_common(const Json::Value &field, const std::string &name, field_type_e type, Json::Value &result) {
    std::stringstream ss;

    /* first check if field exists */
    if (field == Json::Value::null) {
        ss << "field '" << name << "' is missing";
        generate_parse_err(result, ss.str());
    }

    bool rc = true;

    switch (type) {
    case FIELD_TYPE_BYTE:
        if ( (!field.isUInt()) || (field.asInt() > 0xFF)) {
            rc = false;
        }
        break;

    case FIELD_TYPE_UINT16:
        if ( (!field.isUInt()) || (field.asInt() > 0xFFFF)) {
            rc = false;
        }
        break;

    case FIELD_TYPE_UINT32:
        if ( (!field.isUInt()) || (field.asUInt() > 0xFFFFFFFF)) {
            rc = false;
        }
        break;

    case FIELD_TYPE_UINT64:
        if (!field.isUInt64()) {
            rc = false;
        }
        break;

    case FIELD_TYPE_BOOL:
        if (!field.isBool()) {
            rc = false;
        }
        break;

    case FIELD_TYPE_INT:
        if (!field.isInt()) {
            rc = false;
        }
        break;

    case FIELD_TYPE_DOUBLE:
        if (!field.isDouble()) {
            rc = false;
        }
        break;

    case FIELD_TYPE_OBJ:
        if (!field.isObject()) {
            rc = false;
        }
        break;

    case FIELD_TYPE_STR:
        if (!field.isString()) {
            rc = false;
        }
        break;

    case FIELD_TYPE_ARRAY:
        if (!field.isArray()) {
            rc = false;
        }
        break;

    default:
        throw TrexRpcException("unhandled type");
        break;

    }
    if (!rc) {
        ss << "error at offset: " << field.getOffsetStart() << " - '" << name << "' is '" << json_type_to_name(field) << "', expecting '" << type_to_str(type) << "'";
        generate_parse_err(result, ss.str());
    }

}
/**
 * The main function of BaseStation for Mongol.
 *
 * Entry point of program. Upon starting with normal mode values set,
 * this function parses any command line arguments, initializes the controller
 * interface (\sa Controller.h), intitializes the robot communication interface
 * (\sa Serial.h), and then enters the main control loop of the program. There,
 * the program basically gathers user input data from the controller, builds a
 * serial packet, and then sends it to the robot. The program waits for
 * confirmation from the robot in the form of a PKT_RDY packet type before
 * looping again.
 */
int
main (int argc, char* argv[])
{
    // Set default values
    m_ctrl_mode = Ctrl_Mode_Keyboard;
    m_comm_mode = Comm_Mode_Offline;
    m_ui_mode   = UI_Mode_Terminal;

    // Parse command line arguements
    parse_args (argc, argv);

    // Initialize SDL (VIDEO flag also initializes event handling)
    print_log ("Initializing controller... ", Log_Level_Med);
    if (!(initCtrl()))
    {
        print_log ("Controller failed to intialize.\n", Log_Level_High);
        quit_basestation ();
    }
    print_log ("Controller Initialized.\n", Log_Level_Med);

    // Initialize serial port (includes looking for HELLO packet
    // If not port name specified, default to /dev/ttyUSB0 (for Linux)
    if (m_comm_mode == Comm_Mode_Online)
    {
        print_log ("Connecting to robot... ", Log_Level_Med);
        if ((ms_comm_device ? init_serial (ms_comm_device) : init_serial ("/dev/ttyUSB0")) < 0)
        {
            print_log ("Failed to connect\n", Log_Level_High);
            m_comm_mode = Comm_Mode_Offline;
            quit_basestation ();
        }
        print_log ("Robot connected.\n", Log_Level_Med);
    }

    Msg out_msg;
    Msg in_msg;
    char intype_buf [128];
    char outtype_buf [128];
    int print_nxt_received = 0;

    // Main program loop
    for(;;)
    {
        next_event (&out_msg);

        if(m_comm_mode == Comm_Mode_Online)
        {
            do
            {
                serial_write (&out_msg);
                usleep (10);
            }
            while (serial_read (&in_msg) ||
                   (in_msg.type != Msg_Type_Ready));

            if (out_msg.type != Msg_Type_Standby)
            {
                type_to_str (intype_buf, out_msg.type);
                printf ("Sent: %s\n", intype_buf);
                type_to_str (outtype_buf, in_msg.type);
                printf ("Received: %s\n", outtype_buf);
            }
        }
    }

    return 0;
}
Exemple #26
0
static void processor(const char *tx_addr, int port)
{
    sys_init(1);
    sys_log('E', "started port=%d, tx=%s\n", port, tx_addr);

    /* connect to the control thread */
    char addr[MAX_ADDR];
    sys_address(addr, port);
    IO *io = sys_connect(addr, IO_CHUNK);

    tx_attach(tx_addr);

    /* get env code from the tx */
    char *code = tx_program();
    char *res = mem_alloc(MAX_BLOCK);

    while (!io->stop) {
        sys_iready(io, -1);

        int status = -1;
        long long sid = 0LL, time = sys_millis();

        Env *env = NULL;
        Arg *arg = NULL;
        Vars *v = vars_new(0), *r = NULL, *w = NULL;

        Http_Req *req = http_parse_req(io);
        if (io->stop)
            goto exit;

        if (req == NULL) {
            status = http_400(io);
            goto exit;
        }

        if (req->method == OPTIONS) {
            status = http_opts(io);
            goto exit;
        }

        env = env_new("net", code);

        if (str_idx(req->path, "/fn") == 0) {
            int idx = (req->path[3] == '/') ? 4 : 3;
            int i = 0, len = 1, cnt = 0;
            Func **fns = env_funcs(env, req->path + idx, &cnt);

            status = http_200(io);
            while (status == 200 && len) {
                len = pack_fn2csv(fns, cnt, res, MAX_BLOCK, &i);
                status = http_chunk(io, res, len);
            }

            mem_free(fns);
            goto exit;
        }

        /* compare the request with the function defintion */
        Func *fn = env_func(env, req->path + 1);
        if (fn == NULL) {
            Error *err = error_new("unknown function '%s'", req->path + 1);
            status = http_404(io, err->msg);
            mem_free(err);
            goto exit;
        }

        if (fn->rp.name != NULL && req->method != POST) {
            status = http_405(io, POST);
            goto exit;
        }

        if (fn->rp.name == NULL && req->method == POST) {
            status = http_405(io, GET);
            goto exit;
        }

        /* TODO: think what to do with duplicate parameter values */
        for (int i = 0; i < req->args->len; ++i) {
            char *name = req->args->names[i];
            if (array_freq(req->args->names, req->args->len, name) > 1) {
                Error *err = error_new("duplicate parameter '%s' "
                                       "(not supported)",
                                       name);
                status = http_404(io, err->msg);
                mem_free(err);
                goto exit;
            }
        }

        if (fn->pp.len != req->args->len) {
            Error *err = error_new("expected %d primitive parameters, got %d",
                                   fn->pp.len, req->args->len);
            status = http_404(io, err->msg);
            mem_free(err);
            goto exit;
        }

        arg = mem_alloc(sizeof(Arg));
        for (int i = 0; i < fn->pp.len; ++i) {
            char *name = fn->pp.names[i];
            Type t = fn->pp.types[i];

            int idx = array_scan(req->args->names, req->args->len, name);
            if (idx < 0) {
                Error *err = error_new("unknown parameter '%s'", name);
                status = http_404(io, err->msg);
                mem_free(err);
                goto exit;
            }

            char *val = req->args->vals[idx];
            int error = 0;
            if (t == Int) {
                arg->vals[i].v_int = str_int(val, &error);
            } else if (t == Real)
                arg->vals[i].v_real = str_real(val, &error);
            else if (t == Long)
                arg->vals[i].v_long = str_long(val, &error);
            else if (t == String) {
                error = str_len(val) > MAX_STRING;
                if (!error)
                    str_cpy(arg->vals[i].v_str, val);
            }

            if (error) {
                Error *err = error_new("value '%s' (parameter '%s') "
                                       "is not of type '%s'",
                                       val, name, type_to_str(t));
                status = http_404(io, err->msg);
                mem_free(err);
                goto exit;
            }
        }

        if (fn->rp.name != NULL) {
            TBuf *body = NULL;
            if (req->len > 0) {
                Error *err = pack_csv2rel(req->body, fn->rp.head, &body);
                if (err != NULL) {
                    status = http_404(io, err->msg);
                    mem_free(err);
                    goto exit;
                }
            } else {
                body = tbuf_new();
            }

            vars_add(v, fn->rp.name, 0, body);

            /* project the parameter */
            Rel *param = rel_project(rel_load(fn->rp.head, fn->rp.name),
                                     fn->rp.head->names,
                                     fn->rp.head->len);

            rel_eval(param, v, arg);

            /* clean the previous version */
            tbuf_clean(body);
            tbuf_free(body);

            /* replace with the new body */
            int vpos = array_scan(v->names, v->len, fn->rp.name);
            v->vals[vpos] = param->body;

            param->body = NULL;
            rel_free(param);
        }

        /* start a transaction */
        r = vars_new(fn->r.len);
        w = vars_new(fn->w.len);
        for (int i = 0; i < fn->r.len; ++i)
            vars_add(r, fn->r.names[i], 0, NULL);
        for (int i = 0; i < fn->w.len; ++i)
            vars_add(w, fn->w.names[i], 0, NULL);

        sid = tx_enter(addr, r, w);

        /* prepare variables */
        for (int i = 0; i < r->len; ++i) {
            TBuf *body = vol_read(r->vols[i], r->names[i], r->vers[i]);
            vars_add(v, r->names[i], 0, body);
        }
        for (int i = 0; i < w->len; ++i) {
            int pos = array_scan(v->names, v->len, w->names[i]);
            if (pos < 0)
                vars_add(v, w->names[i], 0, NULL);
        }
        for (int i = 0; i < fn->t.len; ++i)
            vars_add(v, fn->t.names[i], 0, NULL);

        /* evaluate the function body */
        for (int i = 0; i < fn->slen; ++i)
            rel_eval(fn->stmts[i], v, arg);

        /* prepare the return value. note, the resulting relation
           is just a container for the body, so it is not freed */
        Rel *ret = NULL;
        if (fn->ret != NULL)
            ret = fn->stmts[fn->slen - 1];

        /* persist the global variables */
        for (int i = 0; i < w->len; ++i) {
            int idx = array_scan(v->names, v->len, w->names[i]);
            if (idx < 0) {
                status = http_500(io);
                goto exit;
            }

            vol_write(w->vols[i], v->vals[idx], w->names[i], w->vers[i]);
            tbuf_free(v->vals[idx]);
            v->vals[idx] = NULL;
        }

        /* confirm a success and send the result back */
        status = http_200(io);
        if (status != 200)
            goto exit;

        tx_commit(sid);

        /* N.B. there is no explicit revert as the transaction manager handles
           nested tx_enter and a connectivity failure as a rollback */

        int len = 1, i = 0;
        while (status == 200 && len) {
            len = pack_rel2csv(ret, res, MAX_BLOCK, i++);
            status = http_chunk(io, res, len);
        }
exit:
        if (status != -1)
            sys_log('E', "%016llX method %c, path %s, time %lldms - %3d\n",
                         sid,
                         (req == NULL) ? '?' : req->method,
                         (req == NULL) ? "malformed" : req->path,
                         sys_millis() - time,
                         status);


        if (r != NULL)
            vars_free(r);
        if (w != NULL)
            vars_free(w);
        if (arg != NULL)
            mem_free(arg);
        if (req != NULL)
            http_free_req(req);
        if (env != NULL)
            env_free(env);
        for (int i = 0; i < v->len; ++i)
            if (v->vals[i] != NULL) {
                tbuf_clean(v->vals[i]);
                tbuf_free(v->vals[i]);
            }
        vars_free(v);

        sys_term(io);
    }

    mem_free(code);
    mem_free(res);
    tx_detach();
    sys_close(io);
}
void fold_expr_funcall(expr *e, symtable *stab)
{
	type *func_ty;
	funcargs *args_from_decl;
	char *sp = NULL;
	unsigned count_decl;

	check_implicit_funcall(e, stab, &sp);

	FOLD_EXPR(e->expr, stab);
	func_ty = e->expr->tree_type;

	if(!type_is_callable(func_ty)){
		warn_at_print_error(&e->expr->where,
				"%s-expression (type '%s') not callable",
				expr_str_friendly(e->expr, 0),
				type_to_str(func_ty));

		fold_had_error = 1;

		e->tree_type = type_nav_btype(cc1_type_nav, type_int);
		return;
	}

	e->tree_type = type_func_call(func_ty, &args_from_decl);

	/* func count comparison, only if the func has arg-decls, or the func is f(void) */
	UCC_ASSERT(args_from_decl, "no funcargs for decl %s", sp);

	count_decl = dynarray_count(args_from_decl->arglist);

	if(check_arg_counts(args_from_decl, count_decl, e->funcargs, e, sp))
		return;

	if(e->funcargs){
		check_arg_voidness_and_nonnulls(
				e, stab,
				args_from_decl, count_decl,
				e->funcargs, sp);
	}

	if(!FUNCARGS_EMPTY_NOVOID(args_from_decl))
		check_arg_types(args_from_decl, e->funcargs, stab, sp, &e->where);

	if(e->funcargs)
		default_promote_args(e->funcargs, count_decl, stab);

	if(type_is_s_or_u(e->tree_type)){
		/* handled transparently by the backend */
		e->f_islval = expr_is_lval_struct;

		cc1_warn_at(&e->expr->where,
				aggregate_return,
				"called function returns aggregate (%s)",
				type_to_str(e->tree_type));
	}

	/* attr */
	{
		type *fnty = e->expr->tree_type;

		/* look through decays */
		if(expr_kind(e->expr, cast) && expr_cast_is_lval2rval(e->expr))
			fnty = expr_cast_child(e->expr)->tree_type;

		format_check_call(fnty, e->funcargs, args_from_decl->variadic);

		sentinel_check(
				&e->where, e,
				e->funcargs, args_from_decl->variadic,
				count_decl, stab);
	}

	/* check the subexp tree type to get the funcall attributes */
	if(func_or_builtin_attr_present(e, attr_warn_unused))
		e->freestanding = 0; /* needs use */

	if(sp && !cc1_fopt.freestanding)
		check_standard_funcs(sp, e->funcargs);
}
Exemple #28
0
Type* TypecheckVisitor::visit_builtin_atom(BuiltinAtom *atom,
                                           Type* arguments[],
                                           uint16_t num_arguments) {
  if(atom->types.size() != num_arguments) {
    driver_.error(atom->location,
                  "number of provided arguments does not match definition of `"+
                  atom->name+"`");
  } else {
    for (size_t i=0; i < atom->types.size(); i++) {

     Type *argument_t = atom->types[i];
 
      if (!arguments[i]->unify(argument_t)) {
        driver_.error(atom->arguments->at(i)->location,
                      "type of "+std::to_string(i+1)+" argument of `"+atom->name+
                      "` is "+arguments[i]->to_str()+" but should be "+
                      argument_t->to_str());
      }
    }
  }

  if (atom->name == "nth") {
    if (*atom->types[0] == TypeType::TUPLE_OR_LIST && atom->types[0]->subtypes.size() > 0 && atom->types[0]->subtypes[0]->t != TypeType::UNKNOWN) {
      Type first = *atom->types[0]->subtypes[0];
      bool all_equal = true;
      for (size_t i=1; i < atom->types[0]->subtypes.size(); i++) {
        if (first != *atom->types[0]->subtypes[i]) {
          all_equal = false;
          break;
        }
      }
      if (all_equal) {
        atom->types[0]->t = TypeType::LIST;
        atom->types[0]->subtypes = {new Type(first)};
      } 
    }

    if (*atom->types[0] == TypeType::TUPLE) {
      ExpressionBase *ind_expr = atom->arguments->at(1);
      if (ind_expr->node_type_ == NodeType::INT_ATOM) {
        INT_T ind = reinterpret_cast<IntAtom*>(ind_expr)->val_;
        if (ind <= 0) {
          driver_.error(atom->arguments->at(1)->location,
                        "second argument of nth must be a positive (>0) Int constant for tuples");

          return &atom->type_;
        }

        // this is needed to handle stuff like:
        //          assert nth(undef, 2) = undef
        if (atom->types[0]->is_unknown() && atom->type_.is_unknown()) {
          return &atom->type_;
        }
        if ((size_t) ind < (atom->types[0]->subtypes.size()+1)) {
          atom->type_.unify(atom->types[0]->subtypes[ind-1]);
        } else {
          driver_.error(atom->arguments->at(1)->location,
                        "index out of bounds for tuple, currently tuple only has "+
                        std::to_string(atom->arguments->size())+" types");

        }
      } else {
        driver_.error(atom->arguments->at(1)->location,
                      "second argument of nth must be an Int constant for tuples but was `"+
                      type_to_str(ind_expr->node_type_)+"`");
      }
    } else {
      atom->type_.unify(atom->types[0]->subtypes[0]);
      arguments[0]->unify(&atom->type_);
      atom->type_.unify(atom->return_type);
    }
  } else {
    // TODO use type_ as return_type_ for builtins
    atom->type_.unify(atom->return_type);
  }
  return &atom->type_;
}