Ejemplo n.º 1
0
bool check_constraints(ast_t* orig, ast_t* typeparams, ast_t* typeargs,
  bool report_errors, pass_opt_t* opt)
{
  ast_t* typeparam = ast_child(typeparams);
  ast_t* typearg = ast_child(typeargs);

  while(typeparam != NULL)
  {
    if(ast_id(typearg) == TK_TYPEPARAMREF)
    {
      ast_t* def = (ast_t*)ast_data(typearg);

      if(def == typeparam)
      {
        typeparam = ast_sibling(typeparam);
        typearg = ast_sibling(typearg);
        continue;
      }
    }

    // Reify the constraint.
    ast_t* constraint = ast_childidx(typeparam, 1);
    ast_t* bind_constraint = bind_type(constraint);
    ast_t* r_constraint = reify(bind_constraint, typeparams, typeargs, opt);

    if(bind_constraint != r_constraint)
      ast_free_unattached(bind_constraint);

    // A bound type must be a subtype of the constraint.
    errorframe_t info = NULL;
    if(!is_subtype(typearg, r_constraint, report_errors ? &info : NULL, opt))
    {
      if(report_errors)
      {
        ast_error(opt->check.errors, orig,
          "type argument is outside its constraint");
        ast_error_continue(opt->check.errors, typearg,
          "argument: %s", ast_print_type(typearg));
        ast_error_continue(opt->check.errors, typeparam,
          "constraint: %s", ast_print_type(r_constraint));
      }

      ast_free_unattached(r_constraint);
      return false;
    }

    ast_free_unattached(r_constraint);

    // A constructable constraint can only be fulfilled by a concrete typearg.
    if(is_constructable(constraint) && !is_concrete(typearg))
    {
      if(report_errors)
      {
        ast_error(opt->check.errors, orig, "a constructable constraint can "
          "only be fulfilled by a concrete type argument");
        ast_error_continue(opt->check.errors, typearg, "argument: %s",
          ast_print_type(typearg));
        ast_error_continue(opt->check.errors, typeparam, "constraint: %s",
          ast_print_type(constraint));
      }

      return false;
    }

    typeparam = ast_sibling(typeparam);
    typearg = ast_sibling(typearg);
  }

  assert(typeparam == NULL);
  assert(typearg == NULL);
  return true;
}
Ejemplo n.º 2
0
/** 
 * Pivot the rows, creating a new resultset
 *
 * Call dbpivot() immediately after dbresults().  It calls dbnextrow() as long as
 * it returns REG_ROW, transforming the results into a cross-tab report.  
 * dbpivot() modifies the metadata such that DB-Library can be used tranparently: 
 * retrieve the rows as usual with dbnumcols(), dbnextrow(), etc. 
 *
 * @dbproc, our old friend
 * @nkeys the number of left-edge columns to group by
 * @keys  an array of left-edge columns to group by
 * @ncols the number of top-edge columns to group by
 * @cols  an array of top-edge columns to group by
 * @func  the aggregation function to use
 * @val   the number of the column to which @func is applied
 *
 * @returns the return code from the final call to dbnextrow().  
 *  Success is normally indicated by NO_MORE_ROWS.  
 */
RETCODE
dbpivot(DBPROCESS *dbproc, int nkeys, int *keys, int ncols, int *cols, DBPIVOT_FUNC func, int val)
{
	enum { logalot = 1 };
	struct pivot_t P, *pp;
	struct agg_t input, *pout = NULL;
	struct key_t *pacross;
	struct metadata_t *metadata, *pmeta;
	size_t i, nmeta = 0;

	tdsdump_log(TDS_DBG_FUNC, "dbpivot(%p, %d,%p, %d,%p, %p, %d)\n", dbproc, nkeys, keys, ncols, cols, func, val);
	if (logalot) {
		char buffer[1024] = {'\0'}, *s = buffer;
		const static char *names[2] = { "\tkeys (down)", "\n\tcols (across)" };
		int *p = keys, *pend = p + nkeys;
		
		for (i=0; i < 2; i++) {
			const char *sep = "";
			s += sprintf(s, "%s: ", names[i]);
			for ( ; p < pend; p++) {
				s += sprintf(s, "%s%d", sep, *p);
				sep = ", ";
			}
			p = cols;
			pend = p + ncols;
			assert(s < buffer + sizeof(buffer));
		}
		tdsdump_log(TDS_DBG_FUNC, "%s\n", buffer);
	}
	
	memset(&input,  0, sizeof(input));
	
	P.dbproc = dbproc;
	if ((pp = tds_find(&P, pivots, npivots, sizeof(*pivots), pivot_key_equal)) == NULL ) {
		pp = realloc(pivots, (1 + npivots) * sizeof(*pivots)); 
		if (!pp)
			return FAIL;
		pivots = pp;
		pp += npivots++;
	} else {
		agg_free(pp->output);
		key_free(pp->across);		
	}
	memset(pp, 0, sizeof(*pp));

	if ((input.row_key.keys = calloc(nkeys, sizeof(*input.row_key.keys))) == NULL)
		return FAIL;
	input.row_key.nkeys = nkeys;
	for (i=0; i < nkeys; i++) {
		int type = dbcoltype(dbproc, keys[i]);
		int len = dbcollen(dbproc, keys[i]);
		assert(type && len);
		
		col_init(input.row_key.keys+i, type, len);
		if (FAIL == dbbind(dbproc, keys[i], bind_type(type), input.row_key.keys[i].len, col_buffer(input.row_key.keys+i)))
			return FAIL;
		if (FAIL == dbnullbind(dbproc, keys[i], &input.row_key.keys[i].null_indicator))
			return FAIL;
	}
	
	if ((input.col_key.keys = calloc(ncols, sizeof(*input.col_key.keys))) == NULL)
		return FAIL;
	input.col_key.nkeys = ncols;
	for (i=0; i < ncols; i++) {
		int type = dbcoltype(dbproc, cols[i]);
		int len = dbcollen(dbproc, cols[i]);
		assert(type && len);
		
		col_init(input.col_key.keys+i, type, len);
		if (FAIL == dbbind(dbproc, cols[i], bind_type(type), input.col_key.keys[i].len, col_buffer(input.col_key.keys+i)))
			return FAIL;
		if (FAIL == dbnullbind(dbproc, cols[i], &input.col_key.keys[i].null_indicator))
			return FAIL;
	}
	
	/* value */ {
		int type = dbcoltype(dbproc, val);
		int len = dbcollen(dbproc, val);
		assert(type && len);
		
		col_init(&input.value, type, len);
		if (FAIL == dbbind(dbproc, val, bind_type(type), input.value.len, col_buffer(&input.value)))
			return FAIL;
		if (FAIL == dbnullbind(dbproc, val, &input.value.null_indicator))
			return FAIL;
	}
	
	while ((pp->status = dbnextrow(dbproc)) == REG_ROW) {
		/* add to unique list of crosstab columns */
		if ((pacross = tds_find(&input.col_key, pp->across, pp->nacross, sizeof(*pp->across), key_equal)) == NULL ) {
			pacross = realloc(pp->across, (1 + pp->nacross) * sizeof(*pp->across)); 
			if (!pacross)
				return FAIL;
			pp->across = pacross;
			pacross += pp->nacross++;
			key_cpy(pacross, &input.col_key);
		}
		assert(pp->across);
		
		if ((pout = tds_find(&input, pp->output, pp->nout, sizeof(*pp->output), agg_equal)) == NULL ) {
			pout = realloc(pp->output, (1 + pp->nout) * sizeof(*pp->output)); 
			if (!pout)
				return FAIL;
			pp->output = pout;
			pout += pp->nout++;

			
			if ((pout->row_key.keys = calloc(input.row_key.nkeys, sizeof(*pout->row_key.keys))) == NULL)
				return FAIL;
			key_cpy(&pout->row_key, &input.row_key);

			if ((pout->col_key.keys = calloc(input.col_key.nkeys, sizeof(*pout->col_key.keys))) == NULL)
				return FAIL;
			key_cpy(&pout->col_key, &input.col_key);

			col_init(&pout->value, input.value.type, input.value.len);
		}
		
		func(&pout->value, &input.value);

	}

	/* Mark this proc as pivoted, so that dbnextrow() sees it when the application calls it */
	pp->dbproc = dbproc;
	pp->dbresults_state = dbproc->dbresults_state;
	dbproc->dbresults_state = pp->output < pout? _DB_RES_RESULTSET_ROWS : _DB_RES_RESULTSET_EMPTY;
	
	/*
	 * Initialize new metadata
	 */
	nmeta = input.row_key.nkeys + pp->nacross;	
	metadata = calloc(nmeta, sizeof(*metadata));
	
	assert(pp->across || pp->nacross == 0);
	
	/* key columns are passed through as-is, verbatim */
	for (i=0; i < input.row_key.nkeys; i++) {
		assert(i < nkeys);
		metadata[i].name = strdup(dbcolname(dbproc, keys[i]));
		metadata[i].pacross = NULL;
		col_cpy(&metadata[i].col, input.row_key.keys+i);
	}

	/* pivoted columms are found in the "across" data */
	for (i=0, pmeta = metadata + input.row_key.nkeys; i < pp->nacross; i++) {
		struct col_t col;
		col_init(&col, SYBFLT8, sizeof(double));
		assert(pmeta + i < metadata + nmeta);
		pmeta[i].name = make_col_name(pp->across+i);
		assert(pp->across);
		pmeta[i].pacross = pp->across + i;
		col_cpy(&pmeta[i].col, pp->nout? &pp->output[0].value : &col);
	}

	if (!reinit_results(dbproc->tds_socket, nmeta, metadata)) {
		return FAIL;
	}
	
	return SUCCEED;
	
#if 0
	for (pp->pout=pp->output; pp->pout < pp->output + pp->nout; pp->pout++) {
		char name[256] = {0};
	
		assert(pp->pout->col_key.keys[0].len < sizeof(name));
		memset(name, '\0', sizeof(name));
		memcpy(name, pp->pout->col_key.keys[0].s, pp->pout->col_key.keys[0].len), 
		printf("%5d  %-30s  %5d\n", pp->pout->row_key.keys[0].i, 
					    name, 
					    pp->pout->value.i );
	}
	exit(1);
#endif
}
Ejemplo n.º 3
0
static bool lc_dump_dyld_bind_info(uint32_t offset, uint32_t size, char *img, lambchop_logger *logger) {
  char *bind_info = img + offset;
  char *p = bind_info;
  if (!size) {
    return true;
  }
  while (p < (bind_info + size)) {
    uint8_t opcode = *p & BIND_OPCODE_MASK;
    uint8_t immediate = *p & BIND_IMMEDIATE_MASK;
    const char *type;
    int64_t sleb;
    uint64_t uleb, uleb2;
    p++;
    switch(opcode) {
      case BIND_OPCODE_DONE:
        return true;
      case BIND_OPCODE_SET_DYLIB_ORDINAL_IMM:
        lambchop_info(logger, "bind_info: op=BIND_OPCODE_SET_DYLIB_ORDINAL_IMM ordinal=%d\n", immediate);
        break;
      case BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB:
        uleb = parse_uleb128(&p);
        lambchop_info(logger, "bind_info: op=BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB ordinal=%d\n", uleb);
        break;
      case BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM:
        lambchop_info(logger,
                      "bind_info: op=BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM flags=0x%x, symbol = %s\n",
                      immediate, p);
        p += strlen(p) + 1;
        break;
      case BIND_OPCODE_SET_TYPE_IMM:
        type = bind_type(immediate);
        if (!type) {
          lambchop_err(logger, "unsupported bind type 0x%x\n", immediate);
          return false;
        }
        lambchop_info(logger, "bind_info: op=BIND_OPCODE_SET_TYPE_IMM type=%s\n", type);
        break;
      case BIND_OPCODE_SET_ADDEND_SLEB:
        sleb = parse_sleb128(&p);
        lambchop_info(logger, "bind_info: op=BIND_OPCODE_SET_ADDEND_SLEB addend=%lld\n", sleb);
        break;
      case BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
        uleb = parse_uleb128(&p);
        lambchop_info(logger,
                      "bind_info: op=BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB segment=%d offset=0x%x\n",
                      immediate, uleb);
        break;
      case BIND_OPCODE_ADD_ADDR_ULEB:
        uleb = parse_uleb128(&p);
        lambchop_info(logger, "bind_info: op=BIND_OPCODE_ADD_ADDR_ULEB offset=0x%x\n", uleb);
        break;
      case BIND_OPCODE_DO_BIND:
        lambchop_info(logger, "bind_info: op=BIND_OPCODE_DO_BIND\n");
        break;
      case BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB:
        uleb = parse_uleb128(&p);
        lambchop_info(logger, "bind_info: op=BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB offset=0x%x\n", uleb);
        break;
      case BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED:
        lambchop_info(logger, "bind_info: op=BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED offset=0x%x\n", immediate);
        break;
      case BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB:
        uleb = parse_uleb128(&p);
        uleb2 = parse_uleb128(&p);
        lambchop_info(logger,
                      "bind_info: op=BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB, times=%d, offset=0x%x\n",
                      uleb, uleb2);
        break;
      default:
        lambchop_err(logger, "unsupported bind info opcode 0x%x\n", opcode);
        return false;
    }
  }
  lambchop_err(logger, "BIND_OPCODE_DONE not found\n");
  return false;
}
Ejemplo n.º 4
0
Archivo: reify.c Proyecto: DevL/ponyc
bool check_constraints(ast_t* orig, ast_t* typeparams, ast_t* typeargs,
  bool report_errors)
{
  ast_t* typeparam = ast_child(typeparams);
  ast_t* typearg = ast_child(typeargs);

  while(typeparam != NULL)
  {
    // Reify the constraint.
    ast_t* constraint = ast_childidx(typeparam, 1);
    ast_t* bind_constraint = bind_type(constraint);
    ast_t* r_constraint = reify(bind_constraint, typeparams, typeargs);

    if(bind_constraint != r_constraint)
      ast_free_unattached(bind_constraint);

    // A bound type must be a subtype of the constraint.
    errorframe_t info = NULL;
    if(!is_subtype(typearg, r_constraint, report_errors ? &info : NULL))
    {
      if(report_errors)
      {
        errorframe_t frame = NULL;
        ast_error_frame(&frame, orig,
          "type argument is outside its constraint");
        ast_error_frame(&frame, typearg,
          "argument: %s", ast_print_type(typearg));
        ast_error_frame(&frame, typeparam,
          "constraint: %s", ast_print_type(r_constraint));
        errorframe_append(&frame, &info);
        errorframe_report(&frame);
      }

      ast_free_unattached(r_constraint);
      return false;
    }

    ast_free_unattached(r_constraint);

    // A constructable constraint can only be fulfilled by a concrete typearg.
    if(is_constructable(constraint) && !is_concrete(typearg))
    {
      if(report_errors)
      {
        ast_error(orig, "a constructable constraint can only be fulfilled "
          "by a concrete type argument");
        ast_error(typearg, "argument: %s", ast_print_type(typearg));
        ast_error(typeparam, "constraint: %s", ast_print_type(constraint));
      }

      return false;
    }

    typeparam = ast_sibling(typeparam);
    typearg = ast_sibling(typearg);
  }

  assert(typeparam == NULL);
  assert(typearg == NULL);
  return true;
}
Ejemplo n.º 5
0
bool check_constraints(ast_t* orig, ast_t* typeparams, ast_t* typeargs,
  bool report_errors)
{
  // Reify the type parameters with the typeargs.
  ast_t* r_typeparams = reify(orig, typeparams, typeparams, typeargs);

  if(r_typeparams == NULL)
    return false;

  ast_t* r_typeparam = ast_child(r_typeparams);
  ast_t* typeparam = ast_child(typeparams);
  ast_t* typearg = ast_child(typeargs);

  while(r_typeparam != NULL)
  {
    // Use the reified constraint.
    ast_t* r_constraint = ast_childidx(r_typeparam, 1);
    r_constraint = bind_type(r_constraint);

    // A bound type must be a subtype of the constraint.
    if(!is_subtype(typearg, r_constraint))
    {
      if(report_errors)
      {
        ast_error(orig, "type argument is outside its constraint");
        ast_error(typearg, "argument: %s", ast_print_type(typearg));
        ast_error(typeparam, "constraint: %s", ast_print_type(r_constraint));
      }

      ast_free_unattached(r_typeparams);
      ast_free_unattached(r_constraint);
      return false;
    }

    ast_free_unattached(r_constraint);

    // A constructable constraint can only be fulfilled by a concrete typearg.
    ast_t* constraint = ast_childidx(typeparam, 1);

    if(is_constructable(constraint) && !is_concrete(typearg))
    {
      if(report_errors)
      {
        ast_error(orig, "a constructable constraint can only be fulfilled "
          "by a concrete type argument");
        ast_error(typearg, "argument: %s", ast_print_type(typearg));
        ast_error(typeparam, "constraint: %s", ast_print_type(constraint));
      }

      ast_free_unattached(r_typeparams);
      return false;
    }

    r_typeparam = ast_sibling(r_typeparam);
    typeparam = ast_sibling(typeparam);
    typearg = ast_sibling(typearg);
  }

  assert(r_typeparam == NULL);
  assert(typearg == NULL);

  ast_free_unattached(r_typeparams);
  return true;
}