better_caller 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Tim Morgan
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,69 @@
1
+ = better_caller
2
+
3
+ Author:: Tim Morgan
4
+ Date:: Dec 23, 2009
5
+ License:: Released under the same terms as Ruby.
6
+
7
+ == Introduction by example
8
+
9
+ Actions speak louder than words. Gone are the days of this old suckageness:
10
+
11
+ caller #=> ["test.rb:8:in `foo'", "test.rb:16:in `<main>'"]
12
+
13
+ With better_caller, you get this new hotness:
14
+
15
+ require 'better_caller'
16
+ better_caller #=> [["test.rb", 8, :foo, #<Binding:0x000001010cae50>], ["test.rb", 16, :"<main>", #<Binding:0x000001010caef8>]]
17
+
18
+ There are a couple of things you may notice. First of all, the okay-that's-nice
19
+ thing: String parsing is a thing of the past. You get the file, line, and method
20
+ as separate elements. This happens <b>at the Ruby interpreter level</b>.
21
+
22
+ Now, the holy-shit-that's-awesome feature: <b>You get Bindings, all the way up
23
+ the stack.</b> Yes, that's right, you can do this:
24
+
25
+ eval "local_variables", better_caller.first.last #=> [ :var1, :var2, :foo ]
26
+
27
+ You also get this stuff in exception, mondo excellent for debugging:
28
+
29
+ $!.better_backtrace # now you can figure out what your local variables were at the time of the exception!
30
+
31
+ == This is horribly slow, right? You're using some +set_trace_func+ magic that's going to make my Ruby 1,000,000% slower, right?
32
+
33
+ No. better_caller is a C function that uses the internal Ruby memory structures
34
+ to build its output. Absolutely no +set_trace_func+ and no speed hit.
35
+
36
+ == Super ominous alpha warning
37
+
38
+ better_caller is extremely, hyperbolically alpha right now. Here are some known
39
+ obstacles currently preventing it from blowing minds:
40
+
41
+ * <b>It only works with a very specific version of Ruby (in particular,
42
+ 1.9.1p376).</b> This is because it uses some private Ruby C functions to work
43
+ its magic, so it keeps a copy of some header files that you're not really
44
+ supposed to be using.
45
+ * <b>It causes "invalid dfp" crashes sometimes.</b> Every so often, for reasons
46
+ I _really_ wish I understood, the Ruby interpreter will come down in a ball of
47
+ fire after regurgitating "invalid dfp" to your console. DFP's and CFP's are
48
+ still pretty much witch-voodoo to me so I'm having a very hard time debugging
49
+ this problem.
50
+
51
+ Despite that, it does work sometimes, and when it does, I think it rocks. If you
52
+ do too, please do me the honor of contributing to this project, _especially_ if
53
+ you're one of the three people on the planet that understand the workings of
54
+ Ruby frame pointers. That would be swell.
55
+
56
+ === Additional to-do items
57
+
58
+ * Comments
59
+ * Specs
60
+
61
+ == Release History
62
+
63
+ <b>0.0.1</b> (Dec 23, 2009)
64
+
65
+ * First public release.
66
+
67
+ == Copyright
68
+
69
+ See LICENSE for copyright information.
@@ -0,0 +1,148 @@
1
+ #include "ruby.h"
2
+ #include "vm_core.h"
3
+
4
+ #define ENV_IN_HEAP_P(th, env) \
5
+ (!((th)->stack < (env) && (env) < ((th)->stack + (th)->stack_size)))
6
+
7
+ static VALUE binding_from_cfp(rb_thread_t *th, rb_control_frame_t *cfp) {
8
+ if (cfp == 0) return Qnil;
9
+
10
+ VALUE *penvptr = GC_GUARDED_PTR_REF(*(cfp->dfp));
11
+ rb_control_frame_t *pcfp = VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_FINISH ? RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp) : cfp;
12
+ if (!ENV_IN_HEAP_P(th, penvptr)) {
13
+ while (pcfp->dfp != penvptr) {
14
+ pcfp++;
15
+ if (pcfp->dfp == 0) return Qnil;
16
+ }
17
+ }
18
+
19
+ VALUE bindval = rb_binding_new();
20
+ rb_binding_t *bind;
21
+
22
+ GetBindingPtr(bindval, bind);
23
+ bind->env = rb_vm_make_env_object(th, cfp);
24
+ return bindval;
25
+ }
26
+
27
+ static VALUE backtrace_each(rb_thread_t *th, const rb_control_frame_t *limit_cfp, const rb_control_frame_t *cfp, const char *file, int line_no, VALUE ary) {
28
+ VALUE elem, locals;
29
+ int i;
30
+
31
+ while (cfp > limit_cfp) {
32
+ elem = 0;
33
+ locals = 0;
34
+ if (cfp->iseq != 0) {
35
+ if (cfp->pc != 0) {
36
+ rb_iseq_t *iseq = cfp->iseq;
37
+
38
+ elem = rb_ary_new();
39
+ rb_ary_push(elem, iseq->filename);
40
+ rb_ary_push(elem, INT2FIX(rb_vm_get_sourceline(cfp)));
41
+ rb_ary_push(elem, rb_str_intern(iseq->name));
42
+ rb_ary_push(elem, binding_from_cfp(th, cfp));
43
+ rb_ary_push(ary, elem);
44
+ }
45
+ }
46
+ else if (RUBYVM_CFUNC_FRAME_P(cfp)) {
47
+ elem = rb_ary_new();
48
+ rb_ary_push(elem, rb_str_new2(file));
49
+ rb_ary_push(elem, INT2FIX(line_no));
50
+ rb_ary_push(elem, ID2SYM(cfp->method_id));
51
+ rb_ary_push(elem, Qnil);
52
+ rb_ary_push(ary, elem);
53
+ }
54
+ cfp = RUBY_VM_NEXT_CONTROL_FRAME(cfp);
55
+ }
56
+ return rb_ary_reverse(ary);
57
+ }
58
+
59
+ static inline VALUE backtrace(rb_thread_t *th, int lev) {
60
+ VALUE ary;
61
+ const rb_control_frame_t *cfp = th->cfp;
62
+ const rb_control_frame_t *top_of_cfp = (void *)(th->stack + th->stack_size);
63
+ top_of_cfp -= 2;
64
+
65
+ if (lev < 0) ary = rb_ary_new();
66
+ else {
67
+ while (lev-- >= 0) {
68
+ cfp++;
69
+ if (cfp >= top_of_cfp) return Qnil;
70
+ }
71
+ ary = rb_ary_new();
72
+ }
73
+
74
+ ary = backtrace_each(th, RUBY_VM_NEXT_CONTROL_FRAME(cfp), top_of_cfp, RSTRING_PTR(th->vm->progname), 0, ary);
75
+ return ary;
76
+ }
77
+
78
+ static VALUE better_caller(int argc, VALUE *argv) {
79
+ VALUE level;
80
+ int lev;
81
+
82
+ rb_scan_args(argc, argv, "01", &level);
83
+
84
+ if (NIL_P(level)) lev = 1;
85
+ else lev = NUM2INT(level);
86
+ if (lev < 0) rb_raise(rb_eArgError, "negative level (%d)", lev);
87
+
88
+ return backtrace(GET_THREAD(), lev);
89
+ }
90
+
91
+ // static VALUE thread_bindings(VALUE self) {
92
+ // VALUE bindings = rb_iv_get(self, "@bindings");
93
+ // if (bindings == Qnil) return Qnil;
94
+ // return rb_ary_subseq(bindings, 0, RARRAY_LEN(bindings) - 1);
95
+ // }
96
+ //
97
+ static VALUE exception_better_backtrace(VALUE self) {
98
+ return rb_iv_get(self, "@better_backtrace");
99
+ }
100
+ //
101
+ static void process_event(rb_event_flag_t event, VALUE data, VALUE self, ID id, VALUE klass) {
102
+ // VALUE thread = rb_thread_current();
103
+ // VALUE subarray;
104
+ //
105
+ // VALUE bindings = rb_iv_get(thread, "@bindings");
106
+ // if (bindings == Qnil) {
107
+ // bindings = rb_ary_new();
108
+ // rb_iv_set(thread, "@bindings", bindings);
109
+ // }
110
+ //
111
+ switch (event) {
112
+ // // case RUBY_EVENT_LINE:
113
+ // // if (RARRAY_LEN(bindings) == 0) rb_ary_push(bindings, rb_binding_new());
114
+ // // break;
115
+ //
116
+ // case RUBY_EVENT_CLASS:
117
+ // case RUBY_EVENT_CALL:
118
+ // case RUBY_EVENT_C_CALL:
119
+ // subarray = rb_ary_new();
120
+ // rb_ary_push(subarray, rb_str_new2(rb_sourcefile()));
121
+ // rb_ary_push(subarray, id ? ID2SYM(id) : Qnil);
122
+ // rb_ary_push(subarray, rb_binding_new());
123
+ // rb_ary_push(bindings, subarray);
124
+ // break;
125
+ //
126
+ // case RUBY_EVENT_END:
127
+ // case RUBY_EVENT_RETURN:
128
+ // case RUBY_EVENT_C_RETURN:
129
+ // rb_ary_pop(bindings);
130
+ // break;
131
+ //
132
+ case RUBY_EVENT_RAISE:
133
+ rb_iv_set(rb_gv_get("$!"), "@better_backtrace", better_caller(0, 0));
134
+ // rb_iv_set(rb_gv_get("$!"), "@bindings", bindings);
135
+ // rb_ary_pop(bindings);
136
+ break;
137
+ }
138
+ }
139
+
140
+ void Init_better_caller() {
141
+ rb_define_method(rb_eException, "better_backtrace", exception_better_backtrace, 0);
142
+ // rb_define_method(rb_cThread, "bindings", thread_bindings, 0);
143
+ rb_define_global_function("better_caller", better_caller, -1);
144
+ // int events = RUBY_EVENT_CLASS|RUBY_EVENT_CALL|RUBY_EVENT_C_CALL|RUBY_EVENT_END|RUBY_EVENT_RETURN|RUBY_EVENT_C_RETURN|RUBY_EVENT_RAISE;
145
+ // rb_add_event_hook(process_event, events, Qnil);
146
+ // rb_add_event_hook(process_event, RUBY_EVENT_ALL, Qnil);
147
+ rb_add_event_hook(process_event, RUBY_EVENT_RAISE, Qnil);
148
+ }
@@ -0,0 +1,36 @@
1
+ /**********************************************************************
2
+
3
+ debug.h - YARV Debug function interface
4
+
5
+ $Author: ko1 $
6
+ created at: 04/08/25 02:33:49 JST
7
+
8
+ Copyright (C) 2004-2007 Koichi Sasada
9
+
10
+ **********************************************************************/
11
+
12
+ #ifndef RUBY_DEBUG_H
13
+ #define RUBY_DEBUG_H
14
+
15
+ #include "ruby/ruby.h"
16
+ #include "node.h"
17
+
18
+ #define dpv(h,v) ruby_debug_print_value(-1, 0, h, v)
19
+ #define dp(v) ruby_debug_print_value(-1, 0, "", v)
20
+ #define dpi(i) ruby_debug_print_id(-1, 0, "", i)
21
+ #define dpn(n) ruby_debug_print_node(-1, 0, "", n)
22
+
23
+ #define bp() ruby_debug_breakpoint()
24
+
25
+ VALUE ruby_debug_print_value(int level, int debug_level, const char *header, VALUE v);
26
+ ID ruby_debug_print_id(int level, int debug_level, const char *header, ID id);
27
+ NODE *ruby_debug_print_node(int level, int debug_level, const char *header, const NODE *node);
28
+ int ruby_debug_print_indent(int level, int debug_level, int indent_level);
29
+ void ruby_debug_breakpoint(void);
30
+ void ruby_debug_gc_check_func(void);
31
+
32
+ #ifdef RUBY_DEBUG_ENV
33
+ void ruby_set_debug_option(const char *str);
34
+ #endif
35
+
36
+ #endif /* RUBY_DEBUG_H */
@@ -0,0 +1,41 @@
1
+ /**********************************************************************
2
+
3
+ dln.h -
4
+
5
+ $Author: nobu $
6
+ created at: Wed Jan 19 16:53:09 JST 1994
7
+
8
+ Copyright (C) 1993-2007 Yukihiro Matsumoto
9
+
10
+ **********************************************************************/
11
+
12
+ #ifndef DLN_H
13
+ #define DLN_H
14
+
15
+ #ifdef __cplusplus
16
+ # ifndef HAVE_PROTOTYPES
17
+ # define HAVE_PROTOTYPES 1
18
+ # endif
19
+ # ifndef HAVE_STDARG_PROTOTYPES
20
+ # define HAVE_STDARG_PROTOTYPES 1
21
+ # endif
22
+ #endif
23
+
24
+ #undef _
25
+ #ifdef HAVE_PROTOTYPES
26
+ # define _(args) args
27
+ #else
28
+ # define _(args) ()
29
+ #endif
30
+
31
+ DEPRECATED(char *dln_find_exe(const char*,const char*));
32
+ DEPRECATED(char *dln_find_file(const char*,const char*));
33
+ char *dln_find_exe_r(const char*,const char*,char*,int);
34
+ char *dln_find_file_r(const char*,const char*,char*,int);
35
+
36
+ #ifdef USE_DLN_A_OUT
37
+ extern char *dln_argv0;
38
+ #endif
39
+
40
+ void *dln_load(const char*);
41
+ #endif
@@ -0,0 +1,147 @@
1
+ ENC_DEFINE("ASCII-8BIT");
2
+ ENC_DEFINE("Big5");
3
+ ENC_DEFINE("CP949");
4
+ ENC_DEFINE("Emacs-Mule");
5
+ ENC_DEFINE("EUC-JP");
6
+ ENC_DEFINE("EUC-KR");
7
+ ENC_DEFINE("EUC-TW");
8
+ ENC_DEFINE("GB18030");
9
+ ENC_DEFINE("GBK");
10
+ ENC_DEFINE("ISO-8859-1");
11
+ ENC_DEFINE("ISO-8859-2");
12
+ ENC_DEFINE("ISO-8859-3");
13
+ ENC_DEFINE("ISO-8859-4");
14
+ ENC_DEFINE("ISO-8859-5");
15
+ ENC_DEFINE("ISO-8859-6");
16
+ ENC_DEFINE("ISO-8859-7");
17
+ ENC_DEFINE("ISO-8859-8");
18
+ ENC_DEFINE("ISO-8859-9");
19
+ ENC_DEFINE("ISO-8859-10");
20
+ ENC_DEFINE("ISO-8859-11");
21
+ ENC_DEFINE("ISO-8859-13");
22
+ ENC_DEFINE("ISO-8859-14");
23
+ ENC_DEFINE("ISO-8859-15");
24
+ ENC_DEFINE("ISO-8859-16");
25
+ ENC_DEFINE("KOI8-R");
26
+ ENC_DEFINE("KOI8-U");
27
+ ENC_DEFINE("Shift_JIS");
28
+ ENC_DEFINE("US-ASCII");
29
+ ENC_DEFINE("UTF-8");
30
+ ENC_DEFINE("UTF-16BE");
31
+ ENC_DEFINE("UTF-16LE");
32
+ ENC_DEFINE("UTF-32BE");
33
+ ENC_DEFINE("UTF-32LE");
34
+ ENC_DEFINE("Windows-1251");
35
+ ENC_ALIAS("BINARY", "ASCII-8BIT");
36
+ ENC_REPLICATE("IBM437", "ASCII-8BIT");
37
+ ENC_ALIAS("CP437", "IBM437");
38
+ ENC_REPLICATE("IBM737", "ASCII-8BIT");
39
+ ENC_ALIAS("CP737", "IBM737");
40
+ ENC_REPLICATE("IBM775", "ASCII-8BIT");
41
+ ENC_ALIAS("CP775", "IBM775");
42
+ ENC_REPLICATE("CP850", "ASCII-8BIT");
43
+ ENC_ALIAS("IBM850", "CP850");
44
+ ENC_REPLICATE("IBM852", "ASCII-8BIT");
45
+ ENC_REPLICATE("CP852", "IBM852");
46
+ ENC_REPLICATE("IBM855", "ASCII-8BIT");
47
+ ENC_REPLICATE("CP855", "IBM855");
48
+ ENC_REPLICATE("IBM857", "ASCII-8BIT");
49
+ ENC_ALIAS("CP857", "IBM857");
50
+ ENC_REPLICATE("IBM860", "ASCII-8BIT");
51
+ ENC_ALIAS("CP860", "IBM860");
52
+ ENC_REPLICATE("IBM861", "ASCII-8BIT");
53
+ ENC_ALIAS("CP861", "IBM861");
54
+ ENC_REPLICATE("IBM862", "ASCII-8BIT");
55
+ ENC_ALIAS("CP862", "IBM862");
56
+ ENC_REPLICATE("IBM863", "ASCII-8BIT");
57
+ ENC_ALIAS("CP863", "IBM863");
58
+ ENC_REPLICATE("IBM864", "ASCII-8BIT");
59
+ ENC_ALIAS("CP864", "IBM864");
60
+ ENC_REPLICATE("IBM865", "ASCII-8BIT");
61
+ ENC_ALIAS("CP865", "IBM865");
62
+ ENC_REPLICATE("IBM866", "ASCII-8BIT");
63
+ ENC_ALIAS("CP866", "IBM866");
64
+ ENC_REPLICATE("IBM869", "ASCII-8BIT");
65
+ ENC_ALIAS("CP869", "IBM869");
66
+ ENC_REPLICATE("Windows-1258", "ASCII-8BIT");
67
+ ENC_ALIAS("CP1258", "Windows-1258");
68
+ ENC_REPLICATE("GB1988", "ASCII-8BIT");
69
+ ENC_REPLICATE("macCentEuro", "ASCII-8BIT");
70
+ ENC_REPLICATE("macCroatian", "ASCII-8BIT");
71
+ ENC_REPLICATE("macCyrillic", "ASCII-8BIT");
72
+ ENC_REPLICATE("macGreek", "ASCII-8BIT");
73
+ ENC_REPLICATE("macIceland", "ASCII-8BIT");
74
+ ENC_REPLICATE("macRoman", "ASCII-8BIT");
75
+ ENC_REPLICATE("macRomania", "ASCII-8BIT");
76
+ ENC_REPLICATE("macThai", "ASCII-8BIT");
77
+ ENC_REPLICATE("macTurkish", "ASCII-8BIT");
78
+ ENC_REPLICATE("macUkraine", "ASCII-8BIT");
79
+ ENC_ALIAS("CP950", "BIG5");
80
+ ENC_REPLICATE("stateless-ISO-2022-JP", "Emacs-Mule");
81
+ ENC_ALIAS("eucJP", "EUC-JP") /* UI-OSF Application Platform Profile for Japanese Environment Version 1.1 */;
82
+ ENC_REPLICATE("eucJP-ms", "EUC-JP") /* TOG/JVC CDE/Motif Technical WG */;
83
+ ENC_ALIAS("euc-jp-ms", "eucJP-ms");
84
+ ENC_REPLICATE("CP51932", "EUC-JP");
85
+ ENC_ALIAS("eucKR", "EUC-KR");
86
+ ENC_ALIAS("eucTW", "EUC-TW");
87
+ ENC_ALIAS("EUC-CN", "GB2312");
88
+ ENC_ALIAS("eucCN", "GB2312");
89
+ ENC_REPLICATE("GB12345", "GB2312");
90
+ ENC_ALIAS("CP936", "GBK");
91
+ ENC_DUMMY("ISO-2022-JP");
92
+ ENC_ALIAS("ISO2022-JP", "ISO-2022-JP");
93
+ ENC_REPLICATE("ISO-2022-JP-2", "ISO-2022-JP");
94
+ ENC_ALIAS("ISO2022-JP2", "ISO-2022-JP-2");
95
+ ENC_ALIAS("ISO8859-1", "ISO-8859-1");
96
+ ENC_REPLICATE("Windows-1252", "ISO-8859-1");
97
+ ENC_ALIAS("CP1252", "Windows-1252");
98
+ ENC_ALIAS("ISO8859-2", "ISO-8859-2");
99
+ ENC_REPLICATE("Windows-1250", "ISO-8859-2");
100
+ ENC_ALIAS("CP1250", "Windows-1250");
101
+ ENC_ALIAS("ISO8859-3", "ISO-8859-3");
102
+ ENC_ALIAS("ISO8859-4", "ISO-8859-4");
103
+ ENC_ALIAS("ISO8859-5", "ISO-8859-5");
104
+ ENC_ALIAS("ISO8859-6", "ISO-8859-6");
105
+ ENC_REPLICATE("Windows-1256", "ISO-8859-6");
106
+ ENC_ALIAS("CP1256", "Windows-1256");
107
+ ENC_ALIAS("ISO8859-7", "ISO-8859-7");
108
+ ENC_REPLICATE("Windows-1253", "ISO-8859-7");
109
+ ENC_ALIAS("CP1253", "Windows-1253");
110
+ ENC_ALIAS("ISO8859-8", "ISO-8859-8");
111
+ ENC_REPLICATE("Windows-1255", "ISO-8859-8");
112
+ ENC_ALIAS("CP1255", "Windows-1255");
113
+ ENC_ALIAS("ISO8859-9", "ISO-8859-9");
114
+ ENC_REPLICATE("Windows-1254", "ISO-8859-9");
115
+ ENC_ALIAS("CP1254", "Windows-1254");
116
+ ENC_ALIAS("ISO8859-10", "ISO-8859-10");
117
+ ENC_ALIAS("ISO8859-11", "ISO-8859-11");
118
+ ENC_REPLICATE("TIS-620", "ISO-8859-11");
119
+ ENC_REPLICATE("Windows-874", "ISO-8859-11");
120
+ ENC_ALIAS("CP874", "Windows-874");
121
+ ENC_ALIAS("ISO8859-13", "ISO-8859-13");
122
+ ENC_REPLICATE("Windows-1257", "ISO-8859-13");
123
+ ENC_ALIAS("CP1257", "Windows-1257");
124
+ ENC_ALIAS("ISO8859-14", "ISO-8859-14");
125
+ ENC_ALIAS("ISO8859-15", "ISO-8859-15");
126
+ ENC_ALIAS("ISO8859-16", "ISO-8859-16");
127
+ ENC_ALIAS("CP878", "KOI8-R");
128
+ ENC_ALIAS("SJIS", "Shift_JIS");
129
+ ENC_REPLICATE("Windows-31J", "Shift_JIS");
130
+ ENC_ALIAS("CP932", "Windows-31J");
131
+ ENC_ALIAS("csWindows31J", "Windows-31J") /* IANA. IE6 don't accept Windows-31J but csWindows31J. */;
132
+ ENC_REPLICATE("MacJapanese", "Shift_JIS");
133
+ ENC_ALIAS("MacJapan", "MacJapanese");
134
+ ENC_ALIAS("ASCII", "US-ASCII");
135
+ ENC_ALIAS("ANSI_X3.4-1968", "US-ASCII");
136
+ ENC_ALIAS("646", "US-ASCII");
137
+ ENC_DUMMY("UTF-7");
138
+ ENC_ALIAS("CP65000", "UTF-7");
139
+ ENC_ALIAS("CP65001", "UTF-8");
140
+ ENC_REPLICATE("UTF8-MAC", "UTF-8");
141
+ ENC_ALIAS("UTF-8-MAC", "UTF8-MAC");
142
+ ENC_ALIAS("UCS-2BE", "UTF-16BE");
143
+ ENC_ALIAS("UCS-4BE", "UTF-32BE");
144
+ ENC_ALIAS("UCS-4LE", "UTF-32LE");
145
+ ENC_ALIAS("CP1251", "Windows-1251");
146
+
147
+ #define ENCODING_COUNT 83