In Files

  • tk/lib/multi-tk.rb
  • tk/lib/tk.rb
  • tk/tcltklib.c

Class/Module Index [+]

Quicksearch

TclTkIp

add ThreadGroup check to #new

Public Class Methods

__new__(p1 = v1, p2 = v2) click to toggle source
Alias for: new
new(*args) click to toggle source
 
               # File tk/lib/tk.rb, line 28
def initialize(*args)
  __initialize__(*args)

  @force_default_encoding ||= [false].taint
  @encoding ||= [nil].taint
  def @encoding.to_s; self.join(nil); end
end
            
Also aliased as: __initialize__
new(p1 = v1, p2 = v2) click to toggle source

initialize interpreter

 
               static VALUE
ip_init(argc, argv, self)
    int   argc;
    VALUE *argv;
    VALUE self;
{
    struct tcltkip *ptr;        /* tcltkip data struct */
    VALUE argv0, opts;
    int cnt;
    int st;
    int with_tk = 1;
    Tk_Window mainWin = (Tk_Window)NULL;

    /* security check */
    if (rb_safe_level() >= 4) {
        rb_raise(rb_eSecurityError, 
                 "Cannot create a TclTkIp object at level %d", 
                 rb_safe_level());
    }

    /* create object */
    Data_Get_Struct(self, struct tcltkip, ptr);
    ptr = ALLOC(struct tcltkip);
    /* ptr = (struct tcltkip *)ckalloc(sizeof(struct tcltkip)); */
    DATA_PTR(self) = ptr;
#ifdef RUBY_USE_NATIVE_THREAD
    ptr->tk_thread_id = 0;
#endif
    ptr->ref_count = 0;
    ptr->allow_ruby_exit = 1;
    ptr->return_value = 0;

    /* from Tk_Main() */
    DUMP1("Tcl_CreateInterp");
    ptr->ip = ruby_tcl_create_ip_and_stubs_init(&st);
    if (ptr->ip == NULL) {
        switch(st) {
        case TCLTK_STUBS_OK:
            break;
        case NO_TCL_DLL:
            rb_raise(rb_eLoadError, "tcltklib: fail to open tcl_dll");
        case NO_FindExecutable:
            rb_raise(rb_eLoadError, "tcltklib: can't find Tcl_FindExecutable");
        case NO_CreateInterp:
            rb_raise(rb_eLoadError, "tcltklib: can't find Tcl_CreateInterp()");
        case NO_DeleteInterp:
            rb_raise(rb_eLoadError, "tcltklib: can't find Tcl_DeleteInterp()");
        case FAIL_CreateInterp:
            rb_raise(rb_eRuntimeError, "tcltklib: fail to create a new IP");
        case FAIL_Tcl_InitStubs:
            rb_raise(rb_eRuntimeError, "tcltklib: fail to Tcl_InitStubs()");
        default:
            rb_raise(rb_eRuntimeError, "tcltklib: unknown error(%d) on ruby_tcl_create_ip_and_stubs_init", st);
        }
    }

#if TCL_MAJOR_VERSION >= 8
#if TCL_NAMESPACE_DEBUG
    DUMP1("get current namespace");
    if ((ptr->default_ns = Tcl_GetCurrentNamespace(ptr->ip)) 
        == (Tcl_Namespace*)NULL) {
      rb_raise(rb_eRuntimeError, "a new Tk interpreter has a NULL namespace");
    }
#endif
#endif

    rbtk_preserve_ip(ptr);
    DUMP2("IP ref_count = %d", ptr->ref_count);
    current_interp = ptr->ip;

    ptr->has_orig_exit 
        = Tcl_GetCommandInfo(ptr->ip, "exit", &(ptr->orig_exit_info));

    /* from Tcl_AppInit() */
    DUMP1("Tcl_Init");
    if (Tcl_Init(ptr->ip) == TCL_ERROR) {
        rb_raise(rb_eRuntimeError, "%s", Tcl_GetStringResult(ptr->ip));
    }

    /* set variables */
    cnt = rb_scan_args(argc, argv, "02", &argv0, &opts);
    switch(cnt) {
    case 2:
        /* options */
        if (NIL_P(opts) || opts == Qfalse) {
            /* without Tk */
            with_tk = 0;
        } else {
            /* Tcl_SetVar(ptr->ip, "argv", StringValuePtr(opts), 0); */
            Tcl_SetVar(ptr->ip, "argv", StringValuePtr(opts), TCL_GLOBAL_ONLY);
        }
    case 1:
        /* argv0 */
        if (!NIL_P(argv0)) {
            if (strncmp(StringValuePtr(argv0), "-e", 3) == 0
                || strncmp(StringValuePtr(argv0), "-", 2) == 0) {
                Tcl_SetVar(ptr->ip, "argv0", "ruby", TCL_GLOBAL_ONLY);
            } else {
                /* Tcl_SetVar(ptr->ip, "argv0", StringValuePtr(argv0), 0); */
                Tcl_SetVar(ptr->ip, "argv0", StringValuePtr(argv0), 
                           TCL_GLOBAL_ONLY);
            }
        }
    case 0:
        /* no args */
        ;
    }

    /* from Tcl_AppInit() */
    if (with_tk) {
        DUMP1("Tk_Init");
        st = ruby_tk_stubs_init(ptr->ip);
        switch(st) {
        case TCLTK_STUBS_OK:
            break;
        case NO_Tk_Init:
            rb_raise(rb_eLoadError, "tcltklib: can't find Tk_Init()");
        case FAIL_Tk_Init:
            rb_raise(rb_eRuntimeError, "tcltklib: fail to Tk_Init(). %s", 
                     Tcl_GetStringResult(ptr->ip));
        case FAIL_Tk_InitStubs:
            rb_raise(rb_eRuntimeError, "tcltklib: fail to Tk_InitStubs(). %s", 
                     Tcl_GetStringResult(ptr->ip));
        default:
            rb_raise(rb_eRuntimeError, "tcltklib: unknown error(%d) on ruby_tk_stubs_init", st);
        }

        DUMP1("Tcl_StaticPackage(\"Tk\")");
#if TCL_MAJOR_VERSION >= 8
        Tcl_StaticPackage(ptr->ip, "Tk", Tk_Init, Tk_SafeInit);
#else /* TCL_MAJOR_VERSION < 8 */
        Tcl_StaticPackage(ptr->ip, "Tk", Tk_Init,
                          (Tcl_PackageInitProc *) NULL);
#endif

#ifdef RUBY_USE_NATIVE_THREAD
        /* set Tk thread ID */
        ptr->tk_thread_id = Tcl_GetCurrentThread();
#endif
        /* get main window */
        mainWin = Tk_MainWindow(ptr->ip);
        Tk_Preserve((ClientData)mainWin);
    }

    /* add ruby command to the interpreter */
#if TCL_MAJOR_VERSION >= 8
    DUMP1("Tcl_CreateObjCommand(\"ruby\")");
    Tcl_CreateObjCommand(ptr->ip, "ruby", ip_ruby_eval, (ClientData)NULL,
                         (Tcl_CmdDeleteProc *)NULL);
    DUMP1("Tcl_CreateObjCommand(\"ruby_eval\")");
    Tcl_CreateObjCommand(ptr->ip, "ruby_eval", ip_ruby_eval, (ClientData)NULL,
                         (Tcl_CmdDeleteProc *)NULL);
    DUMP1("Tcl_CreateObjCommand(\"ruby_cmd\")");
    Tcl_CreateObjCommand(ptr->ip, "ruby_cmd", ip_ruby_cmd, (ClientData)NULL,
                         (Tcl_CmdDeleteProc *)NULL);
#else /* TCL_MAJOR_VERSION < 8 */
    DUMP1("Tcl_CreateCommand(\"ruby\")");
    Tcl_CreateCommand(ptr->ip, "ruby", ip_ruby_eval, (ClientData)NULL,
                      (Tcl_CmdDeleteProc *)NULL);
    DUMP1("Tcl_CreateCommand(\"ruby_eval\")");
    Tcl_CreateCommand(ptr->ip, "ruby_eval", ip_ruby_eval, (ClientData)NULL,
                      (Tcl_CmdDeleteProc *)NULL);
    DUMP1("Tcl_CreateCommand(\"ruby_cmd\")");
    Tcl_CreateCommand(ptr->ip, "ruby_cmd", ip_ruby_cmd, (ClientData)NULL,
                      (Tcl_CmdDeleteProc *)NULL);
#endif

    /* add 'interp_exit', 'ruby_exit' and replace 'exit' command */
#if TCL_MAJOR_VERSION >= 8
    DUMP1("Tcl_CreateObjCommand(\"interp_exit\")");
    Tcl_CreateObjCommand(ptr->ip, "interp_exit", ip_InterpExitObjCmd, 
                         (ClientData)mainWin, (Tcl_CmdDeleteProc *)NULL);
    DUMP1("Tcl_CreateObjCommand(\"ruby_exit\")");
    Tcl_CreateObjCommand(ptr->ip, "ruby_exit", ip_RubyExitObjCmd, 
                         (ClientData)mainWin, (Tcl_CmdDeleteProc *)NULL);
    DUMP1("Tcl_CreateObjCommand(\"exit\") --> \"ruby_exit\"");
    Tcl_CreateObjCommand(ptr->ip, "exit", ip_RubyExitObjCmd, 
                         (ClientData)mainWin, (Tcl_CmdDeleteProc *)NULL);
#else /* TCL_MAJOR_VERSION < 8 */
    DUMP1("Tcl_CreateCommand(\"interp_exit\")");
    Tcl_CreateCommand(ptr->ip, "interp_exit", ip_InterpExitCommand, 
                      (ClientData)mainWin, (Tcl_CmdDeleteProc *)NULL);
    DUMP1("Tcl_CreateCommand(\"ruby_exit\")");
    Tcl_CreateCommand(ptr->ip, "ruby_exit", ip_RubyExitCommand, 
                      (ClientData)mainWin, (Tcl_CmdDeleteProc *)NULL);
    DUMP1("Tcl_CreateCommand(\"exit\") --> \"ruby_exit\"");
    Tcl_CreateCommand(ptr->ip, "exit", ip_RubyExitCommand, 
                      (ClientData)mainWin, (Tcl_CmdDeleteProc *)NULL);
#endif

    /* replace vwait and tkwait */
    ip_replace_wait_commands(ptr->ip, mainWin);

    /* wrap namespace command */
    ip_wrap_namespace_command(ptr->ip);

    /* set finalizer */
    Tcl_CallWhenDeleted(ptr->ip, ip_CallWhenDeleted, (ClientData)mainWin);

    if (mainWin != (Tk_Window)NULL) {
        Tk_Release((ClientData)mainWin);
    }

    return self;
}
            
Also aliased as: __new__

Public Instance Methods

__initialize__(*args) click to toggle source
Alias for: new
_conv_listelement(p1) click to toggle source
 
               static VALUE
lib_conv_listelement(self, src)
    VALUE self;
    VALUE src;
{
    int   len, scan_flag;
    volatile VALUE dst;
    int   taint_flag = OBJ_TAINTED(src);
    int thr_crit_bup;

    tcl_stubs_check();

    thr_crit_bup = rb_thread_critical;
    rb_thread_critical = Qtrue;

    StringValue(src);

#if TCL_MAJOR_VERSION >= 8
    len = Tcl_ScanCountedElement(RSTRING_PTR(src), RSTRING_LEN(src), 
                                 &scan_flag);
    dst = rb_str_new(0, len + 1);
    len = Tcl_ConvertCountedElement(RSTRING_PTR(src), RSTRING_LEN(src), 
                                    RSTRING_PTR(dst), scan_flag);
#else /* TCL_MAJOR_VERSION < 8 */
    len = Tcl_ScanElement(RSTRING_PTR(src), &scan_flag);
    dst = rb_str_new(0, len + 1);
    len = Tcl_ConvertElement(RSTRING_PTR(src), RSTRING_PTR(dst), scan_flag);
#endif

    rb_str_resize(dst, len);
    if (taint_flag) OBJ_TAINT(dst);

    rb_thread_critical = thr_crit_bup;

    return dst;
}
            
_create_console() click to toggle source
 
               static VALUE
ip_create_console(self)
    VALUE self;
{
    struct tcltkip *ptr = get_ip(self);
    
    /* ip is deleted? */
    if (deleted_ip(ptr)) {
        rb_raise(rb_eRuntimeError, "interpreter is deleted");
    }

    return tk_funcall(ip_create_console_core, 0, (VALUE*)NULL, self);
}
            
_eval(p1) click to toggle source
 
               static VALUE
ip_eval(self, str)
    VALUE self;
    VALUE str;
{
    struct eval_queue *evq;
#ifdef RUBY_USE_NATIVE_THREAD
    struct tcltkip *ptr;
#endif
    char *eval_str;
    int  *alloc_done;
    int  thr_crit_bup;
    volatile VALUE current = rb_thread_current();
    volatile VALUE ip_obj = self;
    volatile VALUE result;
    volatile VALUE ret;
    Tcl_QueuePosition position;

    thr_crit_bup = rb_thread_critical;
    rb_thread_critical = Qtrue;
    StringValue(str);
    rb_thread_critical = thr_crit_bup;

#ifdef RUBY_USE_NATIVE_THREAD
    ptr = get_ip(ip_obj);
#endif

    if (
#ifdef RUBY_USE_NATIVE_THREAD
        (ptr->tk_thread_id == 0 || ptr->tk_thread_id == Tcl_GetCurrentThread())
        && 
#endif
        (NIL_P(eventloop_thread) || current == eventloop_thread)
        ) {
        if (NIL_P(eventloop_thread)) {
            DUMP2("eval from thread:%lx but no eventloop", current);
        } else {
            DUMP2("eval from current eventloop %lx", current);
        }
        result = ip_eval_real(self, RSTRING_PTR(str), RSTRING_LEN(str));
        if (rb_obj_is_kind_of(result, rb_eException)) {
            rb_exc_raise(result);
        }
        return result;
    }

    DUMP2("eval from thread %lx (NOT current eventloop)", current);

    thr_crit_bup = rb_thread_critical;
    rb_thread_critical = Qtrue;

    /* allocate memory (keep result) */
    /* alloc_done = (int*)ALLOC(int); */
    alloc_done = (int*)ckalloc(sizeof(int));
#if 0 /* use Tcl_Preserve/Release */
    Tcl_Preserve((ClientData)alloc_done); /* XXXXXXXX */
#endif
    *alloc_done = 0;

    /* eval_str = ALLOC_N(char, RSTRING_LEN(str) + 1); */
    eval_str = ckalloc(sizeof(char) * (RSTRING_LEN(str) + 1));
#if 0 /* use Tcl_Preserve/Release */
    Tcl_Preserve((ClientData)eval_str); /* XXXXXXXX */
#endif
    memcpy(eval_str, RSTRING_PTR(str), RSTRING_LEN(str));
    eval_str[RSTRING_LEN(str)] = 0;

    /* allocate memory (freed by Tcl_ServiceEvent) */
    /* evq = (struct eval_queue *)Tcl_Alloc(sizeof(struct eval_queue)); */
    evq = (struct eval_queue *)ckalloc(sizeof(struct eval_queue));
#if 0 /* use Tcl_Preserve/Release */
    Tcl_Preserve(evq);
#endif

    /* allocate result obj */
    result = rb_ary_new3(1, Qnil);

    /* construct event data */
    evq->done = alloc_done;
    evq->str = eval_str;
    evq->len = RSTRING_LEN(str);
    evq->interp = ip_obj;
    evq->result = result;
    evq->thread = current;
    evq->safe_level = rb_safe_level();
    evq->ev.proc = eval_queue_handler;

    position = TCL_QUEUE_TAIL;

    /* add the handler to Tcl event queue */
    DUMP1("add handler");
#ifdef RUBY_USE_NATIVE_THREAD
    if (ptr->tk_thread_id) {
      /* Tcl_ThreadQueueEvent(ptr->tk_thread_id, &(evq->ev), position); */
      Tcl_ThreadQueueEvent(ptr->tk_thread_id, (Tcl_Event*)evq, position);
      Tcl_ThreadAlert(ptr->tk_thread_id);
    } else if (tk_eventloop_thread_id) {
      Tcl_ThreadQueueEvent(tk_eventloop_thread_id, (Tcl_Event*)evq, position);
      /* Tcl_ThreadQueueEvent(tk_eventloop_thread_id, 
                           &(evq->ev), position); */
      Tcl_ThreadAlert(tk_eventloop_thread_id);
    } else {
      /* Tcl_QueueEvent(&(evq->ev), position); */
      Tcl_QueueEvent((Tcl_Event*)evq, position);
    }
#else
    /* Tcl_QueueEvent(&(evq->ev), position); */
    Tcl_QueueEvent((Tcl_Event*)evq, position);
#endif

    rb_thread_critical = thr_crit_bup;

    /* wait for the handler to be processed */
    DUMP2("wait for handler (current thread:%lx)", current);
    while(*alloc_done >= 0) {
      DUMP2("*** wait for handler (current thread:%lx)", current);
      /* rb_thread_stop(); */
      rb_thread_sleep_forever();
      DUMP2("*** wakeup (current thread:%lx)", current);
    }
    DUMP2("back from handler (current thread:%lx)", current);

    /* get result & free allocated memory */
    ret = RARRAY_PTR(result)[0];

#if 0 /* use Tcl_EventuallyFree */
    Tcl_EventuallyFree((ClientData)alloc_done, TCL_DYNAMIC); /* XXXXXXXX */
#else
#if 0 /* use Tcl_Preserve/Release */
    Tcl_Release((ClientData)alloc_done); /* XXXXXXXX */
#else
    /* free(alloc_done); */
    ckfree((char*)alloc_done);
#endif
#endif
#if 0 /* use Tcl_EventuallyFree */
    Tcl_EventuallyFree((ClientData)eval_str, TCL_DYNAMIC); /* XXXXXXXX */
#else
#if 0 /* use Tcl_Preserve/Release */
    Tcl_Release((ClientData)eval_str); /* XXXXXXXX */
#else
    /* free(eval_str); */
    ckfree(eval_str);
#endif
#endif
#if 0 /* evq is freed by Tcl_ServiceEvent */
#if 0 /* use Tcl_Preserve/Release */
    Tcl_Release(evq);
#else
    ckfree((char*)evq);
#endif
#endif

    if (rb_obj_is_kind_of(ret, rb_eException)) {
        DUMP1("raise exception");
        /* rb_exc_raise(ret); */
        rb_exc_raise(rb_exc_new3(rb_obj_class(ret), 
                                 rb_funcall(ret, ID_to_s, 0, 0)));
    }

    return ret;
}
            
Also aliased as: _eval_without_enc
_eval_without_enc(p1) click to toggle source

backup original (without encoding) _eval and _invoke

Alias for: _eval
_fromUTF8(p1, p2 = v2) click to toggle source
 
               static VALUE
ip_fromUTF8(argc, argv, self)
    int   argc;
    VALUE *argv;
    VALUE self;
{
    VALUE str, encodename;

    if (rb_scan_args(argc, argv, "11", &str, &encodename) == 1) {
        encodename = Qnil;
    }
    return lib_fromUTF8_core(self, str, encodename);
}
            
_get_global_var(p1) click to toggle source
 
               static VALUE
ip_get_global_var(self, varname)
    VALUE self;
    VALUE varname;
{
    return ip_get_variable(self, varname, 
                           INT2FIX(TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG));
}
            
_get_global_var2(p1, p2) click to toggle source
 
               static VALUE
ip_get_global_var2(self, varname, index)
    VALUE self;
    VALUE varname;
    VALUE index;
{
    return ip_get_variable2(self, varname, index, 
                            INT2FIX(TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG));
}
            
_get_variable(p1, p2) click to toggle source
 
               static VALUE
ip_get_variable(self, varname, flag)
    VALUE self;
    VALUE varname;
    VALUE flag;
{
    return ip_get_variable2(self, varname, Qnil, flag);
}
            
_get_variable2(p1, p2, p3) click to toggle source
 
               static VALUE
ip_get_variable2(self, varname, index, flag)
    VALUE self;
    VALUE varname;
    VALUE index;
    VALUE flag;
{
    VALUE argv[3];
    VALUE retval;

    StringValue(varname);
    if (!NIL_P(index)) StringValue(index);

    argv[0] = varname;
    argv[1] = index;
    argv[2] = flag;

    retval = tk_funcall(ip_get_variable2_core, 3, argv, self);

    if (NIL_P(retval)) {
        return rb_tainted_str_new2("");
    } else {
        return retval;
    }
}
            
_immediate_invoke(*args) click to toggle source
 
               static VALUE
ip_invoke_immediate(argc, argv, obj)
    int argc;
    VALUE *argv;
    VALUE obj;
{
    /* POTENTIALY INSECURE : can create infinite loop */
    rb_secure(4);
    return ip_invoke_with_position(argc, argv, obj, TCL_QUEUE_HEAD);
}
            
_invoke(*args) click to toggle source
 
               static VALUE
ip_invoke(argc, argv, obj)
    int argc;
    VALUE *argv;
    VALUE obj;
{
    return ip_invoke_with_position(argc, argv, obj, TCL_QUEUE_TAIL);
}
            
Also aliased as: _invoke_without_enc
_invoke_without_enc(*args) click to toggle source
Alias for: _invoke
_ip_id_() click to toggle source
 
               # File tk/lib/tk.rb, line 20
def _ip_id_
  # for RemoteTkIp
  ''
end
            
_make_menu_embeddable(p1) click to toggle source
 
               static VALUE
ip_make_menu_embeddable(interp, menu_path)
    VALUE interp;
    VALUE menu_path;
{
    VALUE argv[1];

    argv[0] = menu_path;
    return tk_funcall(ip_make_menu_embeddable_core, 1, argv, interp);
}
            
_merge_tklist(*args) click to toggle source
 
               static VALUE
lib_merge_tklist(argc, argv, obj)
    int argc;
    VALUE *argv;
    VALUE obj;
{
    int  num, len;
    int  *flagPtr;
    char *dst, *result;
    volatile VALUE str;
    int taint_flag = 0;
    int thr_crit_bup;
    VALUE old_gc;

    if (argc == 0) return rb_str_new2("");

    tcl_stubs_check();

    thr_crit_bup = rb_thread_critical;
    rb_thread_critical = Qtrue;
    old_gc = rb_gc_disable();

    /* based on Tcl/Tk's Tcl_Merge() */
    /* flagPtr = ALLOC_N(int, argc); */
    flagPtr = (int *)ckalloc(sizeof(int) * argc);
#if 0 /* use Tcl_Preserve/Release */
    Tcl_Preserve((ClientData)flagPtr); /* XXXXXXXXXX */
#endif

    /* pass 1 */
    len = 1;
    for(num = 0; num < argc; num++) {
        if (OBJ_TAINTED(argv[num])) taint_flag = 1;
        dst = StringValuePtr(argv[num]);
#if TCL_MAJOR_VERSION >= 8
        len += Tcl_ScanCountedElement(dst, RSTRING_LEN(argv[num]),  
                                      &flagPtr[num]) + 1;
#else /* TCL_MAJOR_VERSION < 8 */
        len += Tcl_ScanElement(dst, &flagPtr[num]) + 1;
#endif
    }

    /* pass 2 */
    /* result = (char *)Tcl_Alloc(len); */
    result = (char *)ckalloc(len);
#if 0 /* use Tcl_Preserve/Release */
    Tcl_Preserve((ClientData)result);
#endif
    dst = result;
    for(num = 0; num < argc; num++) {
#if TCL_MAJOR_VERSION >= 8
        len = Tcl_ConvertCountedElement(RSTRING_PTR(argv[num]), 
                                        RSTRING_LEN(argv[num]), 
                                        dst, flagPtr[num]);
#else /* TCL_MAJOR_VERSION < 8 */
        len = Tcl_ConvertElement(RSTRING_PTR(argv[num]), dst, flagPtr[num]);
#endif
        dst += len;
        *dst = ' ';
        dst++;
    }
    if (dst == result) {
        *dst = 0;
    } else {
        dst[-1] = 0;
    }

#if 0 /* use Tcl_EventuallyFree */
    Tcl_EventuallyFree((ClientData)flagPtr, TCL_DYNAMIC); /* XXXXXXXX */
#else
#if 0 /* use Tcl_Preserve/Release */
    Tcl_Release((ClientData)flagPtr);
#else
    /* free(flagPtr); */
    ckfree((char*)flagPtr);
#endif
#endif

    /* create object */
    str = rb_str_new(result, dst - result - 1);
    if (taint_flag) OBJ_TAINT(str);
#if 0 /* use Tcl_EventuallyFree */
    Tcl_EventuallyFree((ClientData)result, TCL_DYNAMIC); /* XXXXXXXX */
#else
#if 0 /* use Tcl_Preserve/Release */
    Tcl_Release((ClientData)result); /* XXXXXXXXXXX */
#else
    /* Tcl_Free(result); */
    ckfree(result);
#endif
#endif

    if (old_gc == Qfalse) rb_gc_enable();
    rb_thread_critical = thr_crit_bup;

    return str;
}
            
_return_value() click to toggle source

get return code from Tcl_Eval()

 
               static VALUE
ip_retval(self)
    VALUE self;
{
    struct tcltkip *ptr;        /* tcltkip data struct */

    /* get the data strcut */
    ptr = get_ip(self);

    /* ip is deleted? */
    if (deleted_ip(ptr)) {
        return rb_tainted_str_new2("");
    }

    return (INT2FIX(ptr->return_value));
}
            
_set_global_var(p1, p2) click to toggle source
 
               static VALUE
ip_set_global_var(self, varname, value)
    VALUE self;
    VALUE varname;
    VALUE value;
{
    return ip_set_variable(self, varname, value, 
                           INT2FIX(TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG));
}
            
_set_global_var2(p1, p2, p3) click to toggle source
 
               static VALUE
ip_set_global_var2(self, varname, index, value)
    VALUE self;
    VALUE varname;
    VALUE index;
    VALUE value;
{
    return ip_set_variable2(self, varname, index, value, 
                            INT2FIX(TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG));
}
            
_set_variable(p1, p2, p3) click to toggle source
 
               static VALUE
ip_set_variable(self, varname, value, flag)
    VALUE self;
    VALUE varname;
    VALUE value;
    VALUE flag;
{
    return ip_set_variable2(self, varname, Qnil, value, flag);
}
            
_set_variable2(p1, p2, p3, p4) click to toggle source
 
               static VALUE
ip_set_variable2(self, varname, index, value, flag)
    VALUE self;
    VALUE varname;
    VALUE index;
    VALUE value;
    VALUE flag;
{
    VALUE argv[4];
    VALUE retval;

    StringValue(varname);
    if (!NIL_P(index)) StringValue(index);
    StringValue(value);

    argv[0] = varname;
    argv[1] = index;
    argv[2] = value;
    argv[3] = flag;

    retval = tk_funcall(ip_set_variable2_core, 4, argv, self);

    if (NIL_P(retval)) {
        return rb_tainted_str_new2("");
    } else {
        return retval;
    }
}
            
_split_tklist(p1) click to toggle source
 
               static VALUE
ip_split_tklist(self, list_str)
    VALUE self;
    VALUE list_str;
{
    return lib_split_tklist_core(self, list_str);
}
            
_thread_tkwait(p1, p2) click to toggle source
 
               static VALUE
ip_thread_tkwait(self, mode, target)
    VALUE self;
    VALUE mode;
    VALUE target;
{
    VALUE argv[3];
    volatile VALUE cmd_str = rb_str_new2("thread_tkwait");

    argv[0] = cmd_str;
    argv[1] = mode;
    argv[2] = target;

    return ip_invoke_with_position(3, argv, self, TCL_QUEUE_TAIL);
}
            
_thread_vwait(p1) click to toggle source
 
               static VALUE
ip_thread_vwait(self, var)
    VALUE self;
    VALUE var;
{
    VALUE argv[2];
    volatile VALUE cmd_str = rb_str_new2("thread_vwait");

    argv[0] = cmd_str;
    argv[1] = var;

    return ip_invoke_with_position(2, argv, self, TCL_QUEUE_TAIL);
}
            
_toUTF8(p1, p2 = v2) click to toggle source
 
               static VALUE
ip_toUTF8(argc, argv, self)
    int   argc;
    VALUE *argv;
    VALUE self;
{
    VALUE str, encodename;

    if (rb_scan_args(argc, argv, "11", &str, &encodename) == 1) {
        encodename = Qnil;
    }
    return lib_toUTF8_core(self, str, encodename);
}
            
_unset_global_var(p1) click to toggle source
 
               static VALUE
ip_unset_global_var(self, varname)
    VALUE self;
    VALUE varname;
{
    return ip_unset_variable(self, varname, 
                             INT2FIX(TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG));
}
            
_unset_global_var2(p1, p2) click to toggle source
 
               static VALUE
ip_unset_global_var2(self, varname, index)
    VALUE self;
    VALUE varname;
    VALUE index;
{
    return ip_unset_variable2(self, varname, index, 
                              INT2FIX(TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG));
}
            
_unset_variable(p1, p2) click to toggle source
 
               static VALUE
ip_unset_variable(self, varname, flag)
    VALUE self;
    VALUE varname;
    VALUE flag;
{
    return ip_unset_variable2(self, varname, Qnil, flag);
}
            
_unset_variable2(p1, p2, p3) click to toggle source
 
               static VALUE
ip_unset_variable2(self, varname, index, flag)
    VALUE self;
    VALUE varname;
    VALUE index;
    VALUE flag;
{
    VALUE argv[3];
    VALUE retval;

    StringValue(varname);
    if (!NIL_P(index)) StringValue(index);

    argv[0] = varname;
    argv[1] = index;
    argv[2] = flag;

    retval = tk_funcall(ip_unset_variable2_core, 3, argv, self);

    if (NIL_P(retval)) {
        return rb_tainted_str_new2("");
    } else {
        return retval;
    }
}
            
allow_ruby_exit=(p1) click to toggle source

allow_ruby_exit = mode

 
               static VALUE
ip_allow_ruby_exit_set(self, val)
    VALUE self, val;
{
    struct tcltkip *ptr = get_ip(self);
    Tk_Window mainWin;

    rb_secure(4);

    /* ip is deleted? */
    if (deleted_ip(ptr)) {
        rb_raise(rb_eRuntimeError, "interpreter is deleted");
    }

    if (Tcl_IsSafe(ptr->ip)) {
        rb_raise(rb_eSecurityError, 
                 "insecure operation on a safe interpreter");
    }

    /*
     *  Because of cross-threading, the following line may fail to find 
     *  the MainWindow, even if the Tcl/Tk interpreter has one or more.
     *  But it has no problem. Current implementation of both type of 
     *  the "exit" command don't need maiinWin token.
     */
    mainWin = (tk_stubs_init_p())? Tk_MainWindow(ptr->ip): (Tk_Window)NULL;

    if (RTEST(val)) {
        ptr->allow_ruby_exit = 1;
#if TCL_MAJOR_VERSION >= 8
        DUMP1("Tcl_CreateObjCommand(\"exit\") --> \"ruby_exit\"");
        Tcl_CreateObjCommand(ptr->ip, "exit", ip_RubyExitObjCmd, 
                             (ClientData)mainWin, (Tcl_CmdDeleteProc *)NULL);
#else /* TCL_MAJOR_VERSION < 8 */
        DUMP1("Tcl_CreateCommand(\"exit\") --> \"ruby_exit\"");
        Tcl_CreateCommand(ptr->ip, "exit", ip_RubyExitCommand, 
                          (ClientData)mainWin, (Tcl_CmdDeleteProc *)NULL);
#endif
        return Qtrue;

    } else {
        ptr->allow_ruby_exit = 0;
#if TCL_MAJOR_VERSION >= 8
        DUMP1("Tcl_CreateObjCommand(\"exit\") --> \"interp_exit\"");
        Tcl_CreateObjCommand(ptr->ip, "exit", ip_InterpExitObjCmd, 
                             (ClientData)mainWin, (Tcl_CmdDeleteProc *)NULL);
#else /* TCL_MAJOR_VERSION < 8 */
        DUMP1("Tcl_CreateCommand(\"exit\") --> \"interp_exit\"");
        Tcl_CreateCommand(ptr->ip, "exit", ip_InterpExitCommand, 
                          (ClientData)mainWin, (Tcl_CmdDeleteProc *)NULL);
#endif
        return Qfalse;
    }
}
            
allow_ruby_exit?() click to toggle source

allow_ruby_exit?

 
               static VALUE
ip_allow_ruby_exit_p(self)
    VALUE self;
{
    struct tcltkip *ptr = get_ip(self);
    
    /* ip is deleted? */
    if (deleted_ip(ptr)) {
        rb_raise(rb_eRuntimeError, "interpreter is deleted");
    }

    if (ptr->allow_ruby_exit) {
        return Qtrue;
    } else {
        return Qfalse;
    }
}
            
create_dummy_encoding_for_tk(p1) click to toggle source
 
               static VALUE
create_dummy_encoding_for_tk(interp, name)
     VALUE interp;
     VALUE name;
{
  return create_dummy_encoding_for_tk_core(interp, name, Qtrue);
}
            
create_slave(p1, p2 = v2) click to toggle source
 
               static VALUE
ip_create_slave(argc, argv, self)
    int   argc;
    VALUE *argv;
    VALUE self;
{
    struct tcltkip *master = get_ip(self);
    VALUE safemode;
    VALUE name;
    VALUE callargv[2];

    /* ip is deleted? */
    if (deleted_ip(master)) {
        rb_raise(rb_eRuntimeError, 
                 "deleted master cannot create a new slave interpreter");
    }

    /* argument check */
    if (rb_scan_args(argc, argv, "11", &name, &safemode) == 1) {
        safemode = Qfalse;
    }
    if (Tcl_IsSafe(master->ip) != 1
        && (safemode == Qfalse || NIL_P(safemode))) {
        rb_secure(4);
    }

    StringValue(name);
    callargv[0] = name;
    callargv[1] = safemode;

    return tk_funcall(ip_create_slave_core, 2, callargv, self);
}
            
delete() click to toggle source

delete interpreter

 
               static VALUE
ip_delete(self)
    VALUE self;
{
    int  thr_crit_bup;
    struct tcltkip *ptr = get_ip(self);

    if (ptr == (struct tcltkip *)NULL || ptr->ip == (Tcl_Interp*)NULL) {
        DUMP1("delete deleted IP");
        return Qnil;
    }

    thr_crit_bup = rb_thread_critical;
    rb_thread_critical = Qtrue;

    DUMP1("call ip_finalize");
    ip_finalize(ptr->ip);

    DUMP1("delete interp");
    Tcl_DeleteInterp(ptr->ip);
    Tcl_Release(ptr->ip);

    rb_thread_critical = thr_crit_bup;

    return Qnil;
}
            
deleted?() click to toggle source
 
               static VALUE
ip_is_deleted_p(self)
    VALUE self;
{
    struct tcltkip *ptr = get_ip(self);

    if (deleted_ip(ptr)) {
        return Qtrue;
    } else {
        return Qfalse;
    }
}
            
do_one_event(*args) click to toggle source
 
               static VALUE
ip_do_one_event(argc, argv, self)
    int   argc;
    VALUE *argv;
    VALUE self;
{
    return lib_do_one_event_core(argc, argv, self, 0);
}
            
encoding_table() click to toggle source
 
               static VALUE
ip_get_encoding_table(interp)
     VALUE interp;
{
  volatile VALUE table = Qnil;

  table = rb_ivar_get(interp, ID_encoding_table);

  if (NIL_P(table)) {
    /* initialize encoding_table */
    table = create_encoding_table(interp);
    rb_define_singleton_method(table, "get_name", encoding_table_get_name, 1);
    rb_define_singleton_method(table, "get_obj",  encoding_table_get_obj,  1);
  }

  return table;
}
            
get_eventloop_tick() click to toggle source
 
               static VALUE
ip_get_eventloop_tick(self)
    VALUE self;
{
    return get_eventloop_tick(self);
}
            
get_eventloop_weight() click to toggle source
 
               static VALUE
ip_get_eventloop_weight(self)
    VALUE self;
{
    return get_eventloop_weight(self);
}
            
get_no_event_wait() click to toggle source
 
               static VALUE
ip_get_no_event_wait(self)
    VALUE self;
{
    return get_no_event_wait(self);
}
            
has_mainwindow?() click to toggle source
 
               static VALUE
ip_has_mainwindow_p(self)
    VALUE self;
{
    return tk_funcall(ip_has_mainwindow_p_core, 0, (VALUE*)NULL, self);
}
            
invalid_namespace?() click to toggle source

is deleted?

 
               static VALUE
ip_has_invalid_namespace_p(self)
    VALUE self;
{
    struct tcltkip *ptr = get_ip(self);

    if (ptr == (struct tcltkip *)NULL || ptr->ip == (Tcl_Interp *)NULL) {
        /* deleted IP */
        return Qtrue;
    }

#if TCL_NAMESPACE_DEBUG
    if (rbtk_invalid_namespace(ptr)) {
        return Qtrue;
    } else {
        return Qfalse;
    }
#else
    return Qfalse;
#endif
}
            
mainloop(*args) click to toggle source
 
               static VALUE
ip_mainloop(argc, argv, self)
    int   argc;
    VALUE *argv;
    VALUE self;
{
    struct tcltkip *ptr = get_ip(self);

    /* ip is deleted? */
    if (deleted_ip(ptr)) {
        return Qnil;
    }

    if (Tcl_GetMaster(ptr->ip) != (Tcl_Interp*)NULL) {
        /* slave IP */
        return Qnil;
    }
    return lib_mainloop(argc, argv, self);
}
            
mainloop_abort_on_exception() click to toggle source
 
               static VALUE
ip_evloop_abort_on_exc(self)
    VALUE self;
{
    return lib_evloop_abort_on_exc(self);
}
            
mainloop_abort_on_exception=(p1) click to toggle source
 
               static VALUE
ip_evloop_abort_on_exc_set(self, val)
    VALUE self, val;
{
    struct tcltkip *ptr = get_ip(self);

    rb_secure(4);

    /* ip is deleted? */
    if (deleted_ip(ptr)) {
        return lib_evloop_abort_on_exc(self);
    }

    if (Tcl_GetMaster(ptr->ip) != (Tcl_Interp*)NULL) {
        /* slave IP */
        return lib_evloop_abort_on_exc(self);
    }
    return lib_evloop_abort_on_exc_set(self, val);
}
            
mainloop_watchdog(*args) click to toggle source
 
               static VALUE
ip_mainloop_watchdog(argc, argv, self)
    int   argc;
    VALUE *argv;
    VALUE self;
{
    struct tcltkip *ptr = get_ip(self);

    /* ip is deleted? */
    if (deleted_ip(ptr)) {
        return Qnil;
    }

    if (Tcl_GetMaster(ptr->ip) != (Tcl_Interp*)NULL) {
        /* slave IP */
        return Qnil;
    }
    return lib_mainloop_watchdog(argc, argv, self);
}
            
make_safe() click to toggle source
 
               static VALUE
ip_make_safe(self)
    VALUE self;
{
    struct tcltkip *ptr = get_ip(self);
    
    /* ip is deleted? */
    if (deleted_ip(ptr)) {
        rb_raise(rb_eRuntimeError, "interpreter is deleted");
    }

    return tk_funcall(ip_make_safe_core, 0, (VALUE*)NULL, self);
}
            
new(*args) click to toggle source
 
               # File tk/lib/multi-tk.rb, line 27
def new(*args)
  if Thread.current.group != ThreadGroup::Default
    raise SecurityError, 'only ThreadGroup::Default can call TclTkIp.new'
  end
  obj = __new__(*args)
  obj.instance_eval{
    @force_default_encoding ||= [false].taint
    @encoding ||= [nil].taint
    def @encoding.to_s; self.join(nil); end
  }
  obj
end
            
restart() click to toggle source
 
               static VALUE
ip_restart(self)
    VALUE self;
{
    struct tcltkip *ptr = get_ip(self);

    rb_secure(4);

    tcl_stubs_check();

    /* ip is deleted? */
    if (deleted_ip(ptr)) {
        rb_raise(rb_eRuntimeError, "interpreter is deleted");
    }

    if (Tcl_GetMaster(ptr->ip) != (Tcl_Interp*)NULL) {
        /* slave IP */
        return Qnil;
    }
    return lib_restart(self);
}
            
safe?() click to toggle source

is safe?

 
               static VALUE
ip_is_safe_p(self)
    VALUE self;
{
    struct tcltkip *ptr = get_ip(self);
    
    /* ip is deleted? */
    if (deleted_ip(ptr)) {
        rb_raise(rb_eRuntimeError, "interpreter is deleted");
    }

    if (Tcl_IsSafe(ptr->ip)) {
        return Qtrue;
    } else {
        return Qfalse;
    }
}
            
set_eventloop_tick(p1) click to toggle source
 
               static VALUE
ip_set_eventloop_tick(self, tick)
    VALUE self;
    VALUE tick;
{
    struct tcltkip *ptr = get_ip(self);

    /* ip is deleted? */
    if (deleted_ip(ptr)) {
        return get_eventloop_tick(self);
    }

    if (Tcl_GetMaster(ptr->ip) != (Tcl_Interp*)NULL) {
        /* slave IP */
        return get_eventloop_tick(self);
    }
    return set_eventloop_tick(self, tick);
}
            
set_eventloop_weight(p1, p2) click to toggle source
 
               static VALUE
ip_set_eventloop_weight(self, loop_max, no_event)
    VALUE self;
    VALUE loop_max;
    VALUE no_event;
{
    struct tcltkip *ptr = get_ip(self);

    /* ip is deleted? */
    if (deleted_ip(ptr)) {
        return get_eventloop_weight(self);
    }

    if (Tcl_GetMaster(ptr->ip) != (Tcl_Interp*)NULL) {
        /* slave IP */
        return get_eventloop_weight(self);
    }
    return set_eventloop_weight(self, loop_max, no_event);
}
            
set_max_block_time(p1) click to toggle source
 
               static VALUE
set_max_block_time(self, time)
    VALUE self;
    VALUE time;
{
    struct Tcl_Time tcl_time;
    VALUE divmod;

    switch(TYPE(time)) {
    case T_FIXNUM:
    case T_BIGNUM:
        /* time is micro-second value */
        divmod = rb_funcall(time, rb_intern("divmod"), 1, LONG2NUM(1000000));
        tcl_time.sec  = NUM2LONG(RARRAY_PTR(divmod)[0]);
        tcl_time.usec = NUM2LONG(RARRAY_PTR(divmod)[1]);
        break;

    case T_FLOAT:
        /* time is second value */
        divmod = rb_funcall(time, rb_intern("divmod"), 1, INT2FIX(1));
        tcl_time.sec  = NUM2LONG(RARRAY_PTR(divmod)[0]);
        tcl_time.usec = (long)(NUM2DBL(RARRAY_PTR(divmod)[1]) * 1000000);

    default:
        {
            VALUE tmp = rb_funcall(time, ID_inspect, 0, 0);
            rb_raise(rb_eArgError, "invalid value for time: '%s'", 
                     StringValuePtr(tmp));
        }
    }

    Tcl_SetMaxBlockTime(&tcl_time);

    return Qnil;
}
            
set_no_event_wait(p1) click to toggle source
 
               static VALUE
ip_set_no_event_wait(self, wait)
    VALUE self;
    VALUE wait;
{
    struct tcltkip *ptr = get_ip(self);

    /* ip is deleted? */
    if (deleted_ip(ptr)) {
        return get_no_event_wait(self);
    }

    if (Tcl_GetMaster(ptr->ip) != (Tcl_Interp*)NULL) {
        /* slave IP */
        return get_no_event_wait(self);
    }
    return set_no_event_wait(self, wait);
}
            
slave_of?(p1) click to toggle source

self is slave of master?

 
               static VALUE
ip_is_slave_of_p(self, master)
    VALUE self, master;
{
    if (!rb_obj_is_kind_of(master, tcltkip_class)) {
        rb_raise(rb_eArgError, "expected TclTkIp object");
    }

    if (Tcl_GetMaster(get_ip(self)->ip) == get_ip(master)->ip) {
      return Qtrue;
    } else {
      return Qfalse;
    }
}
            

Commenting is here to help enhance the documentation. For example, code samples, or clarification of the documentation.

If you have questions about Ruby or the documentation, please post to one of the Ruby mailing lists. You will get better, faster, help that way.

If you wish to post a correction of the docs, please do so, but also file bug report so that it can be corrected for the next release. Thank you.

If you want to help improve the Ruby documentation, please visit Documenting-ruby.org.

blog comments powered by Disqus