Ruby: encoding.c Source File

Ruby 3.2.5p208 (2024-07-26 revision 31d0f1a2e7dbfb60731d1f05b868e1d578cda493)

encoding.c
1/**********************************************************************
2
3 encoding.c -
4
5 $Author$
6 created at: Thu May 24 17:23:27 JST 2007
7
8 Copyright (C) 2007 Yukihiro Matsumoto
9
10**********************************************************************/
11
12#include "ruby/internal/config.h"
13
14#include <ctype.h>
15
16#include "encindex.h"
17#include "internal.h"
18#include "internal/enc.h"
19#include "internal/encoding.h"
20#include "internal/error.h"
21#include "internal/inits.h"
22#include "internal/load.h"
23#include "internal/object.h"
24#include "internal/string.h"
25#include "internal/vm.h"
26#include "regenc.h"
27#include "ruby/encoding.h"
28#include "ruby/util.h"
29#include "ruby_assert.h"
30#include "vm_sync.h"
31
32#ifndef ENC_DEBUG
33#define ENC_DEBUG 0
34#endif
35#define ENC_ASSERT(expr) RUBY_ASSERT_WHEN(ENC_DEBUG, expr)
36#define MUST_STRING(str) (ENC_ASSERT(RB_TYPE_P(str, T_STRING)), str)
37
38#undef rb_ascii8bit_encindex
39#undef rb_utf8_encindex
40#undef rb_usascii_encindex
41
42typedef OnigEncodingType rb_raw_encoding;
43
44#if defined __GNUC__ && __GNUC__ >= 4
45#pragma GCC visibility push(default)
46int rb_enc_register(const char *name, rb_encoding *encoding);
47void rb_enc_set_base(const char *name, const char *orig);
48int rb_enc_set_dummy(int index);
49void rb_encdb_declare(const char *name);
50int rb_encdb_replicate(const char *name, const char *orig);
51int rb_encdb_dummy(const char *name);
52int rb_encdb_alias(const char *alias, const char *orig);
53#pragma GCC visibility pop
54#endif
55
56static ID id_encoding;
57 VALUE rb_cEncoding;
58
59#define ENCODING_LIST_CAPA 256
60static VALUE rb_encoding_list;
61
62 struct rb_encoding_entry {
63 const char *name;
64 rb_encoding *enc;
65 rb_encoding *base;
66};
67
68 static struct enc_table {
69 struct rb_encoding_entry list[ENCODING_LIST_CAPA];
70 int count;
71 st_table *names;
72} global_enc_table;
73
74static rb_encoding *global_enc_ascii,
75 *global_enc_utf_8,
76 *global_enc_us_ascii;
77
78#define GLOBAL_ENC_TABLE_ENTER(enc_table) struct enc_table *enc_table = &global_enc_table; RB_VM_LOCK_ENTER()
79#define GLOBAL_ENC_TABLE_LEAVE() RB_VM_LOCK_LEAVE()
80#define GLOBAL_ENC_TABLE_EVAL(enc_table, expr) do { \
81 GLOBAL_ENC_TABLE_ENTER(enc_table); \
82 { \
83 expr; \
84 } \
85 GLOBAL_ENC_TABLE_LEAVE(); \
86} while (0)
87
88
89#define ENC_DUMMY_FLAG (1<<24)
90#define ENC_INDEX_MASK (~(~0U<<24))
91
92#define ENC_TO_ENCINDEX(enc) (int)((enc)->ruby_encoding_index & ENC_INDEX_MASK)
93#define ENC_DUMMY_P(enc) ((enc)->ruby_encoding_index & ENC_DUMMY_FLAG)
94#define ENC_SET_DUMMY(enc) ((enc)->ruby_encoding_index |= ENC_DUMMY_FLAG)
95
96#define ENCODING_COUNT ENCINDEX_BUILTIN_MAX
97#define UNSPECIFIED_ENCODING INT_MAX
98
99#define ENCODING_NAMELEN_MAX 63
100#define valid_encoding_name_p(name) ((name) && strlen(name) <= ENCODING_NAMELEN_MAX)
101
102static const rb_data_type_t encoding_data_type = {
103 "encoding",
104 {0, 0, 0,},
105 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
106};
107
108#define is_data_encoding(obj) (RTYPEDDATA_P(obj) && RTYPEDDATA_TYPE(obj) == &encoding_data_type)
109#define is_obj_encoding(obj) (RB_TYPE_P((obj), T_DATA) && is_data_encoding(obj))
110
111int
112rb_data_is_encoding(VALUE obj)
113{
114 return is_data_encoding(obj);
115}
116
117static VALUE
118enc_new(rb_encoding *encoding)
119{
120 VALUE enc = TypedData_Wrap_Struct(rb_cEncoding, &encoding_data_type, (void *)encoding);
121 rb_obj_freeze(enc);
122 FL_SET_RAW(enc, RUBY_FL_SHAREABLE);
123 return enc;
124}
125
126static void
127enc_list_update(int index, rb_raw_encoding *encoding)
128{
129 RUBY_ASSERT(index < ENCODING_LIST_CAPA);
130
131 VALUE list = rb_encoding_list;
132 if (list && NIL_P(rb_ary_entry(list, index))) {
133 /* initialize encoding data */
134 rb_ary_store(list, index, enc_new(encoding));
135 }
136}
137
138static VALUE
139enc_list_lookup(int idx)
140{
141 VALUE list, enc = Qnil;
142
143 if (idx < ENCODING_LIST_CAPA) {
144 list = rb_encoding_list;
145 RUBY_ASSERT(list);
146 enc = rb_ary_entry(list, idx);
147 }
148
149 if (NIL_P(enc)) {
150 rb_bug("rb_enc_from_encoding_index(%d): not created yet", idx);
151 }
152 else {
153 return enc;
154 }
155}
156
157static VALUE
158rb_enc_from_encoding_index(int idx)
159{
160 return enc_list_lookup(idx);
161}
162
163 VALUE
164rb_enc_from_encoding(rb_encoding *encoding)
165{
166 int idx;
167 if (!encoding) return Qnil;
168 idx = ENC_TO_ENCINDEX(encoding);
169 return rb_enc_from_encoding_index(idx);
170}
171
172int
173rb_enc_to_index(rb_encoding *enc)
174{
175 return enc ? ENC_TO_ENCINDEX(enc) : 0;
176}
177
178int
179rb_enc_dummy_p(rb_encoding *enc)
180{
181 return ENC_DUMMY_P(enc) != 0;
182}
183
184static int
185check_encoding(rb_encoding *enc)
186{
187 int index = rb_enc_to_index(enc);
188 if (rb_enc_from_index(index) != enc)
189 return -1;
190 if (rb_enc_autoload_p(enc)) {
191 index = rb_enc_autoload(enc);
192 }
193 return index;
194}
195
196static int
197enc_check_encoding(VALUE obj)
198{
199 if (!is_obj_encoding(obj)) {
200 return -1;
201 }
202 return check_encoding(RDATA(obj)->data);
203}
204
205NORETURN(static void not_encoding(VALUE enc));
206static void
207not_encoding(VALUE enc)
208{
209 rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE" (expected Encoding)",
210 rb_obj_class(enc));
211}
212
213static rb_encoding *
214must_encoding(VALUE enc)
215{
216 int index = enc_check_encoding(enc);
217 if (index < 0) {
218 not_encoding(enc);
219 }
220 return DATA_PTR(enc);
221}
222
223static rb_encoding *
224must_encindex(int index)
225{
226 rb_encoding *enc = rb_enc_from_index(index);
227 if (!enc) {
228 rb_raise(rb_eEncodingError, "encoding index out of bound: %d",
229 index);
230 }
231 if (ENC_TO_ENCINDEX(enc) != (int)(index & ENC_INDEX_MASK)) {
232 rb_raise(rb_eEncodingError, "wrong encoding index %d for %s (expected %d)",
233 index, rb_enc_name(enc), ENC_TO_ENCINDEX(enc));
234 }
235 if (rb_enc_autoload_p(enc) && rb_enc_autoload(enc) == -1) {
236 rb_loaderror("failed to load encoding (%s)",
237 rb_enc_name(enc));
238 }
239 return enc;
240}
241
242int
243rb_to_encoding_index(VALUE enc)
244{
245 int idx;
246 const char *name;
247
248 idx = enc_check_encoding(enc);
249 if (idx >= 0) {
250 return idx;
251 }
252 else if (NIL_P(enc = rb_check_string_type(enc))) {
253 return -1;
254 }
255 if (!rb_enc_asciicompat(rb_enc_get(enc))) {
256 return -1;
257 }
258 if (!(name = rb_str_to_cstr(enc))) {
259 return -1;
260 }
261 return rb_enc_find_index(name);
262}
263
264static const char *
265name_for_encoding(volatile VALUE *enc)
266{
267 VALUE name = StringValue(*enc);
268 const char *n;
269
270 if (!rb_enc_asciicompat(rb_enc_get(name))) {
271 rb_raise(rb_eArgError, "invalid encoding name (non ASCII)");
272 }
273 if (!(n = rb_str_to_cstr(name))) {
274 rb_raise(rb_eArgError, "invalid encoding name (NUL byte)");
275 }
276 return n;
277}
278
279/* Returns encoding index or UNSPECIFIED_ENCODING */
280static int
281str_find_encindex(VALUE enc)
282{
283 int idx = rb_enc_find_index(name_for_encoding(&enc));
284 RB_GC_GUARD(enc);
285 return idx;
286}
287
288static int
289str_to_encindex(VALUE enc)
290{
291 int idx = str_find_encindex(enc);
292 if (idx < 0) {
293 rb_raise(rb_eArgError, "unknown encoding name - %"PRIsVALUE, enc);
294 }
295 return idx;
296}
297
298static rb_encoding *
299str_to_encoding(VALUE enc)
300{
301 return rb_enc_from_index(str_to_encindex(enc));
302}
303
304 rb_encoding *
305rb_to_encoding(VALUE enc)
306{
307 if (enc_check_encoding(enc) >= 0) return RDATA(enc)->data;
308 return str_to_encoding(enc);
309}
310
311 rb_encoding *
312rb_find_encoding(VALUE enc)
313{
314 int idx;
315 if (enc_check_encoding(enc) >= 0) return RDATA(enc)->data;
316 idx = str_find_encindex(enc);
317 if (idx < 0) return NULL;
318 return rb_enc_from_index(idx);
319}
320
321static int
322enc_table_expand(struct enc_table *enc_table, int newsize)
323{
324 if (newsize > ENCODING_LIST_CAPA) {
325 rb_raise(rb_eEncodingError, "too many encoding (> %d)", ENCODING_LIST_CAPA);
326 }
327 return newsize;
328}
329
330static int
331enc_register_at(struct enc_table *enc_table, int index, const char *name, rb_encoding *base_encoding)
332{
333 struct rb_encoding_entry *ent = &enc_table->list[index];
334 rb_raw_encoding *encoding;
335
336 if (!valid_encoding_name_p(name)) return -1;
337 if (!ent->name) {
338 ent->name = name = strdup(name);
339 }
340 else if (STRCASECMP(name, ent->name)) {
341 return -1;
342 }
343 encoding = (rb_raw_encoding *)ent->enc;
344 if (!encoding) {
345 encoding = xmalloc(sizeof(rb_encoding));
346 }
347 if (base_encoding) {
348 *encoding = *base_encoding;
349 }
350 else {
351 memset(encoding, 0, sizeof(*ent->enc));
352 }
353 encoding->name = name;
354 encoding->ruby_encoding_index = index;
355 ent->enc = encoding;
356 st_insert(enc_table->names, (st_data_t)name, (st_data_t)index);
357
358 enc_list_update(index, encoding);
359 return index;
360}
361
362static int
363enc_register(struct enc_table *enc_table, const char *name, rb_encoding *encoding)
364{
365 int index = enc_table->count;
366
367 enc_table->count = enc_table_expand(enc_table, index + 1);
368 return enc_register_at(enc_table, index, name, encoding);
369}
370
371static void set_encoding_const(const char *, rb_encoding *);
372static int enc_registered(struct enc_table *enc_table, const char *name);
373
374static rb_encoding *
375enc_from_index(struct enc_table *enc_table, int index)
376{
377 if (UNLIKELY(index < 0 || enc_table->count <= (index &= ENC_INDEX_MASK))) {
378 return 0;
379 }
380 return enc_table->list[index].enc;
381}
382
383 rb_encoding *
384rb_enc_from_index(int index)
385{
386 return enc_from_index(&global_enc_table, index);
387}
388
389int
390rb_enc_register(const char *name, rb_encoding *encoding)
391{
392 int index;
393
394 GLOBAL_ENC_TABLE_ENTER(enc_table);
395 {
396 index = enc_registered(enc_table, name);
397
398 if (index >= 0) {
399 rb_encoding *oldenc = enc_from_index(enc_table, index);
400 if (STRCASECMP(name, rb_enc_name(oldenc))) {
401 index = enc_register(enc_table, name, encoding);
402 }
403 else if (rb_enc_autoload_p(oldenc) || !ENC_DUMMY_P(oldenc)) {
404 enc_register_at(enc_table, index, name, encoding);
405 }
406 else {
407 rb_raise(rb_eArgError, "encoding %s is already registered", name);
408 }
409 }
410 else {
411 index = enc_register(enc_table, name, encoding);
412 set_encoding_const(name, rb_enc_from_index(index));
413 }
414 }
415 GLOBAL_ENC_TABLE_LEAVE();
416 return index;
417}
418
419int
420enc_registered(struct enc_table *enc_table, const char *name)
421{
422 st_data_t idx = 0;
423
424 if (!name) return -1;
425 if (!enc_table->names) return -1;
426 if (st_lookup(enc_table->names, (st_data_t)name, &idx)) {
427 return (int)idx;
428 }
429 return -1;
430}
431
432void
433rb_encdb_declare(const char *name)
434{
435 GLOBAL_ENC_TABLE_ENTER(enc_table);
436 {
437 int idx = enc_registered(enc_table, name);
438 if (idx < 0) {
439 idx = enc_register(enc_table, name, 0);
440 }
441 set_encoding_const(name, rb_enc_from_index(idx));
442 }
443 GLOBAL_ENC_TABLE_LEAVE();
444}
445
446static void
447enc_check_addable(struct enc_table *enc_table, const char *name)
448{
449 if (enc_registered(enc_table, name) >= 0) {
450 rb_raise(rb_eArgError, "encoding %s is already registered", name);
451 }
452 else if (!valid_encoding_name_p(name)) {
453 rb_raise(rb_eArgError, "invalid encoding name: %s", name);
454 }
455}
456
457static rb_encoding*
458set_base_encoding(struct enc_table *enc_table, int index, rb_encoding *base)
459{
460 rb_encoding *enc = enc_table->list[index].enc;
461
462 ASSUME(enc);
463 enc_table->list[index].base = base;
464 if (ENC_DUMMY_P(base)) ENC_SET_DUMMY((rb_raw_encoding *)enc);
465 return enc;
466}
467
468/* for encdb.h
469 * Set base encoding for encodings which are not replicas
470 * but not in their own files.
471 */
472void
473rb_enc_set_base(const char *name, const char *orig)
474{
475 GLOBAL_ENC_TABLE_ENTER(enc_table);
476 {
477 int idx = enc_registered(enc_table, name);
478 int origidx = enc_registered(enc_table, orig);
479 set_base_encoding(enc_table, idx, rb_enc_from_index(origidx));
480 }
481 GLOBAL_ENC_TABLE_LEAVE();
482}
483
484/* for encdb.h
485 * Set encoding dummy.
486 */
487int
488rb_enc_set_dummy(int index)
489{
490 rb_encoding *enc = global_enc_table.list[index].enc;
491 ENC_SET_DUMMY((rb_raw_encoding *)enc);
492 return index;
493}
494
495static int
496enc_replicate(struct enc_table *enc_table, const char *name, rb_encoding *encoding)
497{
498 int idx;
499
500 enc_check_addable(enc_table, name);
501 idx = enc_register(enc_table, name, encoding);
502 if (idx < 0) rb_raise(rb_eArgError, "invalid encoding name: %s", name);
503 set_base_encoding(enc_table, idx, encoding);
504 set_encoding_const(name, rb_enc_from_index(idx));
505 return idx;
506}
507
508int
509rb_enc_replicate(const char *name, rb_encoding *encoding)
510{
511 int r;
512
513 GLOBAL_ENC_TABLE_EVAL(enc_table,
514 r = enc_replicate(enc_table, name, encoding));
515
516 return r;
517}
518
519/*
520 * call-seq:
521 * enc.replicate(name) -> encoding
522 *
523 * Returns a replicated encoding of _enc_ whose name is _name_.
524 * The new encoding should have the same byte structure of _enc_.
525 * If _name_ is used by another encoding, raise ArgumentError.
526 *
527 */
528static VALUE
529enc_replicate_m(VALUE encoding, VALUE name)
530{
531 int idx;
532 rb_warn_deprecated_to_remove("3.3", "Encoding#replicate", "the original encoding");
533
534 idx = rb_enc_replicate(name_for_encoding(&name), rb_to_encoding(encoding));
535 RB_GC_GUARD(name);
536 return rb_enc_from_encoding_index(idx);
537}
538
539static int
540enc_replicate_with_index(struct enc_table *enc_table, const char *name, rb_encoding *origenc, int idx)
541{
542 if (idx < 0) {
543 idx = enc_register(enc_table, name, origenc);
544 }
545 else {
546 idx = enc_register_at(enc_table, idx, name, origenc);
547 }
548 if (idx >= 0) {
549 set_base_encoding(enc_table, idx, origenc);
550 set_encoding_const(name, rb_enc_from_index(idx));
551 }
552 else {
553 rb_raise(rb_eArgError, "failed to replicate encoding");
554 }
555 return idx;
556}
557
558int
559rb_encdb_replicate(const char *name, const char *orig)
560{
561 int r;
562
563 GLOBAL_ENC_TABLE_ENTER(enc_table);
564 {
565 int origidx = enc_registered(enc_table, orig);
566 int idx = enc_registered(enc_table, name);
567
568 if (origidx < 0) {
569 origidx = enc_register(enc_table, orig, 0);
570 }
571 r = enc_replicate_with_index(enc_table, name, rb_enc_from_index(origidx), idx);
572 }
573 GLOBAL_ENC_TABLE_LEAVE();
574
575 return r;
576}
577
578int
579rb_define_dummy_encoding(const char *name)
580{
581 int index;
582
583 GLOBAL_ENC_TABLE_ENTER(enc_table);
584 {
585 index = enc_replicate(enc_table, name, rb_ascii8bit_encoding());
586 rb_encoding *enc = enc_table->list[index].enc;
587 ENC_SET_DUMMY((rb_raw_encoding *)enc);
588 }
589 GLOBAL_ENC_TABLE_LEAVE();
590
591 return index;
592}
593
594int
595rb_encdb_dummy(const char *name)
596{
597 int index;
598
599 GLOBAL_ENC_TABLE_ENTER(enc_table);
600 {
601 index = enc_replicate_with_index(enc_table, name,
602 rb_ascii8bit_encoding(),
603 enc_registered(enc_table, name));
604 rb_encoding *enc = enc_table->list[index].enc;
605 ENC_SET_DUMMY((rb_raw_encoding *)enc);
606 }
607 GLOBAL_ENC_TABLE_LEAVE();
608
609 return index;
610}
611
612/*
613 * call-seq:
614 * enc.dummy? -> true or false
615 *
616 * Returns true for dummy encodings.
617 * A dummy encoding is an encoding for which character handling is not properly
618 * implemented.
619 * It is used for stateful encodings.
620 *
621 * Encoding::ISO_2022_JP.dummy? #=> true
622 * Encoding::UTF_8.dummy? #=> false
623 *
624 */
625static VALUE
626enc_dummy_p(VALUE enc)
627{
628 return RBOOL(ENC_DUMMY_P(must_encoding(enc)));
629}
630
631/*
632 * call-seq:
633 * enc.ascii_compatible? -> true or false
634 *
635 * Returns whether ASCII-compatible or not.
636 *
637 * Encoding::UTF_8.ascii_compatible? #=> true
638 * Encoding::UTF_16BE.ascii_compatible? #=> false
639 *
640 */
641static VALUE
642enc_ascii_compatible_p(VALUE enc)
643{
644 return RBOOL(rb_enc_asciicompat(must_encoding(enc)));
645}
646
647/*
648 * Returns non-zero when the encoding is Unicode series other than UTF-7 else 0.
649 */
650int
651rb_enc_unicode_p(rb_encoding *enc)
652{
653 return ONIGENC_IS_UNICODE(enc);
654}
655
656static st_data_t
657enc_dup_name(st_data_t name)
658{
659 return (st_data_t)strdup((const char *)name);
660}
661
662/*
663 * Returns copied alias name when the key is added for st_table,
664 * else returns NULL.
665 */
666static int
667enc_alias_internal(struct enc_table *enc_table, const char *alias, int idx)
668{
669 return st_insert2(enc_table->names, (st_data_t)alias, (st_data_t)idx,
670 enc_dup_name);
671}
672
673static int
674enc_alias(struct enc_table *enc_table, const char *alias, int idx)
675{
676 if (!valid_encoding_name_p(alias)) return -1;
677 if (!enc_alias_internal(enc_table, alias, idx))
678 set_encoding_const(alias, enc_from_index(enc_table, idx));
679 return idx;
680}
681
682int
683rb_enc_alias(const char *alias, const char *orig)
684{
685 int idx, r;
686
687 GLOBAL_ENC_TABLE_ENTER(enc_table);
688 {
689 enc_check_addable(enc_table, alias);
690 if ((idx = rb_enc_find_index(orig)) < 0) {
691 r = -1;
692 }
693 else {
694 r = enc_alias(enc_table, alias, idx);
695 }
696 }
697 GLOBAL_ENC_TABLE_LEAVE();
698
699 return r;
700}
701
702int
703rb_encdb_alias(const char *alias, const char *orig)
704{
705 int r;
706
707 GLOBAL_ENC_TABLE_ENTER(enc_table);
708 {
709 int idx = enc_registered(enc_table, orig);
710
711 if (idx < 0) {
712 idx = enc_register(enc_table, orig, 0);
713 }
714 r = enc_alias(enc_table, alias, idx);
715 }
716 GLOBAL_ENC_TABLE_LEAVE();
717
718 return r;
719}
720
721static void
722rb_enc_init(struct enc_table *enc_table)
723{
724 enc_table_expand(enc_table, ENCODING_COUNT + 1);
725 if (!enc_table->names) {
726 enc_table->names = st_init_strcasetable_with_size(ENCODING_LIST_CAPA);
727 }
728#define OnigEncodingASCII_8BIT OnigEncodingASCII
729#define ENC_REGISTER(enc) enc_register_at(enc_table, ENCINDEX_##enc, rb_enc_name(&OnigEncoding##enc), &OnigEncoding##enc)
730 ENC_REGISTER(ASCII_8BIT);
731 ENC_REGISTER(UTF_8);
732 ENC_REGISTER(US_ASCII);
733 global_enc_ascii = enc_table->list[ENCINDEX_ASCII_8BIT].enc;
734 global_enc_utf_8 = enc_table->list[ENCINDEX_UTF_8].enc;
735 global_enc_us_ascii = enc_table->list[ENCINDEX_US_ASCII].enc;
736#undef ENC_REGISTER
737#undef OnigEncodingASCII_8BIT
738#define ENCDB_REGISTER(name, enc) enc_register_at(enc_table, ENCINDEX_##enc, name, NULL)
739 ENCDB_REGISTER("UTF-16BE", UTF_16BE);
740 ENCDB_REGISTER("UTF-16LE", UTF_16LE);
741 ENCDB_REGISTER("UTF-32BE", UTF_32BE);
742 ENCDB_REGISTER("UTF-32LE", UTF_32LE);
743 ENCDB_REGISTER("UTF-16", UTF_16);
744 ENCDB_REGISTER("UTF-32", UTF_32);
745 ENCDB_REGISTER("UTF8-MAC", UTF8_MAC);
746
747 ENCDB_REGISTER("EUC-JP", EUC_JP);
748 ENCDB_REGISTER("Windows-31J", Windows_31J);
749#undef ENCDB_REGISTER
750 enc_table->count = ENCINDEX_BUILTIN_MAX;
751}
752
753 rb_encoding *
754rb_enc_get_from_index(int index)
755{
756 return must_encindex(index);
757}
758
759int rb_require_internal_silent(VALUE fname);
760
761static int
762load_encoding(const char *name)
763{
764 VALUE enclib = rb_sprintf("enc/%s.so", name);
765 VALUE debug = ruby_debug;
766 VALUE errinfo;
767 char *s = RSTRING_PTR(enclib) + 4, *e = RSTRING_END(enclib) - 3;
768 int loaded;
769 int idx;
770
771 while (s < e) {
772 if (!ISALNUM(*s)) *s = '_';
773 else if (ISUPPER(*s)) *s = (char)TOLOWER(*s);
774 ++s;
775 }
776 enclib = rb_fstring(enclib);
777 ruby_debug = Qfalse;
778 errinfo = rb_errinfo();
779 loaded = rb_require_internal_silent(enclib);
780 ruby_debug = debug;
781 rb_set_errinfo(errinfo);
782
783 GLOBAL_ENC_TABLE_ENTER(enc_table);
784 {
785 if (loaded < 0 || 1 < loaded) {
786 idx = -1;
787 }
788 else if ((idx = enc_registered(enc_table, name)) < 0) {
789 idx = -1;
790 }
791 else if (rb_enc_autoload_p(enc_table->list[idx].enc)) {
792 idx = -1;
793 }
794 }
795 GLOBAL_ENC_TABLE_LEAVE();
796
797 return idx;
798}
799
800static int
801enc_autoload_body(struct enc_table *enc_table, rb_encoding *enc)
802{
803 rb_encoding *base = enc_table->list[ENC_TO_ENCINDEX(enc)].base;
804
805 if (base) {
806 int i = 0;
807 do {
808 if (i >= enc_table->count) return -1;
809 } while (enc_table->list[i].enc != base && (++i, 1));
810 if (rb_enc_autoload_p(base)) {
811 if (rb_enc_autoload(base) < 0) return -1;
812 }
813 i = enc->ruby_encoding_index;
814 enc_register_at(enc_table, i & ENC_INDEX_MASK, rb_enc_name(enc), base);
815 ((rb_raw_encoding *)enc)->ruby_encoding_index = i;
816 i &= ENC_INDEX_MASK;
817 return i;
818 }
819 else {
820 return -2;
821 }
822}
823
824int
825rb_enc_autoload(rb_encoding *enc)
826{
827 int i;
828 GLOBAL_ENC_TABLE_EVAL(enc_table, i = enc_autoload_body(enc_table, enc));
829 if (i == -2) {
830 i = load_encoding(rb_enc_name(enc));
831 }
832 return i;
833}
834
835/* Return encoding index or UNSPECIFIED_ENCODING from encoding name */
836int
837rb_enc_find_index(const char *name)
838{
839 int i = enc_registered(&global_enc_table, name);
840 rb_encoding *enc;
841
842 if (i < 0) {
843 i = load_encoding(name);
844 }
845 else if (!(enc = rb_enc_from_index(i))) {
846 if (i != UNSPECIFIED_ENCODING) {
847 rb_raise(rb_eArgError, "encoding %s is not registered", name);
848 }
849 }
850 else if (rb_enc_autoload_p(enc)) {
851 if (rb_enc_autoload(enc) < 0) {
852 rb_warn("failed to load encoding (%s); use ASCII-8BIT instead",
853 name);
854 return 0;
855 }
856 }
857 return i;
858}
859
860int
861rb_enc_find_index2(const char *name, long len)
862{
863 char buf[ENCODING_NAMELEN_MAX+1];
864
865 if (len > ENCODING_NAMELEN_MAX) return -1;
866 memcpy(buf, name, len);
867 buf[len] = '\0';
868 return rb_enc_find_index(buf);
869}
870
871 rb_encoding *
872rb_enc_find(const char *name)
873{
874 int idx = rb_enc_find_index(name);
875 if (idx < 0) idx = 0;
876 return rb_enc_from_index(idx);
877}
878
879static inline int
880enc_capable(VALUE obj)
881{
882 if (SPECIAL_CONST_P(obj)) return SYMBOL_P(obj);
883 switch (BUILTIN_TYPE(obj)) {
884 case T_STRING:
885 case T_REGEXP:
886 case T_FILE:
887 case T_SYMBOL:
888 return TRUE;
889 case T_DATA:
890 if (is_data_encoding(obj)) return TRUE;
891 default:
892 return FALSE;
893 }
894}
895
896int
897rb_enc_capable(VALUE obj)
898{
899 return enc_capable(obj);
900}
901
902 ID
903rb_id_encoding(void)
904{
905 CONST_ID(id_encoding, "encoding");
906 return id_encoding;
907}
908
909static int
910enc_get_index_str(VALUE str)
911{
912 int i = ENCODING_GET_INLINED(str);
913 if (i == ENCODING_INLINE_MAX) {
914 VALUE iv;
915
916#if 0
917 iv = rb_ivar_get(str, rb_id_encoding());
918 i = NUM2INT(iv);
919#else
920 /*
921 * Tentatively, assume ASCII-8BIT, if encoding index instance
922 * variable is not found. This can happen when freeing after
923 * all instance variables are removed in `obj_free`.
924 */
925 iv = rb_attr_get(str, rb_id_encoding());
926 i = NIL_P(iv) ? ENCINDEX_ASCII_8BIT : NUM2INT(iv);
927#endif
928 }
929 return i;
930}
931
932int
933rb_enc_get_index(VALUE obj)
934{
935 int i = -1;
936 VALUE tmp;
937
938 if (SPECIAL_CONST_P(obj)) {
939 if (!SYMBOL_P(obj)) return -1;
940 obj = rb_sym2str(obj);
941 }
942 switch (BUILTIN_TYPE(obj)) {
943 case T_STRING:
944 case T_SYMBOL:
945 case T_REGEXP:
946 i = enc_get_index_str(obj);
947 break;
948 case T_FILE:
949 tmp = rb_funcallv(obj, rb_intern("internal_encoding"), 0, 0);
950 if (NIL_P(tmp)) {
951 tmp = rb_funcallv(obj, rb_intern("external_encoding"), 0, 0);
952 }
953 if (is_obj_encoding(tmp)) {
954 i = enc_check_encoding(tmp);
955 }
956 break;
957 case T_DATA:
958 if (is_data_encoding(obj)) {
959 i = enc_check_encoding(obj);
960 }
961 break;
962 default:
963 break;
964 }
965 return i;
966}
967
968static void
969enc_set_index(VALUE obj, int idx)
970{
971 if (!enc_capable(obj)) {
972 rb_raise(rb_eArgError, "cannot set encoding on non-encoding capable object");
973 }
974
975 if (idx < ENCODING_INLINE_MAX) {
976 ENCODING_SET_INLINED(obj, idx);
977 return;
978 }
979 ENCODING_SET_INLINED(obj, ENCODING_INLINE_MAX);
980 rb_ivar_set(obj, rb_id_encoding(), INT2NUM(idx));
981}
982
983void
984rb_enc_set_index(VALUE obj, int idx)
985{
986 rb_check_frozen(obj);
987 must_encindex(idx);
988 enc_set_index(obj, idx);
989}
990
991 VALUE
992rb_enc_associate_index(VALUE obj, int idx)
993{
994 rb_encoding *enc;
995 int oldidx, oldtermlen, termlen;
996
997/* enc_check_capable(obj);*/
998 rb_check_frozen(obj);
999 oldidx = rb_enc_get_index(obj);
1000 if (oldidx == idx)
1001 return obj;
1002 if (SPECIAL_CONST_P(obj)) {
1003 rb_raise(rb_eArgError, "cannot set encoding");
1004 }
1005 enc = must_encindex(idx);
1006 if (!ENC_CODERANGE_ASCIIONLY(obj) ||
1007 !rb_enc_asciicompat(enc)) {
1008 ENC_CODERANGE_CLEAR(obj);
1009 }
1010 termlen = rb_enc_mbminlen(enc);
1011 oldtermlen = rb_enc_mbminlen(rb_enc_from_index(oldidx));
1012 if (oldtermlen != termlen && RB_TYPE_P(obj, T_STRING)) {
1013 rb_str_change_terminator_length(obj, oldtermlen, termlen);
1014 }
1015 enc_set_index(obj, idx);
1016 return obj;
1017}
1018
1019 VALUE
1020rb_enc_associate(VALUE obj, rb_encoding *enc)
1021{
1022 return rb_enc_associate_index(obj, rb_enc_to_index(enc));
1023}
1024
1025 rb_encoding*
1026rb_enc_get(VALUE obj)
1027{
1028 return rb_enc_from_index(rb_enc_get_index(obj));
1029}
1030
1031static rb_encoding*
1032rb_encoding_check(rb_encoding* enc, VALUE str1, VALUE str2)
1033{
1034 if (!enc)
1035 rb_raise(rb_eEncCompatError, "incompatible character encodings: %s and %s",
1036 rb_enc_name(rb_enc_get(str1)),
1037 rb_enc_name(rb_enc_get(str2)));
1038 return enc;
1039}
1040
1041static rb_encoding* enc_compatible_str(VALUE str1, VALUE str2);
1042
1043 rb_encoding*
1044rb_enc_check_str(VALUE str1, VALUE str2)
1045{
1046 rb_encoding *enc = enc_compatible_str(MUST_STRING(str1), MUST_STRING(str2));
1047 return rb_encoding_check(enc, str1, str2);
1048}
1049
1050 rb_encoding*
1051rb_enc_check(VALUE str1, VALUE str2)
1052{
1053 rb_encoding *enc = rb_enc_compatible(str1, str2);
1054 return rb_encoding_check(enc, str1, str2);
1055}
1056
1057static rb_encoding*
1058enc_compatible_latter(VALUE str1, VALUE str2, int idx1, int idx2)
1059{
1060 int isstr1, isstr2;
1061 rb_encoding *enc1 = rb_enc_from_index(idx1);
1062 rb_encoding *enc2 = rb_enc_from_index(idx2);
1063
1064 isstr2 = RB_TYPE_P(str2, T_STRING);
1065 if (isstr2 && RSTRING_LEN(str2) == 0)
1066 return enc1;
1067 isstr1 = RB_TYPE_P(str1, T_STRING);
1068 if (isstr1 && isstr2 && RSTRING_LEN(str1) == 0)
1069 return (rb_enc_asciicompat(enc1) && rb_enc_str_asciionly_p(str2)) ? enc1 : enc2;
1070 if (!rb_enc_asciicompat(enc1) || !rb_enc_asciicompat(enc2)) {
1071 return 0;
1072 }
1073
1074 /* objects whose encoding is the same of contents */
1075 if (!isstr2 && idx2 == ENCINDEX_US_ASCII)
1076 return enc1;
1077 if (!isstr1 && idx1 == ENCINDEX_US_ASCII)
1078 return enc2;
1079
1080 if (!isstr1) {
1081 VALUE tmp = str1;
1082 int idx0 = idx1;
1083 str1 = str2;
1084 str2 = tmp;
1085 idx1 = idx2;
1086 idx2 = idx0;
1087 idx0 = isstr1;
1088 isstr1 = isstr2;
1089 isstr2 = idx0;
1090 }
1091 if (isstr1) {
1092 int cr1, cr2;
1093
1094 cr1 = rb_enc_str_coderange(str1);
1095 if (isstr2) {
1096 cr2 = rb_enc_str_coderange(str2);
1097 if (cr1 != cr2) {
1098 /* may need to handle ENC_CODERANGE_BROKEN */
1099 if (cr1 == ENC_CODERANGE_7BIT) return enc2;
1100 if (cr2 == ENC_CODERANGE_7BIT) return enc1;
1101 }
1102 if (cr2 == ENC_CODERANGE_7BIT) {
1103 return enc1;
1104 }
1105 }
1106 if (cr1 == ENC_CODERANGE_7BIT)
1107 return enc2;
1108 }
1109 return 0;
1110}
1111
1112static rb_encoding*
1113enc_compatible_str(VALUE str1, VALUE str2)
1114{
1115 int idx1 = enc_get_index_str(str1);
1116 int idx2 = enc_get_index_str(str2);
1117
1118 if (idx1 < 0 || idx2 < 0)
1119 return 0;
1120
1121 if (idx1 == idx2) {
1122 return rb_enc_from_index(idx1);
1123 }
1124 else {
1125 return enc_compatible_latter(str1, str2, idx1, idx2);
1126 }
1127}
1128
1129 rb_encoding*
1130rb_enc_compatible(VALUE str1, VALUE str2)
1131{
1132 int idx1 = rb_enc_get_index(str1);
1133 int idx2 = rb_enc_get_index(str2);
1134
1135 if (idx1 < 0 || idx2 < 0)
1136 return 0;
1137
1138 if (idx1 == idx2) {
1139 return rb_enc_from_index(idx1);
1140 }
1141
1142 return enc_compatible_latter(str1, str2, idx1, idx2);
1143}
1144
1145void
1146rb_enc_copy(VALUE obj1, VALUE obj2)
1147{
1148 rb_enc_associate_index(obj1, rb_enc_get_index(obj2));
1149}
1150
1151
1152/*
1153 * call-seq:
1154 * obj.encoding -> encoding
1155 *
1156 * Returns the Encoding object that represents the encoding of obj.
1157 */
1158
1159 VALUE
1160rb_obj_encoding(VALUE obj)
1161{
1162 int idx = rb_enc_get_index(obj);
1163 if (idx < 0) {
1164 rb_raise(rb_eTypeError, "unknown encoding");
1165 }
1166 return rb_enc_from_encoding_index(idx & ENC_INDEX_MASK);
1167}
1168
1169int
1170rb_enc_fast_mbclen(const char *p, const char *e, rb_encoding *enc)
1171{
1172 return ONIGENC_MBC_ENC_LEN(enc, (UChar*)p, (UChar*)e);
1173}
1174
1175int
1176rb_enc_mbclen(const char *p, const char *e, rb_encoding *enc)
1177{
1178 int n = ONIGENC_PRECISE_MBC_ENC_LEN(enc, (UChar*)p, (UChar*)e);
1179 if (MBCLEN_CHARFOUND_P(n) && MBCLEN_CHARFOUND_LEN(n) <= e-p)
1180 return MBCLEN_CHARFOUND_LEN(n);
1181 else {
1182 int min = rb_enc_mbminlen(enc);
1183 return min <= e-p ? min : (int)(e-p);
1184 }
1185}
1186
1187int
1188rb_enc_precise_mbclen(const char *p, const char *e, rb_encoding *enc)
1189{
1190 int n;
1191 if (e <= p)
1192 return ONIGENC_CONSTRUCT_MBCLEN_NEEDMORE(1);
1193 n = ONIGENC_PRECISE_MBC_ENC_LEN(enc, (UChar*)p, (UChar*)e);
1194 if (e-p < n)
1195 return ONIGENC_CONSTRUCT_MBCLEN_NEEDMORE(n-(int)(e-p));
1196 return n;
1197}
1198
1199int
1200rb_enc_ascget(const char *p, const char *e, int *len, rb_encoding *enc)
1201{
1202 unsigned int c;
1203 int l;
1204 if (e <= p)
1205 return -1;
1206 if (rb_enc_asciicompat(enc)) {
1207 c = (unsigned char)*p;
1208 if (!ISASCII(c))
1209 return -1;
1210 if (len) *len = 1;
1211 return c;
1212 }
1213 l = rb_enc_precise_mbclen(p, e, enc);
1214 if (!MBCLEN_CHARFOUND_P(l))
1215 return -1;
1216 c = rb_enc_mbc_to_codepoint(p, e, enc);
1217 if (!rb_enc_isascii(c, enc))
1218 return -1;
1219 if (len) *len = l;
1220 return c;
1221}
1222
1223unsigned int
1224rb_enc_codepoint_len(const char *p, const char *e, int *len_p, rb_encoding *enc)
1225{
1226 int r;
1227 if (e <= p)
1228 rb_raise(rb_eArgError, "empty string");
1229 r = rb_enc_precise_mbclen(p, e, enc);
1230 if (!MBCLEN_CHARFOUND_P(r)) {
1231 rb_raise(rb_eArgError, "invalid byte sequence in %s", rb_enc_name(enc));
1232 }
1233 if (len_p) *len_p = MBCLEN_CHARFOUND_LEN(r);
1234 return rb_enc_mbc_to_codepoint(p, e, enc);
1235}
1236
1237int
1238rb_enc_codelen(int c, rb_encoding *enc)
1239{
1240 int n = ONIGENC_CODE_TO_MBCLEN(enc,c);
1241 if (n == 0) {
1242 rb_raise(rb_eArgError, "invalid codepoint 0x%x in %s", c, rb_enc_name(enc));
1243 }
1244 return n;
1245}
1246
1247int
1248rb_enc_toupper(int c, rb_encoding *enc)
1249{
1250 return (ONIGENC_IS_ASCII_CODE(c)?ONIGENC_ASCII_CODE_TO_UPPER_CASE(c):(c));
1251}
1252
1253int
1254rb_enc_tolower(int c, rb_encoding *enc)
1255{
1256 return (ONIGENC_IS_ASCII_CODE(c)?ONIGENC_ASCII_CODE_TO_LOWER_CASE(c):(c));
1257}
1258
1259/*
1260 * call-seq:
1261 * enc.inspect -> string
1262 *
1263 * Returns a string which represents the encoding for programmers.
1264 *
1265 * Encoding::UTF_8.inspect #=> "#<Encoding:UTF-8>"
1266 * Encoding::ISO_2022_JP.inspect #=> "#<Encoding:ISO-2022-JP (dummy)>"
1267 */
1268static VALUE
1269enc_inspect(VALUE self)
1270{
1271 rb_encoding *enc;
1272
1273 if (!is_data_encoding(self)) {
1274 not_encoding(self);
1275 }
1276 if (!(enc = DATA_PTR(self)) || rb_enc_from_index(rb_enc_to_index(enc)) != enc) {
1277 rb_raise(rb_eTypeError, "broken Encoding");
1278 }
1279 return rb_enc_sprintf(rb_usascii_encoding(),
1280 "#<%"PRIsVALUE":%s%s%s>", rb_obj_class(self),
1281 rb_enc_name(enc),
1282 (ENC_DUMMY_P(enc) ? " (dummy)" : ""),
1283 rb_enc_autoload_p(enc) ? " (autoload)" : "");
1284}
1285
1286/*
1287 * call-seq:
1288 * enc.name -> string
1289 * enc.to_s -> string
1290 *
1291 * Returns the name of the encoding.
1292 *
1293 * Encoding::UTF_8.name #=> "UTF-8"
1294 */
1295static VALUE
1296enc_name(VALUE self)
1297{
1298 return rb_fstring_cstr(rb_enc_name((rb_encoding*)DATA_PTR(self)));
1299}
1300
1301static int
1302enc_names_i(st_data_t name, st_data_t idx, st_data_t args)
1303{
1304 VALUE *arg = (VALUE *)args;
1305
1306 if ((int)idx == (int)arg[0]) {
1307 VALUE str = rb_fstring_cstr((char *)name);
1308 rb_ary_push(arg[1], str);
1309 }
1310 return ST_CONTINUE;
1311}
1312
1313/*
1314 * call-seq:
1315 * enc.names -> array
1316 *
1317 * Returns the list of name and aliases of the encoding.
1318 *
1319 * Encoding::WINDOWS_31J.names #=> ["Windows-31J", "CP932", "csWindows31J", "SJIS", "PCK"]
1320 */
1321static VALUE
1322enc_names(VALUE self)
1323{
1324 VALUE args[2];
1325
1326 args[0] = (VALUE)rb_to_encoding_index(self);
1327 args[1] = rb_ary_new2(0);
1328 st_foreach(global_enc_table.names, enc_names_i, (st_data_t)args);
1329 return args[1];
1330}
1331
1332/*
1333 * call-seq:
1334 * Encoding.list -> [enc1, enc2, ...]
1335 *
1336 * Returns the list of loaded encodings.
1337 *
1338 * Encoding.list
1339 * #=> [#<Encoding:ASCII-8BIT>, #<Encoding:UTF-8>,
1340 * #<Encoding:ISO-2022-JP (dummy)>]
1341 *
1342 * Encoding.find("US-ASCII")
1343 * #=> #<Encoding:US-ASCII>
1344 *
1345 * Encoding.list
1346 * #=> [#<Encoding:ASCII-8BIT>, #<Encoding:UTF-8>,
1347 * #<Encoding:US-ASCII>, #<Encoding:ISO-2022-JP (dummy)>]
1348 *
1349 */
1350static VALUE
1351enc_list(VALUE klass)
1352{
1353 VALUE ary = rb_ary_new2(0);
1354 rb_ary_replace(ary, rb_encoding_list);
1355 return ary;
1356}
1357
1358/*
1359 * call-seq:
1360 * Encoding.find(string) -> enc
1361 *
1362 * Search the encoding with specified <i>name</i>.
1363 * <i>name</i> should be a string.
1364 *
1365 * Encoding.find("US-ASCII") #=> #<Encoding:US-ASCII>
1366 *
1367 * Names which this method accept are encoding names and aliases
1368 * including following special aliases
1369 *
1370 * "external":: default external encoding
1371 * "internal":: default internal encoding
1372 * "locale":: locale encoding
1373 * "filesystem":: filesystem encoding
1374 *
1375 * An ArgumentError is raised when no encoding with <i>name</i>.
1376 * Only <code>Encoding.find("internal")</code> however returns nil
1377 * when no encoding named "internal", in other words, when Ruby has no
1378 * default internal encoding.
1379 */
1380static VALUE
1381enc_find(VALUE klass, VALUE enc)
1382{
1383 int idx;
1384 if (is_obj_encoding(enc))
1385 return enc;
1386 idx = str_to_encindex(enc);
1387 if (idx == UNSPECIFIED_ENCODING) return Qnil;
1388 return rb_enc_from_encoding_index(idx);
1389}
1390
1391/*
1392 * call-seq:
1393 * Encoding.compatible?(obj1, obj2) -> enc or nil
1394 *
1395 * Checks the compatibility of two objects.
1396 *
1397 * If the objects are both strings they are compatible when they are
1398 * concatenatable. The encoding of the concatenated string will be returned
1399 * if they are compatible, nil if they are not.
1400 *
1401 * Encoding.compatible?("\xa1".force_encoding("iso-8859-1"), "b")
1402 * #=> #<Encoding:ISO-8859-1>
1403 *
1404 * Encoding.compatible?(
1405 * "\xa1".force_encoding("iso-8859-1"),
1406 * "\xa1\xa1".force_encoding("euc-jp"))
1407 * #=> nil
1408 *
1409 * If the objects are non-strings their encodings are compatible when they
1410 * have an encoding and:
1411 * * Either encoding is US-ASCII compatible
1412 * * One of the encodings is a 7-bit encoding
1413 *
1414 */
1415static VALUE
1416enc_compatible_p(VALUE klass, VALUE str1, VALUE str2)
1417{
1418 rb_encoding *enc;
1419
1420 if (!enc_capable(str1)) return Qnil;
1421 if (!enc_capable(str2)) return Qnil;
1422 enc = rb_enc_compatible(str1, str2);
1423 if (!enc) return Qnil;
1424 return rb_enc_from_encoding(enc);
1425}
1426
1427NORETURN(static VALUE enc_s_alloc(VALUE klass));
1428/* :nodoc: */
1429static VALUE
1430enc_s_alloc(VALUE klass)
1431{
1432 rb_undefined_alloc(klass);
1433 UNREACHABLE_RETURN(Qnil);
1434}
1435
1436/* :nodoc: */
1437static VALUE
1438enc_dump(int argc, VALUE *argv, VALUE self)
1439{
1440 rb_check_arity(argc, 0, 1);
1441 return enc_name(self);
1442}
1443
1444/* :nodoc: */
1445static VALUE
1446enc_load(VALUE klass, VALUE str)
1447{
1448 return str;
1449}
1450
1451/* :nodoc: */
1452static VALUE
1453enc_m_loader(VALUE klass, VALUE str)
1454{
1455 return enc_find(klass, str);
1456}
1457
1458 rb_encoding *
1459rb_ascii8bit_encoding(void)
1460{
1461 return global_enc_ascii;
1462}
1463
1464int
1465rb_ascii8bit_encindex(void)
1466{
1467 return ENCINDEX_ASCII_8BIT;
1468}
1469
1470 rb_encoding *
1471rb_utf8_encoding(void)
1472{
1473 return global_enc_utf_8;
1474}
1475
1476int
1477rb_utf8_encindex(void)
1478{
1479 return ENCINDEX_UTF_8;
1480}
1481
1482 rb_encoding *
1483rb_usascii_encoding(void)
1484{
1485 return global_enc_us_ascii;
1486}
1487
1488int
1489rb_usascii_encindex(void)
1490{
1491 return ENCINDEX_US_ASCII;
1492}
1493
1494int rb_locale_charmap_index(void);
1495
1496int
1497rb_locale_encindex(void)
1498{
1499 int idx = rb_locale_charmap_index();
1500
1501 if (idx < 0) idx = ENCINDEX_UTF_8;
1502
1503 if (enc_registered(&global_enc_table, "locale") < 0) {
1504# if defined _WIN32
1505 void Init_w32_codepage(void);
1506 Init_w32_codepage();
1507# endif
1508 GLOBAL_ENC_TABLE_ENTER(enc_table);
1509 {
1510 enc_alias_internal(enc_table, "locale", idx);
1511 }
1512 GLOBAL_ENC_TABLE_LEAVE();
1513 }
1514
1515 return idx;
1516}
1517
1518 rb_encoding *
1519rb_locale_encoding(void)
1520{
1521 return rb_enc_from_index(rb_locale_encindex());
1522}
1523
1524int
1525rb_filesystem_encindex(void)
1526{
1527 int idx = enc_registered(&global_enc_table, "filesystem");
1528 if (idx < 0) idx = ENCINDEX_ASCII_8BIT;
1529 return idx;
1530}
1531
1532 rb_encoding *
1533rb_filesystem_encoding(void)
1534{
1535 return rb_enc_from_index(rb_filesystem_encindex());
1536}
1537
1538 struct default_encoding {
1539 int index; /* -2 => not yet set, -1 => nil */
1540 rb_encoding *enc;
1541};
1542
1543static struct default_encoding default_external = {0};
1544
1545static int
1546enc_set_default_encoding(struct default_encoding *def, VALUE encoding, const char *name)
1547{
1548 int overridden = FALSE;
1549
1550 if (def->index != -2)
1551 /* Already set */
1552 overridden = TRUE;
1553
1554 GLOBAL_ENC_TABLE_ENTER(enc_table);
1555 {
1556 if (NIL_P(encoding)) {
1557 def->index = -1;
1558 def->enc = 0;
1559 char *name_dup = strdup(name);
1560
1561 st_data_t existing_name = (st_data_t)name_dup;
1562 if (st_delete(enc_table->names, &existing_name, NULL)) {
1563 xfree((void *)existing_name);
1564 }
1565
1566 st_insert(enc_table->names, (st_data_t)name_dup,
1567 (st_data_t)UNSPECIFIED_ENCODING);
1568 }
1569 else {
1570 def->index = rb_enc_to_index(rb_to_encoding(encoding));
1571 def->enc = 0;
1572 enc_alias_internal(enc_table, name, def->index);
1573 }
1574
1575 if (def == &default_external) {
1576 enc_alias_internal(enc_table, "filesystem", Init_enc_set_filesystem_encoding());
1577 }
1578 }
1579 GLOBAL_ENC_TABLE_LEAVE();
1580
1581 return overridden;
1582}
1583
1584 rb_encoding *
1585rb_default_external_encoding(void)
1586{
1587 if (default_external.enc) return default_external.enc;
1588
1589 if (default_external.index >= 0) {
1590 default_external.enc = rb_enc_from_index(default_external.index);
1591 return default_external.enc;
1592 }
1593 else {
1594 return rb_locale_encoding();
1595 }
1596}
1597
1598 VALUE
1599rb_enc_default_external(void)
1600{
1601 return rb_enc_from_encoding(rb_default_external_encoding());
1602}
1603
1604/*
1605 * call-seq:
1606 * Encoding.default_external -> enc
1607 *
1608 * Returns default external encoding.
1609 *
1610 * The default external encoding is used by default for strings created from
1611 * the following locations:
1612 *
1613 * * CSV
1614 * * File data read from disk
1615 * * SDBM
1616 * * StringIO
1617 * * Zlib::GzipReader
1618 * * Zlib::GzipWriter
1619 * * String#inspect
1620 * * Regexp#inspect
1621 *
1622 * While strings created from these locations will have this encoding, the
1623 * encoding may not be valid. Be sure to check String#valid_encoding?.
1624 *
1625 * File data written to disk will be transcoded to the default external
1626 * encoding when written, if default_internal is not nil.
1627 *
1628 * The default external encoding is initialized by the -E option.
1629 * If -E isn't set, it is initialized to UTF-8 on Windows and the locale on
1630 * other operating systems.
1631 */
1632static VALUE
1633get_default_external(VALUE klass)
1634{
1635 return rb_enc_default_external();
1636}
1637
1638void
1639rb_enc_set_default_external(VALUE encoding)
1640{
1641 if (NIL_P(encoding)) {
1642 rb_raise(rb_eArgError, "default external can not be nil");
1643 }
1644 enc_set_default_encoding(&default_external, encoding,
1645 "external");
1646}
1647
1648/*
1649 * call-seq:
1650 * Encoding.default_external = enc
1651 *
1652 * Sets default external encoding. You should not set
1653 * Encoding::default_external in ruby code as strings created before changing
1654 * the value may have a different encoding from strings created after the value
1655 * was changed., instead you should use <tt>ruby -E</tt> to invoke ruby with
1656 * the correct default_external.
1657 *
1658 * See Encoding::default_external for information on how the default external
1659 * encoding is used.
1660 */
1661static VALUE
1662set_default_external(VALUE klass, VALUE encoding)
1663{
1664 rb_warning("setting Encoding.default_external");
1665 rb_enc_set_default_external(encoding);
1666 return encoding;
1667}
1668
1669static struct default_encoding default_internal = {-2};
1670
1671 rb_encoding *
1672rb_default_internal_encoding(void)
1673{
1674 if (!default_internal.enc && default_internal.index >= 0) {
1675 default_internal.enc = rb_enc_from_index(default_internal.index);
1676 }
1677 return default_internal.enc; /* can be NULL */
1678}
1679
1680 VALUE
1681rb_enc_default_internal(void)
1682{
1683 /* Note: These functions cope with default_internal not being set */
1684 return rb_enc_from_encoding(rb_default_internal_encoding());
1685}
1686
1687/*
1688 * call-seq:
1689 * Encoding.default_internal -> enc
1690 *
1691 * Returns default internal encoding. Strings will be transcoded to the
1692 * default internal encoding in the following places if the default internal
1693 * encoding is not nil:
1694 *
1695 * * CSV
1696 * * Etc.sysconfdir and Etc.systmpdir
1697 * * File data read from disk
1698 * * File names from Dir
1699 * * Integer#chr
1700 * * String#inspect and Regexp#inspect
1701 * * Strings returned from Readline
1702 * * Strings returned from SDBM
1703 * * Time#zone
1704 * * Values from ENV
1705 * * Values in ARGV including $PROGRAM_NAME
1706 *
1707 * Additionally String#encode and String#encode! use the default internal
1708 * encoding if no encoding is given.
1709 *
1710 * The script encoding (__ENCODING__), not default_internal, is used as the
1711 * encoding of created strings.
1712 *
1713 * Encoding::default_internal is initialized with -E option or nil otherwise.
1714 */
1715static VALUE
1716get_default_internal(VALUE klass)
1717{
1718 return rb_enc_default_internal();
1719}
1720
1721void
1722rb_enc_set_default_internal(VALUE encoding)
1723{
1724 enc_set_default_encoding(&default_internal, encoding,
1725 "internal");
1726}
1727
1728/*
1729 * call-seq:
1730 * Encoding.default_internal = enc or nil
1731 *
1732 * Sets default internal encoding or removes default internal encoding when
1733 * passed nil. You should not set Encoding::default_internal in ruby code as
1734 * strings created before changing the value may have a different encoding
1735 * from strings created after the change. Instead you should use
1736 * <tt>ruby -E</tt> to invoke ruby with the correct default_internal.
1737 *
1738 * See Encoding::default_internal for information on how the default internal
1739 * encoding is used.
1740 */
1741static VALUE
1742set_default_internal(VALUE klass, VALUE encoding)
1743{
1744 rb_warning("setting Encoding.default_internal");
1745 rb_enc_set_default_internal(encoding);
1746 return encoding;
1747}
1748
1749static void
1750set_encoding_const(const char *name, rb_encoding *enc)
1751{
1752 VALUE encoding = rb_enc_from_encoding(enc);
1753 char *s = (char *)name;
1754 int haslower = 0, hasupper = 0, valid = 0;
1755
1756 if (ISDIGIT(*s)) return;
1757 if (ISUPPER(*s)) {
1758 hasupper = 1;
1759 while (*++s && (ISALNUM(*s) || *s == '_')) {
1760 if (ISLOWER(*s)) haslower = 1;
1761 }
1762 }
1763 if (!*s) {
1764 if (s - name > ENCODING_NAMELEN_MAX) return;
1765 valid = 1;
1766 rb_define_const(rb_cEncoding, name, encoding);
1767 }
1768 if (!valid || haslower) {
1769 size_t len = s - name;
1770 if (len > ENCODING_NAMELEN_MAX) return;
1771 if (!haslower || !hasupper) {
1772 do {
1773 if (ISLOWER(*s)) haslower = 1;
1774 if (ISUPPER(*s)) hasupper = 1;
1775 } while (*++s && (!haslower || !hasupper));
1776 len = s - name;
1777 }
1778 len += strlen(s);
1779 if (len++ > ENCODING_NAMELEN_MAX) return;
1780 MEMCPY(s = ALLOCA_N(char, len), name, char, len);
1781 name = s;
1782 if (!valid) {
1783 if (ISLOWER(*s)) *s = ONIGENC_ASCII_CODE_TO_UPPER_CASE((int)*s);
1784 for (; *s; ++s) {
1785 if (!ISALNUM(*s)) *s = '_';
1786 }
1787 if (hasupper) {
1788 rb_define_const(rb_cEncoding, name, encoding);
1789 }
1790 }
1791 if (haslower) {
1792 for (s = (char *)name; *s; ++s) {
1793 if (ISLOWER(*s)) *s = ONIGENC_ASCII_CODE_TO_UPPER_CASE((int)*s);
1794 }
1795 rb_define_const(rb_cEncoding, name, encoding);
1796 }
1797 }
1798}
1799
1800static int
1801rb_enc_name_list_i(st_data_t name, st_data_t idx, st_data_t arg)
1802{
1803 VALUE ary = (VALUE)arg;
1804 VALUE str = rb_fstring_cstr((char *)name);
1805 rb_ary_push(ary, str);
1806 return ST_CONTINUE;
1807}
1808
1809/*
1810 * call-seq:
1811 * Encoding.name_list -> ["enc1", "enc2", ...]
1812 *
1813 * Returns the list of available encoding names.
1814 *
1815 * Encoding.name_list
1816 * #=> ["US-ASCII", "ASCII-8BIT", "UTF-8",
1817 * "ISO-8859-1", "Shift_JIS", "EUC-JP",
1818 * "Windows-31J",
1819 * "BINARY", "CP932", "eucJP"]
1820 *
1821 */
1822
1823static VALUE
1824rb_enc_name_list(VALUE klass)
1825{
1826 VALUE ary = rb_ary_new2(global_enc_table.names->num_entries);
1827 st_foreach(global_enc_table.names, rb_enc_name_list_i, (st_data_t)ary);
1828 return ary;
1829}
1830
1831static int
1832rb_enc_aliases_enc_i(st_data_t name, st_data_t orig, st_data_t arg)
1833{
1834 VALUE *p = (VALUE *)arg;
1835 VALUE aliases = p[0], ary = p[1];
1836 int idx = (int)orig;
1837 VALUE key, str = rb_ary_entry(ary, idx);
1838
1839 if (NIL_P(str)) {
1840 rb_encoding *enc = rb_enc_from_index(idx);
1841
1842 if (!enc) return ST_CONTINUE;
1843 if (STRCASECMP((char*)name, rb_enc_name(enc)) == 0) {
1844 return ST_CONTINUE;
1845 }
1846 str = rb_fstring_cstr(rb_enc_name(enc));
1847 rb_ary_store(ary, idx, str);
1848 }
1849 key = rb_fstring_cstr((char *)name);
1850 rb_hash_aset(aliases, key, str);
1851 return ST_CONTINUE;
1852}
1853
1854/*
1855 * call-seq:
1856 * Encoding.aliases -> {"alias1" => "orig1", "alias2" => "orig2", ...}
1857 *
1858 * Returns the hash of available encoding alias and original encoding name.
1859 *
1860 * Encoding.aliases
1861 * #=> {"BINARY"=>"ASCII-8BIT", "ASCII"=>"US-ASCII", "ANSI_X3.4-1968"=>"US-ASCII",
1862 * "SJIS"=>"Windows-31J", "eucJP"=>"EUC-JP", "CP932"=>"Windows-31J"}
1863 *
1864 */
1865
1866static VALUE
1867rb_enc_aliases(VALUE klass)
1868{
1869 VALUE aliases[2];
1870 aliases[0] = rb_hash_new();
1871 aliases[1] = rb_ary_new();
1872
1873 st_foreach(global_enc_table.names, rb_enc_aliases_enc_i, (st_data_t)aliases);
1874
1875 return aliases[0];
1876}
1877
1878/*
1879 * An \Encoding instance represents a character encoding usable in Ruby.
1880 * It is defined as a constant under the \Encoding namespace.
1881 * It has a name and, optionally, aliases:
1882 *
1883 * Encoding::US_ASCII.name # => "US-ASCII"
1884 * Encoding::US_ASCII.names # => ["US-ASCII", "ASCII", "ANSI_X3.4-1968", "646"]
1885 *
1886 * A Ruby method that accepts an encoding as an argument will accept:
1887 *
1888 * - An \Encoding object.
1889 * - The name of an encoding.
1890 * - An alias for an encoding name.
1891 *
1892 * These are equivalent:
1893 *
1894 * 'foo'.encode(Encoding::US_ASCII) # Encoding object.
1895 * 'foo'.encode('US-ASCII') # Encoding name.
1896 * 'foo'.encode('ASCII') # Encoding alias.
1897 *
1898 * For a full discussion of encodings and their uses,
1899 * see {the Encodings document}[rdoc-ref:encodings.rdoc].
1900 *
1901 * Encoding::ASCII_8BIT is a special-purpose encoding that is usually used for
1902 * a string of bytes, not a string of characters.
1903 * But as the name indicates, its characters in the ASCII range
1904 * are considered as ASCII characters.
1905 * This is useful when you use other ASCII-compatible encodings.
1906 *
1907 */
1908
1909void
1910Init_Encoding(void)
1911{
1912 VALUE list;
1913 int i;
1914
1915 rb_cEncoding = rb_define_class("Encoding", rb_cObject);
1916 rb_define_alloc_func(rb_cEncoding, enc_s_alloc);
1917 rb_undef_method(CLASS_OF(rb_cEncoding), "new");
1918 rb_define_method(rb_cEncoding, "to_s", enc_name, 0);
1919 rb_define_method(rb_cEncoding, "inspect", enc_inspect, 0);
1920 rb_define_method(rb_cEncoding, "name", enc_name, 0);
1921 rb_define_method(rb_cEncoding, "names", enc_names, 0);
1922 rb_define_method(rb_cEncoding, "dummy?", enc_dummy_p, 0);
1923 rb_define_method(rb_cEncoding, "ascii_compatible?", enc_ascii_compatible_p, 0);
1924 rb_define_method(rb_cEncoding, "replicate", enc_replicate_m, 1);
1925 rb_define_singleton_method(rb_cEncoding, "list", enc_list, 0);
1926 rb_define_singleton_method(rb_cEncoding, "name_list", rb_enc_name_list, 0);
1927 rb_define_singleton_method(rb_cEncoding, "aliases", rb_enc_aliases, 0);
1928 rb_define_singleton_method(rb_cEncoding, "find", enc_find, 1);
1929 rb_define_singleton_method(rb_cEncoding, "compatible?", enc_compatible_p, 2);
1930
1931 rb_define_method(rb_cEncoding, "_dump", enc_dump, -1);
1932 rb_define_singleton_method(rb_cEncoding, "_load", enc_load, 1);
1933
1934 rb_define_singleton_method(rb_cEncoding, "default_external", get_default_external, 0);
1935 rb_define_singleton_method(rb_cEncoding, "default_external=", set_default_external, 1);
1936 rb_define_singleton_method(rb_cEncoding, "default_internal", get_default_internal, 0);
1937 rb_define_singleton_method(rb_cEncoding, "default_internal=", set_default_internal, 1);
1938 rb_define_singleton_method(rb_cEncoding, "locale_charmap", rb_locale_charmap, 0); /* in localeinit.c */
1939
1940 struct enc_table *enc_table = &global_enc_table;
1941
1942 list = rb_encoding_list = rb_ary_new2(ENCODING_LIST_CAPA);
1943 RBASIC_CLEAR_CLASS(list);
1944 rb_gc_register_mark_object(list);
1945
1946 for (i = 0; i < enc_table->count; ++i) {
1947 rb_ary_push(list, enc_new(enc_table->list[i].enc));
1948 }
1949
1950 rb_marshal_define_compat(rb_cEncoding, Qnil, 0, enc_m_loader);
1951}
1952
1953void
1954Init_encodings(void)
1955{
1956 rb_enc_init(&global_enc_table);
1957}
1958
1959/* locale insensitive ctype functions */
1960
1961void
1962rb_enc_foreach_name(int (*func)(st_data_t name, st_data_t idx, st_data_t arg), st_data_t arg)
1963{
1964 st_foreach(global_enc_table.names, func, arg);
1965}
RUBY_ASSERT
#define RUBY_ASSERT(expr)
Asserts that the given expression is truthy if and only if RUBY_DEBUG is truthy.
Definition assert.h:177
rb_define_method
#define rb_define_method(klass, mid, func, arity)
Defines klass#mid.
Definition cxxanyargs.hpp:670
rb_define_singleton_method
#define rb_define_singleton_method(klass, mid, func, arity)
Defines klass.mid.
Definition cxxanyargs.hpp:685
rb_enc_isascii
static bool rb_enc_isascii(OnigCodePoint c, rb_encoding *enc)
Identical to rb_isascii(), except it additionally takes an encoding.
Definition ctype.h:82
rb_enc_sprintf
VALUE rb_enc_sprintf(rb_encoding *enc, const char *fmt,...)
Identical to rb_sprintf(), except it additionally takes an encoding.
Definition sprintf.c:1200
RUBY_FL_SHAREABLE
@ RUBY_FL_SHAREABLE
This flag has something to do with Ractor.
Definition fl_type.h:298
rb_define_class
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
Definition class.c:923
rb_undef_method
void rb_undef_method(VALUE klass, const char *name)
Defines an undef of a method.
Definition class.c:2113
ENCODING_SET_INLINED
#define ENCODING_SET_INLINED(obj, i)
Old name of RB_ENCODING_SET_INLINED.
Definition encoding.h:105
ENC_CODERANGE_7BIT
#define ENC_CODERANGE_7BIT
Old name of RUBY_ENC_CODERANGE_7BIT.
Definition coderange.h:180
T_FILE
#define T_FILE
Old name of RUBY_T_FILE.
Definition value_type.h:62
T_STRING
#define T_STRING
Old name of RUBY_T_STRING.
Definition value_type.h:78
xfree
#define xfree
Old name of ruby_xfree.
Definition xmalloc.h:58
ISUPPER
#define ISUPPER
Old name of rb_isupper.
Definition ctype.h:89
SPECIAL_CONST_P
#define SPECIAL_CONST_P
Old name of RB_SPECIAL_CONST_P.
Definition special_consts.h:56
UNREACHABLE_RETURN
#define UNREACHABLE_RETURN
Old name of RBIMPL_UNREACHABLE_RETURN.
Definition assume.h:29
T_DATA
#define T_DATA
Old name of RUBY_T_DATA.
Definition value_type.h:60
CLASS_OF
#define CLASS_OF
Old name of rb_class_of.
Definition globals.h:203
xmalloc
#define xmalloc
Old name of ruby_xmalloc.
Definition xmalloc.h:53
ISDIGIT
#define ISDIGIT
Old name of rb_isdigit.
Definition ctype.h:93
ISLOWER
#define ISLOWER
Old name of rb_islower.
Definition ctype.h:90
ASSUME
#define ASSUME
Old name of RBIMPL_ASSUME.
Definition assume.h:27
MBCLEN_CHARFOUND_LEN
#define MBCLEN_CHARFOUND_LEN(ret)
Old name of ONIGENC_MBCLEN_CHARFOUND_LEN.
Definition encoding.h:533
ENCODING_INLINE_MAX
#define ENCODING_INLINE_MAX
Old name of RUBY_ENCODING_INLINE_MAX.
Definition encoding.h:66
STRCASECMP
#define STRCASECMP
Old name of st_locale_insensitive_strcasecmp.
Definition ctype.h:102
ISASCII
#define ISASCII
Old name of rb_isascii.
Definition ctype.h:85
TOLOWER
#define TOLOWER
Old name of rb_tolower.
Definition ctype.h:101
NUM2INT
#define NUM2INT
Old name of RB_NUM2INT.
Definition int.h:44
INT2NUM
#define INT2NUM
Old name of RB_INT2NUM.
Definition int.h:43
Qnil
#define Qnil
Old name of RUBY_Qnil.
Definition special_consts.h:60
Qfalse
#define Qfalse
Old name of RUBY_Qfalse.
Definition special_consts.h:59
NIL_P
#define NIL_P
Old name of RB_NIL_P.
Definition special_consts.h:55
MBCLEN_CHARFOUND_P
#define MBCLEN_CHARFOUND_P(ret)
Old name of ONIGENC_MBCLEN_CHARFOUND_P.
Definition encoding.h:532
T_SYMBOL
#define T_SYMBOL
Old name of RUBY_T_SYMBOL.
Definition value_type.h:80
ENC_CODERANGE_ASCIIONLY
#define ENC_CODERANGE_ASCIIONLY(obj)
Old name of RB_ENC_CODERANGE_ASCIIONLY.
Definition coderange.h:185
BUILTIN_TYPE
#define BUILTIN_TYPE
Old name of RB_BUILTIN_TYPE.
Definition value_type.h:85
ENCODING_GET_INLINED
#define ENCODING_GET_INLINED(obj)
Old name of RB_ENCODING_GET_INLINED.
Definition encoding.h:107
ENC_CODERANGE_CLEAR
#define ENC_CODERANGE_CLEAR(obj)
Old name of RB_ENC_CODERANGE_CLEAR.
Definition coderange.h:187
CONST_ID
#define CONST_ID
Old name of RUBY_CONST_ID.
Definition symbol.h:47
rb_ary_new2
#define rb_ary_new2
Old name of rb_ary_new_capa.
Definition array.h:651
ISALNUM
#define ISALNUM
Old name of rb_isalnum.
Definition ctype.h:91
FL_SET_RAW
#define FL_SET_RAW
Old name of RB_FL_SET_RAW.
Definition fl_type.h:138
SYMBOL_P
#define SYMBOL_P
Old name of RB_SYMBOL_P.
Definition value_type.h:88
T_REGEXP
#define T_REGEXP
Old name of RUBY_T_REGEXP.
Definition value_type.h:77
ruby_debug
#define ruby_debug
This variable controls whether the interpreter is in debug mode.
Definition error.h:470
rb_raise
void rb_raise(VALUE exc, const char *fmt,...)
Exception entry point.
Definition error.c:3150
rb_bug
void rb_bug(const char *fmt,...)
Interpreter panic switch.
Definition error.c:794
rb_set_errinfo
void rb_set_errinfo(VALUE err)
Sets the current exception ($!) to the given value.
Definition eval.c:1884
rb_eTypeError
VALUE rb_eTypeError
TypeError exception.
Definition error.c:1091
rb_eEncCompatError
VALUE rb_eEncCompatError
Encoding::CompatibilityError exception.
Definition error.c:1098
rb_warn
void rb_warn(const char *fmt,...)
Identical to rb_warning(), except it reports always regardless of runtime -W flag.
Definition error.c:411
rb_eArgError
VALUE rb_eArgError
ArgumentError exception.
Definition error.c:1092
rb_loaderror
void rb_loaderror(const char *fmt,...)
Raises an instance of rb_eLoadError.
Definition error.c:3169
rb_errinfo
VALUE rb_errinfo(void)
This is the same as $! in Ruby.
Definition eval.c:1878
rb_eEncodingError
VALUE rb_eEncodingError
EncodingError exception.
Definition error.c:1097
rb_warning
void rb_warning(const char *fmt,...)
Issues a warning.
Definition error.c:442
rb_obj_class
VALUE rb_obj_class(VALUE obj)
Queries the class of an object.
Definition object.c:191
rb_cEncoding
VALUE rb_cEncoding
Encoding class.
Definition encoding.c:57
rb_obj_freeze
VALUE rb_obj_freeze(VALUE obj)
Just calls rb_obj_freeze_inline() inside.
Definition object.c:1183
encoding.h
Encoding relates APIs.
rb_enc_name
static const char * rb_enc_name(rb_encoding *enc)
Queries the (canonical) name of the passed encoding.
Definition encoding.h:433
rb_locale_charmap
VALUE rb_locale_charmap(VALUE klass)
Returns a platform-depended "charmap" of the current locale.
Definition localeinit.c:91
rb_enc_asciicompat
static bool rb_enc_asciicompat(rb_encoding *enc)
Queries if the passed encoding is in some sense compatible with ASCII.
Definition encoding.h:784
rb_enc_mbc_to_codepoint
static OnigCodePoint rb_enc_mbc_to_codepoint(const char *p, const char *e, rb_encoding *enc)
Identical to rb_enc_codepoint(), except it assumes the passed character is not broken.
Definition encoding.h:607
rb_enc_mbminlen
static int rb_enc_mbminlen(rb_encoding *enc)
Queries the minimum number of bytes that the passed encoding needs to represent a character.
Definition encoding.h:448
rb_enc_str_coderange
int rb_enc_str_coderange(VALUE str)
Scans the passed string to collect its code range.
Definition string.c:821
rb_enc_str_asciionly_p
int rb_enc_str_asciionly_p(VALUE str)
Queries if the passed string is "ASCII only".
Definition string.c:833
rb_check_frozen
#define rb_check_frozen
Just another name of rb_check_frozen.
Definition error.h:264
rb_check_arity
static int rb_check_arity(int argc, int min, int max)
Ensures that the passed integer is in the passed range.
Definition error.h:280
rb_check_string_type
VALUE rb_check_string_type(VALUE obj)
Try converting an object to its stringised representation using its to_str method,...
Definition string.c:2640
rb_attr_get
VALUE rb_attr_get(VALUE obj, ID name)
Identical to rb_ivar_get()
Definition variable.c:1226
rb_ivar_set
VALUE rb_ivar_set(VALUE obj, ID name, VALUE val)
Identical to rb_iv_set(), except it accepts the name as an ID instead of a C string.
Definition variable.c:1606
rb_ivar_get
VALUE rb_ivar_get(VALUE obj, ID name)
Identical to rb_iv_get(), except it accepts the name as an ID instead of a C string.
Definition variable.c:1218
rb_define_alloc_func
void rb_define_alloc_func(VALUE klass, rb_alloc_func_t func)
Sets the allocator function of a class.
rb_intern
ID rb_intern(const char *name)
Finds or creates a symbol of the given name.
Definition symbol.c:796
rb_sym2str
VALUE rb_sym2str(VALUE id)
Identical to rb_id2str(), except it takes an instance of rb_cSymbol rather than an ID.
Definition symbol.c:943
rb_define_const
void rb_define_const(VALUE klass, const char *name, VALUE val)
Defines a Ruby level constant under a namespace.
Definition variable.c:3440
util.h
strdup
#define strdup(s)
Just another name of ruby_strdup.
Definition util.h:176
rb_sprintf
VALUE rb_sprintf(const char *fmt,...)
Ruby's extended sprintf(3).
Definition sprintf.c:1219
rb_marshal_define_compat
void rb_marshal_define_compat(VALUE newclass, VALUE oldclass, VALUE(*dumper)(VALUE), VALUE(*loader)(VALUE, VALUE))
Marshal format compatibility layer.
Definition marshal.c:150
MEMCPY
#define MEMCPY(p1, p2, type, n)
Handy macro to call memcpy.
Definition memory.h:366
ALLOCA_N
#define ALLOCA_N(type, n)
Definition memory.h:286
RB_GC_GUARD
#define RB_GC_GUARD(v)
Prevents premature destruction of local objects.
Definition memory.h:161
DATA_PTR
#define DATA_PTR(obj)
Convenient getter macro.
Definition rdata.h:71
RDATA
#define RDATA(obj)
Convenient casting macro.
Definition rdata.h:63
StringValue
#define StringValue(v)
Ensures that the parameter object is a String.
Definition rstring.h:72
RSTRING_END
static char * RSTRING_END(VALUE str)
Queries the end of the contents pointer of the string.
Definition rstring.h:528
RSTRING_LEN
static long RSTRING_LEN(VALUE str)
Queries the length of the string.
Definition rstring.h:484
RSTRING_PTR
static char * RSTRING_PTR(VALUE str)
Queries the contents pointer of the string.
Definition rstring.h:498
TypedData_Wrap_Struct
#define TypedData_Wrap_Struct(klass, data_type, sval)
Converts sval, a pointer to your struct, into a Ruby object.
Definition rtypeddata.h:441
OnigEncodingTypeST
Definition onigmo.h:160
default_encoding
Definition encoding.c:1538
enc_table
Definition encoding.c:68
rb_data_type_struct
This is the struct that holds necessary info for a struct.
Definition rtypeddata.h:190
rb_encoding_entry
Definition encoding.c:62
st_table
Definition st.h:79
ID
uintptr_t ID
Type that represents a Ruby identifier such as a variable name.
Definition value.h:52
VALUE
uintptr_t VALUE
Type that represents a Ruby object.
Definition value.h:40
RB_TYPE_P
static bool RB_TYPE_P(VALUE obj, enum ruby_value_type t)
Queries if the given object is of given type.
Definition value_type.h:375