2 * base code for various Tcl extensions
3 * Copyright 2006-2012 Ian Jackson
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21 #include "chiark-tcl-base.h"
23 void cht_scriptinv_init(ScriptToInvoke *si) {
29 void cht_scriptinv_cancel(ScriptToInvoke *si) {
30 if (si->script) { Tcl_DecrRefCount(si->script); si->script= 0; }
31 if (si->xargs) { Tcl_DecrRefCount(si->xargs); si->xargs= 0; }
35 int cht_scriptinv_set(ScriptToInvoke *si, Tcl_Interp *ip,
36 Tcl_Obj *newscript, Tcl_Obj *xargs) {
39 cht_scriptinv_cancel(si);
40 if (!newscript) return 0;
42 rc= Tcl_ListObjLength(ip, newscript, &si->llen); if (rc) return rc;
43 Tcl_IncrRefCount(newscript);
46 rc= Tcl_ListObjLength(ip, xargs, &xlength); if (rc) return rc;
47 Tcl_IncrRefCount(xargs);
48 assert(si->llen < INT_MAX/2 && xlength < INT_MAX/2);
52 si->script= newscript;
58 int cht_scriptinv_invoke_fg(ScriptToInvoke *si, int argc,
59 Tcl_Obj *const *argv) {
63 if (!si->ipq) return TCL_OK;
65 for (i=0; i<argc; i++) Tcl_IncrRefCount(argv[i]);
67 invoke= Tcl_DuplicateObj(si->script);
68 Tcl_IncrRefCount(invoke);
71 rc= Tcl_ListObjAppendList(si->ipq, invoke, si->xargs);
75 rc= Tcl_ListObjReplace(si->ipq, invoke,si->llen,0, argc,argv);
78 rc= Tcl_EvalObjEx(si->ipq, invoke, TCL_EVAL_GLOBAL|TCL_EVAL_DIRECT);
84 for (i=0; i<argc; i++) Tcl_DecrRefCount(argv[i]);
85 if (invoke) Tcl_DecrRefCount(invoke);
89 void cht_scriptinv_invoke(ScriptToInvoke *si, int argc, Tcl_Obj *const *argv) {
91 rc= cht_scriptinv_invoke_fg(si, argc, argv);
92 if (rc) Tcl_BackgroundError(si->ipq);