~ubuntu-branches/ubuntu/quantal/ruby1.9.1/quantal

« back to all changes in this revision

Viewing changes to encoding.c

  • Committer: Bazaar Package Importer
  • Author(s): Lucas Nussbaum
  • Date: 2010-07-31 17:08:39 UTC
  • mfrom: (1.1.4 upstream) (8.1.2 sid)
  • Revision ID: james.westby@ubuntu.com-20100731170839-j034dmpdqt1cc4p6
Tags: 1.9.2~svn28788-1
* New release based on upstream snapshot from the 1.9.2 branch,
  after 1.9.2 RC2. That branch is (supposed to be) binary-compatible
  with the 1.9.1 branch.
  + Builds fine on i386. Closes: #580852.
* Upgrade to Standards-Version: 3.9.1. No changes needed.
* Updated generated incs.
* Patches that still need work:
  + Unclear status, need more investigation:
   090729_fix_Makefile_deps.dpatch
   090803_exclude_rdoc.dpatch
   203_adjust_base_of_search_path.dpatch
   902_define_YAML_in_yaml_stringio.rb.dpatch
   919_common.mk_tweaks.dpatch
   931_libruby_suffix.dpatch
   940_test_thread_mutex_sync_shorter.dpatch
  + Maybe not needed anymore, keeping but not applying.
   102_skip_test_copy_stream.dpatch (test doesn't block anymore?)
   104_skip_btest_io.dpatch (test doesn't block anymore?)
   201_gem_prelude.dpatch (we don't use that rubygems anyway?)
   202_gem_default_dir.dpatch (we don't use that rubygems anyway?)
   940_test_file_exhaustive_fails_as_root.dpatch
   940_test_priority_fails.dpatch
   100518_load_libc_libm.dpatch
* Add disable-tests.diff: disable some tests that cause failures on FreeBSD.
  Closes: #590002, #543805, #542927.
* However, many new failures on FreeBSD. Since that version is still an
  improvement, add the check that makes test suite failures non-fatal on
  FreeBSD again. That still needs to be investigated.
* Re-add 903_skip_base_ruby_check.dpatch
* Add build-dependency on ruby1.8 and drop all pre-generated files.

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 
3
3
  encoding.c -
4
4
 
5
 
  $Author: yugui $
 
5
  $Author: naruse $
6
6
  created at: Thu May 24 17:23:27 JST 2007
7
7
 
8
8
  Copyright (C) 2007 Yukihiro Matsumoto
45
45
#define ENCODING_COUNT ENCINDEX_BUILTIN_MAX
46
46
#define UNSPECIFIED_ENCODING INT_MAX
47
47
 
 
48
#define ENCODING_NAMELEN_MAX 63
 
49
#define valid_encoding_name_p(name) ((name) && strlen(name) <= ENCODING_NAMELEN_MAX)
 
50
 
48
51
#define enc_autoload_p(enc) (!rb_enc_mbmaxlen(enc))
49
52
 
50
53
static int load_encoding(const char *name);
51
54
 
52
 
static void
53
 
enc_mark(void *ptr)
 
55
static size_t
 
56
enc_memsize(const void *p)
54
57
{
 
58
    return 0;
55
59
}
56
60
 
 
61
static const rb_data_type_t encoding_data_type = {
 
62
    "encoding", 0, 0, enc_memsize,
 
63
};
 
64
 
 
65
#define is_data_encoding(obj) (RTYPEDDATA_P(obj) && RTYPEDDATA_TYPE(obj) == &encoding_data_type)
 
66
 
57
67
static VALUE
58
68
enc_new(rb_encoding *encoding)
59
69
{
60
 
    return Data_Wrap_Struct(rb_cEncoding, enc_mark, 0, encoding);
 
70
    return TypedData_Wrap_Struct(rb_cEncoding, &encoding_data_type, encoding);
61
71
}
62
72
 
63
 
VALUE
64
 
rb_enc_from_encoding(rb_encoding *encoding)
 
73
static VALUE
 
74
rb_enc_from_encoding_index(int idx)
65
75
{
66
76
    VALUE list, enc;
67
 
    int idx;
68
77
 
69
 
    if (!encoding) return Qnil;
70
 
    idx = ENC_TO_ENCINDEX(encoding);
71
78
    if (!(list = rb_encoding_list)) {
72
 
        rb_bug("rb_enc_from_encoding(%d\"%s\"): no rb_encoding_list",
73
 
               idx, rb_enc_name(encoding));
 
79
        rb_bug("rb_enc_from_encoding_index(%d): no rb_encoding_list", idx);
74
80
    }
75
81
    enc = rb_ary_entry(list, idx);
76
82
    if (NIL_P(enc)) {
77
 
        rb_bug("rb_enc_from_encoding(%d\"%s\"): not created yet",
78
 
               idx, rb_enc_name(encoding));
 
83
        rb_bug("rb_enc_from_encoding_index(%d): not created yet", idx);
79
84
    }
80
85
    return enc;
81
86
}
82
87
 
 
88
VALUE
 
89
rb_enc_from_encoding(rb_encoding *encoding)
 
90
{
 
91
    int idx;
 
92
    if (!encoding) return Qnil;
 
93
    idx = ENC_TO_ENCINDEX(encoding);
 
94
    return rb_enc_from_encoding_index(idx);
 
95
}
 
96
 
83
97
static int enc_autoload(rb_encoding *);
84
98
 
85
99
static int
97
111
static int
98
112
enc_check_encoding(VALUE obj)
99
113
{
100
 
    if (SPECIAL_CONST_P(obj) || BUILTIN_TYPE(obj) != T_DATA ||
101
 
        RDATA(obj)->dmark != enc_mark) {
 
114
    if (SPECIAL_CONST_P(obj) || !rb_typeddata_is_kind_of(obj, &encoding_data_type)) {
102
115
        return -1;
103
116
    }
104
117
    return check_encoding(RDATA(obj)->data);
183
196
    struct rb_encoding_entry *ent = &enc_table.list[index];
184
197
    VALUE list;
185
198
 
 
199
    if (!valid_encoding_name_p(name)) return -1;
186
200
    if (!ent->name) {
187
201
        ent->name = name = strdup(name);
188
202
    }
275
289
    return enc;
276
290
}
277
291
 
 
292
/* for encdb.h
 
293
 * Set base encoding for encodings which are not replicas
 
294
 * but not in their own files.
 
295
 */
 
296
void
 
297
rb_enc_set_base(const char *name, const char *orig)
 
298
{
 
299
    int idx = rb_enc_registered(name);
 
300
    int origidx = rb_enc_registered(orig);
 
301
    set_base_encoding(idx, rb_enc_from_index(origidx));
 
302
}
 
303
 
278
304
int
279
305
rb_enc_replicate(const char *name, rb_encoding *encoding)
280
306
{
287
313
    return idx;
288
314
}
289
315
 
 
316
/*
 
317
 * call-seq:
 
318
 *   enc.replicate(name) -> encoding
 
319
 *
 
320
 * Returns a replicated encoding of _enc_ whose name is _name_.
 
321
 * The new encoding should have the same byte structure of _enc_.
 
322
 * If _name_ is used by another encoding, raise ArgumentError.
 
323
 *
 
324
 */
 
325
static VALUE
 
326
enc_replicate(VALUE encoding, VALUE name)
 
327
{
 
328
    return rb_enc_from_encoding_index(
 
329
        rb_enc_replicate(StringValueCStr(name),
 
330
                         rb_to_encoding(encoding)));
 
331
}
 
332
 
290
333
static int
291
 
enc_replicate(int idx, const char *name, rb_encoding *origenc)
 
334
enc_replicate_with_index(const char *name, rb_encoding *origenc, int idx)
292
335
{
293
336
    if (idx < 0) {
294
337
        idx = enc_register(name, origenc);
312
355
    if (origidx < 0) {
313
356
        origidx = enc_register(orig, 0);
314
357
    }
315
 
    return enc_replicate(idx, name, rb_enc_from_index(origidx));
 
358
    return enc_replicate_with_index(name, rb_enc_from_index(origidx), idx);
316
359
}
317
360
 
318
361
int
328
371
int
329
372
rb_encdb_dummy(const char *name)
330
373
{
331
 
    int index = enc_replicate(rb_enc_registered(name), name,
332
 
                              rb_ascii8bit_encoding());
 
374
    int index = enc_replicate_with_index(name, rb_ascii8bit_encoding(),
 
375
                                         rb_enc_registered(name));
333
376
    rb_encoding *enc = enc_table.list[index].enc;
334
377
 
335
378
    ENC_SET_DUMMY(enc);
338
381
 
339
382
/*
340
383
 * call-seq:
341
 
 *   enc.dummy? => true or false
 
384
 *   enc.dummy? -> true or false
342
385
 *
343
386
 * Returns true for dummy encodings.
344
387
 * A dummy encoding is an encoding for which character handling is not properly
355
398
    return ENC_DUMMY_P(enc_table.list[must_encoding(enc)].enc) ? Qtrue : Qfalse;
356
399
}
357
400
 
 
401
/*
 
402
 * call-seq:
 
403
 *   enc.ascii_compatible? -> true or false
 
404
 *
 
405
 * Returns whether ASCII-compatible or not.
 
406
 *
 
407
 *   Encoding::UTF_8.ascii_compatible?     #=> true
 
408
 *   Encoding::UTF_16BE.ascii_compatible?  #=> false
 
409
 *
 
410
 */
 
411
static VALUE
 
412
enc_ascii_compatible_p(VALUE enc)
 
413
{
 
414
    return rb_enc_asciicompat(enc_table.list[must_encoding(enc)].enc) ? Qtrue : Qfalse;
 
415
}
 
416
 
 
417
/*
 
418
 * Returns 1 when the encoding is Unicode series other than UTF-7 else 0.
 
419
 */
 
420
int
 
421
rb_enc_unicode_p(rb_encoding *enc)
 
422
{
 
423
    const char *name = rb_enc_name(enc);
 
424
    return name[0] == 'U' && name[1] == 'T' && name[2] == 'F' && name[4] != '7';
 
425
}
 
426
 
358
427
static const char *
359
428
enc_alias_internal(const char *alias, int idx)
360
429
{
366
435
static int
367
436
enc_alias(const char *alias, int idx)
368
437
{
 
438
    if (!valid_encoding_name_p(alias)) return -1;
369
439
    alias = enc_alias_internal(alias, idx);
370
440
    set_encoding_const(alias, rb_enc_from_index(idx));
371
441
    return idx;
544
614
      case T_STRING:
545
615
      case T_REGEXP:
546
616
      case T_FILE:
547
 
        return Qtrue;
 
617
        return TRUE;
548
618
      case T_DATA:
549
 
        if (RDATA(obj)->dmark == enc_mark) return Qtrue;
 
619
        if (is_data_encoding(obj)) return TRUE;
550
620
      default:
551
 
        return Qfalse;
 
621
        return FALSE;
552
622
    }
553
623
}
554
624
 
588
658
        else obj = tmp;
589
659
        if (NIL_P(obj)) break;
590
660
      case T_DATA:
591
 
        if (RDATA(obj)->dmark == enc_mark) {
 
661
        if (is_data_encoding(obj)) {
592
662
            i = enc_check_encoding(obj);
593
663
        }
594
664
        else {
616
686
{
617
687
/*    enc_check_capable(obj);*/
618
688
    if (rb_enc_get_index(obj) == idx)
619
 
        return obj;
 
689
        return obj;
620
690
    if (SPECIAL_CONST_P(obj)) {
621
691
        rb_raise(rb_eArgError, "cannot set encoding");
622
692
    }
670
740
    enc2 = rb_enc_from_index(idx2);
671
741
 
672
742
    if (TYPE(str2) == T_STRING && RSTRING_LEN(str2) == 0)
673
 
        return enc1;
 
743
        return (idx1 == ENCINDEX_US_ASCII && rb_enc_asciicompat(enc2)) ? enc2 : enc1;
674
744
    if (TYPE(str1) == T_STRING && RSTRING_LEN(str1) == 0)
675
 
        return enc2;
 
745
        return (idx2 == ENCINDEX_US_ASCII && rb_enc_asciicompat(enc1)) ? enc1 : enc2;
676
746
    if (!rb_enc_asciicompat(enc1) || !rb_enc_asciicompat(enc2)) {
677
747
        return 0;
678
748
    }
722
792
 
723
793
/*
724
794
 *  call-seq:
725
 
 *     obj.encoding   => encoding
 
795
 *     obj.encoding   -> encoding
726
796
 *
727
797
 *  Returns the Encoding object that represents the encoding of obj.
728
798
 */
738
808
}
739
809
 
740
810
int
 
811
rb_enc_fast_mbclen(const char *p, const char *e, rb_encoding *enc)
 
812
{
 
813
    return ONIGENC_MBC_ENC_LEN(enc, (UChar*)p, (UChar*)e);
 
814
}
 
815
 
 
816
int
741
817
rb_enc_mbclen(const char *p, const char *e, rb_encoding *enc)
742
818
{
743
819
    int n = ONIGENC_PRECISE_MBC_ENC_LEN(enc, (UChar*)p, (UChar*)e);
745
821
        return MBCLEN_CHARFOUND_LEN(n);
746
822
    else {
747
823
        int min = rb_enc_mbminlen(enc);
748
 
        return min <= e-p ? min : e-p;
 
824
        return min <= e-p ? min : (int)(e-p);
749
825
    }
750
826
}
751
827
 
757
833
        return ONIGENC_CONSTRUCT_MBCLEN_NEEDMORE(1);
758
834
    n = ONIGENC_PRECISE_MBC_ENC_LEN(enc, (UChar*)p, (UChar*)e);
759
835
    if (e-p < n)
760
 
        return ONIGENC_CONSTRUCT_MBCLEN_NEEDMORE(n-(e-p));
 
836
        return ONIGENC_CONSTRUCT_MBCLEN_NEEDMORE(n-(int)(e-p));
761
837
    return n;
762
838
}
763
839
 
785
861
}
786
862
 
787
863
unsigned int
788
 
rb_enc_codepoint(const char *p, const char *e, rb_encoding *enc)
 
864
rb_enc_codepoint_len(const char *p, const char *e, int *len_p, rb_encoding *enc)
789
865
{
790
866
    int r;
791
867
    if (e <= p)
792
868
        rb_raise(rb_eArgError, "empty string");
793
869
    r = rb_enc_precise_mbclen(p, e, enc);
794
 
    if (MBCLEN_CHARFOUND_P(r))
 
870
    if (MBCLEN_CHARFOUND_P(r)) {
 
871
        if (len_p) *len_p = MBCLEN_CHARFOUND_LEN(r);
795
872
        return rb_enc_mbc_to_codepoint(p, e, enc);
 
873
    }
796
874
    else
797
875
        rb_raise(rb_eArgError, "invalid byte sequence in %s", rb_enc_name(enc));
798
876
}
799
877
 
 
878
#undef rb_enc_codepoint
 
879
unsigned int
 
880
rb_enc_codepoint(const char *p, const char *e, rb_encoding *enc)
 
881
{
 
882
    return rb_enc_codepoint_len(p, e, 0, enc);
 
883
}
 
884
 
800
885
int
801
886
rb_enc_codelen(int c, rb_encoding *enc)
802
887
{
821
906
 
822
907
/*
823
908
 * call-seq:
824
 
 *   enc.inspect => string
 
909
 *   enc.inspect -> string
825
910
 *
826
911
 * Returns a string which represents the encoding for programmers.
827
912
 *
840
925
 
841
926
/*
842
927
 * call-seq:
843
 
 *   enc.name => string
 
928
 *   enc.name -> string
844
929
 *
845
930
 * Returns the name of the encoding.
846
931
 *
847
 
 *   Encoding::UTF_8.name       => "UTF-8"
 
932
 *   Encoding::UTF_8.name      #=> "UTF-8"
848
933
 */
849
934
static VALUE
850
935
enc_name(VALUE self)
867
952
 
868
953
/*
869
954
 * call-seq:
870
 
 *   enc.names => array
 
955
 *   enc.names -> array
871
956
 *
872
957
 * Returns the list of name and aliases of the encoding.
873
958
 *
874
 
 *   Encoding::WINDOWS_31J.names => ["Windows-31J", "CP932", "csWindows31J"]
 
959
 *   Encoding::WINDOWS_31J.names  #=> ["Windows-31J", "CP932", "csWindows31J"]
875
960
 */
876
961
static VALUE
877
962
enc_names(VALUE self)
886
971
 
887
972
/*
888
973
 * call-seq:
889
 
 *   Encoding.list => [enc1, enc2, ...]
 
974
 *   Encoding.list -> [enc1, enc2, ...]
890
975
 *
891
976
 * Returns the list of loaded encodings.
892
977
 *
893
978
 *   Encoding.list
894
 
 *   => [#<Encoding:ASCII-8BIT>, #<Encoding:UTF-8>,
895
 
 *       #<Encoding:ISO-2022-JP (dummy)>]
 
979
 *   #=> [#<Encoding:ASCII-8BIT>, #<Encoding:UTF-8>,
 
980
 *         #<Encoding:ISO-2022-JP (dummy)>]
896
981
 *
897
982
 *   Encoding.find("US-ASCII")
898
 
 *   => #<Encoding:US-ASCII>
 
983
 *   #=> #<Encoding:US-ASCII>
899
984
 *
900
985
 *   Encoding.list
901
 
 *   => [#<Encoding:ASCII-8BIT>, #<Encoding:UTF-8>,
902
 
 *       #<Encoding:US-ASCII>, #<Encoding:ISO-2022-JP (dummy)>]
 
986
 *   #=> [#<Encoding:ASCII-8BIT>, #<Encoding:UTF-8>,
 
987
 *         #<Encoding:US-ASCII>, #<Encoding:ISO-2022-JP (dummy)>]
903
988
 *
904
989
 */
905
990
static VALUE
912
997
 
913
998
/*
914
999
 * call-seq:
915
 
 *   Encoding.find(string) => enc
916
 
 *   Encoding.find(symbol) => enc
 
1000
 *   Encoding.find(string) -> enc
 
1001
 *   Encoding.find(symbol) -> enc
917
1002
 *
918
1003
 * Search the encoding with specified <i>name</i>.
919
1004
 * <i>name</i> should be a string or symbol.
920
1005
 *
921
 
 *   Encoding.find("US-ASCII")  => #<Encoding:US-ASCII>
922
 
 *   Encoding.find(:Shift_JIS)  => #<Encoding:Shift_JIS>
 
1006
 *   Encoding.find("US-ASCII")  #=> #<Encoding:US-ASCII>
 
1007
 *   Encoding.find(:Shift_JIS)  #=> #<Encoding:Shift_JIS>
923
1008
 *
924
1009
 * Names which this method accept are encoding names and aliases
925
1010
 * including following special aliases
942
1027
 
943
1028
/*
944
1029
 * call-seq:
945
 
 *   Encoding.compatible?(str1, str2) => enc or nil
 
1030
 *   Encoding.compatible?(str1, str2) -> enc or nil
946
1031
 *
947
1032
 * Checks the compatibility of two strings.
948
 
 * If they are compatible, means concatenatable, 
949
 
 * returns an encoding which the concatinated string will be.
 
1033
 * If they are compatible, means concatenatable,
 
1034
 * returns an encoding which the concatenated string will be.
950
1035
 * If they are not compatible, nil is returned.
951
1036
 *
952
1037
 *   Encoding.compatible?("\xa1".force_encoding("iso-8859-1"), "b")
953
 
 *   => #<Encoding:ISO-8859-1>
 
1038
 *   #=> #<Encoding:ISO-8859-1>
954
1039
 *
955
1040
 *   Encoding.compatible?(
956
1041
 *     "\xa1".force_encoding("iso-8859-1"),
957
1042
 *     "\xa1\xa1".force_encoding("euc-jp"))
958
 
 *   => nil
 
1043
 *   #=> nil
959
1044
 *
960
1045
 */
961
1046
static VALUE
1030
1115
    return ENCINDEX_US_ASCII;
1031
1116
}
1032
1117
 
1033
 
static int
 
1118
int
1034
1119
rb_locale_encindex(void)
1035
1120
{
1036
1121
    VALUE charmap = rb_locale_charmap(rb_cEncoding);
1053
1138
}
1054
1139
 
1055
1140
static int
1056
 
rb_filesystem_encindex(void)
 
1141
enc_set_filesystem_encoding(void)
1057
1142
{
1058
1143
    int idx;
1059
1144
#if defined NO_LOCALE_CHARMAP
1062
1147
    char cp[sizeof(int) * 8 / 3 + 4];
1063
1148
    snprintf(cp, sizeof cp, "CP%d", AreFileApisANSI() ? GetACP() : GetOEMCP());
1064
1149
    idx = rb_enc_find_index(cp);
1065
 
#elif defined __APPLE__
1066
 
    idx = rb_enc_to_index(rb_enc_find("UTF8-MAC"));
 
1150
    if (idx < 0) idx = rb_ascii8bit_encindex();
1067
1151
#else
1068
1152
    idx = rb_enc_to_index(rb_default_external_encoding());
1069
1153
#endif
1070
1154
 
1071
 
    if (rb_enc_registered("filesystem") < 0) enc_alias_internal("filesystem", idx);
 
1155
    enc_alias_internal("filesystem", idx);
 
1156
    return idx;
 
1157
}
1072
1158
 
 
1159
int
 
1160
rb_filesystem_encindex(void)
 
1161
{
 
1162
    int idx = rb_enc_registered("filesystem");
 
1163
    if (idx < 0)
 
1164
        idx = rb_ascii8bit_encindex();
1073
1165
    return idx;
1074
1166
}
1075
1167
 
1084
1176
    rb_encoding *enc;
1085
1177
};
1086
1178
 
 
1179
static struct default_encoding default_external = {0};
 
1180
 
1087
1181
static int
1088
1182
enc_set_default_encoding(struct default_encoding *def, VALUE encoding, const char *name)
1089
1183
{
1090
 
    int overridden = Qfalse;
 
1184
    int overridden = FALSE;
 
1185
 
1091
1186
    if (def->index != -2)
1092
1187
        /* Already set */
1093
 
        overridden = Qtrue;
 
1188
        overridden = TRUE;
1094
1189
 
1095
1190
    if (NIL_P(encoding)) {
1096
1191
        def->index = -1;
1104
1199
        enc_alias_internal(name, def->index);
1105
1200
    }
1106
1201
 
 
1202
    if (def == &default_external)
 
1203
        enc_set_filesystem_encoding();
 
1204
 
1107
1205
    return overridden;
1108
1206
}
1109
1207
 
1110
 
static struct default_encoding default_external = {0};
1111
 
 
1112
1208
rb_encoding *
1113
1209
rb_default_external_encoding(void)
1114
1210
{
1131
1227
 
1132
1228
/*
1133
1229
 * call-seq:
1134
 
 *   Encoding.default_external => enc
 
1230
 *   Encoding.default_external -> enc
1135
1231
 *
1136
1232
 * Returns default external encoding.
1137
1233
 *
1187
1283
 
1188
1284
/*
1189
1285
 * call-seq:
1190
 
 *   Encoding.default_internal => enc
 
1286
 *   Encoding.default_internal -> enc
1191
1287
 *
1192
1288
 * Returns default internal encoding.
1193
1289
 *
1223
1319
 
1224
1320
/*
1225
1321
 * call-seq:
1226
 
 *   Encoding.locale_charmap => string
 
1322
 *   Encoding.locale_charmap -> string
1227
1323
 *
1228
1324
 * Returns the locale charmap name.
1229
1325
 *
1230
1326
 *   Debian GNU/Linux
1231
1327
 *     LANG=C
1232
 
 *       Encoding.locale_charmap  => "ANSI_X3.4-1968"
 
1328
 *       Encoding.locale_charmap  #=> "ANSI_X3.4-1968"
1233
1329
 *     LANG=ja_JP.EUC-JP
1234
 
 *       Encoding.locale_charmap  => "EUC-JP"
 
1330
 *       Encoding.locale_charmap  #=> "EUC-JP"
1235
1331
 *
1236
1332
 *   SunOS 5
1237
1333
 *     LANG=C
1238
 
 *       Encoding.locale_charmap  => "646"
 
1334
 *       Encoding.locale_charmap  #=> "646"
1239
1335
 *     LANG=ja
1240
 
 *       Encoding.locale_charmap  => "eucJP"
 
1336
 *       Encoding.locale_charmap  #=> "eucJP"
1241
1337
 *
1242
 
 * The result is higly platform dependent.
 
1338
 * The result is highly platform dependent.
1243
1339
 * So Encoding.find(Encoding.locale_charmap) may cause an error.
1244
1340
 * If you need some encoding object even for unknown locale,
1245
1341
 * Encoding.find("locale") can be used.
1283
1379
        }
1284
1380
    }
1285
1381
    if (!*s) {
 
1382
        if (s - name > ENCODING_NAMELEN_MAX) return;
1286
1383
        valid = 1;
1287
1384
        rb_define_const(rb_cEncoding, name, encoding);
1288
1385
    }
1289
1386
    if (!valid || haslower) {
1290
 
        int len = strlen(name) + 1;
 
1387
        size_t len = s - name;
 
1388
        if (len > ENCODING_NAMELEN_MAX) return;
1291
1389
        if (!haslower || !hasupper) {
1292
1390
            do {
1293
1391
                if (ISLOWER(*s)) haslower = 1;
1294
1392
                if (ISUPPER(*s)) hasupper = 1;
1295
1393
            } while (*++s && (!haslower || !hasupper));
 
1394
            len = s - name;
1296
1395
        }
 
1396
        len += strlen(s);
 
1397
        if (len++ > ENCODING_NAMELEN_MAX) return;
1297
1398
        MEMCPY(s = ALLOCA_N(char, len), name, char, len);
1298
1399
        name = s;
1299
1400
        if (!valid) {
1326
1427
 
1327
1428
/*
1328
1429
 * call-seq:
1329
 
 *   Encoding.name_list => ["enc1", "enc2", ...]
 
1430
 *   Encoding.name_list -> ["enc1", "enc2", ...]
1330
1431
 *
1331
1432
 * Returns the list of available encoding names.
1332
1433
 *
1333
1434
 *   Encoding.name_list
1334
 
 *   => ["US-ASCII", "ASCII-8BIT", "UTF-8",
1335
 
 *       "ISO-8859-1", "Shift_JIS", "EUC-JP",
1336
 
 *       "Windows-31J",
1337
 
 *       "BINARY", "CP932", "eucJP"]
 
1435
 *   #=> ["US-ASCII", "ASCII-8BIT", "UTF-8",
 
1436
 *         "ISO-8859-1", "Shift_JIS", "EUC-JP",
 
1437
 *         "Windows-31J",
 
1438
 *         "BINARY", "CP932", "eucJP"]
1338
1439
 *
1339
1440
 */
1340
1441
 
1373
1474
 
1374
1475
/*
1375
1476
 * call-seq:
1376
 
 *   Encoding.aliases => {"alias1" => "orig1", "alias2" => "orig2", ...}
 
1477
 *   Encoding.aliases -> {"alias1" => "orig1", "alias2" => "orig2", ...}
1377
1478
 *
1378
1479
 * Returns the hash of available encoding alias and original encoding name.
1379
1480
 *
1380
1481
 *   Encoding.aliases
1381
 
 *   => {"BINARY"=>"ASCII-8BIT", "ASCII"=>"US-ASCII", "ANSI_X3.4-1986"=>"US-ASCII",
1382
 
 *       "SJIS"=>"Shift_JIS", "eucJP"=>"EUC-JP", "CP932"=>"Windows-31J"}
 
1482
 *   #=> {"BINARY"=>"ASCII-8BIT", "ASCII"=>"US-ASCII", "ANSI_X3.4-1986"=>"US-ASCII",
 
1483
 *         "SJIS"=>"Shift_JIS", "eucJP"=>"EUC-JP", "CP932"=>"Windows-31J"}
1383
1484
 *
1384
1485
 */
1385
1486
 
1403
1504
 
1404
1505
    rb_cEncoding = rb_define_class("Encoding", rb_cObject);
1405
1506
    rb_undef_alloc_func(rb_cEncoding);
 
1507
    rb_undef_method(CLASS_OF(rb_cEncoding), "new");
1406
1508
    rb_define_method(rb_cEncoding, "to_s", enc_name, 0);
1407
1509
    rb_define_method(rb_cEncoding, "inspect", enc_inspect, 0);
1408
1510
    rb_define_method(rb_cEncoding, "name", enc_name, 0);
1409
1511
    rb_define_method(rb_cEncoding, "names", enc_names, 0);
1410
1512
    rb_define_method(rb_cEncoding, "dummy?", enc_dummy_p, 0);
 
1513
    rb_define_method(rb_cEncoding, "ascii_compatible?", enc_ascii_compatible_p, 0);
 
1514
    rb_define_method(rb_cEncoding, "replicate", enc_replicate, 1);
1411
1515
    rb_define_singleton_method(rb_cEncoding, "list", enc_list, 0);
1412
1516
    rb_define_singleton_method(rb_cEncoding, "name_list", rb_enc_name_list, 0);
1413
1517
    rb_define_singleton_method(rb_cEncoding, "aliases", rb_enc_aliases, 0);