aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Tcl_shipped.html38
-rw-r--r--jim.c46
-rw-r--r--jim_tcl.txt12
-rw-r--r--tests/exists.test78
4 files changed, 162 insertions, 12 deletions
diff --git a/Tcl_shipped.html b/Tcl_shipped.html
index b0a1f85..a7baa5a 100644
--- a/Tcl_shipped.html
+++ b/Tcl_shipped.html
@@ -726,6 +726,11 @@ Add <em>info channels</em>
The <em>bio</em> extension is gone. Now <em>aio</em> supports <em>copyto</em>.
</p>
</li>
+<li>
+<p>
+Add <em>exists</em> command
+</p>
+</li>
</ol></div>
<div class="paragraph"><p>Since v0.62:</p></div>
<div class="olist arabic"><ol class="arabic">
@@ -2713,6 +2718,7 @@ cellspacing="0" cellpadding="4">
<td align="left" valign="top"><p class="table"><a href="#_exec">exec</a></p></td>
</tr>
<tr>
+<td align="left" valign="top"><p class="table"><a href="#_exists">exists</a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_exit">exit</a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_expr">expr</a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_file">file</a></p></td>
@@ -2720,9 +2726,9 @@ cellspacing="0" cellpadding="4">
<td align="left" valign="top"><p class="table"><a href="#_flush">flush</a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_for">for</a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_foreach">foreach</a></p></td>
-<td align="left" valign="top"><p class="table"><a href="#_format">format</a></p></td>
</tr>
<tr>
+<td align="left" valign="top"><p class="table"><a href="#_format">format</a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_getref">getref</a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_gets">gets</a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_glob">glob</a></p></td>
@@ -2730,9 +2736,9 @@ cellspacing="0" cellpadding="4">
<td align="left" valign="top"><p class="table"><a href="#_if">if</a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_incr">incr</a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_info">info</a></p></td>
-<td align="left" valign="top"><p class="table"><a href="#_join">join</a></p></td>
</tr>
<tr>
+<td align="left" valign="top"><p class="table"><a href="#_join">join</a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_kill">kill</a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_lambda">lambda</a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_lappend">lappend</a></p></td>
@@ -2740,9 +2746,9 @@ cellspacing="0" cellpadding="4">
<td align="left" valign="top"><p class="table"><a href="#_lindex">lindex</a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_linsert">linsert</a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_list">list</a></p></td>
-<td align="left" valign="top"><p class="table"><a href="#_llength">llength</a></p></td>
</tr>
<tr>
+<td align="left" valign="top"><p class="table"><a href="#_llength">llength</a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_lmap">lmap</a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_load">load</a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_local">local</a></p></td>
@@ -2750,9 +2756,9 @@ cellspacing="0" cellpadding="4">
<td align="left" valign="top"><p class="table"><a href="#_lrepeat">lrepeat</a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_lreplace">lreplace</a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_lreverse">lreverse</a></p></td>
-<td align="left" valign="top"><p class="table"><a href="#_lsearch">lsearch</a></p></td>
</tr>
<tr>
+<td align="left" valign="top"><p class="table"><a href="#_lsearch">lsearch</a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_lset">lset</a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_lsort">lsort</a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_open">open</a></p></td>
@@ -2760,9 +2766,9 @@ cellspacing="0" cellpadding="4">
<td align="left" valign="top"><p class="table"><a href="#cmd_1">os.gethostname</a></p></td>
<td align="left" valign="top"><p class="table"><a href="#cmd_1">os.getids</a></p></td>
<td align="left" valign="top"><p class="table"><a href="#cmd_1">os.uptime</a></p></td>
-<td align="left" valign="top"><p class="table"><a href="#cmd_1">os.wait</a></p></td>
</tr>
<tr>
+<td align="left" valign="top"><p class="table"><a href="#cmd_1">os.wait</a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_package">package</a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_pid">pid</a></p></td>
<td align="left" valign="top"><p class="table"><a href="#cmd_1">posix</a></p></td>
@@ -2770,9 +2776,9 @@ cellspacing="0" cellpadding="4">
<td align="left" valign="top"><p class="table"><a href="#_puts">puts</a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_pwd">pwd</a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_rand">rand</a></p></td>
-<td align="left" valign="top"><p class="table"><a href="#_range">range</a></p></td>
</tr>
<tr>
+<td align="left" valign="top"><p class="table"><a href="#_range">range</a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_read">read</a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_ref">ref</a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_regexp">regexp</a></p></td>
@@ -2780,9 +2786,9 @@ cellspacing="0" cellpadding="4">
<td align="left" valign="top"><p class="table"><a href="#_rename">rename</a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_return">return</a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_scan">scan</a></p></td>
-<td align="left" valign="top"><p class="table"><a href="#_seek">seek</a></p></td>
</tr>
<tr>
+<td align="left" valign="top"><p class="table"><a href="#_seek">seek</a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_set">set</a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_setref">setref</a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_signal">signal</a></p></td>
@@ -2790,9 +2796,9 @@ cellspacing="0" cellpadding="4">
<td align="left" valign="top"><p class="table"><a href="#_socket">socket</a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_source">source</a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_split">split</a></p></td>
-<td align="left" valign="top"><p class="table"><a href="#_stackdump">stackdump</a></p></td>
</tr>
<tr>
+<td align="left" valign="top"><p class="table"><a href="#_stackdump">stackdump</a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_stacktrace">stacktrace</a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_string">string</a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_subst">subst</a></p></td>
@@ -2800,9 +2806,9 @@ cellspacing="0" cellpadding="4">
<td align="left" valign="top"><p class="table"><a href="#_syslog">syslog</a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_tailcall">tailcall</a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_tell">tell</a></p></td>
-<td align="left" valign="top"><p class="table"><a href="#_throw">throw</a></p></td>
</tr>
<tr>
+<td align="left" valign="top"><p class="table"><a href="#_throw">throw</a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_time">time</a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_try">try</a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_unknown">unknown</a></p></td>
@@ -2810,9 +2816,9 @@ cellspacing="0" cellpadding="4">
<td align="left" valign="top"><p class="table"><a href="#cmd_2">update</a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_uplevel">uplevel</a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_upvar">upvar</a></p></td>
-<td align="left" valign="top"><p class="table"><a href="#cmd_2">vwait</a></p></td>
</tr>
<tr>
+<td align="left" valign="top"><p class="table"><a href="#cmd_2">vwait</a></p></td>
<td align="left" valign="top"><p class="table"><a href="#_while">while</a></p></td>
<td align="left" valign="top"><p class="table"></p></td>
<td align="left" valign="top"><p class="table"></p></td>
@@ -2820,7 +2826,6 @@ cellspacing="0" cellpadding="4">
<td align="left" valign="top"><p class="table"></p></td>
<td align="left" valign="top"><p class="table"></p></td>
<td align="left" valign="top"><p class="table"></p></td>
-<td align="left" valign="top"><p class="table"></p></td>
</tr>
</tbody>
</table>
@@ -3533,6 +3538,15 @@ option in <em>catch</em>) will be set to a list, as follows:</p></div>
this variable is unset, in which case the original environment is used).</p></div>
</div>
<div class="sect2">
+<h3 id="_exists">exists</h3>
+<div class="paragraph"><p><tt><strong>exists ?-var|-proc|-command?</strong> <em>name</em></tt></p></div>
+<div class="paragraph"><p>Checks the existence of the given variable, procedure or command
+respectively and returns 1 if it exists or 0 if not. This command
+provides a more simplified/convenient version of <em>info exists</em>,
+<em>info procs</em> and <em>info commands</em>.</p></div>
+<div class="paragraph"><p>If the type is omitted, a type of <em>-var</em> is used. The type may be abbreviated.</p></div>
+</div>
+<div class="sect2">
<h3 id="_exit">exit</h3>
<div class="paragraph"><p><tt><strong>exit</strong> <em>?returnCode?</em></tt></p></div>
<div class="paragraph"><p>Terminate the process, returning <strong>returnCode</strong> to the
@@ -6806,7 +6820,7 @@ official policies, either expressed or implied, of the Jim Tcl Project.</tt></pr
<div id="footnotes"><hr /></div>
<div id="footer">
<div id="footer-text">
-Last updated 2010-11-15 11:22:37 EST
+Last updated 2010-11-22 20:39:26 EST
</div>
</div>
</body>
diff --git a/jim.c b/jim.c
index 9a9342c..accb9d5 100644
--- a/jim.c
+++ b/jim.c
@@ -12995,6 +12995,51 @@ static int Jim_InfoCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg
return JIM_OK;
}
+/* [exists] */
+static int Jim_ExistsCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+ Jim_Obj *objPtr;
+
+ static const char * const options[] = {
+ "-command", "-proc", "-var", NULL
+ };
+ enum
+ {
+ OPT_COMMAND, OPT_PROC, OPT_VAR
+ };
+ int option;
+
+ if (argc == 2) {
+ option = OPT_VAR;
+ objPtr = argv[1];
+ }
+ else if (argc == 3) {
+ if (Jim_GetEnum(interp, argv[1], options, &option, NULL, JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK) {
+ return JIM_ERR;
+ }
+ objPtr = argv[2];
+ }
+ else {
+ Jim_WrongNumArgs(interp, 1, argv, "?option? name");
+ return JIM_ERR;
+ }
+
+ /* Test for the the most common commands first, just in case it makes a difference */
+ switch (option) {
+ case OPT_VAR:
+ Jim_SetResultBool(interp, Jim_GetVariable(interp, objPtr, 0) != NULL);
+ break;
+
+ case OPT_COMMAND:
+ case OPT_PROC: {
+ Jim_Cmd *cmd = Jim_GetCommand(interp, objPtr, JIM_NONE);
+ Jim_SetResultBool(interp, cmd != NULL && (option == OPT_COMMAND || !cmd->cmdProc));
+ break;
+ }
+ }
+ return JIM_OK;
+}
+
/* [split] */
static int Jim_SplitCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
@@ -13501,6 +13546,7 @@ static const struct {
{"dict", Jim_DictCoreCommand},
{"subst", Jim_SubstCoreCommand},
{"info", Jim_InfoCoreCommand},
+ {"exists", Jim_ExistsCoreCommand},
{"split", Jim_SplitCoreCommand},
{"join", Jim_JoinCoreCommand},
{"format", Jim_FormatCoreCommand},
diff --git a/jim_tcl.txt b/jim_tcl.txt
index 0834a57..737485a 100644
--- a/jim_tcl.txt
+++ b/jim_tcl.txt
@@ -64,6 +64,7 @@ Since v0.63:
2. Add aio '$handle filename'
3. Add 'info channels'
4. The 'bio' extension is gone. Now 'aio' supports 'copyto'.
+5. Add 'exists' command
Since v0.62:
@@ -2059,6 +2060,17 @@ option in 'catch') will be set to a list, as follows:
The environment for the executed command is set from $::env (unless
this variable is unset, in which case the original environment is used).
+exists
+~~~~~~
++*exists ?-var|-proc|-command?* 'name'+
+
+Checks the existence of the given variable, procedure or command
+respectively and returns 1 if it exists or 0 if not. This command
+provides a more simplified/convenient version of 'info exists',
+'info procs' and 'info commands'.
+
+If the type is omitted, a type of '-var' is used. The type may be abbreviated.
+
exit
~~~~
+*exit* '?returnCode?'+
diff --git a/tests/exists.test b/tests/exists.test
new file mode 100644
index 0000000..ae35a87
--- /dev/null
+++ b/tests/exists.test
@@ -0,0 +1,78 @@
+source [file dirname [info script]]/testing.tcl
+
+needs cmd exists
+
+test exists-1.1 "Exists var" {
+ set a 1
+ exists a
+} 1
+
+test exists-1.1 "Exists var" {
+ unset -nocomplain b
+ exists b
+} 0
+
+test exists-1.1 "Exists -var" {
+ exists -var a
+} 1
+
+test exists-1.1 "Exists -var" {
+ exists -var b
+} 0
+
+test exists-1.1 "Exists in proc" {
+ proc a {name} { exists $name }
+ a ::a
+} 1
+
+test exists-1.1 "Exists in proc" {
+ a ::b
+} 0
+
+test exists-1.1 "Exists in proc" {
+ a name
+} 1
+
+test exists-1.1 "Exists in proc" {
+ a none
+} 0
+
+test exists-1.1 "Exists -proc" {
+ exists -proc a
+} 1
+
+test exists-1.1 "Exists -proc" {
+ exists -proc bogus
+} 0
+
+test exists-1.1 "Exists -proc" {
+ exists -proc info
+} 0
+
+test exists-1.1 "Exists -command" {
+ exists -command a
+} 1
+
+test exists-1.1 "Exists -command" {
+ exists -command info
+} 1
+
+test exists-1.1 "Exists -command" {
+ exists -command bogus
+} 0
+
+test exists-1.1 "Exists local lambda after exit" {
+ proc a {} {
+ local lambda {} {dummy}
+ }
+ exists -proc [a]
+} 0
+
+test exists-1.1 "Exists local lambda" {
+ proc a {} {
+ exists -proc [local lambda {} {dummy}]
+ }
+ a
+} 1
+
+testreport