Skip to content

Commit

Permalink
some work on string
Browse files Browse the repository at this point in the history
git-svn-id: http://svn.macosforge.org/repository/ruby/MacRuby/branches/icu@3581 23306eb0-4c56-4727-a40e-e92c0eb68959
  • Loading branch information
lrz committed Feb 20, 2010
1 parent 485aef2 commit 39b55f1
Show file tree
Hide file tree
Showing 6 changed files with 802 additions and 515 deletions.
12 changes: 5 additions & 7 deletions encoding.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,12 @@
* Copyright (C) 2000 Information-technology Promotion Agency, Japan
*/

#include "encoding.h"
#include <string.h>

#include "ruby.h"
#include "ruby/encoding.h"
#include "encoding.h"

VALUE rb_cEncoding;

static rb_encoding_t *default_internal = NULL;
Expand Down Expand Up @@ -241,9 +244,6 @@ Init_PreEncoding(void)
default_internal = rb_encodings[ENCODING_UTF8];
}

VALUE
mr_enc_s_is_compatible(VALUE klass, SEL sel, VALUE str1, VALUE str2);

void
Init_Encoding(void)
{
Expand All @@ -266,10 +266,8 @@ Init_Encoding(void)
rb_objc_define_method(CLASS_OF(rb_cEncoding), "aliases",
mr_enc_s_aliases, 0);
//rb_define_singleton_method(rb_cEncoding, "find", enc_find, 1);
// it's defined on Encoding, but it requires String's internals so it's
// defined with String
rb_objc_define_method(CLASS_OF(rb_cEncoding), "compatible?",
mr_enc_s_is_compatible, 2);
mr_enc_s_is_compatible, 2); // in string.c

//rb_define_method(rb_cEncoding, "_dump", enc_dump, -1);
//rb_define_singleton_method(rb_cEncoding, "_load", enc_load, 1);
Expand Down
16 changes: 14 additions & 2 deletions encoding.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
extern "C" {
#endif

#include "ruby.h"

#if defined(__cplusplus)
# include "unicode/unistr.h"
#else
Expand Down Expand Up @@ -84,6 +82,18 @@ rb_klass_is_rstr(VALUE klass)

#define IS_RSTR(x) (rb_klass_is_rstr(*(VALUE *)x))

static inline void
rstr_modify(VALUE str)
{
const long mask = RBASIC(str)->flags;
if ((mask & FL_FREEZE) == FL_FREEZE) {
rb_raise(rb_eRuntimeError, "can't modify frozen/immutable string");
}
if ((mask & FL_TAINT) == FL_TAINT && rb_safe_level() >= 4) {
rb_raise(rb_eSecurityError, "Insecure: can't modify string");
}
}

typedef struct {
long start_offset_in_bytes;
long end_offset_in_bytes;
Expand Down Expand Up @@ -276,6 +286,8 @@ void rb_str_get_uchars(VALUE str, UChar **chars_p, long *chars_len_p,
bool *need_free_p);
long rb_str_chars_len(VALUE str);

VALUE mr_enc_s_is_compatible(VALUE klass, SEL sel, VALUE str1, VALUE str2);

// Return a string object appropriate for bstr_ calls. This does nothing for
// data/binary RubyStrings.
VALUE rb_str_bstr(VALUE str);
Expand Down
52 changes: 31 additions & 21 deletions parse.y
Original file line number Diff line number Diff line change
Expand Up @@ -5067,36 +5067,34 @@ yycompile(struct parser_params *parser, const char *f, int line)
}
#endif /* !RIPPER */

struct lex_get_str_context {
VALUE str;
UChar *chars;
long chars_len;
};

static VALUE
lex_get_str(struct parser_params *parser, VALUE s)
{
long beg = 0, len;
const long n = CFStringGetLength((CFStringRef)s);
struct lex_get_str_context *ctx = (struct lex_get_str_context *)s;

long beg = 0;
if (lex_gets_ptr > 0) {
if (n == lex_gets_ptr) {
if (ctx->chars_len == lex_gets_ptr) {
return Qnil;
}
beg += lex_gets_ptr;
}

CFRange search_range;
if (CFStringFindCharacterFromSet((CFStringRef)s,
CFCharacterSetGetPredefined(kCFCharacterSetNewline),
CFRangeMake(beg, n - beg),
0,
&search_range)) {
lex_gets_ptr = search_range.location + 1;
len = search_range.location - beg;
}
else {
lex_gets_ptr = n;
len = lex_gets_ptr - beg;
lex_gets_ptr = ctx->chars_len;
for (long i = beg; i < ctx->chars_len; i++) {
if (ctx->chars[i] == '\n') {
lex_gets_ptr = i + 1;
break;
}
}

CFStringRef subs = CFStringCreateWithSubstring(NULL, (CFStringRef)s,
CFRangeMake(beg, lex_gets_ptr - beg));
CFMakeCollectable(subs);
return (VALUE)subs;
return rb_unicode_str_new(&ctx->chars[beg], lex_gets_ptr - beg);
}

static VALUE
Expand All @@ -5118,15 +5116,27 @@ rb_compile_string(const char *f, VALUE s, int line)
return rb_parser_compile_string(rb_parser_new(), f, s, line);
}

NODE*
NODE *
rb_parser_compile_string(VALUE vparser, const char *f, VALUE s, int line)
{
struct parser_params *parser;
Data_Get_Struct(vparser, struct parser_params, parser);

UChar *chars = NULL;
long chars_len = 0;
bool need_free = false;
rb_str_get_uchars(s, &chars, &chars_len, &need_free);
assert(!need_free);

struct lex_get_str_context *ctx = (struct lex_get_str_context *)
xmalloc(sizeof(struct lex_get_str_context));
GC_WB(&ctx->str, s);
ctx->chars = chars;
ctx->chars_len = chars_len;

lex_gets = lex_get_str;
lex_gets_ptr = 0;
GC_WB(&lex_input, s);
GC_WB(&lex_input, ctx);
lex_pbeg = lex_p = lex_pend = 0;
compile_for_eval = rb_parse_in_eval();

Expand Down
19 changes: 11 additions & 8 deletions ruby.c
Original file line number Diff line number Diff line change
Expand Up @@ -553,30 +553,33 @@ proc_options(int argc, char **argv, struct cmdline_options *opt)

case 'e':
forbid_setid("-e");
if (!*++s) {
if (*++s == '\0') {
s = argv[1];
argc--, argv++;
argc--;
argv++;
}
if (!s) {
if (s == NULL) {
rb_raise(rb_eRuntimeError, "no code specified for -e");
}
if (!opt->e_script) {
opt->e_script = rb_str_new(0, 0);
if (opt->script == 0)
if (opt->e_script == 0) {
opt->e_script = rb_str_new(NULL, 0);
if (opt->script == NULL) {
opt->script = "-e";
}
}
rb_str_cat2(opt->e_script, s);
rb_str_cat2(opt->e_script, "\n");
break;

case 'r':
forbid_setid("-r");
if (*++s) {
if (*++s != '\0') {
add_modules(s);
}
else if (argv[1]) {
add_modules(argv[1]);
argc--, argv++;
argc--;
argv++;
}
break;

Expand Down
Loading

0 comments on commit 39b55f1

Please sign in to comment.