Skip to content
This repository
Newer
Older
100644 842 lines (735 sloc) 16.772 kb
19f18d3b » Laurent Sansonetti
2010-02-25 a new Symbol class, unicode-aware + refactored/cleaned symbol generation
1 /*
2 * MacRuby Symbols.
3 *
4 * This file is covered by the Ruby license. See COPYING for more details.
5 *
95957256 » Laurent Sansonetti
2011-01-15 update copyrights to 2011
6 * Copyright (C) 2010-2011, Apple Inc. All rights reserved.
19f18d3b » Laurent Sansonetti
2010-02-25 a new Symbol class, unicode-aware + refactored/cleaned symbol generation
7 */
8
9 #include <wctype.h>
10
d0898dd2 » Laurent Sansonetti
2011-01-08 include/ruby/macruby.h -> macruby_internal.h
11 #include "macruby_internal.h"
19f18d3b » Laurent Sansonetti
2010-02-25 a new Symbol class, unicode-aware + refactored/cleaned symbol generation
12 #include "ruby/encoding.h"
13 #include "encoding.h"
14 #include "symbol.h"
15 #include "ruby/node.h"
16 #include "vm.h"
b3f59324 » Laurent Sansonetti
2010-02-28 added NSString primitives to Symbol
17 #include "objc.h"
19f18d3b » Laurent Sansonetti
2010-02-25 a new Symbol class, unicode-aware + refactored/cleaned symbol generation
18
19 VALUE rb_cSymbol;
20
21 static CFMutableDictionaryRef sym_id = NULL, id_str = NULL;
22 static long last_id = 0;
23
24 typedef struct {
25 VALUE klass;
41240b43 » Laurent Sansonetti
2010-02-27 misc fixes
26 VALUE str;
19f18d3b » Laurent Sansonetti
2010-02-25 a new Symbol class, unicode-aware + refactored/cleaned symbol generation
27 ID id;
28 } rb_sym_t;
29
30 #define RSYM(obj) ((rb_sym_t *)(obj))
31
32 static rb_sym_t *
41240b43 » Laurent Sansonetti
2010-02-27 misc fixes
33 sym_alloc(VALUE str, ID id)
19f18d3b » Laurent Sansonetti
2010-02-25 a new Symbol class, unicode-aware + refactored/cleaned symbol generation
34 {
171f9c2a » Laurent Sansonetti
2010-05-11 create symbols from the auto zone, allowing associative references to…
35 rb_sym_t *sym = (rb_sym_t *)xmalloc(sizeof(rb_sym_t));
19f18d3b » Laurent Sansonetti
2010-02-25 a new Symbol class, unicode-aware + refactored/cleaned symbol generation
36 assert(rb_cSymbol != 0);
37 sym->klass = rb_cSymbol;
171f9c2a » Laurent Sansonetti
2010-05-11 create symbols from the auto zone, allowing associative references to…
38 GC_WB(&sym->str, str);
19f18d3b » Laurent Sansonetti
2010-02-25 a new Symbol class, unicode-aware + refactored/cleaned symbol generation
39 sym->id = id;
40 return sym;
41 }
42
14920942 » Laurent Sansonetti
2010-03-05 better detect if symbols are printable
43 static bool
44 is_identchar(UChar c)
45 {
46 return isalnum(c) || c == '_' || !isascii(c);
47 }
48
19f18d3b » Laurent Sansonetti
2010-02-25 a new Symbol class, unicode-aware + refactored/cleaned symbol generation
49 ID
50 rb_intern_str(VALUE str)
51 {
d1673a26 » Laurent Sansonetti
2011-01-05 introduce a better unichar API, which should be as fast as before the…
52 RB_STR_GET_UCHARS(str, chars, chars_len);
b37c99d0 » Laurent Sansonetti
2010-03-05 better symbols sanitization
53
94e3ea5e » Laurent Sansonetti
2011-01-04 avoid grabbing the uchar buffer twice
54 const unsigned long name_hash = rb_str_hash_uchars(chars, chars_len);
55 ID id = (ID)CFDictionaryGetValue(sym_id, (const void *)name_hash);
56 if (id != 0) {
57 goto return_id;
58 }
59
60 rb_sym_t *sym = NULL;
b37c99d0 » Laurent Sansonetti
2010-03-05 better symbols sanitization
61 long pos = 0;
4ee0afb8 » Laurent Sansonetti
2010-02-26 some misc fixes/cleanup
62 if (chars_len > 0) {
b37c99d0 » Laurent Sansonetti
2010-03-05 better symbols sanitization
63 UChar c = chars[0];
4ee0afb8 » Laurent Sansonetti
2010-02-26 some misc fixes/cleanup
64 switch (c) {
65 case '$':
66 id = ID_GLOBAL;
b37c99d0 » Laurent Sansonetti
2010-03-05 better symbols sanitization
67 goto new_id;
4ee0afb8 » Laurent Sansonetti
2010-02-26 some misc fixes/cleanup
68
69 case '@':
b37c99d0 » Laurent Sansonetti
2010-03-05 better symbols sanitization
70 if (chars_len > 1 && chars[1] == '@') {
71 pos++;
4ee0afb8 » Laurent Sansonetti
2010-02-26 some misc fixes/cleanup
72 id = ID_CLASS;
19f18d3b » Laurent Sansonetti
2010-02-25 a new Symbol class, unicode-aware + refactored/cleaned symbol generation
73 }
4ee0afb8 » Laurent Sansonetti
2010-02-26 some misc fixes/cleanup
74 else {
75 id = ID_INSTANCE;
76 }
b37c99d0 » Laurent Sansonetti
2010-03-05 better symbols sanitization
77 pos++;
4ee0afb8 » Laurent Sansonetti
2010-02-26 some misc fixes/cleanup
78 break;
79
80 default:
b37c99d0 » Laurent Sansonetti
2010-03-05 better symbols sanitization
81 if (chars_len > 1 && chars[chars_len - 1] == '=') {
4ee0afb8 » Laurent Sansonetti
2010-02-26 some misc fixes/cleanup
82 // Attribute assignment.
83 id = rb_intern_str(rb_str_substr(str, 0, chars_len - 1));
84 if (!is_attrset_id(id)) {
85 id = rb_id_attrset(id);
86 goto id_register;
87 }
88 id = ID_ATTRSET;
89 }
90 else if (iswupper(c)) {
91 id = ID_CONST;
92 }
93 else {
94 id = ID_LOCAL;
95 }
96 break;
97 }
19f18d3b » Laurent Sansonetti
2010-02-25 a new Symbol class, unicode-aware + refactored/cleaned symbol generation
98 }
99
b37c99d0 » Laurent Sansonetti
2010-03-05 better symbols sanitization
100 if (pos < chars_len && !isdigit(chars[pos])) {
101 for (; pos < chars_len; pos++) {
14920942 » Laurent Sansonetti
2010-03-05 better detect if symbols are printable
102 if (!is_identchar(chars[pos])) {
103 break;
b37c99d0 » Laurent Sansonetti
2010-03-05 better symbols sanitization
104 }
105 }
106 }
107 if (pos < chars_len) {
108 id = ID_JUNK;
109 }
110
111 new_id:
19f18d3b » Laurent Sansonetti
2010-02-25 a new Symbol class, unicode-aware + refactored/cleaned symbol generation
112 id |= ++last_id << ID_SCOPE_SHIFT;
113
114 id_register:
115 //printf("register %s hash %ld id %ld\n", RSTRING_PTR(str), name_hash, id);
41240b43 » Laurent Sansonetti
2010-02-27 misc fixes
116 sym = sym_alloc(str, id);
19f18d3b » Laurent Sansonetti
2010-02-25 a new Symbol class, unicode-aware + refactored/cleaned symbol generation
117 CFDictionarySetValue(sym_id, (const void *)name_hash, (const void *)id);
118 CFDictionarySetValue(id_str, (const void *)id, (const void *)sym);
119
94e3ea5e » Laurent Sansonetti
2011-01-04 avoid grabbing the uchar buffer twice
120 return_id:
19f18d3b » Laurent Sansonetti
2010-02-25 a new Symbol class, unicode-aware + refactored/cleaned symbol generation
121 return id;
122 }
123
124 VALUE
125 rb_id2str(ID id)
126 {
127 VALUE sym = (VALUE)CFDictionaryGetValue(id_str, (const void *)id);
128 if (sym != 0) {
129 //printf("lookup %ld -> %s\n", id, rb_sym2name(sym));
130 return sym;
131 }
132
133 if (is_attrset_id(id)) {
134 // Attribute assignment.
135 ID id2 = (id & ~ID_SCOPE_MASK) | ID_LOCAL;
136
137 while ((sym = rb_id2str(id2)) == 0) {
138 if (!is_local_id(id2)) {
139 //printf("lookup %ld -> FAIL\n", id);
140 return 0;
141 }
142 id2 = (id & ~ID_SCOPE_MASK) | ID_CONST;
143 }
144
41240b43 » Laurent Sansonetti
2010-02-27 misc fixes
145 VALUE str = rb_str_dup(RSYM(sym)->str);
19f18d3b » Laurent Sansonetti
2010-02-25 a new Symbol class, unicode-aware + refactored/cleaned symbol generation
146 rb_str_cat(str, "=", 1);
147 rb_intern_str(str);
148
149 // Retry one more time.
150 sym = (VALUE)CFDictionaryGetValue(id_str, (const void *)id);
151 if (sym != 0) {
152 //printf("lookup %ld -> %s\n", id, rb_sym2name(sym));
153 return sym;
154 }
155 }
156 //printf("lookup %ld -> FAIL\n", id);
157 return 0;
158 }
159
160 ID
161 rb_intern3(const char *name, long len, rb_encoding *enc)
162 {
163 VALUE str = rb_enc_str_new(name, len, enc);
164 return rb_intern_str(str);
165 }
166
167 ID
168 rb_intern2(const char *name, long len)
169 {
170 return rb_intern_str(rb_str_new(name, len));
171 }
172
173 ID
174 rb_intern(const char *name)
175 {
176 return rb_intern_str(rb_str_new2(name));
177 }
178
179 ID
180 rb_sym2id(VALUE sym)
181 {
182 return RSYM(sym)->id;
183 }
184
185 VALUE
186 rb_name2sym(const char *name)
187 {
188 return rb_id2str(rb_intern(name));
189 }
190
191 VALUE
192 rb_sym_to_s(VALUE sym)
193 {
41240b43 » Laurent Sansonetti
2010-02-27 misc fixes
194 return rb_str_dup(RSYM(sym)->str);
19f18d3b » Laurent Sansonetti
2010-02-25 a new Symbol class, unicode-aware + refactored/cleaned symbol generation
195 }
196
197 const char *
198 rb_sym2name(VALUE sym)
199 {
200 return RSTRING_PTR(RSYM(sym)->str);
201 }
202
203 /*
204 * call-seq:
205 * Symbol.all_symbols => array
206 *
207 * Returns an array of all the symbols currently in Ruby's symbol
208 * table.
209 *
210 * Symbol.all_symbols.size #=> 903
211 * Symbol.all_symbols[1,20] #=> [:floor, :ARGV, :Binding, :symlink,
212 * :chown, :EOFError, :$;, :String,
213 * :LOCK_SH, :"setuid?", :$<,
214 * :default_proc, :compact, :extend,
215 * :Tms, :getwd, :$=, :ThreadGroup,
216 * :wait2, :$>]
217 */
218
219 static VALUE
220 rsym_all_symbols(VALUE klass, SEL sel)
221 {
222 VALUE ary = rb_ary_new();
223 const long count = CFDictionaryGetCount(id_str);
224 if (count >= 0) {
225 const void **values = (const void **)malloc(sizeof(void *) * count);
226 CFDictionaryGetKeysAndValues(id_str, NULL, values);
227 for (long i = 0; i < count; i++) {
228 rb_ary_push(ary, (VALUE)values[i]);
229 }
230 free(values);
231 }
232 return ary;
233 }
234
e68823cd » Laurent Sansonetti
2010-06-19 trim the parser and command-line parsing from static
235 #if MACRUBY_STATIC
236 struct rb_op_tbl_entry rb_op_tbl[] = {
237 {'+', "+"},
238 {'-', "-"},
239 {'*', "*"},
240 {'/', "/"},
241 {'%', "%"},
242 {'|', "|"},
243 {'^', "^"},
244 {'&', "&"},
245 {'!', "!"},
246 {'>', ">"},
247 {'<', "<"},
248 {'~', "~"},
249 {'!', "!"},
250 {'`', "`"},
251 {334, ".."},
252 {335, "..."},
253 {323, "**"},
254 {321, "+@"},
255 {322, "-@"},
256 {324, "<=>"},
257 {328, ">="},
258 {329, "<="},
259 {325, "=="},
260 {326, "==="},
261 {327, "!="},
262 {332, "=~"},
263 {333, "!~"},
264 {336, "[]"},
265 {337, "[]="},
266 {338, "<<"},
267 {339, ">>"},
268 {340, "::"},
269 {0, NULL}
270 };
271 #endif
272
19f18d3b » Laurent Sansonetti
2010-02-25 a new Symbol class, unicode-aware + refactored/cleaned symbol generation
273 void
274 Init_PreSymbol(void)
275 {
276 sym_id = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
171f9c2a » Laurent Sansonetti
2010-05-11 create symbols from the auto zone, allowing associative references to…
277 id_str = CFDictionaryCreateMutable(NULL, 0, NULL,
278 &kCFTypeDictionaryValueCallBacks);
19f18d3b » Laurent Sansonetti
2010-02-25 a new Symbol class, unicode-aware + refactored/cleaned symbol generation
279 last_id = 1000;
280
281 // Pre-register parser symbols.
282 for (int i = 0; rb_op_tbl[i].token != 0; i++) {
283 ID id = rb_op_tbl[i].token;
4ee0afb8 » Laurent Sansonetti
2010-02-26 some misc fixes/cleanup
284 VALUE str = rb_str_new2(rb_op_tbl[i].name);
41240b43 » Laurent Sansonetti
2010-02-27 misc fixes
285 rb_sym_t *sym = sym_alloc(str, id);
4ee0afb8 » Laurent Sansonetti
2010-02-26 some misc fixes/cleanup
286 unsigned long name_hash = rb_str_hash(str);
19f18d3b » Laurent Sansonetti
2010-02-25 a new Symbol class, unicode-aware + refactored/cleaned symbol generation
287
288 //printf("pre-register %s hash %ld id %ld\n", RSTRING_PTR(str), name_hash, id);
289
290 CFDictionarySetValue(sym_id, (const void *)name_hash, (const void *)id);
291 CFDictionarySetValue(id_str, (const void *)id, (const void *)sym);
292 }
293 }
294
295 /*
3d2b5582 » Laurent Sansonetti
2010-03-02 added Symbol#<=>, fixed some bugs in String#<=>
296 * call-seq:
297 *
298 * str <=> other => -1, 0, +1 or nil
299 *
300 * Compares _sym_ with _other_ in string form.
301 */
302
303 static VALUE
304 rsym_cmp(VALUE sym, SEL sel, VALUE other)
305 {
306 if (TYPE(other) != T_SYMBOL) {
307 return Qnil;
308 }
309 return INT2FIX(rb_str_cmp(RSYM(sym)->str, RSYM(other)->str));
310 }
311
312 /*
ac2e5f60 » Laurent Sansonetti
2010-03-04 added Symbol#casecmp, fixed a bug in String#casecmp
313 * call-seq:
314 *
315 * sym.casecmp(other) => -1, 0, +1 or nil
316 *
317 * Case-insensitive version of <code>Symbol#<=></code>.
318 */
319
320 static VALUE
321 rsym_casecmp(VALUE sym, SEL sel, VALUE other)
322 {
323 if (TYPE(other) != T_SYMBOL) {
324 return Qnil;
325 }
326 return INT2FIX(rb_str_casecmp(RSYM(sym)->str, RSYM(other)->str));
327 }
328
329 /*
19f18d3b » Laurent Sansonetti
2010-02-25 a new Symbol class, unicode-aware + refactored/cleaned symbol generation
330 * call-seq:
331 * sym == obj => true or false
332 *
333 * Equality---If <i>sym</i> and <i>obj</i> are exactly the same
334 * symbol, returns <code>true</code>. Otherwise, compares them
335 * as strings.
336 */
337
338 static VALUE
339 rsym_equal(VALUE sym, SEL sel, VALUE other)
340 {
341 return sym == other ? Qtrue : Qfalse;
342 }
343
344 /*
345 * call-seq:
346 * sym.inspect => string
347 *
348 * Returns the representation of <i>sym</i> as a symbol literal.
349 *
350 * :fred.inspect #=> ":fred"
351 */
352
41240b43 » Laurent Sansonetti
2010-02-27 misc fixes
353 static bool
14920942 » Laurent Sansonetti
2010-03-05 better detect if symbols are printable
354 is_special_global_name(UChar *ptr, long len)
355 {
356 if (len <= 0) {
357 return false;
358 }
359
360 long pos = 0;
361 switch (ptr[pos]) {
362 case '~': case '*': case '$': case '?': case '!':
363 case '@': case '/': case '\\': case ';': case ',':
364 case '.': case '=': case ':': case '<': case '>':
365 case '\"': case '&': case '`': case '\'': case '+': case '0':
366 pos++;
367 break;
368
369 case '-':
370 pos++;
371 if (pos < len && is_identchar(ptr[pos])) {
372 pos++;
373 }
374 break;
375
376 default:
377 if (!isdigit(ptr[pos])) {
378 return false;
379 }
380 do {
381 pos++;
382 }
383 while (pos < len && isdigit(ptr[pos]));
384 break;
385 }
386 return pos == len;
387 }
388
389 static bool
41240b43 » Laurent Sansonetti
2010-02-27 misc fixes
390 sym_should_be_escaped(VALUE sym)
391 {
d1673a26 » Laurent Sansonetti
2011-01-05 introduce a better unichar API, which should be as fast as before the…
392 RB_STR_GET_UCHARS(RSYM(sym)->str, chars, chars_len);
41240b43 » Laurent Sansonetti
2010-02-27 misc fixes
393
14920942 » Laurent Sansonetti
2010-03-05 better detect if symbols are printable
394 if (chars_len == 0) {
395 return true;
396 }
397
41240b43 » Laurent Sansonetti
2010-02-27 misc fixes
398 bool escape = false;
399 for (long i = 0; i < chars_len; i++) {
14920942 » Laurent Sansonetti
2010-03-05 better detect if symbols are printable
400 if (!isprint(chars[i])) {
41240b43 » Laurent Sansonetti
2010-02-27 misc fixes
401 escape = true;
402 break;
403 }
404 }
405
14920942 » Laurent Sansonetti
2010-03-05 better detect if symbols are printable
406 if (escape) {
407 goto bail;
408 }
409
410 long pos = 0;
411 bool localid = false;
412
413 switch (chars[pos]) {
414 case '\0':
415 escape = true;
416 break;
417
418 case '$':
419 pos++;
420 if (pos < chars_len && is_special_global_name(&chars[pos],
421 chars_len - pos)) {
422 goto bail;
423 }
424 goto id;
425
426 case '@':
427 pos++;
428 if (pos < chars_len && chars[pos] == '@') {
429 pos++;
430 }
431 goto id;
432
433 case '<':
434 pos++;
435 if (pos < chars_len) {
436 if (chars[pos] == '<') {
437 pos++;
438 }
439 else if (chars[pos] == '=') {
440 pos++;
441 if (pos < chars_len && chars[pos] == '>') {
442 pos++;
443 }
444 }
445 }
446 break;
447
448 case '>':
449 pos++;
450 if (pos < chars_len) {
451 if (chars[pos] == '>' || chars[pos] == '=') {
452 pos++;
453 }
454 }
455 break;
456
457 case '=':
458 pos++;
459 if (pos == chars_len) {
460 escape = true;
461 goto bail;
462 }
463 else {
464 if (chars[pos] == '~') {
465 pos++;
466 }
467 else if (chars[pos] == '=') {
468 pos++;
469 if (pos < chars_len && chars[pos] == '=') {
470 pos++;
471 }
472 }
473 else {
474 escape = true;
475 goto bail;
476 }
477 }
478 break;
479
480 case '*':
481 pos++;
482 if (pos < chars_len && chars[pos] == '*') {
483 pos++;
484 }
485 break;
486
487 case '+':
488 case '-':
489 pos++;
490 if (pos < chars_len && chars[pos] == '@') {
491 pos++;
492 }
493 break;
494
495 case '|': case '^': case '&': case '/':
496 case '%': case '~': case '`':
497 pos++;
498 break;
499
500 case '[':
501 pos++;
502 if (pos < chars_len && chars[pos] != ']') {
503 escape = true;
504 goto bail;
505 }
506 pos++;
507 if (pos < chars_len && chars[pos] == '=') {
508 pos++;
509 }
510 break;
511
512 case '!':
513 pos++;
514 if (pos == chars_len) {
515 goto bail;
516 }
517 else {
518 if (chars[pos] == '=' || chars[pos] == '~') {
519 pos++;
520 }
521 else {
522 escape = true;
523 goto bail;
524 }
525 }
526 break;
527
528 default:
529 localid = !isupper(chars[pos]);
530 // fall through
531
532 id:
533 if (pos >= chars_len
534 || (chars[pos] != '_' && !isalpha(chars[pos])
535 && isascii(chars[pos]))) {
536 escape = true;
537 goto bail;
538 }
539 while (pos < chars_len && is_identchar(chars[pos])) {
540 pos++;
541 }
542 if (localid) {
543 if (pos < chars_len
544 && (chars[pos] == '!' || chars[pos] == '?'
545 || chars[pos] == '=')) {
546 pos++;
547 }
548 }
549 break;
550 }
551
552 if (pos < chars_len) {
553 escape = true;
554 }
555
556 bail:
41240b43 » Laurent Sansonetti
2010-02-27 misc fixes
557 return escape;
558 }
559
19f18d3b » Laurent Sansonetti
2010-02-25 a new Symbol class, unicode-aware + refactored/cleaned symbol generation
560 static VALUE
561 rsym_inspect(VALUE sym, SEL sel)
562 {
563 VALUE str = rb_str_new2(":");
41240b43 » Laurent Sansonetti
2010-02-27 misc fixes
564 if (sym_should_be_escaped(sym)) {
565 rb_str_concat(str, rb_str_inspect(RSYM(sym)->str));
566 }
567 else {
568 rb_str_concat(str, RSYM(sym)->str);
569 }
19f18d3b » Laurent Sansonetti
2010-02-25 a new Symbol class, unicode-aware + refactored/cleaned symbol generation
570 return str;
571 }
572
573 /*
574 * call-seq:
575 * sym.to_proc
576 *
577 * Returns a _Proc_ object which respond to the given method by _sym_.
578 *
579 * (1..3).collect(&:to_s) #=> ["1", "2", "3"]
580 */
581
582 static VALUE
583 rsym_to_proc(VALUE sym, SEL sel)
584 {
dfec2d3e » Laurent Sansonetti
2010-05-08 Symbol#to_proc now generates a Proc that can accept a variable number…
585 ID mid = SYM2ID(sym);
586 rb_vm_block_t *b = rb_vm_create_block_calling_mid(mid);
19f18d3b » Laurent Sansonetti
2010-02-25 a new Symbol class, unicode-aware + refactored/cleaned symbol generation
587 return rb_proc_alloc_with_block(rb_cProc, b);
588 }
589
590 /*
591 * call-seq:
592 * sym.id2name => string
593 * sym.to_s => string
594 *
595 * Returns the name or string corresponding to <i>sym</i>.
596 *
597 * :fred.id2name #=> "fred"
598 */
599
600 static VALUE
601 rsym_to_s(VALUE sym, SEL sel)
602 {
603 return rb_sym_to_s(sym);
604 }
605
606 /*
607 * call-seq:
608 * sym.to_sym => sym
609 * sym.intern => sym
610 *
611 * In general, <code>to_sym</code> returns the <code>Symbol</code>
612 * corresponding to an object. As <i>sym</i> is already a symbol,
613 * <code>self</code> is returned in this case.
614 */
615
616 static VALUE
617 rsym_to_sym(VALUE sym, SEL sel)
618 {
619 return sym;
620 }
621
f5017871 » Laurent Sansonetti
2010-03-03 added #empty?
622 /*
623 * call-seq:
624 * sym.empty? => true or false
625 *
626 * Returns that _sym_ is :"" or not.
627 */
628
629 static VALUE
630 rsym_empty(VALUE sym, SEL sel)
631 {
632 return rb_str_chars_len(RSYM(sym)->str) == 0 ? Qtrue : Qfalse;
633 }
634
d13c0441 » Laurent Sansonetti
2010-03-12 added Symbol#[]
635 /*
636 * call-seq:
637 * sym[idx] => char
638 * sym[b, n] => char
639 *
640 * Returns <code>sym.to_s[]</code>.
641 */
642
643 static VALUE
644 rsym_aref(VALUE sym, SEL sel, int argc, VALUE *argv)
645 {
646 return rstr_aref(RSYM(sym)->str, sel, argc, argv);
647 }
648
af1c6516 » Laurent Sansonetti
2010-03-20 added Symbol #upcase, #downcase, #swapcase, #capitalize
649 /*
650 * call-seq:
651 * sym.upcase => symbol
652 *
653 * Same as <code>sym.to_s.upcase.intern</code>.
654 */
655
656 static VALUE
657 rsym_upcase(VALUE sym, SEL sel)
658 {
659 return ID2SYM(rb_intern_str(rstr_upcase(RSYM(sym)->str, sel)));
660 }
661
662 /*
663 * call-seq:
664 * sym.downcase => symbol
665 *
666 * Same as <code>sym.to_s.downcase.intern</code>.
667 */
668
669 static VALUE
670 rsym_downcase(VALUE sym, SEL sel)
671 {
672 return ID2SYM(rb_intern_str(rstr_downcase(RSYM(sym)->str, sel)));
673 }
674
675 /*
676 * call-seq:
677 * sym.capitalize => symbol
678 *
679 * Same as <code>sym.to_s.capitalize.intern</code>.
680 */
681
682 static VALUE
683 rsym_capitalize(VALUE sym, SEL sel)
684 {
685 return ID2SYM(rb_intern_str(rstr_capitalize(RSYM(sym)->str, sel)));
686 }
687
688 /*
689 * call-seq:
690 * sym.swapcase => symbol
691 *
692 * Same as <code>sym.to_s.swapcase.intern</code>.
693 */
694
695 static VALUE
696 rsym_swapcase(VALUE sym, SEL sel)
697 {
698 return ID2SYM(rb_intern_str(rstr_swapcase(RSYM(sym)->str, sel)));
699 }
700
a8bd277f » Thibault Martin-Lagardette
2010-03-25 Make Symbol NSCoding compliant
701 // Cocoa primitives
702
703 static void *
704 rsym_imp_copy(void *rcv, SEL sel)
705 {
706 return rcv;
707 }
708
b3f59324 » Laurent Sansonetti
2010-02-28 added NSString primitives to Symbol
709 static CFIndex
710 rsym_imp_length(void *rcv, SEL sel)
711 {
712 return CFStringGetLength((CFStringRef)RSYM(rcv)->str);
713 }
714
715 static UniChar
716 rsym_imp_characterAtIndex(void *rcv, SEL sel, CFIndex idx)
717 {
718 return CFStringGetCharacterAtIndex((CFStringRef)RSYM(rcv)->str, idx);
719 }
720
a8bd277f » Thibault Martin-Lagardette
2010-03-25 Make Symbol NSCoding compliant
721 #define RSYM_NSCODER_KEY "MRSymbolStr"
722
723 static void
724 rsym_imp_encodeWithCoder(void *rcv, SEL sel, void *coder)
725 {
726 rb_str_NSCoder_encode(coder, RSYM(rcv)->str, RSYM_NSCODER_KEY);
727 }
728
729 static VALUE
730 rsym_imp_initWithCoder(void *rcv, SEL sel, void *coder)
731 {
732 return ID2SYM(rb_intern_str(rb_str_NSCoder_decode(coder, RSYM_NSCODER_KEY)));
733 }
734
735 static Class
736 rsym_imp_classForKeyedArchiver(void *rcv, SEL sel)
737 {
738 return (Class)rb_cSymbol;
739 }
740
19f18d3b » Laurent Sansonetti
2010-02-25 a new Symbol class, unicode-aware + refactored/cleaned symbol generation
741 void
742 Init_Symbol(void)
743 {
744 // rb_cSymbol is defined earlier in Init_PreVM().
745 rb_set_class_path(rb_cSymbol, rb_cObject, "Symbol");
746 rb_const_set(rb_cObject, rb_intern("Symbol"), rb_cSymbol);
747
748 rb_undef_alloc_func(rb_cSymbol);
749 rb_undef_method(*(VALUE *)rb_cSymbol, "new");
750 rb_objc_define_method(*(VALUE *)rb_cSymbol, "all_symbols",
751 rsym_all_symbols, 0);
752
98864a55 » Laurent Sansonetti
2010-03-24 Symbol must not respond to #to_i and #to_f
753 // Undefine methods defined on NSString.
754 rb_undef_method(rb_cSymbol, "to_i");
755 rb_undef_method(rb_cSymbol, "to_f");
e48fb267 » Watson1978
2010-12-02 will not have the Symbol#to_str.
756 rb_undef_method(rb_cSymbol, "to_str");
98864a55 » Laurent Sansonetti
2010-03-24 Symbol must not respond to #to_i and #to_f
757
19f18d3b » Laurent Sansonetti
2010-02-25 a new Symbol class, unicode-aware + refactored/cleaned symbol generation
758 rb_objc_define_method(rb_cSymbol, "==", rsym_equal, 1);
3d2b5582 » Laurent Sansonetti
2010-03-02 added Symbol#<=>, fixed some bugs in String#<=>
759 rb_objc_define_method(rb_cSymbol, "<=>", rsym_cmp, 1);
ac2e5f60 » Laurent Sansonetti
2010-03-04 added Symbol#casecmp, fixed a bug in String#casecmp
760 rb_objc_define_method(rb_cSymbol, "casecmp", rsym_casecmp, 1);
19f18d3b » Laurent Sansonetti
2010-02-25 a new Symbol class, unicode-aware + refactored/cleaned symbol generation
761 rb_objc_define_method(rb_cSymbol, "eql?", rsym_equal, 1);
762 rb_objc_define_method(rb_cSymbol, "inspect", rsym_inspect, 0);
763 rb_objc_define_method(rb_cSymbol, "to_proc", rsym_to_proc, 0);
764 rb_objc_define_method(rb_cSymbol, "to_s", rsym_to_s, 0);
765 rb_objc_define_method(rb_cSymbol, "id2name", rsym_to_s, 0);
766 rb_objc_define_method(rb_cSymbol, "description", rsym_to_s, 0);
767 rb_objc_define_method(rb_cSymbol, "intern", rsym_to_sym, 0);
768 rb_objc_define_method(rb_cSymbol, "to_sym", rsym_to_sym, 0);
f5017871 » Laurent Sansonetti
2010-03-03 added #empty?
769 rb_objc_define_method(rb_cSymbol, "empty?", rsym_empty, 0);
d13c0441 » Laurent Sansonetti
2010-03-12 added Symbol#[]
770 rb_objc_define_method(rb_cSymbol, "[]", rsym_aref, -1);
af1c6516 » Laurent Sansonetti
2010-03-20 added Symbol #upcase, #downcase, #swapcase, #capitalize
771 rb_objc_define_method(rb_cSymbol, "upcase", rsym_upcase, 0);
772 rb_objc_define_method(rb_cSymbol, "downcase", rsym_downcase, 0);
773 rb_objc_define_method(rb_cSymbol, "swapcase", rsym_swapcase, 0);
774 rb_objc_define_method(rb_cSymbol, "capitalize", rsym_capitalize, 0);
b3f59324 » Laurent Sansonetti
2010-02-28 added NSString primitives to Symbol
775
776 // Cocoa primitives.
a8bd277f » Thibault Martin-Lagardette
2010-03-25 Make Symbol NSCoding compliant
777 rb_objc_install_method2((Class)rb_cSymbol, "copy",
778 (IMP)rsym_imp_copy);
b3f59324 » Laurent Sansonetti
2010-02-28 added NSString primitives to Symbol
779 rb_objc_install_method2((Class)rb_cSymbol, "length",
780 (IMP)rsym_imp_length);
781 rb_objc_install_method2((Class)rb_cSymbol, "characterAtIndex:",
782 (IMP)rsym_imp_characterAtIndex);
a8bd277f » Thibault Martin-Lagardette
2010-03-25 Make Symbol NSCoding compliant
783 rb_objc_install_method2((Class)rb_cSymbol, "encodeWithCoder:",
784 (IMP)rsym_imp_encodeWithCoder);
785 rb_objc_install_method2((Class)rb_cSymbol, "initWithCoder:",
786 (IMP)rsym_imp_initWithCoder);
787 rb_objc_install_method2((Class)rb_cSymbol, "classForKeyedArchiver",
788 (IMP)rsym_imp_classForKeyedArchiver);
19f18d3b » Laurent Sansonetti
2010-02-25 a new Symbol class, unicode-aware + refactored/cleaned symbol generation
789 }
e68823cd » Laurent Sansonetti
2010-06-19 trim the parser and command-line parsing from static
790
791 int
792 rb_is_const_id(ID id)
793 {
794 return is_const_id(id) ? Qtrue : Qfalse;
795 }
796
797 int
798 rb_is_class_id(ID id)
799 {
800 return is_class_id(id) ? Qtrue : Qfalse;
801 }
802
803 int
804 rb_is_instance_id(ID id)
805 {
806 return is_instance_id(id) ? Qtrue : Qfalse;
807 }
808
809 int
810 rb_is_local_id(ID id)
811 {
812 return is_local_id(id) ? Qtrue : Qfalse;
813 }
814
815 int
816 rb_is_junk_id(ID id)
817 {
818 return is_junk_id(id) ? Qtrue : Qfalse;
819 }
820
821 ID
822 rb_id_attrset(ID id)
823 {
824 id &= ~ID_SCOPE_MASK;
825 id |= ID_ATTRSET;
826 return id;
827 }
f7384831 » Laurent Sansonetti
2010-08-03 honor the original string encoding when generating substrings out of …
828
829 VALUE
830 rb_sym_str(VALUE sym)
831 {
832 return RSYM(sym)->str;
833 }
00b147f0 » Laurent Sansonetti
2010-09-29 add basic support for __method__ and __callee__
834
835 VALUE
836 rb_sel_to_sym(SEL sel)
837 {
838 if (sel == 0) {
839 return Qnil;
840 }
841 return ID2SYM(rb_intern(sel_getName(sel)));
842 }
Something went wrong with that request. Please try again.