Пример #1
0
  /*
   * This is a primitive so #initialize_copy can work.
   */
  Regexp* Regexp::initialize(STATE, String* pattern, Fixnum* options) {
    const UChar *pat;
    const UChar *end;
    OnigErrorInfo err_info;
    OnigOptionType opts;
    OnigEncoding enc;
    int err, num_names, kcode;

    pat = (UChar*)pattern->byte_address();
    end = pat + pattern->size();

    opts  = options->to_native();
    kcode = opts & KCODE_MASK;
    opts &= OPTION_MASK;

    if(kcode == 0) {
      enc = current_encoding(state);
    } else {
      // Don't attempt to fix the encoding later, it's been specified by the
      // user.
      enc = get_enc_from_kcode(kcode);
      forced_encoding_ = true;
    }

    thread::Mutex::LockGuard lg(state->shared().onig_lock());

    err = onig_new(&this->onig_data, pat, end, opts, enc, ONIG_SYNTAX_RUBY, &err_info);

    if(err != ONIG_NORMAL) {
      UChar onig_err_buf[ONIG_MAX_ERROR_MESSAGE_LEN];
      char err_buf[1024];
      onig_error_code_to_str(onig_err_buf, err, &err_info);
      snprintf(err_buf, 1024, "%s: %s", onig_err_buf, pat);

      Exception::regexp_error(state, err_buf);
      return 0;
    }

    this->source(state, pattern);

    num_names = onig_number_of_names(this->onig_data);

    if(num_names == 0) {
      this->names(state, nil<LookupTable>());
    } else {
      struct _gather_data gd;
      gd.state = state;
      LookupTable* tbl = LookupTable::create(state);
      gd.tbl = tbl;
      onig_foreach_name(this->onig_data, (int (*)(const OnigUChar*, const OnigUChar*,int,int*,OnigRegex,void*))_gather_names, (void*)&gd);
      this->names(state, tbl);
    }

    make_managed(state);

    return this;
  }
Пример #2
0
  /*
   * This is a primitive so #initialize_copy can work.
   */
  Regexp* Regexp::initialize(STATE, String* pattern, Fixnum* options) {
    const UChar *pat;
    const UChar *end;
    OnigErrorInfo err_info;
    OnigEncoding enc;

    OnigOptionType opts = options->to_native();

    if(LANGUAGE_18_ENABLED(state)) {
      int kcode = opts & KCODE_MASK;

      pat = (UChar*)pattern->byte_address();
      end = pat + pattern->byte_size();

      if(kcode == 0) {
        enc = pattern->get_encoding_kcode_fallback(state);
      } else {
        // Don't attempt to fix the encoding later, it's been specified by the
        // user.
        enc = get_enc_from_kcode(kcode);
        fixed_encoding_ = true;
      }
    } else {
      fixed_encoding_ = opts & OPTION_FIXEDENCODING;
      no_encoding_    = opts & OPTION_NOENCODING;

      Encoding* source_enc = pattern->encoding(state);

      switch(opts & KCODE_MASK) {
      case KCODE_NONE:
        source_enc = 0;
        no_encoding_ = true;
        break;
      case KCODE_EUC:
        source_enc = Encoding::find(state, "EUC-JP");
        fixed_encoding_ = true;
        break;
      case KCODE_SJIS:
        source_enc = Encoding::find(state, "Windows-31J");
        fixed_encoding_ = true;
        break;
      case KCODE_UTF8:
        source_enc = Encoding::utf8_encoding(state);
        fixed_encoding_ = true;
        break;
      }

      String* converted = pattern->convert_escaped(state, source_enc, fixed_encoding_);

      pat = (UChar*)converted->byte_address();
      end = pat + converted->byte_size();
      enc = source_enc->get_encoding();

      pattern = pattern->string_dup(state);
      pattern->encoding(state, source_enc);
    }

    utilities::thread::Mutex::LockGuard lg(state->shared().onig_lock());

    int err = onig_new(&this->onig_data, pat, end, opts & OPTION_MASK, enc, ONIG_SYNTAX_RUBY, &err_info);

    if(err != ONIG_NORMAL) {
      UChar onig_err_buf[ONIG_MAX_ERROR_MESSAGE_LEN];
      char err_buf[1024];
      onig_error_code_to_str(onig_err_buf, err, &err_info);
      snprintf(err_buf, 1024, "%s: %s", onig_err_buf, pat);

      Exception::regexp_error(state, err_buf);
      return 0;
    }

    this->source(state, pattern);

    int num_names = onig_number_of_names(this->onig_data);

    if(num_names == 0) {
      this->names(state, nil<LookupTable>());
    } else {
      struct _gather_data gd;
      gd.state = state;
      LookupTable* tbl = LookupTable::create(state);
      gd.tbl = tbl;
      onig_foreach_name(this->onig_data, (int (*)(const OnigUChar*, const OnigUChar*,int,int*,OnigRegex,void*))_gather_names, (void*)&gd);
      this->names(state, tbl);
    }

    make_managed(state);

    return this;
  }