Пример #1
0
  void Environment::load_argv(int argc, char** argv) {
    String* str = 0;
    Encoding* enc = Encoding::default_external(state);

    Array* os_ary = Array::create(state, argc);
    for(int i = 0; i < argc; i++) {
      str = String::create(state, argv[i]);
      str->encoding(state, enc);
      os_ary->set(state, i, str);
    }

    G(rubinius)->set_const(state, "OS_ARGV", os_ary);

    char buf[MAXPATHLEN];
    str = String::create(state, getcwd(buf, MAXPATHLEN));
    str->encoding(state, enc);
    G(rubinius)->set_const(state, "OS_STARTUP_DIR", str);

    str = String::create(state, argv[0]);
    str->encoding(state, enc);
    state->vm()->set_const("ARG0", str);

    Array* ary = Array::create(state, argc - 1);
    int which_arg = 0;
    bool skip_xflags = true;

    for(int i=1; i < argc; i++) {
      char* arg = argv[i];

      if(strcmp(arg, "--") == 0) {
        skip_xflags = false;
      } else if(strncmp(arg, "-X", 2) == 0) {
        if(skip_xflags) continue;
      } else if(arg[1] != '-') {
        skip_xflags = false;
      }

      str = String::create(state, arg);
      str->taint(state);
      str->encoding(state, enc);
      ary->set(state, which_arg++, str);
    }

    state->vm()->set_const("ARGV", ary);

    // Now finish up with the config
    if(config.print_config > 1) {
      std::cout << "========= Configuration =========\n";
      config.print(true);
      std::cout << "=================================\n";
    } else if(config.print_config) {
      config.print();
    }

    state->shared().set_use_capi_lock(config.capi_lock);
  }
Пример #2
0
  String* Time::strftime(STATE, String* format) {
    struct tm64 tm = get_tm();

    struct timespec64 ts;
    ts.tv_sec = seconds_;
    ts.tv_nsec = nanoseconds_;

    int off = 0;
    if(Fixnum* offset = try_as<Fixnum>(utc_offset(state))) {
      off = offset->to_int();
    }

    if(format->byte_size() == 0) return String::create(state, NULL, 0);

    char stack_str[STRFTIME_STACK_BUF];

    size_t chars = ::strftime_extended(stack_str, STRFTIME_STACK_BUF,
                       format->c_str(state), &tm, &ts, CBOOL(is_gmt_) ? 1 : 0,
                       off);

    size_t buf_size = format->byte_size();

    String* result = 0;

    if(chars == 0) {
      buf_size *= 2;
      char* malloc_str = (char*)malloc(buf_size);

      if(!malloc_str) {
        Exception::memory_error(state);
        return NULL;
      }

      chars = ::strftime_extended(malloc_str, buf_size,
                  format->c_str(state), &tm, &ts, CBOOL(is_gmt_) ? 1 : 0,
                  off);
      if(chars) {
        result = String::create(state, malloc_str, chars);
        result->encoding(state, format->encoding());
      }

      free(malloc_str);
    } else {
      result = String::create(state, stack_str, chars);
      result->encoding(state, format->encoding());
    }

    return result;
  }
Пример #3
0
  Object* MatchData::nth_capture(STATE, native_int which) {
    if(region_->num_fields() <= which) return cNil;

    Tuple* sub = try_as<Tuple>(region_->at(state, which));
    if(!sub) return cNil;

    Fixnum* beg = try_as<Fixnum>(sub->at(state, 0));
    Fixnum* fin = try_as<Fixnum>(sub->at(state, 1));

    native_int b = beg->to_native();
    native_int f = fin->to_native();
    native_int max = source_->byte_size();

    if(!beg || !fin ||
        f > max ||
        b < 0) {
      return cNil;
    }

    const char* str = (char*)source_->byte_address();
    native_int sz = f - b;

    if(sz > max) sz = max;

    String* string = String::create(state, str + b, sz);
    string->encoding(state, source_->encoding());

    return string;
  }
Пример #4
0
  Symbol* UnMarshaller::get_symbol() {
    char stack_data[STACK_BUF_SZ];
    char *malloc_data = NULL;
    char *data = stack_data;
    size_t count;

    Encoding* enc = try_as<Encoding>(unmarshal());

    stream >> count;
    stream.get();

    if(count >= STACK_BUF_SZ) {
      malloc_data = (char*)malloc(count + 1);
      data = malloc_data;
    }

    stream.read(data, count + 1);
    data[count] = 0; // clamp

    String* str = String::create(state, data, count);
    if(enc) str->encoding(state, enc);

    Symbol* sym = state->symbol(str);

    if(malloc_data) {
      free(malloc_data);
    }

    return sym;
  }
Пример #5
0
  String* String::string_dup(STATE) {
    Module* mod = klass_;
    Class*  cls = try_as_instance<Class>(mod);

    if(unlikely(!cls)) {
      while(!cls) {
        mod = mod->superclass();

        if(mod->nil_p()) rubinius::bug("Object::class_object() failed to find a class");

        cls = try_as_instance<Class>(mod);
      }
    }

    String* so = state->new_object<String>(cls);

    so->set_tainted(is_tainted_p());

    so->num_bytes(state, num_bytes());
    so->encoding(state, encoding());
    so->data(state, data());
    so->hash_value(state, hash_value());

    so->shared(state, Qtrue);
    shared(state, Qtrue);

    return so;
  }
Пример #6
0
 String* Time::locale_string(STATE, const char* data) {
   String* str = String::create(state, data);
   Encoding* locale = Encoding::find(state, "locale");
   if(!locale->nil_p()) {
     str->encoding(state, locale);
   }
   return str;
 }
Пример #7
0
  VALUE rb_external_str_new_with_enc(const char* string, long size, rb_encoding* encoding) {
    NativeMethodEnvironment* env = NativeMethodEnvironment::get();

    String* str = String::create(env->state(), string, size);
    str->taint(env->state());

    Encoding* enc = Encoding::find(env->state(), encoding->name);
    if(enc == Encoding::usascii_encoding(env->state())
       && !CBOOL(str->ascii_only_p(env->state()))) {
      str->encoding(env->state(), Encoding::ascii8bit_encoding(env->state()));
    } else {
      str->encoding(env->state(), enc);
    }

    // TODO: handle transcoding if necessary
    return env->get_handle(str);
  }
Пример #8
0
    void test_string_with_encoding() {
        mar->sstream.str(std::string("s\nE\n10\nASCII-8BIT\n4\nblah\n"));
        Object* obj = mar->unmarshal();

        TS_ASSERT(kind_of<String>(obj));
        String *str = as<String>(obj);
        TS_ASSERT_EQUALS(std::string(str->c_str(state)), "blah");
        TS_ASSERT_EQUALS(std::string(str->encoding()->name()->c_str(state)), "ASCII-8BIT");
    }
Пример #9
0
    void test_string_no_encoding() {
        mar->sstream.str(std::string("s\nE\n0\n\n4\nblah\n"));
        Object* obj = mar->unmarshal();

        TS_ASSERT(kind_of<String>(obj));
        String *str = as<String>(obj);
        TS_ASSERT_EQUALS(std::string(str->c_str(state)), "blah");
        TS_ASSERT_EQUALS(str->encoding(), Qnil);
    }
Пример #10
0
String* Float::to_s_minimal(STATE) {
    char buffer[FLOAT_TO_S_STRLEN];

    int len = double_to_string(buffer, FLOAT_TO_S_STRLEN, val);
    String* str = String::create(state, buffer, len);
    infect(state, str);
    str->encoding(state, Encoding::usascii_encoding(state));
    str->ascii_only(state, cTrue);
    str->valid_encoding(state, cTrue);

    return str;
}
Пример #11
0
  String* String::from_bytearray(STATE, ByteArray* ba, Integer* start, Integer* count) {
    String* s = state->new_object<String>(G(string));

    s->num_bytes(state, count);
    s->characters(state, count);
    s->encoding(state, Qnil);
    s->hash_value(state, (Integer*)Qnil);
    s->shared(state, Qfalse);

    // fetch_bytes NULL terminates
    s->data(state, ba->fetch_bytes(state, start, count));

    return s;
  }
Пример #12
0
  String* SymbolTable::lookup_string(STATE, const Symbol* sym) {
    if(sym->nil_p()) {
      Exception::argument_error(state, "Cannot look up Symbol from nil");
      return NULL;
    }

    size_t sym_index = sym->index();
    if(sym_index >= strings.size()) {
      return NULL;
    }
    std::string& str = strings[sym_index];
    String* s = String::create(state, str.data(), str.size());
    s->encoding(state, Encoding::usascii_encoding(state));
    return s;
  }
Пример #13
0
  String* String::from_chararray(STATE, CharArray* ca, Fixnum* start,
                                 Fixnum* count)
  {
    String* s = state->new_object<String>(G(string));

    s->num_bytes(state, count);
    s->encoding(state, Qnil);
    s->hash_value(state, nil<Fixnum>());
    s->shared(state, Qfalse);

    // fetch_bytes NULL terminates
    s->data(state, ca->fetch_bytes(state, start, count));

    return s;
  }
Пример #14
0
  Object* Dir::read(STATE) {
    guard(state);

    struct dirent ent;
    struct dirent* entp = &ent;
    if(int erno = readdir_r(os(), entp, &entp)) {
      Exception::raise_errno_error(state, "readdir_r(3) failed", erno);
    }

    if(!entp) return cNil;

    String* str = String::create(state, ent.d_name);
    str->encoding(state, encoding());
    return str;
  }
Пример #15
0
  String* String::create_reserved(STATE, native_int bytes) {
    String *so;

    so = state->new_object<String>(G(string));

    so->num_bytes(state, Fixnum::from(0));
    so->encoding(state, Qnil);
    so->hash_value(state, nil<Fixnum>());
    so->shared(state, Qfalse);

    CharArray* ba = CharArray::create(state, bytes+1);
    ba->raw_bytes()[bytes] = 0;

    so->data(state, ba);

    return so;
  }
Пример #16
0
String* Float::to_s_formatted(STATE, String* format) {
    char buf[FLOAT_TO_S_STRLEN];

    size_t size = snprintf(buf, FLOAT_TO_S_STRLEN, format->c_str(state), val);

    if(size >= FLOAT_TO_S_STRLEN) {
        std::ostringstream msg;
        msg << "formatted string exceeds " << FLOAT_TO_S_STRLEN << " bytes";
        Exception::argument_error(state, msg.str().c_str());
    }
    String* str = String::create(state, buf, size);
    infect(state, str);
    str->encoding(state, Encoding::usascii_encoding(state));
    str->ascii_only(state, cTrue);
    str->valid_encoding(state, cTrue);
    return str;
}
Пример #17
0
  String* SymbolTable::lookup_string(STATE, const Symbol* sym) {
    utilities::thread::SpinLock::LockGuard guard(lock_);
    if(sym->nil_p()) {
      Exception::argument_error(state, "Cannot look up Symbol from nil");
      return NULL;
    }

    size_t sym_index = sym->index();
    if(sym_index >= strings.size()) {
      return NULL;
    }
    std::string& str = strings[sym_index];
    int enc = encodings[sym_index];
    String* s = String::create(state, str.data(), str.size());
    s->encoding(state, Encoding::from_index(state, enc));
    return s;
  }
Пример #18
0
  /*
   * Creates a String instance with +num_bytes+ bytes of storage.
   * It also pins the CharArray used for storage, so it can be passed
   * to an external function (like ::read)
   */
  String* String::create_pinned(STATE, Fixnum* size) {
    String *so;

    so = state->new_object<String>(G(string));

    so->num_bytes(state, size);
    so->encoding(state, Qnil);
    so->hash_value(state, nil<Fixnum>());
    so->shared(state, Qfalse);

    native_int bytes = size->to_native() + 1;
    CharArray* ba = CharArray::create_pinned(state, bytes);
    ba->raw_bytes()[bytes-1] = 0;

    so->data(state, ba);

    return so;
  }
Пример #19
0
  String* String::create_reserved(STATE, size_t bytes) {
    String *so;

    so = state->new_object<String>(G(string));

    so->num_bytes(state, Fixnum::from(0));
    so->characters(state, Fixnum::from(0));
    so->encoding(state, Qnil);
    so->hash_value(state, (Integer*)Qnil);
    so->shared(state, Qfalse);

    ByteArray* ba = ByteArray::create(state, bytes);
    ba->raw_bytes()[bytes-1] = 0;

    so->data(state, ba);

    return so;
  }
Пример #20
0
  /*
   * Creates a String instance with +num_bytes+ bytes of storage.
   * It also pins the ByteArray used for storage, so it can be passed
   * to an external function (like ::read)
   */
  String* String::create_pinned(STATE, Fixnum* size) {
    String *so;

    so = state->new_object<String>(G(string));

    so->num_bytes(state, size);
    so->characters(state, size);
    so->encoding(state, Qnil);
    so->hash_value(state, (Integer*)Qnil);
    so->shared(state, Qfalse);

    size_t bytes = size->to_native() + 1;
    ByteArray* ba = ByteArray::create_pinned(state, bytes);
    ba->bytes[bytes-1] = 0;

    so->data(state, ba);

    return so;
  }
Пример #21
0
  String* UnMarshaller::get_string() {
    size_t count;

    Encoding* enc = try_as<Encoding>(unmarshal());

    stream >> count;
    // String::create adds room for a trailing null on its own
    // using pinned here allows later stages to optimize these literal
    // strings better.
    String* str = String::create(state, NULL, count);

    stream.get(); // read off newline
    stream.read(reinterpret_cast<char*>(str->byte_address()), count);
    stream.get(); // read off newline

    if(enc) str->encoding(state, enc);

    return str;
  }
Пример #22
0
  String* MatchData::pre_matched(STATE) {
    Fixnum* beg = try_as<Fixnum>(full_->at(state, 0));

    native_int max = source_->byte_size();
    native_int sz = beg->to_native();

    String* string;

    if(!beg || sz <= 0) {
      string = String::create(state, 0, 0);
    } else {
      if(sz > max) sz = max;

      const char* str = (char*)source_->byte_address();

      string = String::create(state, str, sz);
    }

    string->encoding(state, source_->encoding());

    return string;
  }
Пример #23
0
  String* MatchData::post_matched(STATE) {
    Fixnum* fin = try_as<Fixnum>(full_->at(state, 1));

    native_int f = fin->to_native();
    native_int max = source_->byte_size();

    String* string;

    if(!fin || f >= max) {
      string = String::create(state, 0, 0);
    } else {
      const char* str = (char*)source_->byte_address();
      native_int sz = max - f;

      if(sz > max) sz = max;

      string = String::create(state, str + f, sz);
    }

    string->encoding(state, source_->encoding());

    return string;
  }
Пример #24
0
  String* MatchData::matched_string(STATE) {
    Fixnum* beg = try_as<Fixnum>(full_->at(state, 0));
    Fixnum* fin = try_as<Fixnum>(full_->at(state, 1));

    native_int max = source_->byte_size();
    native_int f = fin->to_native();
    native_int b = beg->to_native();

    String* string;

    if(!beg || !fin ||
        f > max || b > max || b < 0) {
      string = String::create(state, 0, 0);
    } else {
      const char* str = (char*)source_->byte_address();
      native_int sz = fin->to_native() - beg->to_native();

      string = String::create(state, str + beg->to_native(), sz);
    }

    string->encoding(state, source_->encoding());

    return string;
  }
Пример #25
0
  void Environment::load_argv(int argc, char** argv) {
    String* str = 0;
    Encoding* enc = Encoding::default_external(state);

    Array* os_ary = Array::create(state, argc);
    for(int i = 0; i < argc; i++) {
      str = String::create(state, argv[i]);
      str->encoding(state, enc);
      os_ary->set(state, i, str);
    }

    G(rubinius)->set_const(state, "OS_ARGV", os_ary);

    char buf[MAXPATHLEN];
    str = String::create(state, getcwd(buf, MAXPATHLEN));
    str->encoding(state, enc);
    G(rubinius)->set_const(state, "OS_STARTUP_DIR", str);

    str = String::create(state, argv[0]);
    str->encoding(state, enc);
    state->vm()->set_const("ARG0", str);

    Array* ary = Array::create(state, argc - 1);
    int which_arg = 0;
    bool skip_xflags = true;

    for(int i=1; i < argc; i++) {
      char* arg = argv[i];

      if(strcmp(arg, "--") == 0) {
        skip_xflags = false;
      } else if(strncmp(arg, "-X", 2) == 0) {
        if(skip_xflags) continue;
      } else if(arg[1] != '-') {
        skip_xflags = false;
      }

      str = String::create(state, arg);
      str->taint(state);
      str->encoding(state, enc);
      ary->set(state, which_arg++, str);
    }

    state->vm()->set_const("ARGV", ary);

    // Now finish up with the config
    if(config.print_config > 1) {
      std::cout << "========= Configuration =========\n";
      config.print(true);
      std::cout << "=================================\n";
    } else if(config.print_config) {
      config.print();
    }

    if(config.agent_start > 0) {
      // if port_ is 1, the user wants to use a randomly assigned local
      // port which will be written to the temp file for console to pick
      // up.

      int port = config.agent_start;
      if(port == 1) port = 0;
      start_agent(port);
    }

    if(config.report_path.set_p()) {
      // Test that we can actually use this path
      int fd = open(config.report_path, O_RDONLY | O_CREAT, 0666);
      if(!fd) {
        std::cerr << "Unable to use " << config.report_path << " for crash reports.\n";
        std::cerr << "Unable to open path: " << strerror(errno) << "\n";

        // Don't use the home dir path even, just use stderr
        report_path[0] = 0;
      } else {
        close(fd);
        unlink(config.report_path);
        strncpy(report_path, config.report_path, sizeof(report_path) - 1);
      }
    }

    state->shared().set_use_capi_lock(config.capi_lock);
  }
Пример #26
0
  void Environment::load_argv(int argc, char** argv) {
    String* str = 0;
    Encoding* enc = Encoding::default_external(state);

    Array* os_ary = Array::create(state, argc);
    for(int i = 0; i < argc; i++) {
      str = String::create(state, argv[i]);
      str->encoding(state, enc);
      os_ary->set(state, i, str);
    }

    G(rubinius)->set_const(state, "OS_ARGV", os_ary);

    char buf[MAXPATHLEN];
    str = String::create(state, getcwd(buf, MAXPATHLEN));
    str->encoding(state, enc);
    G(rubinius)->set_const(state, "OS_STARTUP_DIR", str);

    str = String::create(state, argv[0]);
    str->encoding(state, enc);
    state->vm()->set_const("ARG0", str);

    Array* ary = Array::create(state, argc - 1);
    int which_arg = 0;
    bool skip_xflags = true;

    for(int i=1; i < argc; i++) {
      char* arg = argv[i];

      if(strcmp(arg, "--") == 0) {
        skip_xflags = false;
      } else if(strncmp(arg, "-X", 2) == 0) {
        if(skip_xflags) continue;
      } else if(arg[1] != '-') {
        skip_xflags = false;
      }

      str = String::create(state, arg);
      str->taint(state);
      str->encoding(state, enc);
      ary->set(state, which_arg++, str);
    }

    state->vm()->set_const("ARGV", ary);

    // Now finish up with the config
    if(config.print_config > 1) {
      std::cout << "========= Configuration =========\n";
      config.print(true);
      std::cout << "=================================\n";
    } else if(config.print_config) {
      config.print();
    }

    if(config.agent_start > 0) {
      // if port_ is 1, the user wants to use a randomly assigned local
      // port which will be written to the temp file for console to pick
      // up.

      int port = config.agent_start;
      if(port == 1) port = 0;
      start_agent(port);
    }

    state->shared().set_use_capi_lock(config.capi_lock);
  }