Beispiel #1
1
static VALUE rb_mysql_result_each(int argc, VALUE * argv, VALUE self) {
  VALUE defaults, opts, block;
  ID db_timezone, app_timezone, dbTz, appTz;
  unsigned long i;
  const char * errstr;
  int symbolizeKeys, asArray, castBool, cacheRows, cast;
  MYSQL_FIELD * fields = NULL;

  GET_RESULT(self);

  defaults = rb_iv_get(self, "@query_options");
  Check_Type(defaults, T_HASH);
  if (rb_scan_args(argc, argv, "01&", &opts, &block) == 1) {
    opts = rb_funcall(defaults, intern_merge, 1, opts);
  } else {
    opts = defaults;
  }

  symbolizeKeys = RTEST(rb_hash_aref(opts, sym_symbolize_keys));
  asArray       = rb_hash_aref(opts, sym_as) == sym_array;
  castBool      = RTEST(rb_hash_aref(opts, sym_cast_booleans));
  cacheRows     = RTEST(rb_hash_aref(opts, sym_cache_rows));
  cast          = RTEST(rb_hash_aref(opts, sym_cast));

  if (wrapper->is_streaming && cacheRows) {
    rb_warn(":cache_rows is ignored if :stream is true");
  }

  dbTz = rb_hash_aref(opts, sym_database_timezone);
  if (dbTz == sym_local) {
    db_timezone = intern_local;
  } else if (dbTz == sym_utc) {
    db_timezone = intern_utc;
  } else {
    if (!NIL_P(dbTz)) {
      rb_warn(":database_timezone option must be :utc or :local - defaulting to :local");
    }
    db_timezone = intern_local;
  }

  appTz = rb_hash_aref(opts, sym_application_timezone);
  if (appTz == sym_local) {
    app_timezone = intern_local;
  } else if (appTz == sym_utc) {
    app_timezone = intern_utc;
  } else {
    app_timezone = Qnil;
  }

  if (wrapper->is_streaming) {
    /* When streaming, we will only yield rows, not return them. */
    if (wrapper->rows == Qnil) {
      wrapper->rows = rb_ary_new();
    }

    if (!wrapper->streamingComplete) {
      VALUE row;

      fields = mysql_fetch_fields(wrapper->result);

      do {
        row = rb_mysql_result_fetch_row(self, db_timezone, app_timezone, symbolizeKeys, asArray, castBool, cast, fields);
        if (row != Qnil) {
          wrapper->numberOfRows++;
          if (block != Qnil) {
            rb_yield(row);
          }
        }
      } while(row != Qnil);

      rb_mysql_result_free_result(wrapper);
      wrapper->streamingComplete = 1;

      // Check for errors, the connection might have gone out from under us
      // mysql_error returns an empty string if there is no error
      errstr = mysql_error(wrapper->client_wrapper->client);
      if (errstr[0]) {
        rb_raise(cMysql2Error, "%s", errstr);
      }
    } else {
      rb_raise(cMysql2Error, "You have already fetched all the rows for this query and streaming is true. (to reiterate you must requery).");
    }
  } else {
    if (wrapper->lastRowProcessed == 0) {
      wrapper->numberOfRows = mysql_num_rows(wrapper->result);
      if (wrapper->numberOfRows == 0) {
        wrapper->rows = rb_ary_new();
        return wrapper->rows;
      }
      wrapper->rows = rb_ary_new2(wrapper->numberOfRows);
    } else if (!cacheRows && wrapper->lastRowProcessed == wrapper->numberOfRows) {
      mysql_data_seek(wrapper->result, 0);
      wrapper->lastRowProcessed = 0;
      wrapper->rows = rb_ary_new2(wrapper->numberOfRows);
    }

    if (cacheRows && wrapper->lastRowProcessed == wrapper->numberOfRows) {
      /* we've already read the entire dataset from the C result into our */
      /* internal array. Lets hand that over to the user since it's ready to go */
      for (i = 0; i < wrapper->numberOfRows; i++) {
        rb_yield(rb_ary_entry(wrapper->rows, i));
      }
    } else {
      unsigned long rowsProcessed = 0;
      rowsProcessed = RARRAY_LEN(wrapper->rows);
      fields = mysql_fetch_fields(wrapper->result);

      for (i = 0; i < wrapper->numberOfRows; i++) {
        VALUE row;
        if (cacheRows && i < rowsProcessed) {
          row = rb_ary_entry(wrapper->rows, i);
        } else {
          row = rb_mysql_result_fetch_row(self, db_timezone, app_timezone, symbolizeKeys, asArray, castBool, cast, fields);
          if (cacheRows) {
            rb_ary_store(wrapper->rows, i, row);
          }
          wrapper->lastRowProcessed++;
        }

        if (row == Qnil) {
          /* we don't need the mysql C dataset around anymore, peace it */
          if (cacheRows) {
            rb_mysql_result_free_result(wrapper);
          }
          return Qnil;
        }

        if (block != Qnil) {
          rb_yield(row);
        }
      }
      if (wrapper->lastRowProcessed == wrapper->numberOfRows && cacheRows) {
        /* we don't need the mysql C dataset around anymore, peace it */
        rb_mysql_result_free_result(wrapper);
      }
    }
  }

  return wrapper->rows;
}
Beispiel #2
0
/* Marks the object as changed, meaning vertices must be updated. */
static
VALUE ray_drawable_set_textured(VALUE self, VALUE val) {
  say_drawable_set_textured(ray_rb2drawable(self), RTEST(val));
  return self;
}
Beispiel #3
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 (!NIL_P(sym)) nextvalue = rb_hash_lookup2(hash, sym, Qundef);
		if (nextvalue == Qundef) {
		    if (NIL_P(sym)) {
			sym = rb_sym_intern(start + 1,
					    len - 2 /* without parenthesis */,
					    enc);
		    }
		    nextvalue = rb_hash_default_value(hash, sym);
		    if (NIL_P(nextvalue)) {
			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;
		    if (width > 1) FILL(' ', width-1);
		}
		else {
		    if (width > 1) 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') {
		    str = rb_inspect(arg);
		}
		else {
		    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 (FIXNUM_P(val) || RB_TYPE_P(val, T_BIGNUM)) {
		    den = INT2FIX(1);
		    num = val;
		}
		else if (RB_TYPE_P(val, T_RATIONAL)) {
		    den = rb_rational_den(val);
		    num = rb_rational_num(val);
		}
		else {
		    nextvalue = val;
		    goto float_value;
		}
		if (!(flags&FPREC)) prec = default_float_precision;
		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 = prec + 1; /* 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;
}
Beispiel #4
0
static VALUE
rb_fairy_xmarshaled_queue_initialize(VALUE self, VALUE policy, VALUE buffers_mon, VALUE buffers_cv)
{
  VALUE sz;
  VALUE flag;
  VALUE dir;
  fairy_xmarshaled_queue_t *mq;
  
  GetFairyXMarshaledQueuePtr(self, mq);
  
  sz = rb_fairy_conf("XMARSHAL_QUEUE_CHUNK_SIZE", policy, "chunk_size");
  mq->chunk_size = NUM2LONG(sz);

  sz = rb_fairy_conf("XMARSHAL_QUEUE_BUFFERS_CACHE_LIMIT",
		     policy, "buffers_cache_limit");
  mq->buffers_cache_limit = NUM2LONG(sz);

  flag = rb_fairy_conf("XMARSHAL_QUEUE_USE_STRING_BUFFER",
		       policy, "use_string_buffer");
  mq->use_string_buffer_p = RTEST(flag);


  flag = rb_fairy_conf("XMARSHAL_QUEUE_LOG_MSTORE",
		       policy, "log_mstore");
  mq->log_mstore_p = RTEST(flag);

  dir = rb_fairy_conf("TMP_DIR", policy, "buffer_dir");
  mq->buffer_dir = dir;

  mq->push_queue = Qnil;
  
  mq->buffers = rb_xthread_fifo_new();
  if (NIL_P(buffers_mon)) {
    buffers_mon = rb_xthread_monitor_new();
  }
  mq->buffers_mon = buffers_mon;
  
  if (NIL_P(buffers_cv)) {
    buffers_cv = rb_funcall(buffers_mon, rb_intern("new_cond"), 0);
  }
  mq->buffers_cv = buffers_cv;
  
  mq->pop_queue = Qnil;

  mq->queue_push = rb_fairy_xmarshaled_queue_empty_push;

  if (CLASS_OF(mq->buffers_mon) == rb_cXThreadMonitor) {
    mq->mon_synchronize = rb_xthread_monitor_synchronize;
    mq->cv_wait = rb_fairy_xmarshaled_queue_monitor_cond_wait;
    mq->cv_broadcast = rb_xthread_monitor_cond_broadcast;
  }
  else if (CLASS_OF(mq->buffers_mon) == rb_cFiberMonMonitor) {
    mq->mon_synchronize = rb_fibermon_monitor_synchronize;
    mq->cv_wait = rb_fibermon_cond_wait;
    mq->cv_broadcast = rb_fibermon_cond_broadcast;
  }
  else {
    mq->mon_synchronize = rb_fairy_xmarshaled_queue_genmon_synchronize;
    mq->cv_wait = rb_fairy_xmarshaled_queue_gencond_wait;
    mq->cv_broadcast = rb_fairy_xmarshaled_queue_gencond_broadcast;
  }

  return self;
}
Beispiel #5
0
VALUE
rb_str_format(int argc, const VALUE *argv, VALUE fmt)
{
    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;
	ID id = 0;

	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 == '<') ? '>' : '}';

		for (; p < end && *p != term; ) {
		    p += rb_enc_mbclen(p, end, enc);
		}
		if (p >= end) {
		    rb_raise(rb_eArgError, "malformed name - unmatched parenthesis");
		}
		if (id) {
		    rb_raise(rb_eArgError, "name%.*s after <%s>",
			     (int)(p - start + 1), start, rb_id2name(id));
		}
		id = rb_intern3(start + 1, p - start - 1, enc);
		nextvalue = GETNAMEARG(ID2SYM(id), start, (int)(p - start + 1));
		if (nextvalue == Qundef) {
		    rb_raise(rb_eKeyError, "key%.*s not found", (int)(p - start + 1), 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);
		}
		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);
			blen += len;
			if (flags&FMINUS) {
			    CHECK(width);
			    while (width--) {
				buf[blen++] = ' ';
			    }
			}
			rb_enc_associate(result, enc);
			break;
		    }
		}
		PUSH(RSTRING_PTR(str), len);
		rb_enc_associate(result, enc);
	    }
	    break;

	  case 'd':
	  case 'i':
	  case 'o':
	  case 'x':
	  case 'X':
	  case 'b':
	  case 'B':
	  case 'u':
	    {
		volatile VALUE tmp1;
		volatile VALUE val = GETARG();
		char fbuf[32], 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 (!bignum) {
		    if (base == 2) {
			val = rb_int2big(v);
			goto bin_retry;
		    }
		    if (sign) {
			char c = *p;
			if (c == 'i') c = 'd'; /* %d and %i are identical */
			if (v < 0) {
			    v = -v;
			    sc = '-';
			    width--;
			}
			else if (flags & FPLUS) {
			    sc = '+';
			    width--;
			}
			else if (flags & FSPACE) {
			    sc = ' ';
			    width--;
			}
			snprintf(fbuf, sizeof(fbuf), "%%l%c", c);
			snprintf(nbuf, sizeof(nbuf), fbuf, v);
			s = nbuf;
		    }
		    else {
			s = nbuf;
			if (v < 0) {
			    dots = 1;
			}
			snprintf(fbuf, sizeof(fbuf), "%%l%c", *p == 'X' ? 'x' : *p);
			snprintf(++s, sizeof(nbuf) - 1, fbuf, v);
			if (v < 0) {
			    char d = 0;

			    s = remove_sign_bits(s, base);
			    switch (base) {
			      case 16:
				d = 'f'; break;
			      case 8:
				d = '7'; break;
			    }
			    if (d && *s != d) {
				*--s = d;
			    }
			}
		    }
		    len = (int)strlen(s);
		}
		else {
		    if (sign) {
			tmp = rb_big2str(val, base);
			s = RSTRING_PTR(tmp);
			if (s[0] == '-') {
			    s++;
			    sc = '-';
			    width--;
			}
			else if (flags & FPLUS) {
			    sc = '+';
			    width--;
			}
			else if (flags & FSPACE) {
			    sc = ' ';
			    width--;
			}
		    }
		    else {
			if (!RBIGNUM_SIGN(val)) {
			    val = rb_big_clone(val);
			    rb_big_2comp(val);
			}
			tmp1 = tmp = rb_big2str0(val, base, RBIGNUM_SIGN(val));
			s = RSTRING_PTR(tmp);
			if (*s == '-') {
			    dots = 1;
			    if (base == 10) {
				rb_warning("negative number for %%u specifier");
			    }
			    s = remove_sign_bits(++s, base);
			    switch (base) {
			      case 16:
				if (s[0] != 'f') *--s = 'f'; break;
			      case 8:
				if (s[0] != '7') *--s = '7'; break;
			      case 2:
				if (s[0] != '1') *--s = '1'; break;
			    }
			}
		    }
		    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 (!bignum && v < 0) {
		    char c = sign_bits(base, p);
		    while (len < prec--) {
			buf[blen++] = c;
		    }
		}
		else if ((flags & (FMINUS|FPREC)) != FMINUS) {
		    char c;

		    if (!sign && bignum && !RBIGNUM_SIGN(val))
			c = sign_bits(base, p);
		    else
			c = '0';
		    while (len < prec--) {
			buf[blen++] = c;
		    }
		}
		PUSH(s, len);
		CHECK(width);
		while (width-- > 0) {
		    buf[blen++] = ' ';
		}
	    }
	    break;

	  case 'f':
	  case 'g':
	  case 'G':
	  case 'e':
	  case 'E':
	  case 'a':
	  case 'A':
	    {
		VALUE val = GETARG();
		double fval;
		int i, need = 6;
		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 : 6;
		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:
    /* 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;
}
Beispiel #6
0
/* 
 *  call-seq:
 *     QueryParser.new(options = {}) -> QueryParser
 *
 *  Create a new QueryParser. The QueryParser is used to convert string
 *  queries into Query objects. The options are;
 *
 *  === Options
 *
 *  :default_field::       Default: "*" (all fields). The default field to
 *                         search when no field is specified in the search
 *                         string. It can also be an array of fields.
 *  :analyzer::            Default: StandardAnalyzer. Analyzer used by the
 *                         query parser to parse query terms
 *  :wild_card_downcase::  Default: true. Specifies whether wild-card queries
 *                         and range queries should be downcased or not since
 *                         they are not passed through the parser
 *  :fields::              Default: []. Lets the query parser know what
 *                         fields are available for searching, particularly
 *                         when the "*" is specified as the search field
 *  :tokenized_fields::    Default: :fields. Lets the query parser know which
 *                         fields are tokenized so it knows which fields to
 *                         run the analyzer over.
 *  :validate_fields::     Default: false. Set to true if you want an
 *                         exception to be raised if there is an attempt to
 *                         search a non-existent field
 *  :or_default::          Default: true. Use "OR" as the default boolean
 *                         operator
 *  :default_slop::        Default: 0. Default slop to use in PhraseQuery
 *  :handle_parse_errors:: Default: true. QueryParser will quietly handle all
 *                         parsing errors internally. If you'd like to handle
 *                         them yourself, set this parameter to false.
 *  :clean_string::        Default: true. QueryParser will do a quick
 *                         once-over the query string make sure that quotes
 *                         and brackets match up and special characters are
 *                         escaped
 *  :max_clauses::         Default: 512. the maximum number of clauses
 *                         allowed in boolean queries and the maximum number
 *                         of terms allowed in multi, prefix, wild-card or
 *                         fuzzy queries when those queries are generated by
 *                         rewriting other queries
 */                   
static VALUE
frt_qp_init(int argc, VALUE *argv, VALUE self)
{
    VALUE roptions;
    VALUE rval;
    Analyzer *analyzer = NULL;
    bool has_options = false;

    HashSet *all_fields = NULL;
    HashSet *tkz_fields = NULL;
    HashSet *def_fields = NULL;
    QParser *qp;

    if (rb_scan_args(argc, argv, "01", &roptions) > 0) {
        if (TYPE(roptions) == T_HASH) {
            has_options = true;
            if (Qnil != (rval = rb_hash_aref(roptions, sym_default_field))) {
                def_fields = frt_get_fields(rval);
            }
            if (Qnil != (rval = rb_hash_aref(roptions, sym_analyzer))) {
                analyzer = frt_get_cwrapped_analyzer(rval);
            }
            if (Qnil != (rval = rb_hash_aref(roptions, sym_all_fields))) {
                all_fields = frt_get_fields(rval);
            }
            if (Qnil != (rval = rb_hash_aref(roptions, sym_fields))) {
                all_fields = frt_get_fields(rval);
            }
            if (Qnil != (rval = rb_hash_aref(roptions, sym_tkz_fields))) {
                tkz_fields = frt_get_fields(rval);
            }
        } else {
            def_fields = frt_get_fields(roptions);
        }
    }
    if (all_fields == NULL) {
        all_fields = hs_new_str(&free);
    }

    if (!analyzer) {
        analyzer = mb_standard_analyzer_new(true);
    }

    qp = qp_new(all_fields, def_fields, tkz_fields, analyzer);
    qp->allow_any_fields = true;
    qp->clean_str = true;
    qp->handle_parse_errors = true;
    /* handle options */
    if (argc > 0) {
        if (Qnil != (rval = rb_hash_aref(roptions, sym_handle_parse_errors))) {
            qp->handle_parse_errors = RTEST(rval);
        }
        if (Qnil != (rval = rb_hash_aref(roptions, sym_validate_fields))) {
            qp->allow_any_fields = !RTEST(rval);
        }
        if (Qnil != (rval = rb_hash_aref(roptions, sym_wild_card_downcase))) {
            qp->wild_lower = RTEST(rval);
        }
        if (Qnil != (rval = rb_hash_aref(roptions, sym_or_default))) {
            qp->or_default = RTEST(rval);
        }
        if (Qnil != (rval = rb_hash_aref(roptions, sym_default_slop))) {
            qp->def_slop = FIX2INT(rval);
        }
        if (Qnil != (rval = rb_hash_aref(roptions, sym_clean_string))) {
            qp->clean_str = RTEST(rval);
        }
        if (Qnil != (rval = rb_hash_aref(roptions, sym_max_clauses))) {
            qp->max_clauses = FIX2INT(rval);
        }
    }
    Frt_Wrap_Struct(self, frt_qp_mark, frt_qp_free, qp);
    object_add(qp, self);
    return self;
}
/*
ポリゴン描画
*/
static VALUE drawing_draw_polygon(int argc, VALUE *argv, VALUE self)
{
  VALUE vdst;
  VALUE pairs;
  VALUE mcolor;
  VALUE fill;
  VALUE aa;
  Uint8 alpha;
  Uint32 color;
  int i, vertexes;
  
  rb_scan_args(argc, argv, "32", &vdst, &pairs, &mcolor, &fill, &aa);
  
  // bitmapメソッドを持っていれば、メソッドの値をvdstとする
  VALUE methods = rb_funcall(vdst, rb_intern("methods"), 0);
  if(rb_ary_includes(methods, rb_str_intern(rb_str_new2("to_unit"))) == Qfalse &&
     rb_ary_includes(methods, rb_str_intern(rb_str_new2("bitmap"))) == Qfalse
    )
    rb_raise(eMiyakoError, "this method needs sprite have to_method or bitmap method!");
  if(rb_ary_includes(methods, rb_str_intern(rb_str_new2("to_unit"))) == Qtrue)
    vdst = rb_funcall(vdst, rb_intern("to_unit"), 0);
  vdst = rb_funcall(vdst, rb_intern("bitmap"), 0);

  vertexes = RARRAY_LEN(pairs);
  // 頂点数チェック
  if(vertexes > 65536)
    rb_raise(eMiyakoError, "too many pairs. pairs is less than 65536.");
  
  // 範囲チェック
  for(i=0; i<vertexes; i++)
  {
    VALUE vertex = *(RARRAY_PTR(pairs)+i);
    Sint16 x, y;
    get_position(vertex, &x, &y);
  }
  
	SDL_Surface  *dst = GetSurface(vdst)->surface;

  color = value_2_color(rb_funcall(cColor, rb_intern("to_rgb"), 1, mcolor), dst->format, &alpha);

  if(RTEST(fill) && RTEST(aa) && alpha < 255)
    rb_raise(eMiyakoError, "can't draw filled antialiased alpha polygon");

  Sint16 *px = (Sint16 *)malloc(sizeof(Sint16) * vertexes);
  Sint16 *py = (Sint16 *)malloc(sizeof(Sint16) * vertexes);
  for(i=0; i<vertexes; i++)
  {
    VALUE vertex = *(RARRAY_PTR(pairs)+i);
    get_position(vertex, px+i, py+i);
  }
  
  if(!RTEST(fill) && !RTEST(aa) && alpha == 255)
  {
    for(i=0; i<vertexes-1; i++)
      sge_Line(dst, px[i], py[i], px[i+1], py[i+1], color);
    sge_Line(dst, px[vertexes-1], py[vertexes-1], px[0], py[0], color);
  }
  else if(!RTEST(fill) && !RTEST(aa) && alpha < 255)
  {
    for(i=0; i<vertexes-1; i++)
      sge_LineAlpha(dst, px[i], py[i], px[i+1], py[i+1], color, alpha);
    sge_LineAlpha(dst, px[vertexes-1], py[vertexes-1], px[0], py[0], color, alpha);
  }
  else if(!RTEST(fill) && RTEST(aa) && alpha == 255)
  {
    for(i=0; i<vertexes-1; i++)
      sge_AALine(dst, px[i], py[i], px[i+1], py[i+1], color);
    sge_AALine(dst, px[vertexes-1], py[vertexes-1], px[0], py[0], color);
  }
  else if(!RTEST(fill) && RTEST(aa) && alpha < 255)
  {
    for(i=0; i<vertexes-1; i++)
      sge_AALineAlpha(dst, px[i], py[i], px[i+1], py[i+1], color, alpha);
    sge_AALineAlpha(dst, px[vertexes-1], py[vertexes-1], px[0], py[0], color, alpha);
  }
  else if(RTEST(fill) && !RTEST(aa) && alpha == 255)
    sge_FilledPolygon(dst, (Uint16)vertexes, px, py, color);
  else if(RTEST(fill) && !RTEST(aa) && alpha < 255)
    sge_FilledPolygonAlpha(dst, (Uint16)vertexes, px, py, color, alpha);
  else if(RTEST(fill) && RTEST(aa) && alpha == 255)
    sge_AAFilledPolygon(dst, (Uint16)vertexes, px, py, color);
  
  free(py);
  free(px);

  return Qnil;
}
Beispiel #8
0
static inline void event_callback (struct em_event* e)
{
	const unsigned long signature = e->signature;
	int event = e->event;
	const char *data_str = e->data_str;
	const unsigned long data_num = e->data_num;

	switch (event) {
		case EM_CONNECTION_READ:
		{
			VALUE conn = rb_hash_aref (EmConnsHash, ULONG2NUM (signature));
			if (conn == Qnil)
				rb_raise (EM_eConnectionNotBound, "received %lu bytes of data for unknown signature: %lu", data_num, signature);
			rb_funcall (conn, Intern_receive_data, 1, rb_str_new (data_str, data_num));
			return;
		}
		case EM_CONNECTION_ACCEPTED:
		{
			rb_funcall (EmModule, Intern_event_callback, 3, ULONG2NUM(signature), INT2FIX(event), ULONG2NUM(data_num));
			return;
		}
		case EM_CONNECTION_UNBOUND:
		{
			rb_funcall (EmModule, Intern_event_callback, 3, ULONG2NUM(signature), INT2FIX(event), ULONG2NUM(data_num));
			return;
		}
		case EM_CONNECTION_COMPLETED:
		{
			VALUE conn = ensure_conn(signature);
			rb_funcall (conn, Intern_connection_completed, 0);
			return;
		}
		case EM_CONNECTION_NOTIFY_READABLE:
		{
			VALUE conn = ensure_conn(signature);
			rb_funcall (conn, Intern_notify_readable, 0);
			return;
		}
		case EM_CONNECTION_NOTIFY_WRITABLE:
		{
			VALUE conn = ensure_conn(signature);
			rb_funcall (conn, Intern_notify_writable, 0);
			return;
		}
		case EM_LOOPBREAK_SIGNAL:
		{
			rb_funcall (EmModule, Intern_run_deferred_callbacks, 0);
			return;
		}
		case EM_TIMER_FIRED:
		{
			VALUE timer = rb_funcall (EmTimersHash, Intern_delete, 1, ULONG2NUM (data_num));
			if (timer == Qnil) {
				rb_raise (EM_eUnknownTimerFired, "no such timer: %lu", data_num);
			} else if (timer == Qfalse) {
				/* Timer Canceled */
			} else {
				rb_funcall (timer, Intern_call, 0);
			}
			return;
		}
		#ifdef WITH_SSL
		case EM_SSL_HANDSHAKE_COMPLETED:
		{
			VALUE conn = ensure_conn(signature);
			rb_funcall (conn, Intern_ssl_handshake_completed, 0);
			return;
		}
		case EM_SSL_VERIFY:
		{
			VALUE conn = ensure_conn(signature);
			VALUE should_accept = rb_funcall (conn, Intern_ssl_verify_peer, 1, rb_str_new(data_str, data_num));
			if (RTEST(should_accept))
				evma_accept_ssl_peer (signature);
			return;
		}
		#endif
		case EM_PROXY_TARGET_UNBOUND:
		{
			VALUE conn = ensure_conn(signature);
			rb_funcall (conn, Intern_proxy_target_unbound, 0);
			return;
		}
		case EM_PROXY_COMPLETED:
		{
			VALUE conn = ensure_conn(signature);
			rb_funcall (conn, Intern_proxy_completed, 0);
			return;
		}
	}
}
INT
Test_NtUserCountClipboardFormats(PTESTINFO pti)
{
	RTEST(NtUserCountClipboardFormats() < 1000);
	return APISTATUS_NORMAL;
}
Beispiel #10
0
static VALUE
Game_initialize(int argc, VALUE* argv, VALUE self)
{
  if (!NIL_P(Game_s_current(rb_cGame))) {
    rb_raise(strb_GetStarRubyErrorClass(), "already run");
  }

  volatile VALUE rbWidth, rbHeight, rbOptions;
  rb_scan_args(argc, argv, "21", &rbWidth, &rbHeight, &rbOptions);
  if (NIL_P(rbOptions)) {
    rbOptions = rb_hash_new();
  } else {
    Check_Type(rbOptions, T_HASH);
  }
  Game* game;
  Data_Get_Struct(self, Game, game);

  if (SDL_InitSubSystem(SDL_INIT_VIDEO | SDL_INIT_TIMER)) {
    rb_raise_sdl_error();
  }

  const int width  = NUM2INT(rbWidth);
  const int height = NUM2INT(rbHeight);

  volatile VALUE rbFps = rb_hash_aref(rbOptions, symbol_fps);
  Game_fps_eq(self, !NIL_P(rbFps) ? rbFps : INT2FIX(30));

  volatile VALUE rbTitle = rb_hash_aref(rbOptions, symbol_title);
  Game_title_eq(self, !NIL_P(rbTitle) ? rbTitle : rb_str_new2(""));

  bool cursor = false;

  volatile VALUE val;
  Check_Type(rbOptions, T_HASH);
  if (!NIL_P(val = rb_hash_aref(rbOptions, symbol_cursor))) {
    cursor = RTEST(val);
  }
  if (!NIL_P(val = rb_hash_aref(rbOptions, symbol_fullscreen))) {
    game->isFullscreen = RTEST(val);
  }
  if (!NIL_P(val = rb_hash_aref(rbOptions, symbol_window_scale))) {
    game->windowScale = NUM2INT(val);
    if (game->windowScale < 1) {
      rb_raise(rb_eArgError, "invalid window scale: %d",
               game->windowScale);
    }
  }
  if (!NIL_P(val = rb_hash_aref(rbOptions, symbol_vsync))) {
    game->isVsync = RTEST(val);
  }

  SDL_ShowCursor(cursor ? SDL_ENABLE : SDL_DISABLE);

  volatile VALUE rbScreen =
    rb_class_new_instance(2, (VALUE[]){INT2NUM(width), INT2NUM(height)},
                          strb_GetTextureClass());
  game->screen = rbScreen;

  InitializeScreen(game);

  rb_iv_set(rb_cGame, "current", self);

  return Qnil;
}
Beispiel #11
0
static int
is_integer_p(VALUE v)
{
    VALUE is_int = rb_check_funcall(v, id_integer_p, 0, 0);
    return RTEST(is_int) && is_int != Qundef;
}
Beispiel #12
0
static VALUE
range_step(int argc, VALUE *argv, VALUE range)
{
    VALUE b, e, step, tmp;

    RETURN_SIZED_ENUMERATOR(range, argc, argv, range_step_size);

    b = RANGE_BEG(range);
    e = RANGE_END(range);
    if (argc == 0) {
	step = INT2FIX(1);
    }
    else {
	rb_scan_args(argc, argv, "01", &step);
	if (!rb_obj_is_kind_of(step, rb_cNumeric)) {
	    step = rb_to_int(step);
	}
	if (rb_funcall(step, '<', 1, INT2FIX(0))) {
	    rb_raise(rb_eArgError, "step can't be negative");
	}
	else if (!rb_funcall(step, '>', 1, INT2FIX(0))) {
	    rb_raise(rb_eArgError, "step can't be 0");
	}
    }

    if (FIXNUM_P(b) && FIXNUM_P(e) && FIXNUM_P(step)) { /* fixnums are special */
	long end = FIX2LONG(e);
	long i, unit = FIX2LONG(step);

	if (!EXCL(range))
	    end += 1;
	i = FIX2LONG(b);
	while (i < end) {
	    rb_yield(LONG2NUM(i));
	    if (i + unit < i) break;
	    i += unit;
	}

    }
    else if (SYMBOL_P(b) && SYMBOL_P(e)) { /* symbols are special */
	VALUE args[2], iter[2];

	args[0] = rb_sym_to_s(e);
	args[1] = EXCL(range) ? Qtrue : Qfalse;
	iter[0] = INT2FIX(1);
	iter[1] = step;
	rb_block_call(rb_sym_to_s(b), rb_intern("upto"), 2, args, sym_step_i, (VALUE)iter);
    }
    else if (ruby_float_step(b, e, step, EXCL(range))) {
	/* done */
    }
    else if (rb_obj_is_kind_of(b, rb_cNumeric) ||
	     !NIL_P(rb_check_to_integer(b, "to_int")) ||
	     !NIL_P(rb_check_to_integer(e, "to_int"))) {
	ID op = EXCL(range) ? '<' : idLE;
	VALUE v = b;
	int i = 0;

	while (RTEST(rb_funcall(v, op, 1, e))) {
	    rb_yield(v);
	    i++;
	    v = rb_funcall(b, '+', 1, rb_funcall(INT2NUM(i), '*', 1, step));
	}
    }
    else {
	tmp = rb_check_string_type(b);

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

	    b = tmp;
	    args[0] = e;
	    args[1] = EXCL(range) ? Qtrue : Qfalse;
	    iter[0] = INT2FIX(1);
	    iter[1] = step;
	    rb_block_call(b, rb_intern("upto"), 2, args, step_i, (VALUE)iter);
	}
	else {
	    VALUE args[2];

	    if (!discrete_object_p(b)) {
		rb_raise(rb_eTypeError, "can't iterate from %s",
			 rb_obj_classname(b));
	    }
	    args[0] = INT2FIX(1);
	    args[1] = step;
	    range_each_func(range, step_i, (VALUE)args);
	}
    }
    return range;
}
Beispiel #13
0
static VALUE dm_init_all(VALUE mod)
{
	return C2RbBool(RTEST(dm_init_video_engine(mod)) && RTEST(dm_init_audio_engine(mod)));
}
Beispiel #14
0
INT
Test_NtGdiGetRandomRgn(PTESTINFO pti)
{
    HWND hWnd;
    HDC hDC;
    HRGN hrgn, hrgn2;

    /* Create a window */
    hWnd = CreateWindowW(L"BUTTON", L"TestWindow", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
                         CW_USEDEFAULT, CW_USEDEFAULT, 100, 100,
                         NULL, NULL, g_hInstance, 0);
//	UpdateWindow(hWnd);
    hDC = GetDC(hWnd);

    ASSERT(hDC != NULL);

    hrgn = CreateRectRgn(0,0,0,0);
    hrgn2 = CreateRectRgn(3,3,10,10);
    SetLastError(ERROR_SUCCESS);
    RTEST(NtGdiGetRandomRgn(0, hrgn, 0) == -1);
    RTEST(GetLastError() == ERROR_INVALID_HANDLE);

    SetLastError(ERROR_SUCCESS);
    RTEST(NtGdiGetRandomRgn((HDC)2345, hrgn, 1) == -1);
    RTEST(GetLastError() == ERROR_INVALID_HANDLE);

    SetLastError(ERROR_SUCCESS);
    RTEST(NtGdiGetRandomRgn((HDC)2345, hrgn, 10) == -1);
    RTEST(GetLastError() == ERROR_INVALID_HANDLE);

    SetLastError(ERROR_SUCCESS);
    RTEST(NtGdiGetRandomRgn((HDC)2345, (HRGN)10, 10) == -1);
    RTEST(GetLastError() == ERROR_INVALID_HANDLE);

    SetLastError(ERROR_SUCCESS);
    RTEST(NtGdiGetRandomRgn((HDC)2345, 0, 1) == -1);
    RTEST(GetLastError() == ERROR_INVALID_HANDLE);

    SetLastError(ERROR_SUCCESS);
    RTEST(NtGdiGetRandomRgn(hDC, 0, 0) == 0);
    RTEST(NtGdiGetRandomRgn(hDC, 0, 1) == 0);
    RTEST(NtGdiGetRandomRgn(hDC, (HRGN)-5, 0) == 0);
    RTEST(NtGdiGetRandomRgn(hDC, (HRGN)-5, 1) == 0);
    RTEST(NtGdiGetRandomRgn(hDC, hrgn, 0) == 0);
    RTEST(NtGdiGetRandomRgn(hDC, hrgn, 1) == 0);
    TEST(NtGdiGetRandomRgn(hDC, hrgn, 2) == 0);
    RTEST(NtGdiGetRandomRgn(hDC, hrgn, 3) == 0);
    RTEST(NtGdiGetRandomRgn(hDC, hrgn, 4) == 1);
    RTEST(NtGdiGetRandomRgn(hDC, hrgn, 5) == 0);
    RTEST(NtGdiGetRandomRgn(hDC, hrgn, 10) == 0);
    RTEST(NtGdiGetRandomRgn(hDC, hrgn, -10) == 0);
    RTEST(GetLastError() == ERROR_SUCCESS);

    SelectClipRgn(hDC, hrgn2);
    RTEST(NtGdiGetRandomRgn(hDC, 0, 1) == -1);
    RTEST(GetLastError() == ERROR_SUCCESS);
    RTEST(NtGdiGetRandomRgn(hDC, hrgn, 1) == 1);
    RTEST(CombineRgn(hrgn, hrgn, hrgn, RGN_OR) == SIMPLEREGION);
    RTEST(CombineRgn(hrgn, hrgn, hrgn2, RGN_XOR) == NULLREGION);

    SetRectRgn(hrgn2,0,0,0,0);
    SelectClipRgn(hDC, hrgn2);
    RTEST(NtGdiGetRandomRgn(hDC, hrgn, 1) == 1);

    RTEST(CombineRgn(hrgn2, hrgn, hrgn2, RGN_XOR) == NULLREGION);
    RTEST(CombineRgn(hrgn2, hrgn, hrgn, RGN_OR) == NULLREGION);

    SelectClipRgn(hDC, NULL);
    RTEST(NtGdiGetRandomRgn(hDC, hrgn, 1) == 0);


    RTEST(NtGdiGetRandomRgn(hDC, hrgn, 4) == 1);

    RTEST(GetLastError() == ERROR_SUCCESS);

    ReleaseDC(hWnd, hDC);
    DestroyWindow(hWnd);

    return APISTATUS_NORMAL;
}
Beispiel #15
0
/*
    Method:     ImageList#quantize(<number_colors<, colorspace<, dither<, tree_depth<, measure_error>>>>>)
                     defaults: 256, Magick::RGBColorspace, true, 0, false
    Purpose:    call QuantizeImages
    Returns:    a new ImageList with quantized images. 'scene' is set to the same
                value as self.scene
*/
VALUE
ImageList_quantize(int argc, VALUE *argv, VALUE self)
{
    Image *images, *new_images;
    Image *new_image;
    QuantizeInfo quantize_info;
    ExceptionInfo exception;
    volatile VALUE new_imagelist, scene;

    GetQuantizeInfo(&quantize_info);

    switch (argc)
    {
        case 5:
            quantize_info.measure_error = (MagickBooleanType) RTEST(argv[4]);
        case 4:
            quantize_info.tree_depth = (unsigned long)NUM2INT(argv[3]);
        case 3:
            quantize_info.dither = (MagickBooleanType) RTEST(argv[2]);
        case 2:
            VALUE_TO_ENUM(argv[1], quantize_info.colorspace, ColorspaceType);
        case 1:
            quantize_info.number_colors = NUM2ULONG(argv[0]);
        case 0:
            break;
        default:
            rb_raise(rb_eArgError, "wrong number of arguments (%d for 0 to 5)", argc);
            break;
    }

    if (imagelist_length(self) == 0L)
    {
        rb_raise(rb_eArgError, "no images in this image list");
    }

    // Convert image array to image sequence, clone image sequence.
    GetExceptionInfo(&exception);
    images = images_from_imagelist(self);
    new_images = CloneImageList(images, &exception);
    rm_split(images);
    rm_check_exception(&exception, new_images, DestroyOnError);
    (void) DestroyExceptionInfo(&exception);

    rm_ensure_result(new_images);


    (void) QuantizeImages(&quantize_info, new_images);
    rm_check_exception(&exception, new_images, DestroyOnError);

    // Create new ImageList object, convert mapped image sequence to images,
    // append to images array.
    new_imagelist = ImageList_new();
    while ((new_image = ShiftImageList(&new_images)))
    {
        imagelist_push(new_imagelist, rm_image_new(new_image));
    }

    // Set @scene in new ImageList object to same value as in self.
    scene = rb_iv_get(self, "@scene");
    (void) rb_iv_set(new_imagelist, "@scene", scene);

    return new_imagelist;
}
Beispiel #16
0
static int
rf_getattr(const char *path, struct stat *stbuf) {
  /* If it doesn't exist, it doesn't exist. Simple as that. */
  VALUE retval;
  char *value;
  size_t len;

  debug("rf_getattr(%s)\n", path );
  /* Zero out the stat buffer */
  memset(stbuf, 0, sizeof(struct stat));

  /* "/" is automatically a dir. */
  if (strcmp(path,"/") == 0) {
    stbuf->st_mode = S_IFDIR | 0555;
    stbuf->st_size = 4096;
    stbuf->st_nlink = 1;
    stbuf->st_uid = getuid();
    stbuf->st_gid = getgid();
    stbuf->st_mtime = rf_intval(path,id_mtime,init_time);
    stbuf->st_atime = rf_intval(path,id_atime,init_time);
    stbuf->st_ctime = rf_intval(path,id_ctime,init_time);
    return 0;
  }

  /* If we created it with mknod, then it "exists" */
  debug("  Checking for created file ...");
  if (created_file && (strcmp(created_file,path) == 0)) {
    /* It's created */
    debug(" created.\n");
    stbuf->st_mode = S_IFREG | 0666;
    stbuf->st_nlink = 1 + file_openedP(path);
    stbuf->st_size = 0;
    stbuf->st_uid = getuid();
    stbuf->st_gid = getgid();
    stbuf->st_mtime = created_time;
    stbuf->st_atime = created_time;
    stbuf->st_ctime = created_time;
    return 0;
  }
  debug(" no.\n");

  /* debug("  Checking file_opened ...");
  if (file_openedP(path)) {
    debug(" opened.\n");
    stbuf->st_mode = S_IFREG | 0666;
    stbuf->st_nlink = 1 + file_openedP(path);
    stbuf->st_size = 0;
    stbuf->st_uid = getuid();
    stbuf->st_gid = getgid();
    stbuf->st_mtime = init_time;
    stbuf->st_atime = init_time;
    stbuf->st_ctime = init_time;
    return 0;
  }
  debug(" no.\n");
  */

  debug("  Checking if editor file...");
  switch (editor_fileP(path)) {
  case 2:
    debug(" Yes, and does exist.\n");
    stbuf->st_mode = S_IFREG | 0444;
    stbuf->st_nlink = 1;
    stbuf->st_size = 0;
    stbuf->st_uid = getuid();
    stbuf->st_gid = getgid();
    stbuf->st_mtime = init_time;
    stbuf->st_atime = init_time;
    stbuf->st_ctime = init_time;
    return 0;
  case 1:
    debug(" Yes, but doesn't exist.\n");
    return -ENOENT;
  default:
    debug("No.\n");
  }

  /* If FuseRoot says the path is a directory, we set it 0555.
   * If FuseRoot says the path is a file, it's 0444.
   *
   * Otherwise, -ENOENT */
  debug("Checking filetype ...");
  if (RTEST(rf_call(path, is_directory,Qnil))) {
    debug(" directory.\n");
    stbuf->st_mode = S_IFDIR | 0555;
    stbuf->st_nlink = 1;
    stbuf->st_size = 4096;
    stbuf->st_uid = getuid();
    stbuf->st_gid = getgid();
    stbuf->st_mtime = rf_intval(path,id_mtime,init_time);
    stbuf->st_atime = rf_intval(path,id_atime,init_time);
    stbuf->st_ctime = rf_intval(path,id_ctime,init_time);
    return 0;
  } else if (RTEST(rf_call(path, is_file,Qnil))) {
    debug(" file.\n");
    stbuf->st_mode = S_IFREG | 0444;
    if (RTEST(rf_call(path,can_write,Qnil))) {
      stbuf->st_mode |= 0666;
    }
    if (RTEST(rf_call(path,is_executable,Qnil))) {
      stbuf->st_mode |= 0111;
    }
    stbuf->st_nlink = 1 + file_openedP(path);
    stbuf->st_size = rf_intval(path,id_size,0);
    stbuf->st_uid = getuid();
    stbuf->st_gid = getgid();
    stbuf->st_mtime = rf_intval(path,id_mtime,init_time);
    stbuf->st_atime = rf_intval(path,id_atime,init_time);
    stbuf->st_ctime = rf_intval(path,id_ctime,init_time);
    return 0;
  }
  debug(" nonexistant.\n");
  return -ENOENT;
}
Beispiel #17
0
static VALUE string_spec_rb_cstr_to_inum(VALUE self, VALUE str, VALUE inum, VALUE badcheck) {
  int num = FIX2INT(inum);
  return rb_cstr_to_inum(RSTRING_PTR(str), num, RTEST(badcheck));
}
Beispiel #18
0
/* rf_mknod
 *
 * Used when: This is called when a file is created.
 *
 * Note that this is actually almost useless to RubyFuse, so all we do is check
 *   if a path is writable? and if so, return true. The open() will do the
 *   actual work of creating the file.
 */
static int
rf_mknod(const char *path, mode_t umode, dev_t rdev) {
  opened_file *ptr;

  debug("rf_mknod(%s)\n", path);
  /* Make sure it's not already open. */
  
  debug("  Checking if it's opened ...");
  if (file_openedP(path)) {
    debug(" yes.\n");
    return -EACCES;
  }
  debug(" no.\n");

  /* We ONLY permit regular files. No blocks, characters, fifos, etc. */
  debug("  Checking if an IFREG is requested ...");
  if (!S_ISREG(umode)) {
    debug(" no.\n");
    return -EACCES;
  }
  debug(" yes.\n");

  debug("  Checking if it's an editor file ...");
  switch (editor_fileP(path)) {
  case 2:
    debug(" yes, and it exists.\n");
    return -EEXIST;
  case 1:
    debug(" yes, and it doesn't exist.\n");
    editor_file *eptr;
    eptr = ALLOC(editor_file);
    eptr->writesize = FILE_GROW_SIZE;
    eptr->value = ALLOC_N(char,eptr->writesize);
    eptr->path  = strdup(path);
    eptr->size  = 0;
    eptr->raw = 0;
    eptr->zero_offset = 0;
    eptr->modified = 0;
    *(eptr->value) = '\0';
    eptr->next = editor_head;
    editor_head = eptr;
    return 0;
  default:
    debug("no.\n");
  }

  debug("  Checking if it's a file ..." );
  if (RTEST(rf_call(path, is_file,Qnil))) {
    debug(" yes.\n");
    return -EEXIST;
  }
  debug(" no.\n");

  /* Is this writable to */
  debug("  Checking if it's writable to ...");
  if (!RTEST(rf_call(path,can_write,Qnil))) {
    debug(" no.\n");
    debug("  Checking if it looks like an editor tempfile...");
    if (editor_head && (which_editor == EDITOR_VIM)) {
      char *ptr = strrchr(path,'/');
      while (ptr && isdigit(*ptr)) ptr++;
      if (ptr && (*ptr == '\0')) {
        debug(" yes.\n");
        editor_file *eptr;
        eptr = ALLOC(editor_file);
        eptr->writesize = FILE_GROW_SIZE;
        eptr->value = ALLOC_N(char,eptr->writesize);
        eptr->path  = strdup(path);
        eptr->raw = 0;
        eptr->size  = 0;
        eptr->zero_offset = 0;
        eptr->modified = 0;
        *(eptr->value) = '\0';
        eptr->next = editor_head;
        editor_head = eptr;
        return 0;
      }
Beispiel #19
0
static VALUE rec_pi(VALUE obj, VALUE arg) {
  if(RTEST(rb_inspecting_p(obj))) return arg;
  return Qfalse;
}
Beispiel #20
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);

    check_max_nesting(state, depth);
    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, "[");
        OBJ_INFECT(result, self);
        rb_str_buf_append(result, state->array_nl);
        for (i = 0;  i < len; i++) {
            VALUE element = RARRAY_AT(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);
            element = rb_funcall(element, i_to_json, 2, Vstate, LONG2FIX(depth + 1));
            Check_Type(element, T_STRING);
            rb_str_buf_append(result, element);
        }
        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);
        OBJ_INFECT(result, self);
        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_AT(self, i);
            OBJ_INFECT(result, element);
            if (i > 0) rb_str_buf_append(result, delim);
            rb_str_buf_append(result, shift);
            element = rb_funcall(element, i_to_json, 2, Vstate, LONG2FIX(depth + 1));
            Check_Type(element, T_STRING);
            rb_str_buf_append(result, element);
        }
        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;
}
Beispiel #21
0
static VALUE
cr_has_current_point(VALUE self)
{
  return RTEST (cairo_has_current_point (_SELF));
}
Beispiel #22
0
/*
 * call-seq: configure(opts)
 *
 * Configure this State instance with the Hash _opts_, and return
 * itself.
 */
static inline VALUE cState_configure(VALUE self, VALUE opts)
{
    VALUE tmp;
    GET_STATE(self);
    tmp = rb_convert_type(opts, T_HASH, "Hash", "to_hash");
    if (NIL_P(tmp)) tmp = rb_convert_type(opts, T_HASH, "Hash", "to_h");
    if (NIL_P(tmp)) {
        rb_raise(rb_eArgError, "opts has to be hash like or convertable into a hash");
    }
    opts = tmp;
    tmp = rb_hash_aref(opts, ID2SYM(i_indent));
    if (RTEST(tmp)) {
        Check_Type(tmp, T_STRING);
        state->indent = tmp;
    }
    tmp = rb_hash_aref(opts, ID2SYM(i_space));
    if (RTEST(tmp)) {
        Check_Type(tmp, T_STRING);
        state->space = tmp;
    }
    tmp = rb_hash_aref(opts, ID2SYM(i_space_before));
    if (RTEST(tmp)) {
        Check_Type(tmp, T_STRING);
        state->space_before = tmp;
    }
    tmp = rb_hash_aref(opts, ID2SYM(i_array_nl));
    if (RTEST(tmp)) {
        Check_Type(tmp, T_STRING);
        state->array_nl = tmp;
    }
    tmp = rb_hash_aref(opts, ID2SYM(i_object_nl));
    if (RTEST(tmp)) {
        Check_Type(tmp, T_STRING);
        state->object_nl = tmp;
    }
    tmp = ID2SYM(i_check_circular);

#if WITH_OBJC
    if (CFDictionaryGetValueIfPresent((CFDictionaryRef)opts, (const void *)RB2OC(tmp), 0)) {
#else
    if (st_lookup(RHASH_TBL(opts), tmp, 0)) {
#endif
        tmp = rb_hash_aref(opts, ID2SYM(i_check_circular));
        state->check_circular = RTEST(tmp);
    } else {
        state->check_circular = 1;
    }
    tmp = ID2SYM(i_max_nesting);
    state->max_nesting = 19;
#if WITH_OBJC
    if (CFDictionaryGetValueIfPresent((CFDictionaryRef)opts, (const void *)RB2OC(tmp), 0)) {
#else
    if (st_lookup(RHASH_TBL(opts), tmp, 0)) {
#endif
        VALUE max_nesting = rb_hash_aref(opts, tmp);
        if (RTEST(max_nesting)) {
            Check_Type(max_nesting, T_FIXNUM);
            state->max_nesting = FIX2LONG(max_nesting);
        } else {
            state->max_nesting = 0;
        }
    }
    tmp = rb_hash_aref(opts, ID2SYM(i_allow_nan));
    state->allow_nan = RTEST(tmp);
    return self;
}

/*
 * 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;
}


/*
 * call-seq: new(opts = {})
 *
 * Instantiates a new State object, configured by _opts_.
 *
 * _opts_ can have the following keys:
 *
 * * *indent*: a string used to indent levels (default: ''),
 * * *space*: a string that is put after, a : or , delimiter (default: ''),
 * * *space_before*: a string that is put before a : pair delimiter (default: ''),
 * * *object_nl*: a string that is put at the end of a JSON object (default: ''), 
 * * *array_nl*: a string that is put at the end of a JSON array (default: ''),
 * * *check_circular*: true if checking for circular data structures
 *   should be done, false (the default) otherwise.
 * * *allow_nan*: true if NaN, Infinity, and -Infinity should be
 *   generated, otherwise an exception is thrown, if these values are
 *   encountered. This options defaults to false.
 */
static VALUE cState_initialize(int argc, VALUE *argv, VALUE self)
{
    VALUE opts;
    GET_STATE(self);

    rb_scan_args(argc, argv, "01", &opts);
    state->indent = rb_str_new2("");
    state->space = rb_str_new2("");
    state->space_before = rb_str_new2("");
    state->array_nl = rb_str_new2("");
    state->object_nl = rb_str_new2("");
    if (NIL_P(opts)) {
        state->check_circular = 1;
        state->allow_nan = 0;
        state->max_nesting = 19;
    } else {
        cState_configure(self, opts);
    }
    state->seen = rb_hash_new();
    state->memo = Qnil;
    state->depth = INT2FIX(0);
    return self;
}
Beispiel #23
0
  String* String::transform(STATE, Tuple* tbl, Object* respect_kcode) {
    uint8_t invalid[5];

    if(tbl->num_fields() < 256) {
      return force_as<String>(Primitives::failure());
    }

    Object** tbl_ptr = tbl->field;

    kcode::table* kcode_tbl = 0;
    if(RTEST(respect_kcode)) {
      kcode_tbl = state->shared.kcode_table();
    } else {
      kcode_tbl = kcode::null_table();
    }

    // Pointers to iterate input bytes.
    uint8_t* in_p = byte_address();

    native_int str_size = size();
    native_int data_size = as<CharArray>(data_)->size();
    if(unlikely(str_size > data_size)) {
      str_size = data_size;
    }

    uint8_t* in_end = in_p + str_size;

    // Optimistic estimate that output size will be 1.25 x input.
    native_int out_chunk = str_size * 5 / 4;
    native_int out_size = out_chunk;
    uint8_t* output = (uint8_t*)malloc(out_size);

    uint8_t* out_p = output;
    uint8_t* out_end = out_p + out_size;

    while(in_p < in_end) {
      native_int len = 0;
      uint8_t byte = *in_p;
      uint8_t* cur_p = 0;

      if(kcode::mbchar_p(kcode_tbl, byte)) {
        len = kcode::mbclen(kcode_tbl, byte);
        native_int rem = in_end - in_p;

        // if the character length is greater than the remaining
        // bytes, we have a malformed character. Handled below.
        if(rem >= len) {
          cur_p = in_p;
          in_p += len;
        }
      } else if(String* str = try_as<String>(tbl_ptr[byte])) {
        cur_p = str->byte_address();
        len = str->size();
        in_p++;
      } else {
        Tuple* tbl = as<Tuple>(tbl_ptr[byte]);

        for(native_int i = 0; i < tbl->num_fields(); i += 2) {
          String* key = as<String>(tbl->at(i));

          native_int rem = in_end - in_p;
          native_int klen = key->size();
          if(rem < klen) continue;

          if(memcmp(in_p, key->byte_address(), klen) == 0) {
            String* str = as<String>(tbl->at(i+1));
            cur_p = str->byte_address();
            len = str->size();
            in_p += klen;
            break;
          }
        }
      }

      // We could not map this byte, so we add it to the output
      // in stringified octal notation (ie \nnn).
      if(!cur_p) {
        snprintf((char*)invalid, 5, "\\%03o", *((char*)in_p) & 0377);
        in_p++;
        cur_p = invalid;
        len = 4;
      }

      if(out_p + len > out_end) {
        native_int pos = out_p - output;
        out_size += (len > out_chunk ? len : out_chunk);
        output = (uint8_t*)realloc(output, out_size);
        out_p = output + pos;
        out_end = output + out_size;
      }

      switch(len) {
      case 1:
        *out_p++ = *cur_p;
        break;
      case 2:
        *out_p++ = *cur_p++;
        *out_p++ = *cur_p;
        break;
      case 3:
        *out_p++ = *cur_p++;
        *out_p++ = *cur_p++;
        *out_p++ = *cur_p;
        break;
      default:
        memcpy(out_p, cur_p, len);
        out_p += len;
        break;
      }
    }

    String* result = String::create(state,
                                    reinterpret_cast<const char*>(output),
                                    out_p - output);
    free(output);

    if(tainted_p(state)) result->taint(state);
    return result;
  }
Beispiel #24
0
/*
 * call-seq:
 *    ctx.setup => Qtrue # first time
 *    ctx.setup => nil # thereafter
 *
 * This method is called automatically when a new SSLSocket is created.
 * Normally you do not need to call this method (unless you are writing an extension in C).
 */
static VALUE
ossl_sslctx_setup(VALUE self)
{
    SSL_CTX *ctx;
    X509 *cert = NULL, *client_ca = NULL;
    X509_STORE *store;
    EVP_PKEY *key = NULL;
    char *ca_path = NULL, *ca_file = NULL;
    int i, verify_mode;
    VALUE val;

    if(OBJ_FROZEN(self)) return Qnil;
    Data_Get_Struct(self, SSL_CTX, ctx);

#if !defined(OPENSSL_NO_DH)
    if (RTEST(ossl_sslctx_get_tmp_dh_cb(self))){
	SSL_CTX_set_tmp_dh_callback(ctx, ossl_tmp_dh_callback);
    }
    else{
	SSL_CTX_set_tmp_dh_callback(ctx, ossl_default_tmp_dh_callback);
    }
#endif
    SSL_CTX_set_ex_data(ctx, ossl_ssl_ex_ptr_idx, (void*)self);

    val = ossl_sslctx_get_cert_store(self);
    if(!NIL_P(val)){
	/*
         * WORKAROUND:
	 *   X509_STORE can count references, but
	 *   X509_STORE_free() doesn't care it.
	 *   So we won't increment it but mark it by ex_data.
	 */
        store = GetX509StorePtr(val); /* NO NEED TO DUP */
        SSL_CTX_set_cert_store(ctx, store);
        SSL_CTX_set_ex_data(ctx, ossl_ssl_ex_store_p, (void*)1);
    }

    val = ossl_sslctx_get_extra_cert(self);
    if(!NIL_P(val)){
	rb_block_call(val, rb_intern("each"), 0, 0, ossl_sslctx_add_extra_chain_cert_i, self);
    }

    /* private key may be bundled in certificate file. */
    val = ossl_sslctx_get_cert(self);
    cert = NIL_P(val) ? NULL : GetX509CertPtr(val); /* NO DUP NEEDED */
    val = ossl_sslctx_get_key(self);
    key = NIL_P(val) ? NULL : GetPKeyPtr(val); /* NO DUP NEEDED */
    if (cert && key) {
        if (!SSL_CTX_use_certificate(ctx, cert)) {
            /* Adds a ref => Safe to FREE */
            ossl_raise(eSSLError, "SSL_CTX_use_certificate:");
        }
        if (!SSL_CTX_use_PrivateKey(ctx, key)) {
            /* Adds a ref => Safe to FREE */
            ossl_raise(eSSLError, "SSL_CTX_use_PrivateKey:");
        }
        if (!SSL_CTX_check_private_key(ctx)) {
            ossl_raise(eSSLError, "SSL_CTX_check_private_key:");
        }
    }

    val = ossl_sslctx_get_client_ca(self);
    if(!NIL_P(val)){
	if(TYPE(val) == T_ARRAY){
	    for(i = 0; i < RARRAY_LEN(val); i++){
		client_ca = GetX509CertPtr(RARRAY_PTR(val)[i]);
        	if (!SSL_CTX_add_client_CA(ctx, client_ca)){
		    /* Copies X509_NAME => FREE it. */
        	    ossl_raise(eSSLError, "SSL_CTX_add_client_CA");
        	}
	    }
        }
	else{
	    client_ca = GetX509CertPtr(val); /* NO DUP NEEDED. */
            if (!SSL_CTX_add_client_CA(ctx, client_ca)){
		/* Copies X509_NAME => FREE it. */
        	ossl_raise(eSSLError, "SSL_CTX_add_client_CA");
            }
	}
    }

    val = ossl_sslctx_get_ca_file(self);
    ca_file = NIL_P(val) ? NULL : StringValuePtr(val);
    val = ossl_sslctx_get_ca_path(self);
    ca_path = NIL_P(val) ? NULL : StringValuePtr(val);
    if(ca_file || ca_path){
	if (!SSL_CTX_load_verify_locations(ctx, ca_file, ca_path))
	    rb_warning("can't set verify locations");
    }

    val = ossl_sslctx_get_verify_mode(self);
    verify_mode = NIL_P(val) ? SSL_VERIFY_NONE : NUM2INT(val);
    SSL_CTX_set_verify(ctx, verify_mode, ossl_ssl_verify_callback);
    if (RTEST(ossl_sslctx_get_client_cert_cb(self)))
	SSL_CTX_set_client_cert_cb(ctx, ossl_client_cert_cb);

    val = ossl_sslctx_get_timeout(self);
    if(!NIL_P(val)) SSL_CTX_set_timeout(ctx, NUM2LONG(val));

    val = ossl_sslctx_get_verify_dep(self);
    if(!NIL_P(val)) SSL_CTX_set_verify_depth(ctx, NUM2LONG(val));

    val = ossl_sslctx_get_options(self);
    if(!NIL_P(val)) SSL_CTX_set_options(ctx, NUM2LONG(val));
    rb_obj_freeze(self);

    val = ossl_sslctx_get_sess_id_ctx(self);
    if (!NIL_P(val)){
	StringValue(val);
	if (!SSL_CTX_set_session_id_context(ctx, RSTRING_PTR(val),
					    RSTRING_LEN(val))){
	    ossl_raise(eSSLError, "SSL_CTX_set_session_id_context:");
	}
    }

    if (RTEST(rb_iv_get(self, "@session_get_cb"))) {
	SSL_CTX_sess_set_get_cb(ctx, ossl_sslctx_session_get_cb);
	OSSL_Debug("SSL SESSION get callback added");
    }
    if (RTEST(rb_iv_get(self, "@session_new_cb"))) {
	SSL_CTX_sess_set_new_cb(ctx, ossl_sslctx_session_new_cb);
	OSSL_Debug("SSL SESSION new callback added");
    }
    if (RTEST(rb_iv_get(self, "@session_remove_cb"))) {
	SSL_CTX_sess_set_remove_cb(ctx, ossl_sslctx_session_remove_cb);
	OSSL_Debug("SSL SESSION remove callback added");
    }
    return Qtrue;
}
Beispiel #25
0
static VALUE
rbosa_app_send_event (VALUE self, VALUE event_class, VALUE event_id, VALUE params, VALUE need_retval)
{
    OSErr       error;
    AppleEvent  ae;
    AppleEvent  reply;
    VALUE       rb_timeout;
    SInt32      timeout;
    VALUE       rb_reply;
    unsigned    has_direct_param;

    error = AECreateAppleEvent (RVAL2FOURCHAR (event_class),
                                RVAL2FOURCHAR (event_id),
                                rbosa_element_aedesc (self),
                                kAutoGenerateReturnID,
                                kAnyTransactionID,
                                &ae);
    if (error != noErr)
        rb_raise (rb_eArgError, "Cannot create Apple Event '%s%s' : %s (%d)", 
                  RVAL2CSTR (event_class), RVAL2CSTR (event_id), error_code_to_string (error), error);

    has_direct_param = 0;
    if (!NIL_P (params)) {
        unsigned    i;

        for (i = 0; i < RARRAY (params)->len; i++) {
            VALUE   ary;
            VALUE   type;
            VALUE   element;
            FourCharCode code;

            ary = RARRAY (params)->ptr[i];
            if (NIL_P (ary) || RARRAY (ary)->len != 2)
                continue;

            type = RARRAY (ary)->ptr[0];
            element = RARRAY (ary)->ptr[1];
            code = RVAL2FOURCHAR (type);

            if (code == '----')
                has_direct_param = 1;

            error = AEPutParamDesc (&ae, RVAL2FOURCHAR (type), rbosa_element_aedesc (element));
            if (error != noErr) { 
                AEDisposeDesc (&ae); 
                rb_raise (rb_eArgError, "Cannot add Apple Event parameter '%s' : %s (%d)", 
                          RVAL2CSTR (type), error_code_to_string (error), error);
            }
        } 
    }

    rb_timeout = rb_iv_get (mOSA, "@timeout");
    timeout = NIL_P (rb_timeout) ? kAEDefaultTimeout : NUM2INT (rb_timeout);

    if (has_direct_param == 0)
        AEPutAttributePtr (&ae, 'subj', typeNull, NULL, 0);

    error = AESend (&ae, &reply, (RVAL2CBOOL(need_retval) ? kAEWaitReply : kAENoReply) | kAECanInteract | kAECanSwitchLayer,
                    kAENormalPriority, timeout, NULL, NULL);

    AEDisposeDesc (&ae); 

    if (error != noErr)
        rb_raise (rb_eRuntimeError, "Cannot send Apple Event '%s%s' : %s (%d)", 
                  RVAL2CSTR (event_class), RVAL2CSTR (event_id), error_code_to_string (error), error);

    __rbosa_raise_potential_app_error (&reply);

    if (RTEST (need_retval)) {
        AEDesc  replyObject;

        AEGetParamDesc (&reply, keyDirectObject, typeWildCard, &replyObject);

        rb_reply = rbosa_element_make (cOSAElement, &replyObject, self);
    }
    else {
        rb_reply = Qnil;
    }

    AEDisposeDesc (&reply);
        
    return rb_reply;
}
Beispiel #26
0
void
obj_dump(VALUE obj, yajl_gen gen)
{
  int type;
  yajl_gen_map_open(gen);

  yajl_gen_cstr(gen, "_id");
  yajl_gen_value(gen, obj);

  struct obj_track *tracker = NULL;
  if (st_lookup(objs, (st_data_t)obj, (st_data_t *)&tracker) && BUILTIN_TYPE(obj) != T_NODE) {
    yajl_gen_cstr(gen, "file");
    yajl_gen_cstr(gen, tracker->source);
    yajl_gen_cstr(gen, "line");
    yajl_gen_integer(gen, tracker->line);
  }

  yajl_gen_cstr(gen, "type");
  switch (type=BUILTIN_TYPE(obj)) {
    case T_DATA:
      yajl_gen_cstr(gen, "data");

      if (RBASIC(obj)->klass) {
        yajl_gen_cstr(gen, "class");
        yajl_gen_value(gen, RBASIC(obj)->klass);

        yajl_gen_cstr(gen, "class_name");
        VALUE name = rb_classname(RBASIC(obj)->klass);
        if (RTEST(name))
          yajl_gen_cstr(gen, RSTRING(name)->ptr);
        else
          yajl_gen_cstr(gen, 0);
      }
      break;

    case T_FILE:
      yajl_gen_cstr(gen, "file");
      break;

    case T_FLOAT:
      yajl_gen_cstr(gen, "float");

      yajl_gen_cstr(gen, "data");
      yajl_gen_double(gen, RFLOAT(obj)->value);
      break;

    case T_BIGNUM:
      yajl_gen_cstr(gen, "bignum");

      yajl_gen_cstr(gen, "negative");
      yajl_gen_bool(gen, RBIGNUM(obj)->sign == 0);

      yajl_gen_cstr(gen, "length");
      yajl_gen_integer(gen, RBIGNUM(obj)->len);

      yajl_gen_cstr(gen, "data");
      yajl_gen_string(gen, RBIGNUM(obj)->digits, RBIGNUM(obj)->len);
      break;

    case T_MATCH:
      yajl_gen_cstr(gen, "match");

      yajl_gen_cstr(gen, "data");
      yajl_gen_value(gen, RMATCH(obj)->str);
      break;

    case T_REGEXP:
      yajl_gen_cstr(gen, "regexp");

      yajl_gen_cstr(gen, "length");
      yajl_gen_integer(gen, RREGEXP(obj)->len);

      yajl_gen_cstr(gen, "data");
      yajl_gen_cstr(gen, RREGEXP(obj)->str);
      break;

    case T_SCOPE:
      yajl_gen_cstr(gen, "scope");

      struct SCOPE *scope = (struct SCOPE *)obj;
      if (scope->local_tbl) {
        int i = 1;
        int n = scope->local_tbl[0];
        VALUE *list = &scope->local_vars[-1];
        VALUE cur = *list++;

        yajl_gen_cstr(gen, "node");
        yajl_gen_value(gen, cur);

        if (n) {
          yajl_gen_cstr(gen, "variables");
          yajl_gen_map_open(gen);
          while (n--) {
            cur = *list++;
            yajl_gen_cstr(gen, scope->local_tbl[i] == 95 ? "_" : rb_id2name(scope->local_tbl[i]));
            yajl_gen_value(gen, cur);
            i++;
          }
          yajl_gen_map_close(gen);
        }
      }
      break;

    case T_NODE:
      yajl_gen_cstr(gen, "node");

      yajl_gen_cstr(gen, "node_type");
      yajl_gen_cstr(gen, nd_type_str(obj));

      yajl_gen_cstr(gen, "file");
      yajl_gen_cstr(gen, RNODE(obj)->nd_file);

      yajl_gen_cstr(gen, "line");
      yajl_gen_integer(gen, nd_line(obj));

      yajl_gen_cstr(gen, "node_code");
      yajl_gen_integer(gen, nd_type(obj));

      switch (nd_type(obj)) {
        case NODE_SCOPE:
          break;
      }
      break;

    case T_STRING:
      yajl_gen_cstr(gen, "string");

      yajl_gen_cstr(gen, "length");
      yajl_gen_integer(gen, RSTRING(obj)->len);

      if (FL_TEST(obj, ELTS_SHARED|FL_USER3)) {
        yajl_gen_cstr(gen, "shared");
        yajl_gen_value(gen, RSTRING(obj)->aux.shared);

        yajl_gen_cstr(gen, "flags");
        yajl_gen_array_open(gen);
        if (FL_TEST(obj, ELTS_SHARED))
          yajl_gen_cstr(gen, "elts_shared");
        if (FL_TEST(obj, FL_USER3))
          yajl_gen_cstr(gen, "str_assoc");
        yajl_gen_array_close(gen);
      } else {
        yajl_gen_cstr(gen, "data");
        yajl_gen_string(gen, (unsigned char *)RSTRING(obj)->ptr, RSTRING(obj)->len);
      }
      break;

    case T_VARMAP:
      yajl_gen_cstr(gen, "varmap");

      struct RVarmap *vars = (struct RVarmap *)obj;

      if (vars->next) {
        yajl_gen_cstr(gen, "next");
        yajl_gen_value(gen, (VALUE)vars->next);
      }

      if (vars->id) {
        yajl_gen_cstr(gen, "data");
        yajl_gen_map_open(gen);
        yajl_gen_cstr(gen, rb_id2name(vars->id));
        yajl_gen_value(gen, vars->val);
        yajl_gen_map_close(gen);
      }
      break;

    case T_CLASS:
    case T_MODULE:
    case T_ICLASS:
      yajl_gen_cstr(gen, type==T_CLASS ? "class" : type==T_MODULE ? "module" : "iclass");

      yajl_gen_cstr(gen, "name");
      VALUE name = rb_classname(obj);
      if (RTEST(name))
        yajl_gen_cstr(gen, RSTRING(name)->ptr);
      else
        yajl_gen_cstr(gen, 0);

      yajl_gen_cstr(gen, "super");
      yajl_gen_value(gen, RCLASS(obj)->super);

      yajl_gen_cstr(gen, "super_name");
      VALUE super_name = rb_classname(RCLASS(obj)->super);
      if (RTEST(super_name))
        yajl_gen_cstr(gen, RSTRING(super_name)->ptr);
      else
        yajl_gen_cstr(gen, 0);

      if (FL_TEST(obj, FL_SINGLETON)) {
        yajl_gen_cstr(gen, "singleton");
        yajl_gen_bool(gen, 1);
      }

      if (RCLASS(obj)->iv_tbl && RCLASS(obj)->iv_tbl->num_entries) {
        yajl_gen_cstr(gen, "ivars");
        yajl_gen_map_open(gen);
        st_foreach(RCLASS(obj)->iv_tbl, each_ivar, (st_data_t)gen);
        yajl_gen_map_close(gen);
      }

      if (type != T_ICLASS && RCLASS(obj)->m_tbl && RCLASS(obj)->m_tbl->num_entries) {
        yajl_gen_cstr(gen, "methods");
        yajl_gen_map_open(gen);
        st_foreach(RCLASS(obj)->m_tbl, each_ivar, (st_data_t)gen);
        yajl_gen_map_close(gen);
      }
      break;

    case T_OBJECT:
      yajl_gen_cstr(gen, "object");

      yajl_gen_cstr(gen, "class");
      yajl_gen_value(gen, RBASIC(obj)->klass);

      yajl_gen_cstr(gen, "class_name");
      yajl_gen_cstr(gen, rb_obj_classname(obj));

      struct RClass *klass = RCLASS(obj);

      if (klass->iv_tbl && klass->iv_tbl->num_entries) {
        yajl_gen_cstr(gen, "ivars");
        yajl_gen_map_open(gen);
        st_foreach(klass->iv_tbl, each_ivar, (st_data_t)gen);
        yajl_gen_map_close(gen);
      }
      break;

    case T_ARRAY:
      yajl_gen_cstr(gen, "array");

      struct RArray *ary = RARRAY(obj);

      yajl_gen_cstr(gen, "length");
      yajl_gen_integer(gen, ary->len);

      if (FL_TEST(obj, ELTS_SHARED)) {
        yajl_gen_cstr(gen, "shared");
        yajl_gen_value(gen, ary->aux.shared);
      } else if (ary->len) {
        yajl_gen_cstr(gen, "data");
        yajl_gen_array_open(gen);
        int i;
        for(i=0; i < ary->len; i++)
          yajl_gen_value(gen, ary->ptr[i]);
        yajl_gen_array_close(gen);
      }
      break;

    case T_HASH:
      yajl_gen_cstr(gen, "hash");

      struct RHash *hash = RHASH(obj);

      yajl_gen_cstr(gen, "length");
      if (hash->tbl)
        yajl_gen_integer(gen, hash->tbl->num_entries);
      else
        yajl_gen_integer(gen, 0);

      yajl_gen_cstr(gen, "default");
      yajl_gen_value(gen, hash->ifnone);

      if (hash->tbl && hash->tbl->num_entries) {
        yajl_gen_cstr(gen, "data");
        //yajl_gen_map_open(gen);
        yajl_gen_array_open(gen);
        st_foreach(hash->tbl, each_hash_entry, (st_data_t)gen);
        yajl_gen_array_close(gen);
        //yajl_gen_map_close(gen);
      }
      break;

    default:
      yajl_gen_cstr(gen, "unknown");
  }

  yajl_gen_cstr(gen, "code");
  yajl_gen_integer(gen, BUILTIN_TYPE(obj));

  yajl_gen_map_close(gen);
}
/*
 * call-seq: configure(opts)
 *
 * Configure this State instance with the Hash _opts_, and return
 * itself.
 */
static VALUE cState_configure(VALUE self, VALUE opts)
{
    VALUE tmp;
    GET_STATE(self);
    tmp = rb_check_convert_type(opts, T_HASH, "Hash", "to_hash");
    if (NIL_P(tmp)) tmp = rb_convert_type(opts, T_HASH, "Hash", "to_h");
    opts = tmp;
    tmp = rb_hash_aref(opts, ID2SYM(i_indent));
    if (RTEST(tmp)) {
        unsigned long len;
        Check_Type(tmp, T_STRING);
        len = RSTRING_LEN(tmp);
        state->indent = fstrndup(RSTRING_PTR(tmp), len + 1);
        state->indent_len = len;
    }
    tmp = rb_hash_aref(opts, ID2SYM(i_space));
    if (RTEST(tmp)) {
        unsigned long len;
        Check_Type(tmp, T_STRING);
        len = RSTRING_LEN(tmp);
        state->space = fstrndup(RSTRING_PTR(tmp), len + 1);
        state->space_len = len;
    }
    tmp = rb_hash_aref(opts, ID2SYM(i_space_before));
    if (RTEST(tmp)) {
        unsigned long len;
        Check_Type(tmp, T_STRING);
        len = RSTRING_LEN(tmp);
        state->space_before = fstrndup(RSTRING_PTR(tmp), len + 1);
        state->space_before_len = len;
    }
    tmp = rb_hash_aref(opts, ID2SYM(i_array_nl));
    if (RTEST(tmp)) {
        unsigned long len;
        Check_Type(tmp, T_STRING);
        len = RSTRING_LEN(tmp);
        state->array_nl = fstrndup(RSTRING_PTR(tmp), len + 1);
        state->array_nl_len = len;
    }
    tmp = rb_hash_aref(opts, ID2SYM(i_object_nl));
    if (RTEST(tmp)) {
        unsigned long len;
        Check_Type(tmp, T_STRING);
        len = RSTRING_LEN(tmp);
        state->object_nl = fstrndup(RSTRING_PTR(tmp), len + 1);
        state->object_nl_len = len;
    }
    tmp = ID2SYM(i_max_nesting);
    state->max_nesting = 100;
    if (option_given_p(opts, tmp)) {
        VALUE max_nesting = rb_hash_aref(opts, tmp);
        if (RTEST(max_nesting)) {
            Check_Type(max_nesting, T_FIXNUM);
            state->max_nesting = FIX2LONG(max_nesting);
        } else {
            state->max_nesting = 0;
        }
    }
    tmp = ID2SYM(i_depth);
    state->depth = 0;
    if (option_given_p(opts, tmp)) {
        VALUE depth = rb_hash_aref(opts, tmp);
        if (RTEST(depth)) {
            Check_Type(depth, T_FIXNUM);
            state->depth = FIX2LONG(depth);
        } else {
            state->depth = 0;
        }
    }
    tmp = ID2SYM(i_buffer_initial_length);
    if (option_given_p(opts, tmp)) {
        VALUE buffer_initial_length = rb_hash_aref(opts, tmp);
        if (RTEST(buffer_initial_length)) {
            long initial_length;
            Check_Type(buffer_initial_length, T_FIXNUM);
            initial_length = FIX2LONG(buffer_initial_length);
            if (initial_length > 0) state->buffer_initial_length = initial_length;
        }
    }
    tmp = rb_hash_aref(opts, ID2SYM(i_allow_nan));
    state->allow_nan = RTEST(tmp);
    tmp = rb_hash_aref(opts, ID2SYM(i_ascii_only));
    state->ascii_only = RTEST(tmp);
    return self;
}
Beispiel #28
0
static VALUE
memprof_dump(int argc, VALUE *argv, VALUE self)
{
  VALUE str;
  FILE *out = NULL;

  if (!track_objs)
    rb_raise(rb_eRuntimeError, "object tracking disabled, call Memprof.start first");

  rb_scan_args(argc, argv, "01", &str);

  if (RTEST(str)) {
    out = fopen(StringValueCStr(str), "w");
    if (!out)
      rb_raise(rb_eArgError, "unable to open output file");
  }

  yajl_gen_config conf = { .beautify = 1, .indentString = "  " };
  yajl_gen gen = yajl_gen_alloc2((yajl_print_t)&json_print, &conf, NULL, (void*)out);

  track_objs = 0;

  yajl_gen_array_open(gen);
  st_foreach(objs, objs_each_dump, (st_data_t)gen);
  yajl_gen_array_close(gen);
  yajl_gen_free(gen);

  if (out)
    fclose(out);

  track_objs = 1;

  return Qnil;
}

static VALUE
memprof_dump_all(int argc, VALUE *argv, VALUE self)
{
  char *heaps = *(char**)bin_find_symbol("heaps",0);
  int heaps_used = *(int*)bin_find_symbol("heaps_used",0);

#ifndef sizeof__RVALUE
  size_t sizeof__RVALUE = bin_type_size("RVALUE");
#endif
#ifndef sizeof__heaps_slot
  size_t sizeof__heaps_slot = bin_type_size("heaps_slot");
#endif
#ifndef offset__heaps_slot__limit
  int offset__heaps_slot__limit = bin_type_member_offset("heaps_slot", "limit");
#endif
#ifndef offset__heaps_slot__slot
  int offset__heaps_slot__slot = bin_type_member_offset("heaps_slot", "slot");
#endif

  char *p, *pend;
  int i, limit;

  if (sizeof__RVALUE == 0 || sizeof__heaps_slot == 0)
    rb_raise(eUnsupported, "could not find internal heap");

  VALUE str;
  FILE *out = NULL;

  rb_scan_args(argc, argv, "01", &str);

  if (RTEST(str)) {
    out = fopen(StringValueCStr(str), "w");
    if (!out)
      rb_raise(rb_eArgError, "unable to open output file");
  }

  yajl_gen_config conf = { .beautify = 0, .indentString = "  " };
  yajl_gen gen = yajl_gen_alloc2((yajl_print_t)&json_print, &conf, NULL, (void*)out);

  track_objs = 0;

  //yajl_gen_array_open(gen);

  for (i=0; i < heaps_used; i++) {
    p = *(char**)(heaps + (i * sizeof__heaps_slot) + offset__heaps_slot__slot);
    limit = *(int*)(heaps + (i * sizeof__heaps_slot) + offset__heaps_slot__limit);
    pend = p + (sizeof__RVALUE * limit);

    while (p < pend) {
      if (RBASIC(p)->flags) {
        obj_dump((VALUE)p, gen);
        // XXX ugh
        yajl_gen_clear(gen);
        yajl_gen_free(gen);
        gen = yajl_gen_alloc2((yajl_print_t)&json_print, &conf, NULL, (void*)out);
        while(fputc('\n', out ? out : stdout) == EOF);
      }

      p += sizeof__RVALUE;
    }
  }

  //yajl_gen_array_close(gen);
  yajl_gen_clear(gen);
  yajl_gen_free(gen);

  if (out)
    fclose(out);

  track_objs = 1;

  return Qnil;
}

void
Init_memprof()
{
  VALUE memprof = rb_define_module("Memprof");
  eUnsupported = rb_define_class_under(memprof, "Unsupported", rb_eStandardError);
  rb_define_singleton_method(memprof, "start", memprof_start, 0);
  rb_define_singleton_method(memprof, "stop", memprof_stop, 0);
  rb_define_singleton_method(memprof, "stats", memprof_stats, -1);
  rb_define_singleton_method(memprof, "stats!", memprof_stats_bang, -1);
  rb_define_singleton_method(memprof, "track", memprof_track, -1);
  rb_define_singleton_method(memprof, "dump", memprof_dump, -1);
  rb_define_singleton_method(memprof, "dump_all", memprof_dump_all, -1);

  pagesize = getpagesize();
  objs = st_init_numtable();
  bin_init();
  create_tramp_table();

  gc_hook = Data_Wrap_Struct(rb_cObject, sourcefile_marker, NULL, NULL);
  rb_global_variable(&gc_hook);
  ptr_to_rb_mark_table_add_filename = bin_find_symbol("rb_mark_table_add_filename", NULL);

  rb_classname = bin_find_symbol("classname", 0);
  rb_add_freelist = bin_find_symbol("add_freelist", 0);

  insert_tramp("rb_newobj", newobj_tramp);
  insert_tramp("add_freelist", freelist_tramp);

  if (getenv("MEMPROF"))
    track_objs = 1;

  return;
}
Beispiel #29
0
/*
 * call-seq:
 *  new
 *
 * Create a new document
 */
static VALUE new(int argc, VALUE *argv, VALUE klass)
{
  VALUE uri, external_id, rest, rb_doc;

  rb_scan_args(argc, argv, "0*", &rest);
  uri         = rb_ary_entry(rest, (long)0);
  external_id = rb_ary_entry(rest, (long)1);

  htmlDocPtr doc = htmlNewDoc(
      RTEST(uri) ? (const xmlChar *)StringValuePtr(uri) : NULL,
      RTEST(external_id) ? (const xmlChar *)StringValuePtr(external_id) : NULL
  );
  rb_doc = Nokogiri_wrap_xml_document(klass, doc);
  rb_obj_call_init(rb_doc, argc, argv);
  return rb_doc ;
}

/*
 * call-seq:
 *  read_io(io, url, encoding, options)
 *
 * Read the HTML document from +io+ with given +url+, +encoding+,
 * and +options+.  See Nokogiri::HTML.parse
 */
static VALUE read_io( VALUE klass,
Beispiel #30
0
static VALUE
initialize_params(VALUE vparams, VALUE parser, VALUE arg, VALUE lexer, VALUE lexmid)
{
    struct cparse_params *v;

    Data_Get_Struct(vparams, struct cparse_params, v);
    v->value_v = vparams;
    v->parser = parser;
    v->lexer = lexer;
    if (! NIL_P(lexmid))
        v->lexmid = value_to_id(lexmid);

    v->debug = RTEST(rb_ivar_get(parser, id_yydebug));

    Check_Type(arg, T_ARRAY);
    if (!(13 <= RARRAY_LEN(arg) && RARRAY_LEN(arg) <= 14))
        rb_raise(RaccBug, "[Racc Bug] wrong arg.size %ld", RARRAY_LEN(arg));
    v->action_table   = assert_array  (RARRAY_PTR(arg)[ 0]);
    v->action_check   = assert_array  (RARRAY_PTR(arg)[ 1]);
    v->action_default = assert_array  (RARRAY_PTR(arg)[ 2]);
    v->action_pointer = assert_array  (RARRAY_PTR(arg)[ 3]);
    v->goto_table     = assert_array  (RARRAY_PTR(arg)[ 4]);
    v->goto_check     = assert_array  (RARRAY_PTR(arg)[ 5]);
    v->goto_default   = assert_array  (RARRAY_PTR(arg)[ 6]);
    v->goto_pointer   = assert_array  (RARRAY_PTR(arg)[ 7]);
    v->nt_base        = assert_integer(RARRAY_PTR(arg)[ 8]);
    v->reduce_table   = assert_array  (RARRAY_PTR(arg)[ 9]);
    v->token_table    = assert_hash   (RARRAY_PTR(arg)[10]);
    v->shift_n        = assert_integer(RARRAY_PTR(arg)[11]);
    v->reduce_n       = assert_integer(RARRAY_PTR(arg)[12]);
    if (RARRAY_LEN(arg) > 13) {
        v->use_result_var = RTEST(RARRAY_PTR(arg)[13]);
    }
    else {
        v->use_result_var = TRUE;
    }

    v->tstack = v->debug ? NEW_STACK() : Qnil;
    v->vstack = NEW_STACK();
    v->state = NEW_STACK();
    v->curstate = 0;
    PUSH(v->state, INT2FIX(0));
    v->t = INT2FIX(FINAL_TOKEN + 1);   /* must not init to FINAL_TOKEN */
    v->nerr = 0;
    v->errstatus = 0;
    rb_ivar_set(parser, id_errstatus, LONG2NUM(v->errstatus));

    v->retval = Qnil;
    v->fin = 0;

    v->lex_is_iterator = FALSE;

    rb_iv_set(parser, "@vstack", v->vstack);
    if (v->debug) {
        rb_iv_set(parser, "@tstack", v->tstack);
    }
    else {
        rb_iv_set(parser, "@tstack", Qnil);
    }

    return vparams;
}