static VALUE
tk_conv_args(argc, argv, self)
int argc;
VALUE *argv; /* [0]:base_array, [1]:enc_mode, [2]..[n]:args */
VALUE self;
{
int idx, size;
volatile VALUE dst;
int thr_crit_bup;
VALUE old_gc;
if (argc < 2) {
rb_raise(rb_eArgError, "too few arguments");
}
thr_crit_bup = rb_thread_critical;
rb_thread_critical = Qtrue;
old_gc = rb_gc_disable();
for(size = 0, idx = 2; idx < argc; idx++) {
if (TYPE(argv[idx]) == T_HASH) {
size += 2 * RHASH_SIZE(argv[idx]);
} else {
size++;
}
}
/* dst = rb_ary_new2(argc - 2); */
dst = rb_ary_new2(size);
for(idx = 2; idx < argc; idx++) {
if (TYPE(argv[idx]) == T_HASH) {
if (RTEST(argv[1])) {
hash2kv_enc(argv[idx], dst, self);
} else {
hash2kv(argv[idx], dst, self);
}
} else if (argv[idx] != TK_None) {
rb_ary_push(dst, get_eval_string_core(argv[idx], argv[1], self));
}
}
if (old_gc == Qfalse) rb_gc_enable();
rb_thread_critical = thr_crit_bup;
return rb_ary_plus(argv[0], dst);
}
static VALUE
tk_get_eval_enc_str(self, obj)
VALUE self;
VALUE obj;
{
if (obj == TK_None) {
return obj;
} else {
return get_eval_string_core(obj, Qtrue, self);
}
}
static VALUE
tk_get_eval_string(argc, argv, self)
int argc;
VALUE *argv;
VALUE self;
{
volatile VALUE obj, enc_flag;
if (rb_scan_args(argc, argv, "11", &obj, &enc_flag) == 1) {
enc_flag = Qnil;
}
return get_eval_string_core(obj, enc_flag, self);
}
static VALUE
tk_symbolkey2str(self, keys)
VALUE self;
VALUE keys;
{
volatile VALUE new_keys = rb_hash_new();
if NIL_P(keys) return new_keys;
keys = rb_convert_type(keys, T_HASH, "Hash", "to_hash");
st_foreach(RHASH_TBL(keys), to_strkey, new_keys);
return new_keys;
}
/
static VALUE
tcl2rb_bool(self, value)
VALUE self;
VALUE value;
{
if (TYPE(value) == T_FIXNUM) {
if (NUM2INT(value) == 0) {
return Qfalse;
} else {
return Qtrue;
}
}
if (TYPE(value) == T_TRUE || TYPE(value) == T_FALSE) {
return value;
}
rb_check_type(value, T_STRING);
value = rb_funcall(value, ID_downcase, 0);
if (RSTRING_PTR(value) == (char*)NULL) return Qnil;
if (RSTRING_PTR(value)[0] == '\0'
|| strcmp(RSTRING_PTR(value), "0") == 0
|| strcmp(RSTRING_PTR(value), "no") == 0
|| strcmp(RSTRING_PTR(value), "off") == 0
|| strcmp(RSTRING_PTR(value), "false") == 0) {
return Qfalse;
} else {
return Qtrue;
}
}
static VALUE
tk_do_callback(argc, argv, self)
int argc;
VALUE *argv;
VALUE self;
{
#if 0
volatile VALUE id;
volatile VALUE rest;
rb_scan_args(argc, argv, "1*", &id, &rest);
return rb_apply(rb_hash_aref(CALLBACK_TABLE, id), ID_call, rest);
#endif
return rb_funcall2(rb_hash_aref(CALLBACK_TABLE, argv[0]),
ID_call, argc - 1, argv + 1);
}
static VALUE
tk_eval_cmd(argc, argv, self)
int argc;
VALUE argv[];
VALUE self;
{
volatile VALUE cmd, rest;
rb_scan_args(argc, argv, "1*", &cmd, &rest);
return rb_eval_cmd(cmd, rest, 0);
}
static VALUE
tk_hash_kv(argc, argv, self)
int argc;
VALUE *argv;
VALUE self;
{
volatile VALUE hash, enc_flag, ary;
ary = Qnil;
enc_flag = Qnil;
switch(argc) {
case 3:
ary = argv[2];
case 2:
enc_flag = argv[1];
case 1:
hash = argv[0];
break;
case 0:
rb_raise(rb_eArgError, "too few arguments");
default: /* >= 3 */
rb_raise(rb_eArgError, "too many arguments");
}
switch(TYPE(hash)) {
case T_ARRAY:
if (RTEST(enc_flag)) {
return assoc2kv_enc(hash, ary, self);
} else {
return assoc2kv(hash, ary, self);
}
case T_HASH:
if (RTEST(enc_flag)) {
return hash2kv_enc(hash, ary, self);
} else {
return hash2kv(hash, ary, self);
}
case T_NIL:
if (NIL_P(ary)) {
return rb_ary_new();
} else {
return ary;
}
default:
if (hash == TK_None) {
if (NIL_P(ary)) {
return rb_ary_new();
} else {
return ary;
}
}
rb_raise(rb_eArgError, "Hash is expected for 1st argument");
}
}
static VALUE
tk_install_cmd(argc, argv, self)
int argc;
VALUE *argv;
VALUE self;
{
volatile VALUE cmd;
#if 0
if (rb_scan_args(argc, argv, "01", &cmd) == 0) {
cmd = rb_block_proc();
}
return tk_install_cmd_core(cmd);
#endif
if (argc == 0) {
cmd = rb_block_proc();
} else {
cmd = argv[0];
}
return tk_install_cmd_core(cmd);
}
static VALUE
tcl2rb_num_or_nil(self, value)
VALUE self;
VALUE value;
{
rb_check_type(value, T_STRING);
if (RSTRING_LEN(value) == 0) return Qnil;
return tkstr_to_number(value);
}
static VALUE
tcl2rb_num_or_str(self, value)
VALUE self;
VALUE value;
{
rb_check_type(value, T_STRING);
if (RSTRING_PTR(value) == (char*)NULL) return rb_tainted_str_new2("");
return rb_rescue2(tkstr_to_number, value,
tkstr_to_str, value,
rb_eArgError, 0);
}
static VALUE
tcl2rb_number(self, value)
VALUE self;
VALUE value;
{
return tkstr_to_number(value);
}
static VALUE
tcl2rb_string(self, value)
VALUE self;
VALUE value;
{
rb_check_type(value, T_STRING);
if (RSTRING_PTR(value) == (char*)NULL) return rb_tainted_str_new2("");
return tkstr_to_str(value);
}
static VALUE
tk_uninstall_cmd(self, cmd_id)
VALUE self;
VALUE cmd_id;
{
int head_len = strlen(cmd_id_head);
int prefix_len = strlen(cmd_id_prefix);
StringValue(cmd_id);
if (strncmp(cmd_id_head, RSTRING_PTR(cmd_id), head_len) != 0) {
return Qnil;
}
if (strncmp(cmd_id_prefix,
RSTRING_PTR(cmd_id) + head_len, prefix_len) != 0) {
return Qnil;
}
return rb_hash_delete(CALLBACK_TABLE,
rb_str_new2(RSTRING_PTR(cmd_id) + head_len));
}
static VALUE
tk_conv_args(argc, argv, self)
int argc;
VALUE *argv; /* [0]:base_array, [1]:enc_mode, [2]..[n]:args */
VALUE self;
{
int idx, size;
volatile VALUE dst;
int thr_crit_bup;
VALUE old_gc;
if (argc < 2) {
rb_raise(rb_eArgError, "too few arguments");
}
thr_crit_bup = rb_thread_critical;
rb_thread_critical = Qtrue;
old_gc = rb_gc_disable();
for(size = 0, idx = 2; idx < argc; idx++) {
if (TYPE(argv[idx]) == T_HASH) {
size += 2 * RHASH_SIZE(argv[idx]);
} else {
size++;
}
}
/* dst = rb_ary_new2(argc - 2); */
dst = rb_ary_new2(size);
for(idx = 2; idx < argc; idx++) {
if (TYPE(argv[idx]) == T_HASH) {
if (RTEST(argv[1])) {
hash2kv_enc(argv[idx], dst, self);
} else {
hash2kv(argv[idx], dst, self);
}
} else if (argv[idx] != TK_None) {
rb_ary_push(dst, get_eval_string_core(argv[idx], argv[1], self));
}
}
if (old_gc == Qfalse) rb_gc_enable();
rb_thread_critical = thr_crit_bup;
return rb_ary_plus(argv[0], dst);
}
static VALUE
tk_fromUTF8(argc, argv, self)
int argc;
VALUE *argv;
VALUE self;
{
return rb_funcall2(cTclTkLib, ID_fromUTF8, argc, argv);
}
static VALUE
tk_get_eval_enc_str(self, obj)
VALUE self;
VALUE obj;
{
if (obj == TK_None) {
return obj;
} else {
return get_eval_string_core(obj, Qtrue, self);
}
}
static VALUE
tk_get_eval_string(argc, argv, self)
int argc;
VALUE *argv;
VALUE self;
{
volatile VALUE obj, enc_flag;
if (rb_scan_args(argc, argv, "11", &obj, &enc_flag) == 1) {
enc_flag = Qnil;
}
return get_eval_string_core(obj, enc_flag, self);
}
static VALUE
tk_symbolkey2str(self, keys)
VALUE self;
VALUE keys;
{
volatile VALUE new_keys = rb_hash_new();
if NIL_P(keys) return new_keys;
keys = rb_convert_type(keys, T_HASH, "Hash", "to_hash");
st_foreach(RHASH_TBL(keys), to_strkey, new_keys);
return new_keys;
}
static VALUE
tk_toUTF8(argc, argv, self)
int argc;
VALUE *argv;
VALUE self;
{
return rb_funcall2(cTclTkLib, ID_toUTF8, argc, argv);
}
/
static VALUE
tcl2rb_bool(self, value)
VALUE self;
VALUE value;
{
if (TYPE(value) == T_FIXNUM) {
if (NUM2INT(value) == 0) {
return Qfalse;
} else {
return Qtrue;
}
}
if (TYPE(value) == T_TRUE || TYPE(value) == T_FALSE) {
return value;
}
rb_check_type(value, T_STRING);
value = rb_funcall(value, ID_downcase, 0);
if (RSTRING_PTR(value) == (char*)NULL) return Qnil;
if (RSTRING_PTR(value)[0] == '\0'
|| strcmp(RSTRING_PTR(value), "0") == 0
|| strcmp(RSTRING_PTR(value), "no") == 0
|| strcmp(RSTRING_PTR(value), "off") == 0
|| strcmp(RSTRING_PTR(value), "false") == 0) {
return Qfalse;
} else {
return Qtrue;
}
}
static VALUE
tk_hash_kv(argc, argv, self)
int argc;
VALUE *argv;
VALUE self;
{
volatile VALUE hash, enc_flag, ary;
ary = Qnil;
enc_flag = Qnil;
switch(argc) {
case 3:
ary = argv[2];
case 2:
enc_flag = argv[1];
case 1:
hash = argv[0];
break;
case 0:
rb_raise(rb_eArgError, "too few arguments");
default: /* >= 3 */
rb_raise(rb_eArgError, "too many arguments");
}
switch(TYPE(hash)) {
case T_ARRAY:
if (RTEST(enc_flag)) {
return assoc2kv_enc(hash, ary, self);
} else {
return assoc2kv(hash, ary, self);
}
case T_HASH:
if (RTEST(enc_flag)) {
return hash2kv_enc(hash, ary, self);
} else {
return hash2kv(hash, ary, self);
}
case T_NIL:
if (NIL_P(ary)) {
return rb_ary_new();
} else {
return ary;
}
default:
if (hash == TK_None) {
if (NIL_P(ary)) {
return rb_ary_new();
} else {
return ary;
}
}
rb_raise(rb_eArgError, "Hash is expected for 1st argument");
}
}
static VALUE
tcl2rb_num_or_nil(self, value)
VALUE self;
VALUE value;
{
rb_check_type(value, T_STRING);
if (RSTRING_LEN(value) == 0) return Qnil;
return tkstr_to_number(value);
}
static VALUE
tcl2rb_num_or_str(self, value)
VALUE self;
VALUE value;
{
rb_check_type(value, T_STRING);
if (RSTRING_PTR(value) == (char*)NULL) return rb_tainted_str_new2("");
return rb_rescue2(tkstr_to_number, value,
tkstr_to_str, value,
rb_eArgError, 0);
}