Exemplo n.º 1
0
/* :nodoc: */
static VALUE
nucomp_hash(VALUE self)
{
    st_index_t v, h[2];
    VALUE n;

    get_dat1(self);
    n = rb_hash(dat->real);
    h[0] = NUM2LONG(n);
    n = rb_hash(dat->imag);
    h[1] = NUM2LONG(n);
    v = rb_memhash(h, sizeof(h));
    return LONG2FIX(v);
}
Exemplo n.º 2
0
/* :nodoc: */
static VALUE
nurat_hash(VALUE self, SEL sel)
{
    long v, h[2];
    VALUE n;

    get_dat1(self);
    n = rb_hash(dat->num);
    h[0] = NUM2LONG(n);
    n = rb_hash(dat->den);
    h[1] = NUM2LONG(n);
    v = rb_memhash(h, sizeof(h));
    return LONG2FIX(v);
}
Exemplo n.º 3
0
static VALUE method_line_hash(VALUE self)
{
  st_index_t hash;
  RGeo_GeometryData* self_data;
  VALUE factory;

  self_data = RGEO_GEOMETRY_DATA_PTR(self);
  factory = self_data->factory;
  hash = rb_hash_start(0);
  hash = rgeo_geos_objbase_hash(factory,
    RGEO_FACTORY_DATA_PTR(factory)->globals->feature_line, hash);
  hash = rgeo_geos_coordseq_hash(self_data->geos_context, self_data->geom, hash);
  return LONG2FIX(rb_hash_end(hash));
}
Exemplo n.º 4
0
/*
 * call-seq: to_h
 *
 * Returns the configuration instance variables as a hash, that can be
 * passed to the configure method.
 */
static VALUE cState_to_h(VALUE self)
{
    VALUE result = rb_hash_new();
    GET_STATE(self);
    rb_hash_aset(result, ID2SYM(i_indent), state->indent);
    rb_hash_aset(result, ID2SYM(i_space), state->space);
    rb_hash_aset(result, ID2SYM(i_space_before), state->space_before);
    rb_hash_aset(result, ID2SYM(i_object_nl), state->object_nl);
    rb_hash_aset(result, ID2SYM(i_array_nl), state->array_nl);
    rb_hash_aset(result, ID2SYM(i_check_circular), state->check_circular ? Qtrue : Qfalse);
    rb_hash_aset(result, ID2SYM(i_allow_nan), state->allow_nan ? Qtrue : Qfalse);
    rb_hash_aset(result, ID2SYM(i_max_nesting), LONG2FIX(state->max_nesting));
    return result;
}
Exemplo n.º 5
0
static VALUE
rb_struct_hash(VALUE s)
{
    long i, h;
    VALUE n;

    h = rb_hash(rb_obj_class(s));
    for (i = 0; i < RSTRUCT(s)->len; i++) {
	h = (h << 1) | (h<0 ? 1 : 0);
	n = rb_hash(RSTRUCT(s)->ptr[i]);
	h ^= NUM2LONG(n);
    }
    return LONG2FIX(h);
}
Exemplo n.º 6
0
Arquivo: attr.c Projeto: Vachman/STMT
VALUE oci8_get_ub4_attr(oci8_base_t *base, ub4 attrtype)
{
    ub4 val;
    sword rv;

    rv = OCIAttrGet(base->hp.ptr, base->type, &val, NULL, attrtype, oci8_errhp);
    if (rv != OCI_SUCCESS)
        oci8_raise(oci8_errhp, rv, NULL);
#if SIZEOF_LONG > 4
    return LONG2FIX(val);
#else
    return ULONG2NUM(val);
#endif
}
Exemplo n.º 7
0
static VALUE
range_hash(VALUE range)
{
    long hash = EXCL(range);
    VALUE v;

    v = rb_hash(RANGE_BEG(range));
    hash ^= v << 1;
    v = rb_hash(RANGE_END(range));
    hash ^= v << 9;
    hash ^= EXCL(range) << 24;

    return LONG2FIX(hash);
}
Exemplo n.º 8
0
/*:nodoc:*/
static VALUE ra_buffer_real_size_set(VALUE self, VALUE real_size) {
    RA_BUFFER *buf;
    Data_Get_Struct(self, RA_BUFFER, buf);

    long new_real_size = FIX2LONG(real_size);
    if(new_real_size > buf->size) {
        buf->real_size = buf->size;
    } else if(new_real_size < 0) {
        buf->real_size = 0;
    } else {
        buf->real_size = new_real_size;
    }

    return LONG2FIX(buf->real_size);
}
Exemplo n.º 9
0
static VALUE lzoruby_adler32(VALUE self, VALUE v_adler, VALUE v_buf) {
  lzo_uint32 adler;
  lzo_bytep buf;
  lzo_uint len;

  Check_Type(v_adler, T_FIXNUM);
  Check_Type(v_buf, T_STRING);
  adler = FIX2LONG(v_adler);
  buf = RSTRING_PTR(v_buf);
  len = RSTRING_LEN(v_buf);

  adler = lzo_adler32(adler, buf, len);

  return LONG2FIX(adler);
}
Exemplo n.º 10
0
static VALUE
range_each(VALUE range, SEL sel)
{
    VALUE beg, end;

    RETURN_ENUMERATOR(range, 0, 0);

    beg = RANGE_BEG(range);
    end = RANGE_END(range);

    if (FIXNUM_P(beg) && FIXNUM_P(end)) { /* fixnums are special */
	long lim = FIX2LONG(end);
	long i;

	if (!EXCL(range))
	    lim += 1;
	for (i = FIX2LONG(beg); i < lim; i++) {
	    rb_yield(LONG2FIX(i));
	    RETURN_IF_BROKEN();
	}
    }
    else if (SYMBOL_P(beg) && SYMBOL_P(end)) { /* symbols are special */
	VALUE args[2];

	args[0] = rb_sym_to_s(end);
	args[1] = EXCL(range) ? Qtrue : Qfalse;
	rb_objc_block_call(rb_sym_to_s(beg), selUpto, 2, args, sym_each_i, 0);
    }
    else {
	VALUE tmp = rb_check_string_type(beg);

	if (!NIL_P(tmp)) {
	    VALUE args[2];

	    args[0] = end;
	    args[1] = EXCL(range) ? Qtrue : Qfalse;
	    rb_objc_block_call(beg, selUpto, 2, args, rb_yield, 0);
	}
	else {
	    if (!discrete_object_p(beg)) {
		rb_raise(rb_eTypeError, "can't iterate from %s",
			 rb_obj_classname(beg));
	    }
	    range_each_func(range, each_i, NULL);
	}
    }
    return range;
}
Exemplo n.º 11
0
static VALUE
rb_csa_child_l(VALUE self, VALUE range)
{
    CSA *sa = csa_ptr(self);
    i64 l,r,ll,rr;
    int c,i;
    VALUE charset;
    i64 ret;

#if USE_RANGE
    ll = FIX2LONG(range_first(range));
    rr = FIX2LONG(range_last(range));  if (range_exclude_end_p(range) == Qtrue) rr--;
#else
    if (RALEN(range) != 2) {
      return Qnil;
    }
    ll = FIX2LONG(RAPTR(range)[0]);
    rr = FIX2LONG(RAPTR(range)[1]);
#endif
    l = r = -1;

    if (!rb_block_given_p()) charset = rb_ary_new();
    for (i=0; i<sa->m; i++) {
      c = sa->AtoC[i];
      l = ll;  r = rr;
      ret = sa->searchsub(c, sa, &l, &r);
      if (ret == 0) {
        if (rb_block_given_p()) {
            rb_yield(rb_ary_new3(2,INT2FIX(c),
#if USE_RANGE
                     rb_range_new(LONG2FIX(l), LONG2FIX(r), Qnil)));
#else
                     rb_ary_new3(2,LONG2FIX(l),LONG2FIX(r))));
#endif
        } else {
          rb_ary_push(charset,
            rb_ary_new3(2,INT2FIX(c),
#if USE_RANGE
            rb_range_new(LONG2FIX(l), LONG2FIX(r), Qnil)));
#else
            rb_ary_new3(2,LONG2FIX(l),LONG2FIX(r))));
#endif
        }
      }
    }
Exemplo n.º 12
0
static VALUE
rb_csa_inverse(VALUE self, VALUE oi)
{
    CSA *sa = csa_ptr(self);
    i64 i,j,n;

    i = FIX2LONG(oi);
    n = sa->n;

    if (i < 0 || i > n) {    // error
      return Qnil;
    }

    j = sa->inverse(sa, i);
    return LONG2FIX(j);
}
Exemplo n.º 13
0
static VALUE rb_raise_mysql2_error(mysql_client_wrapper *wrapper) {
  VALUE rb_error_msg = rb_str_new2(mysql_error(wrapper->client));
  VALUE rb_sql_state = rb_tainted_str_new2(mysql_sqlstate(wrapper->client));
  VALUE e;

#ifdef HAVE_RUBY_ENCODING_H
  rb_enc_associate(rb_error_msg, rb_utf8_encoding());
  rb_enc_associate(rb_sql_state, rb_usascii_encoding());
#endif

  e = rb_funcall(cMysql2Error, rb_intern("new"), 2, rb_error_msg, LONG2FIX(wrapper->server_version));
  rb_funcall(e, intern_error_number_eql, 1, UINT2NUM(mysql_errno(wrapper->client)));
  rb_funcall(e, intern_sql_state_eql, 1, rb_sql_state);
  rb_exc_raise(e);
  return Qnil;
}
Exemplo n.º 14
0
inline static VALUE mArray_json_transfrom(VALUE self, VALUE Vstate, VALUE Vdepth) {
    long i, len = RARRAY_LEN(self);
    VALUE shift, result;
    long depth = NIL_P(Vdepth) ? 0 : FIX2LONG(Vdepth);
    VALUE delim = rb_str_new2(",");
    GET_STATE(Vstate);

    if (state->check_circular) {
        VALUE self_id = rb_obj_id(self);
        rb_hash_aset(state->seen, self_id, Qtrue);
        result = rb_str_buf_new(len);
        if (RSTRING_LEN(state->array_nl)) rb_str_append(delim, state->array_nl);
        shift = rb_str_times(state->indent, LONG2FIX(depth + 1));

        rb_str_buf_cat2(result, "[");
        rb_str_buf_append(result, state->array_nl);
        for (i = 0;  i < len; i++) {
            VALUE element = RARRAY_PTR(self)[i];
            if (RTEST(rb_hash_aref(state->seen, rb_obj_id(element)))) {
                rb_raise(eCircularDatastructure,
                        "circular data structures not supported!");
            }
            OBJ_INFECT(result, element);
            if (i > 0) rb_str_buf_append(result, delim);
            rb_str_buf_append(result, shift);
            rb_str_buf_append(result, rb_funcall(element, i_to_json, 2, Vstate, LONG2FIX(depth + 1)));
        }
        if (RSTRING_LEN(state->array_nl)) {
            rb_str_buf_append(result, state->array_nl);
            rb_str_buf_append(result, rb_str_times(state->indent, LONG2FIX(depth)));
        }
        rb_str_buf_cat2(result, "]");
        rb_hash_delete(state->seen, self_id);
    } else {
        result = rb_str_buf_new(len);
        if (RSTRING_LEN(state->array_nl)) rb_str_append(delim, state->array_nl);
        shift = rb_str_times(state->indent, LONG2FIX(depth + 1));

        rb_str_buf_cat2(result, "[");
        rb_str_buf_append(result, state->array_nl);
        for (i = 0;  i < len; i++) {
            VALUE element = RARRAY_PTR(self)[i];
            OBJ_INFECT(result, element);
            if (i > 0) rb_str_buf_append(result, delim);
            rb_str_buf_append(result, shift);
            rb_str_buf_append(result, rb_funcall(element, i_to_json, 2, Vstate, LONG2FIX(depth + 1)));
        }
        rb_str_buf_append(result, state->array_nl);
        if (RSTRING_LEN(state->array_nl)) {
            rb_str_buf_append(result, rb_str_times(state->indent, LONG2FIX(depth)));
        }
        rb_str_buf_cat2(result, "]");
    }
    return result;
}
Exemplo n.º 15
0
Arquivo: range.c Projeto: DashYang/sim
static VALUE
range_hash(VALUE range)
{
    st_index_t hash = EXCL(range);
    VALUE v;

    hash = rb_hash_start(hash);
    v = rb_hash(RANGE_BEG(range));
    hash = rb_hash_uint(hash, NUM2LONG(v));
    v = rb_hash(RANGE_END(range));
    hash = rb_hash_uint(hash, NUM2LONG(v));
    hash = rb_hash_uint(hash, EXCL(range) << 24);
    hash = rb_hash_end(hash);

    return LONG2FIX(hash);
}
Exemplo n.º 16
0
PRIMITIVE VALUE
vm_fast_minus(VALUE left, VALUE right, unsigned char overriden)
{
    if (overriden == 0 && NUMERIC_IMM_P(left) && NUMERIC_IMM_P(right)) {
	if (FIXNUM_P(left) && FIXNUM_P(right)) {
	    const long res = FIX2LONG(left) - FIX2LONG(right);
	    if (FIXABLE(res)) {
		return LONG2FIX(res);
	    }
	}
	else {
	    const double res = IMM2DBL(left) - IMM2DBL(right);
	    return DBL2FIXFLOAT(res);
	}
    }
    return vm_dispatch(0, left, selMINUS, NULL, 0, 1, &right);
}
Exemplo n.º 17
0
static VALUE rb_raise_mysql2_error(mysql_client_wrapper *wrapper) {
  VALUE rb_error_msg = rb_str_new2(mysql_error(wrapper->client));
  VALUE rb_sql_state = rb_tainted_str_new2(mysql_sqlstate(wrapper->client));
  VALUE e;

#ifdef HAVE_RUBY_ENCODING_H
  rb_enc_associate(rb_error_msg, rb_utf8_encoding());
  rb_enc_associate(rb_sql_state, rb_usascii_encoding());
#endif

  e = rb_funcall(cMysql2Error, intern_new_with_args, 4,
                 rb_error_msg,
                 LONG2FIX(wrapper->server_version),
                 UINT2NUM(mysql_errno(wrapper->client)),
                 rb_sql_state);
  rb_exc_raise(e);
}
Exemplo n.º 18
0
VALUE lineStatusIO(VALUE self)
{

    PortDescriptor *port = NULL;

    Data_Get_Struct(self, PortDescriptor, port);

    unsigned long Status = 0, Temp = 0;

    GetCommModemStatus(port->fd, &Temp);

    if (Temp & MS_CTS_ON) Status |= LS_CTS;
    if (Temp & MS_DSR_ON) Status |= LS_DSR;
    if (Temp & MS_RING_ON) Status |= LS_RI;
    if (Temp & MS_RLSD_ON) Status |= LS_DCD;

    return LONG2FIX(Status);
}
Exemplo n.º 19
0
static VALUE
recursive_hash(VALUE range, VALUE dummy, int recur)
{
    st_index_t hash = EXCL(range);
    VALUE v;

    hash = rb_hash_start(hash);
    if (!recur) {
	v = rb_hash(RANGE_BEG(range));
	hash = rb_hash_uint(hash, NUM2LONG(v));
	v = rb_hash(RANGE_END(range));
	hash = rb_hash_uint(hash, NUM2LONG(v));
    }
    hash = rb_hash_uint(hash, EXCL(range) << 24);
    hash = rb_hash_end(hash);

    return LONG2FIX(hash);
}
Exemplo n.º 20
0
static VALUE
rb_csa_lf(VALUE self, VALUE oi)
{
    CSA *sa = csa_ptr(self);
    i64 i, n;
    i64 p;

    i = FIX2LONG(oi);
    n = sa->n;

    if (i < 0 || i > n) {    // error
      return Qnil;
    }

    p = sa->LF(sa, i);

    return LONG2FIX(p);
}
Exemplo n.º 21
0
VALUE
rb_rtype_assert_arguments_type(VALUE self, VALUE expected_args, VALUE args) {
	// 'for' loop initial declarations are only allowed in c99 mode
	long i;
	long e_len = RARRAY_LEN(expected_args);
	for(i = 0; i < RARRAY_LEN(args); i++) {
		VALUE e, v;
		if(i >= e_len) {
			break;
		}
		e = rb_ary_entry(expected_args, i);
		v = rb_ary_entry(args, i);
		if( !RTEST(rb_rtype_valid(self, e, v)) ) {
			VALUE msg = rb_funcall(rb_mRtype, rb_intern("arg_type_error_message"), 3, LONG2FIX(i), e, v);
			rb_raise(rb_eRtypeArgumentTypeError, "%s", StringValueCStr(msg));
		}
	}
	return Qnil;
}
Exemplo n.º 22
0
inline static VALUE mHash_json_transfrom(VALUE self, VALUE Vstate, VALUE Vdepth) {
    long depth, len = RHASH_SIZE(self);
    VALUE result;
    GET_STATE(Vstate);

    depth = 1 + FIX2LONG(Vdepth);
    result = rb_str_buf_new(len);
    state->memo = result;
    state->depth = LONG2FIX(depth);
    state->flag = 0;
    rb_str_buf_cat2(result, "{");
    if (RSTRING_LEN(state->object_nl)) rb_str_buf_append(result, state->object_nl);
    rb_hash_foreach(self, hash_to_json_state_i, Vstate);
    if (RSTRING_LEN(state->object_nl)) rb_str_buf_append(result, state->object_nl);
    if (RSTRING_LEN(state->object_nl)) {
        rb_str_buf_append(result, rb_str_times(state->indent, Vdepth));
    }
    rb_str_buf_cat2(result, "}");
    return result;
}
Exemplo n.º 23
0
VALUE duration_to_fixnum( VALUE self, VALUE duration ) {
  struct icaldurationtype dur_struct;
  char * _duration;

  ID to_string    = rb_intern( "to_string" );

  if( TYPE( duration ) != T_STRING && rb_respond_to( duration, to_string ) )
    duration = rb_funcall( duration, to_string, 0 );

  Check_Type(duration, T_STRING);
  _duration = RSTRING(duration)->ptr;

  icalerror_clear_errno();
  icalerror_set_error_state( ICAL_MALFORMEDDATA_ERROR, ICAL_ERROR_NONFATAL);

  dur_struct = icaldurationtype_from_string( _duration );
  if( icaldurationtype_is_bad_duration( dur_struct ) )
    rb_raise(rb_eArgError, "Malformed Duration");

  return LONG2FIX(icaldurationtype_as_int( dur_struct ));
}
Exemplo n.º 24
0
static VALUE rb_mysql_client_server_info(VALUE self) {
    VALUE version, server_info;
    GET_CLIENT(self);

    REQUIRE_OPEN_DB(wrapper);
#ifdef HAVE_RUBY_ENCODING_H
    rb_encoding *default_internal_enc = rb_default_internal_encoding();
    rb_encoding *conn_enc = rb_to_encoding(wrapper->encoding);
#endif

    version = rb_hash_new();
    rb_hash_aset(version, sym_id, LONG2FIX(mysql_get_server_version(wrapper->client)));
    server_info = rb_str_new2(mysql_get_server_info(wrapper->client));
#ifdef HAVE_RUBY_ENCODING_H
    rb_enc_associate(server_info, conn_enc);
    if (default_internal_enc) {
        server_info = rb_str_export_to_enc(server_info, default_internal_enc);
    }
#endif
    rb_hash_aset(version, sym_version, server_info);
    return version;
}
Exemplo n.º 25
0
PRIMITIVE VALUE
vm_fast_mult(VALUE left, VALUE right, unsigned char overriden)
{
    if (overriden == 0 && NUMERIC_IMM_P(left) && NUMERIC_IMM_P(right)) {
	if (FIXNUM_P(left) && FIXNUM_P(right)) {
	    const long a = FIX2LONG(left);
	    if (a == 0) {
		return left;
	    }
	    const long b = FIX2LONG(right);
	    const long res = a * b;
	    if (FIXABLE(res) && res / a == b) {
		return LONG2FIX(res);
	    }
	}
	else {
	    const double res = IMM2DBL(left) * IMM2DBL(right);
	    return DBL2FIXFLOAT(res);
	}
    }
    return vm_dispatch(0, left, selMULT, NULL, 0, 1, &right);
}
Exemplo n.º 26
0
/*
 * call-seq: getch
 *
 * Works like StringScanner#getch but is UTF8-aware
 */
static VALUE rb_cStringScanner_UTF8_getch(VALUE self) {
  unsigned char *str;
  long len = 0, pos = 0;
  VALUE utf8Str, curStr;
  int8_t lastCharLen=0;
  
#ifndef RUBINIUS
  struct strscanner *scanner;
  GET_SCANNER(self, scanner);

  curStr = scanner->str;
  pos = scanner->curr;
#else
  curStr = rb_iv_get(self, "@string");
  pos = FIX2LONG(rb_iv_get(self, "@pos"));
#endif

  str = (unsigned char *)RSTRING_PTR(curStr);
  len = RSTRING_LEN(curStr);

  if (len > 0 && len > pos) {
    lastCharLen = utf8CharLen(str, len);
    if (lastCharLen < 0) {
      rb_raise(rb_eArgError, "invalid utf-8 byte sequence");
    }
    utf8Str = rb_str_new((char *)str+pos, lastCharLen);
    pos += lastCharLen;
#ifndef RUBINIUS
    scanner->curr = pos;
#else
    rb_iv_set(self, "@pos", LONG2FIX(pos));
#endif
    AS_UTF8(utf8Str);
    return utf8Str;
  } else {
    return Qnil;
  }
}
Exemplo n.º 27
0
static VALUE rb_mysql_client_server_info(VALUE self) {
  MYSQL * client;
  VALUE version, server_info;
#ifdef HAVE_RUBY_ENCODING_H
  rb_encoding *default_internal_enc = rb_default_internal_encoding();
  rb_encoding *conn_enc = rb_to_encoding(rb_iv_get(self, "@encoding"));
#endif

  Data_Get_Struct(self, MYSQL, client);
  REQUIRE_OPEN_DB(client);

  version = rb_hash_new();
  rb_hash_aset(version, sym_id, LONG2FIX(mysql_get_server_version(client)));
  server_info = rb_str_new2(mysql_get_server_info(client));
#ifdef HAVE_RUBY_ENCODING_H
  rb_enc_associate(server_info, conn_enc);
  if (default_internal_enc) {
    server_info = rb_str_export_to_enc(server_info, default_internal_enc);
  }
#endif
  rb_hash_aset(version, sym_version, server_info);
  return version;
}
Exemplo n.º 28
0
static VALUE rb_writev(VALUE io, VALUE list)
{
    rb_io_t * fptr;
    struct iovec * iov;
    long i;
    ssize_t written;
    VALUE tmp;

    Check_Type(list, T_ARRAY);
#ifdef IOV_MAX
    if(RARRAY_LEN(list) > IOV_MAX)
#else
    if(RARRAY_LEN(list) > NUM2INT(rb_IOV_MAX))
#endif
	rb_raise(rb_eArgError, "list is too long");

    tmp = rb_io_check_io(io);
    GetOpenFile(tmp, fptr);
    rb_io_check_writable(fptr);

    iov = xcalloc(RARRAY_LEN(list), sizeof(struct iovec));

    for(i = 0; i < RARRAY_LEN(list); i++) {
	VALUE string = rb_ary_entry(list, i);
	iov[i].iov_base = StringValuePtr(string);
	iov[i].iov_len = RSTRING_LEN(string);
    }

    written = writev(fptr->fd, iov, (int)RARRAY_LEN(list));

    xfree(iov);

    if (written == -1) rb_sys_fail_path(fptr->pathv);

    return LONG2FIX(written);
}
Exemplo n.º 29
0
// www.osr.com/ddk/graphics/gdifncs_027b.htm
BOOL
APIENTRY
XFORMOBJ_bApplyXform(
    IN XFORMOBJ *pxo,
    IN ULONG iMode,
    IN ULONG cPoints,
    IN PVOID pvIn,
    OUT PVOID pvOut)
{
    MATRIX mx;
    XFORMOBJ xoInv;
    POINTL *pptl;
    INT i;

    /* Check parameters */
    if (!pxo || !pvIn || !pvOut || cPoints < 1)
    {
        return FALSE;
    }

    /* Use inverse xform? */
    if (iMode == XF_INV_FXTOL || iMode == XF_INV_LTOL)
    {
        XFORMOBJ_vInit(&xoInv, &mx);
        if (XFORMOBJ_iInverse(&xoInv, pxo) == DDI_ERROR)
        {
            return FALSE;
        }
        pxo = &xoInv;
    }

    /* Convert POINTL to POINTFIX? */
    if (iMode == XF_LTOFX || iMode == XF_LTOL || iMode == XF_INV_LTOL)
    {
        pptl = pvIn;
        for (i = cPoints - 1; i >= 0; i--)
        {
            pptl[i].x = LONG2FIX(pptl[i].x);
            pptl[i].y = LONG2FIX(pptl[i].y);
        }
    }

    /* Do the actual fixpoint transformation */
    if (!XFORMOBJ_bXformFixPoints(pxo, cPoints, pvIn, pvOut))
    {
        return FALSE;
    }

    /* Convert POINTFIX to POINTL? */
    if (iMode == XF_INV_FXTOL || iMode == XF_INV_LTOL || iMode == XF_LTOL)
    {
        pptl = pvOut;
        for (i = cPoints - 1; i >= 0; i--)
        {
            pptl[i].x = FIX2LONG(pptl[i].x);
            pptl[i].y = FIX2LONG(pptl[i].y);
        }
    }

    return TRUE;
}
Exemplo n.º 30
0
VALUE
rb_str_format(int argc, const VALUE *argv, VALUE fmt)
{
    enum {default_float_precision = 6};
    rb_encoding *enc;
    const char *p, *end;
    char *buf;
    long blen, bsiz;
    VALUE result;

    long scanned = 0;
    int coderange = ENC_CODERANGE_7BIT;
    int width, prec, flags = FNONE;
    int nextarg = 1;
    int posarg = 0;
    int tainted = 0;
    VALUE nextvalue;
    VALUE tmp;
    VALUE str;
    volatile VALUE hash = Qundef;

#define CHECK_FOR_WIDTH(f)				 \
    if ((f) & FWIDTH) {					 \
	rb_raise(rb_eArgError, "width given twice");	 \
    }							 \
    if ((f) & FPREC0) {					 \
	rb_raise(rb_eArgError, "width after precision"); \
    }
#define CHECK_FOR_FLAGS(f)				 \
    if ((f) & FWIDTH) {					 \
	rb_raise(rb_eArgError, "flag after width");	 \
    }							 \
    if ((f) & FPREC0) {					 \
	rb_raise(rb_eArgError, "flag after precision"); \
    }

    ++argc;
    --argv;
    if (OBJ_TAINTED(fmt)) tainted = 1;
    StringValue(fmt);
    enc = rb_enc_get(fmt);
    fmt = rb_str_new4(fmt);
    p = RSTRING_PTR(fmt);
    end = p + RSTRING_LEN(fmt);
    blen = 0;
    bsiz = 120;
    result = rb_str_buf_new(bsiz);
    rb_enc_copy(result, fmt);
    buf = RSTRING_PTR(result);
    memset(buf, 0, bsiz);
    ENC_CODERANGE_SET(result, coderange);

    for (; p < end; p++) {
	const char *t;
	int n;
	VALUE sym = Qnil;

	for (t = p; t < end && *t != '%'; t++) ;
	PUSH(p, t - p);
	if (coderange != ENC_CODERANGE_BROKEN && scanned < blen) {
	    scanned += rb_str_coderange_scan_restartable(buf+scanned, buf+blen, enc, &coderange);
	    ENC_CODERANGE_SET(result, coderange);
	}
	if (t >= end) {
	    /* end of fmt string */
	    goto sprint_exit;
	}
	p = t + 1;		/* skip `%' */

	width = prec = -1;
	nextvalue = Qundef;
      retry:
	switch (*p) {
	  default:
	    if (rb_enc_isprint(*p, enc))
		rb_raise(rb_eArgError, "malformed format string - %%%c", *p);
	    else
		rb_raise(rb_eArgError, "malformed format string");
	    break;

	  case ' ':
	    CHECK_FOR_FLAGS(flags);
	    flags |= FSPACE;
	    p++;
	    goto retry;

	  case '#':
	    CHECK_FOR_FLAGS(flags);
	    flags |= FSHARP;
	    p++;
	    goto retry;

	  case '+':
	    CHECK_FOR_FLAGS(flags);
	    flags |= FPLUS;
	    p++;
	    goto retry;

	  case '-':
	    CHECK_FOR_FLAGS(flags);
	    flags |= FMINUS;
	    p++;
	    goto retry;

	  case '0':
	    CHECK_FOR_FLAGS(flags);
	    flags |= FZERO;
	    p++;
	    goto retry;

	  case '1': case '2': case '3': case '4':
	  case '5': case '6': case '7': case '8': case '9':
	    n = 0;
	    GETNUM(n, width);
	    if (*p == '$') {
		if (nextvalue != Qundef) {
		    rb_raise(rb_eArgError, "value given twice - %d$", n);
		}
		nextvalue = GETPOSARG(n);
		p++;
		goto retry;
	    }
	    CHECK_FOR_WIDTH(flags);
	    width = n;
	    flags |= FWIDTH;
	    goto retry;

	  case '<':
	  case '{':
	    {
		const char *start = p;
		char term = (*p == '<') ? '>' : '}';
		int len;

		for (; p < end && *p != term; ) {
		    p += rb_enc_mbclen(p, end, enc);
		}
		if (p >= end) {
		    rb_raise(rb_eArgError, "malformed name - unmatched parenthesis");
		}
#if SIZEOF_INT < SIZEOF_SIZE_T
		if ((size_t)(p - start) >= INT_MAX) {
		    const int message_limit = 20;
		    len = (int)(rb_enc_right_char_head(start, start + message_limit, p, enc) - start);
		    rb_enc_raise(enc, rb_eArgError,
				 "too long name (%"PRIdSIZE" bytes) - %.*s...%c",
				 (size_t)(p - start - 2), len, start, term);
		}
#endif
		len = (int)(p - start + 1); /* including parenthesis */
		if (sym != Qnil) {
		    rb_enc_raise(enc, rb_eArgError, "named%.*s after <%"PRIsVALUE">",
				 len, start, rb_sym2str(sym));
		}
		CHECKNAMEARG(start, len, enc);
		get_hash(&hash, argc, argv);
		sym = rb_check_symbol_cstr(start + 1,
					   len - 2 /* without parenthesis */,
					   enc);
		if (sym != Qnil) nextvalue = rb_hash_lookup2(hash, sym, Qundef);
		if (nextvalue == Qundef) {
		    rb_enc_raise(enc, rb_eKeyError, "key%.*s not found", len, start);
		}
		if (term == '}') goto format_s;
		p++;
		goto retry;
	    }

	  case '*':
	    CHECK_FOR_WIDTH(flags);
	    flags |= FWIDTH;
	    GETASTER(width);
	    if (width < 0) {
		flags |= FMINUS;
		width = -width;
	    }
	    p++;
	    goto retry;

	  case '.':
	    if (flags & FPREC0) {
		rb_raise(rb_eArgError, "precision given twice");
	    }
	    flags |= FPREC|FPREC0;

	    prec = 0;
	    p++;
	    if (*p == '*') {
		GETASTER(prec);
		if (prec < 0) {	/* ignore negative precision */
		    flags &= ~FPREC;
		}
		p++;
		goto retry;
	    }

	    GETNUM(prec, precision);
	    goto retry;

	  case '\n':
	  case '\0':
	    p--;
	  case '%':
	    if (flags != FNONE) {
		rb_raise(rb_eArgError, "invalid format character - %%");
	    }
	    PUSH("%", 1);
	    break;

	  case 'c':
	    {
		VALUE val = GETARG();
		VALUE tmp;
		unsigned int c;
		int n;

		tmp = rb_check_string_type(val);
		if (!NIL_P(tmp)) {
		    if (rb_enc_strlen(RSTRING_PTR(tmp),RSTRING_END(tmp),enc) != 1) {
			rb_raise(rb_eArgError, "%%c requires a character");
		    }
		    c = rb_enc_codepoint_len(RSTRING_PTR(tmp), RSTRING_END(tmp), &n, enc);
		    RB_GC_GUARD(tmp);
		}
		else {
		    c = NUM2INT(val);
		    n = rb_enc_codelen(c, enc);
		}
		if (n <= 0) {
		    rb_raise(rb_eArgError, "invalid character");
		}
		if (!(flags & FWIDTH)) {
		    CHECK(n);
		    rb_enc_mbcput(c, &buf[blen], enc);
		    blen += n;
		}
		else if ((flags & FMINUS)) {
		    CHECK(n);
		    rb_enc_mbcput(c, &buf[blen], enc);
		    blen += n;
		    FILL(' ', width-1);
		}
		else {
		    FILL(' ', width-1);
		    CHECK(n);
		    rb_enc_mbcput(c, &buf[blen], enc);
		    blen += n;
		}
	    }
	    break;

	  case 's':
	  case 'p':
	  format_s:
	    {
		VALUE arg = GETARG();
		long len, slen;

		if (*p == 'p') arg = rb_inspect(arg);
		str = rb_obj_as_string(arg);
		if (OBJ_TAINTED(str)) tainted = 1;
		len = RSTRING_LEN(str);
		rb_str_set_len(result, blen);
		if (coderange != ENC_CODERANGE_BROKEN && scanned < blen) {
		    int cr = coderange;
		    scanned += rb_str_coderange_scan_restartable(buf+scanned, buf+blen, enc, &cr);
		    ENC_CODERANGE_SET(result,
				      (cr == ENC_CODERANGE_UNKNOWN ?
				       ENC_CODERANGE_BROKEN : (coderange = cr)));
		}
		enc = rb_enc_check(result, str);
		if (flags&(FPREC|FWIDTH)) {
		    slen = rb_enc_strlen(RSTRING_PTR(str),RSTRING_END(str),enc);
		    if (slen < 0) {
			rb_raise(rb_eArgError, "invalid mbstring sequence");
		    }
		    if ((flags&FPREC) && (prec < slen)) {
			char *p = rb_enc_nth(RSTRING_PTR(str), RSTRING_END(str),
					     prec, enc);
			slen = prec;
			len = p - RSTRING_PTR(str);
		    }
		    /* need to adjust multi-byte string pos */
		    if ((flags&FWIDTH) && (width > slen)) {
			width -= (int)slen;
			if (!(flags&FMINUS)) {
			    CHECK(width);
			    while (width--) {
				buf[blen++] = ' ';
			    }
			}
			CHECK(len);
			memcpy(&buf[blen], RSTRING_PTR(str), len);
			RB_GC_GUARD(str);
			blen += len;
			if (flags&FMINUS) {
			    CHECK(width);
			    while (width--) {
				buf[blen++] = ' ';
			    }
			}
			rb_enc_associate(result, enc);
			break;
		    }
		}
		PUSH(RSTRING_PTR(str), len);
		RB_GC_GUARD(str);
		rb_enc_associate(result, enc);
	    }
	    break;

	  case 'd':
	  case 'i':
	  case 'o':
	  case 'x':
	  case 'X':
	  case 'b':
	  case 'B':
	  case 'u':
	    {
		volatile VALUE val = GETARG();
                int valsign;
		char nbuf[64], *s;
		const char *prefix = 0;
		int sign = 0, dots = 0;
		char sc = 0;
		long v = 0;
		int base, bignum = 0;
		int len;

		switch (*p) {
		  case 'd':
		  case 'i':
		  case 'u':
		    sign = 1; break;
		  case 'o':
		  case 'x':
		  case 'X':
		  case 'b':
		  case 'B':
		    if (flags&(FPLUS|FSPACE)) sign = 1;
		    break;
		}
		if (flags & FSHARP) {
		    switch (*p) {
		      case 'o':
			prefix = "0"; break;
		      case 'x':
			prefix = "0x"; break;
		      case 'X':
			prefix = "0X"; break;
		      case 'b':
			prefix = "0b"; break;
		      case 'B':
			prefix = "0B"; break;
		    }
		}

	      bin_retry:
		switch (TYPE(val)) {
		  case T_FLOAT:
		    if (FIXABLE(RFLOAT_VALUE(val))) {
			val = LONG2FIX((long)RFLOAT_VALUE(val));
			goto bin_retry;
		    }
		    val = rb_dbl2big(RFLOAT_VALUE(val));
		    if (FIXNUM_P(val)) goto bin_retry;
		    bignum = 1;
		    break;
		  case T_STRING:
		    val = rb_str_to_inum(val, 0, TRUE);
		    goto bin_retry;
		  case T_BIGNUM:
		    bignum = 1;
		    break;
		  case T_FIXNUM:
		    v = FIX2LONG(val);
		    break;
		  default:
		    val = rb_Integer(val);
		    goto bin_retry;
		}

		switch (*p) {
		  case 'o':
		    base = 8; break;
		  case 'x':
		  case 'X':
		    base = 16; break;
		  case 'b':
		  case 'B':
		    base = 2; break;
		  case 'u':
		  case 'd':
		  case 'i':
		  default:
		    base = 10; break;
		}

                if (base != 10) {
                    int numbits = ffs(base)-1;
                    size_t abs_nlz_bits;
                    size_t numdigits = rb_absint_numwords(val, numbits, &abs_nlz_bits);
                    long i;
                    if (INT_MAX-1 < numdigits) /* INT_MAX is used because rb_long2int is used later. */
                        rb_raise(rb_eArgError, "size too big");
                    if (sign) {
                        if (numdigits == 0)
                            numdigits = 1;
                        tmp = rb_str_new(NULL, numdigits);
                        valsign = rb_integer_pack(val, RSTRING_PTR(tmp), RSTRING_LEN(tmp),
                                1, CHAR_BIT-numbits, INTEGER_PACK_BIG_ENDIAN);
                        for (i = 0; i < RSTRING_LEN(tmp); i++)
                            RSTRING_PTR(tmp)[i] = ruby_digitmap[((unsigned char *)RSTRING_PTR(tmp))[i]];
                        s = RSTRING_PTR(tmp);
                        if (valsign < 0) {
                            sc = '-';
                            width--;
                        }
                        else if (flags & FPLUS) {
                            sc = '+';
                            width--;
                        }
                        else if (flags & FSPACE) {
                            sc = ' ';
                            width--;
                        }
                    }
                    else {
                        /* Following conditional "numdigits++" guarantees the
                         * most significant digit as
                         * - '1'(bin), '7'(oct) or 'f'(hex) for negative numbers
                         * - '0' for zero
                         * - not '0' for positive numbers.
                         *
                         * It also guarantees the most significant two
                         * digits will not be '11'(bin), '77'(oct), 'ff'(hex)
                         * or '00'.  */
                        if (numdigits == 0 ||
                                ((abs_nlz_bits != (size_t)(numbits-1) ||
                                  !rb_absint_singlebit_p(val)) &&
                                 (!bignum ? v < 0 : BIGNUM_NEGATIVE_P(val))))
                            numdigits++;
                        tmp = rb_str_new(NULL, numdigits);
                        valsign = rb_integer_pack(val, RSTRING_PTR(tmp), RSTRING_LEN(tmp),
                                1, CHAR_BIT-numbits, INTEGER_PACK_2COMP | INTEGER_PACK_BIG_ENDIAN);
                        for (i = 0; i < RSTRING_LEN(tmp); i++)
                            RSTRING_PTR(tmp)[i] = ruby_digitmap[((unsigned char *)RSTRING_PTR(tmp))[i]];
                        s = RSTRING_PTR(tmp);
                        dots = valsign < 0;
                    }
                    len = rb_long2int(RSTRING_END(tmp) - s);
                }
                else if (!bignum) {
                    valsign = 1;
                    if (v < 0) {
                        v = -v;
                        sc = '-';
                        width--;
                        valsign = -1;
                    }
                    else if (flags & FPLUS) {
                        sc = '+';
                        width--;
                    }
                    else if (flags & FSPACE) {
                        sc = ' ';
                        width--;
                    }
                    snprintf(nbuf, sizeof(nbuf), "%ld", v);
                    s = nbuf;
		    len = (int)strlen(s);
		}
		else {
                    tmp = rb_big2str(val, 10);
                    s = RSTRING_PTR(tmp);
                    valsign = 1;
                    if (s[0] == '-') {
                        s++;
                        sc = '-';
                        width--;
                        valsign = -1;
                    }
                    else if (flags & FPLUS) {
                        sc = '+';
                        width--;
                    }
                    else if (flags & FSPACE) {
                        sc = ' ';
                        width--;
                    }
		    len = rb_long2int(RSTRING_END(tmp) - s);
		}

		if (dots) {
		    prec -= 2;
		    width -= 2;
		}

		if (*p == 'X') {
		    char *pp = s;
		    int c;
		    while ((c = (int)(unsigned char)*pp) != 0) {
			*pp = rb_enc_toupper(c, enc);
			pp++;
		    }
		}
		if (prefix && !prefix[1]) { /* octal */
		    if (dots) {
			prefix = 0;
		    }
		    else if (len == 1 && *s == '0') {
			len = 0;
			if (flags & FPREC) prec--;
		    }
		    else if ((flags & FPREC) && (prec > len)) {
			prefix = 0;
		    }
		}
		else if (len == 1 && *s == '0') {
		    prefix = 0;
		}
		if (prefix) {
		    width -= (int)strlen(prefix);
		}
		if ((flags & (FZERO|FMINUS|FPREC)) == FZERO) {
		    prec = width;
		    width = 0;
		}
		else {
		    if (prec < len) {
			if (!prefix && prec == 0 && len == 1 && *s == '0') len = 0;
			prec = len;
		    }
		    width -= prec;
		}
		if (!(flags&FMINUS)) {
		    CHECK(width);
		    while (width-- > 0) {
			buf[blen++] = ' ';
		    }
		}
		if (sc) PUSH(&sc, 1);
		if (prefix) {
		    int plen = (int)strlen(prefix);
		    PUSH(prefix, plen);
		}
		CHECK(prec - len);
		if (dots) PUSH("..", 2);
		if (!sign && valsign < 0) {
		    char c = sign_bits(base, p);
		    while (len < prec--) {
			buf[blen++] = c;
		    }
		}
		else if ((flags & (FMINUS|FPREC)) != FMINUS) {
		    while (len < prec--) {
			buf[blen++] = '0';
		    }
		}
		PUSH(s, len);
		RB_GC_GUARD(tmp);
		CHECK(width);
		while (width-- > 0) {
		    buf[blen++] = ' ';
		}
	    }
	    break;

	  case 'f':
	    {
		VALUE val = GETARG(), num, den;
		int sign = (flags&FPLUS) ? 1 : 0, zero = 0;
		long len, done = 0;
		int prefix = 0;
		if (!RB_TYPE_P(val, T_RATIONAL)) {
		    nextvalue = val;
		    goto float_value;
		}
		if (!(flags&FPREC)) prec = default_float_precision;
		den = rb_rational_den(val);
		num = rb_rational_num(val);
		if (FIXNUM_P(num)) {
		    if ((SIGNED_VALUE)num < 0) {
			long n = -FIX2LONG(num);
			num = LONG2FIX(n);
			sign = -1;
		    }
		}
		else if (rb_num_negative_p(num)) {
		    sign = -1;
		    num = rb_funcallv(num, idUMinus, 0, 0);
		}
		if (den != INT2FIX(1) || prec > 1) {
		    const ID idDiv = rb_intern("div");
		    VALUE p10 = rb_int_positive_pow(10, prec);
		    VALUE den_2 = rb_funcall(den, idDiv, 1, INT2FIX(2));
		    num = rb_funcallv(num, '*', 1, &p10);
		    num = rb_funcallv(num, '+', 1, &den_2);
		    num = rb_funcallv(num, idDiv, 1, &den);
		}
		else if (prec >= 0) {
		    zero = prec;
		}
		val = rb_obj_as_string(num);
		len = RSTRING_LEN(val) + zero;
		if (prec >= len) ++len; /* integer part 0 */
		if (sign || (flags&FSPACE)) ++len;
		if (prec > 0) ++len; /* period */
		CHECK(len > width ? len : width);
		if (sign || (flags&FSPACE)) {
		    buf[blen++] = sign > 0 ? '+' : sign < 0 ? '-' : ' ';
		    prefix++;
		    done++;
		}
		len = RSTRING_LEN(val) + zero;
		t = RSTRING_PTR(val);
		if (len > prec) {
		    memcpy(&buf[blen], t, len - prec);
		    blen += len - prec;
		    done += len - prec;
		}
		else {
		    buf[blen++] = '0';
		    done++;
		}
		if (prec > 0) {
		    buf[blen++] = '.';
		    done++;
		}
		if (zero) {
		    FILL('0', zero);
		    done += zero;
		}
		else if (prec > len) {
		    FILL('0', prec - len);
		    memcpy(&buf[blen], t, len);
		    blen += len;
		    done += prec;
		}
		else if (prec > 0) {
		    memcpy(&buf[blen], t + len - prec, prec);
		    blen += prec;
		    done += prec;
		}
		if ((flags & FWIDTH) && width > done) {
		    int fill = ' ';
		    long shifting = 0;
		    if (!(flags&FMINUS)) {
			shifting = done;
			if (flags&FZERO) {
			    shifting -= prefix;
			    fill = '0';
			}
			blen -= shifting;
			memmove(&buf[blen + width - done], &buf[blen], shifting);
		    }
		    FILL(fill, width - done);
		    blen += shifting;
		}
		RB_GC_GUARD(val);
		break;
	    }
	  case 'g':
	  case 'G':
	  case 'e':
	  case 'E':
	    /* TODO: rational support */
	  case 'a':
	  case 'A':
	  float_value:
	    {
		VALUE val = GETARG();
		double fval;
		int i, need;
		char fbuf[32];

		fval = RFLOAT_VALUE(rb_Float(val));
		if (isnan(fval) || isinf(fval)) {
		    const char *expr;

		    if (isnan(fval)) {
			expr = "NaN";
		    }
		    else {
			expr = "Inf";
		    }
		    need = (int)strlen(expr);
		    if ((!isnan(fval) && fval < 0.0) || (flags & FPLUS))
			need++;
		    if ((flags & FWIDTH) && need < width)
			need = width;

		    CHECK(need + 1);
		    snprintf(&buf[blen], need + 1, "%*s", need, "");
		    if (flags & FMINUS) {
			if (!isnan(fval) && fval < 0.0)
			    buf[blen++] = '-';
			else if (flags & FPLUS)
			    buf[blen++] = '+';
			else if (flags & FSPACE)
			    blen++;
			memcpy(&buf[blen], expr, strlen(expr));
		    }
		    else {
			if (!isnan(fval) && fval < 0.0)
			    buf[blen + need - strlen(expr) - 1] = '-';
			else if (flags & FPLUS)
			    buf[blen + need - strlen(expr) - 1] = '+';
			else if ((flags & FSPACE) && need > width)
			    blen++;
			memcpy(&buf[blen + need - strlen(expr)], expr,
			       strlen(expr));
		    }
		    blen += strlen(&buf[blen]);
		    break;
		}

		fmt_setup(fbuf, sizeof(fbuf), *p, flags, width, prec);
		need = 0;
		if (*p != 'e' && *p != 'E') {
		    i = INT_MIN;
		    frexp(fval, &i);
		    if (i > 0)
			need = BIT_DIGITS(i);
		}
		need += (flags&FPREC) ? prec : default_float_precision;
		if ((flags&FWIDTH) && need < width)
		    need = width;
		need += 20;

		CHECK(need);
		snprintf(&buf[blen], need, fbuf, fval);
		blen += strlen(&buf[blen]);
	    }
	    break;
	}
	flags = FNONE;
    }

  sprint_exit:
    RB_GC_GUARD(fmt);
    /* XXX - We cannot validate the number of arguments if (digit)$ style used.
     */
    if (posarg >= 0 && nextarg < argc) {
	const char *mesg = "too many arguments for format string";
	if (RTEST(ruby_debug)) rb_raise(rb_eArgError, "%s", mesg);
	if (RTEST(ruby_verbose)) rb_warn("%s", mesg);
    }
    rb_str_resize(result, blen);

    if (tainted) OBJ_TAINT(result);
    return result;
}