os/persistentdata/persistentstorage/sqlite3api/TEST/TCL/tcldistribution/generic/tclTest.c
Update contrib.
4 * This file contains C command procedures for a bunch of additional
5 * Tcl commands that are used for testing out Tcl's C interfaces.
6 * These commands are not normally included in Tcl applications;
7 * they're only used for testing.
9 * Copyright (c) 1993-1994 The Regents of the University of California.
10 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
11 * Copyright (c) 1998-2000 Ajuba Solutions.
12 * Copyright (c) 2003 by Kevin B. Kenny. All rights reserved.
13 * Portions Copyright (c) 2007 Nokia Corporation and/or its subsidiaries. All rights reserved.
15 * See the file "license.terms" for information on usage and redistribution
16 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
18 * RCS: @(#) $Id: tclTest.c,v 1.62.2.13 2006/09/22 01:26:23 andreas_kupries Exp $
25 #if defined(__SYMBIAN32__)
26 #include "tclSymbianGlobals.h"
30 * Required for Testregexp*Cmd
32 #include "tclRegexp.h"
35 * Required for TestlocaleCmd
40 * Required for the TestChannelCmd and TestChannelEventCmd
45 * Declare external functions used in Windows tests.
49 * Dynamic string shared by TestdcallCmd and DelCallbackProc; used
50 * to collect the results of the various deletion callbacks.
53 static Tcl_DString delString;
54 static Tcl_Interp *delInterp;
57 * One of the following structures exists for each asynchronous
58 * handler created by the "testasync" command".
61 typedef struct TestAsyncHandler {
62 int id; /* Identifier for this handler. */
63 Tcl_AsyncHandler handler; /* Tcl's token for the handler. */
64 char *command; /* Command to invoke when the
65 * handler is invoked. */
66 struct TestAsyncHandler *nextPtr; /* Next is list of handlers. */
69 static TestAsyncHandler *firstHandler = NULL;
72 * The dynamic string below is used by the "testdstring" command
73 * to test the dynamic string facilities.
76 static Tcl_DString dstring;
79 * The command trace below is used by the "testcmdtraceCmd" command
80 * to test the command tracing facilities.
83 static Tcl_Trace cmdTrace;
86 * One of the following structures exists for each command created
90 typedef struct DelCmd {
91 Tcl_Interp *interp; /* Interpreter in which command exists. */
92 char *deleteCmd; /* Script to execute when command is
93 * deleted. Malloc'ed. */
97 * The following is used to keep track of an encoding that invokes a Tcl
101 typedef struct TclEncoding {
108 * The counter below is used to determine if the TestsaveresultFree
109 * routine was called for a result.
112 static int freeCount;
115 * Boolean flag used by the "testsetmainloop" and "testexitmainloop"
118 static int exitMainLoop = 0;
121 * Event structure used in testing the event queue management procedures.
123 typedef struct TestEvent {
124 Tcl_Event header; /* Header common to all events */
125 Tcl_Interp* interp; /* Interpreter that will handle the event */
126 Tcl_Obj* command; /* Command to evaluate when the event occurs */
127 Tcl_Obj* tag; /* Tag for this event used to delete it */
131 * Forward declarations for procedures defined later in this file:
134 int Tcltest_Init _ANSI_ARGS_((Tcl_Interp *interp));
135 static int AsyncHandlerProc _ANSI_ARGS_((ClientData clientData,
136 Tcl_Interp *interp, int code));
137 static void CleanupTestSetassocdataTests _ANSI_ARGS_((
138 ClientData clientData, Tcl_Interp *interp));
139 static void CmdDelProc1 _ANSI_ARGS_((ClientData clientData));
140 static void CmdDelProc2 _ANSI_ARGS_((ClientData clientData));
141 static int CmdProc1 _ANSI_ARGS_((ClientData clientData,
142 Tcl_Interp *interp, int argc, CONST char **argv));
143 static int CmdProc2 _ANSI_ARGS_((ClientData clientData,
144 Tcl_Interp *interp, int argc, CONST char **argv));
145 static void CmdTraceDeleteProc _ANSI_ARGS_((
146 ClientData clientData, Tcl_Interp *interp,
147 int level, char *command, Tcl_CmdProc *cmdProc,
148 ClientData cmdClientData, int argc,
150 static void CmdTraceProc _ANSI_ARGS_((ClientData clientData,
151 Tcl_Interp *interp, int level, char *command,
152 Tcl_CmdProc *cmdProc, ClientData cmdClientData,
153 int argc, char **argv));
154 static int CreatedCommandProc _ANSI_ARGS_((
155 ClientData clientData, Tcl_Interp *interp,
156 int argc, CONST char **argv));
157 static int CreatedCommandProc2 _ANSI_ARGS_((
158 ClientData clientData, Tcl_Interp *interp,
159 int argc, CONST char **argv));
160 static void DelCallbackProc _ANSI_ARGS_((ClientData clientData,
161 Tcl_Interp *interp));
162 static int DelCmdProc _ANSI_ARGS_((ClientData clientData,
163 Tcl_Interp *interp, int argc, CONST char **argv));
164 static void DelDeleteProc _ANSI_ARGS_((ClientData clientData));
165 static void EncodingFreeProc _ANSI_ARGS_((ClientData clientData));
166 static int EncodingToUtfProc _ANSI_ARGS_((ClientData clientData,
167 CONST char *src, int srcLen, int flags,
168 Tcl_EncodingState *statePtr, char *dst,
169 int dstLen, int *srcReadPtr, int *dstWrotePtr,
171 static int EncodingFromUtfProc _ANSI_ARGS_((ClientData clientData,
172 CONST char *src, int srcLen, int flags,
173 Tcl_EncodingState *statePtr, char *dst,
174 int dstLen, int *srcReadPtr, int *dstWrotePtr,
176 static void ExitProcEven _ANSI_ARGS_((ClientData clientData));
177 static void ExitProcOdd _ANSI_ARGS_((ClientData clientData));
178 static int GetTimesCmd _ANSI_ARGS_((ClientData clientData,
179 Tcl_Interp *interp, int argc, CONST char **argv));
180 static void MainLoop _ANSI_ARGS_((void));
181 static int NoopCmd _ANSI_ARGS_((ClientData clientData,
182 Tcl_Interp *interp, int argc, CONST char **argv));
183 static int NoopObjCmd _ANSI_ARGS_((ClientData clientData,
184 Tcl_Interp *interp, int objc,
185 Tcl_Obj *CONST objv[]));
186 static int ObjTraceProc _ANSI_ARGS_(( ClientData clientData,
190 Tcl_Command commandToken,
192 Tcl_Obj *CONST objv[] ));
193 static void ObjTraceDeleteProc _ANSI_ARGS_(( ClientData ));
194 static void PrintParse _ANSI_ARGS_((Tcl_Interp *interp,
195 Tcl_Parse *parsePtr));
196 static void SpecialFree _ANSI_ARGS_((char *blockPtr));
197 static int StaticInitProc _ANSI_ARGS_((Tcl_Interp *interp));
198 static int TestaccessprocCmd _ANSI_ARGS_((ClientData dummy,
199 Tcl_Interp *interp, int argc, CONST char **argv));
200 static int PretendTclpAccess _ANSI_ARGS_((CONST char *path,
202 static int TestAccessProc1 _ANSI_ARGS_((CONST char *path,
204 static int TestAccessProc2 _ANSI_ARGS_((CONST char *path,
206 static int TestAccessProc3 _ANSI_ARGS_((CONST char *path,
208 static int TestasyncCmd _ANSI_ARGS_((ClientData dummy,
209 Tcl_Interp *interp, int argc, CONST char **argv));
210 static int TestcmdinfoCmd _ANSI_ARGS_((ClientData dummy,
211 Tcl_Interp *interp, int argc, CONST char **argv));
212 static int TestcmdtokenCmd _ANSI_ARGS_((ClientData dummy,
213 Tcl_Interp *interp, int argc, CONST char **argv));
214 static int TestcmdtraceCmd _ANSI_ARGS_((ClientData dummy,
215 Tcl_Interp *interp, int argc, CONST char **argv));
216 static int TestcreatecommandCmd _ANSI_ARGS_((ClientData dummy,
217 Tcl_Interp *interp, int argc, CONST char **argv));
218 static int TestdcallCmd _ANSI_ARGS_((ClientData dummy,
219 Tcl_Interp *interp, int argc, CONST char **argv));
220 static int TestdelCmd _ANSI_ARGS_((ClientData dummy,
221 Tcl_Interp *interp, int argc, CONST char **argv));
222 static int TestdelassocdataCmd _ANSI_ARGS_((ClientData dummy,
223 Tcl_Interp *interp, int argc, CONST char **argv));
224 static int TestdstringCmd _ANSI_ARGS_((ClientData dummy,
225 Tcl_Interp *interp, int argc, CONST char **argv));
226 static int TestencodingObjCmd _ANSI_ARGS_((ClientData dummy,
227 Tcl_Interp *interp, int objc,
228 Tcl_Obj *CONST objv[]));
229 static int TestevalexObjCmd _ANSI_ARGS_((ClientData dummy,
230 Tcl_Interp *interp, int objc,
231 Tcl_Obj *CONST objv[]));
232 static int TestevalobjvObjCmd _ANSI_ARGS_((ClientData dummy,
233 Tcl_Interp *interp, int objc,
234 Tcl_Obj *CONST objv[]));
235 static int TesteventObjCmd _ANSI_ARGS_((ClientData unused,
238 Tcl_Obj *CONST objv[]));
239 static int TesteventProc _ANSI_ARGS_((Tcl_Event* event,
241 static int TesteventDeleteProc _ANSI_ARGS_((
243 ClientData clientData));
244 static int TestexithandlerCmd _ANSI_ARGS_((ClientData dummy,
245 Tcl_Interp *interp, int argc, CONST char **argv));
246 static int TestexprlongCmd _ANSI_ARGS_((ClientData dummy,
247 Tcl_Interp *interp, int argc, CONST char **argv));
248 static int TestexprparserObjCmd _ANSI_ARGS_((ClientData dummy,
249 Tcl_Interp *interp, int objc,
250 Tcl_Obj *CONST objv[]));
251 static int TestexprstringCmd _ANSI_ARGS_((ClientData dummy,
252 Tcl_Interp *interp, int argc, CONST char **argv));
253 static int TestfileCmd _ANSI_ARGS_((ClientData dummy,
254 Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
255 static int TestfilelinkCmd _ANSI_ARGS_((ClientData dummy,
256 Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
257 static int TestfeventCmd _ANSI_ARGS_((ClientData dummy,
258 Tcl_Interp *interp, int argc, CONST char **argv));
259 static int TestgetassocdataCmd _ANSI_ARGS_((ClientData dummy,
260 Tcl_Interp *interp, int argc, CONST char **argv));
261 static int TestgetplatformCmd _ANSI_ARGS_((ClientData dummy,
262 Tcl_Interp *interp, int argc, CONST char **argv));
263 static int TestgetvarfullnameCmd _ANSI_ARGS_((
264 ClientData dummy, Tcl_Interp *interp,
265 int objc, Tcl_Obj *CONST objv[]));
266 static int TestinterpdeleteCmd _ANSI_ARGS_((ClientData dummy,
267 Tcl_Interp *interp, int argc, CONST char **argv));
268 static int TestlinkCmd _ANSI_ARGS_((ClientData dummy,
269 Tcl_Interp *interp, int argc, CONST char **argv));
270 static int TestlocaleCmd _ANSI_ARGS_((ClientData dummy,
271 Tcl_Interp *interp, int objc,
272 Tcl_Obj *CONST objv[]));
273 static int TestMathFunc _ANSI_ARGS_((ClientData clientData,
274 Tcl_Interp *interp, Tcl_Value *args,
275 Tcl_Value *resultPtr));
276 static int TestMathFunc2 _ANSI_ARGS_((ClientData clientData,
277 Tcl_Interp *interp, Tcl_Value *args,
278 Tcl_Value *resultPtr));
279 static int TestmainthreadCmd _ANSI_ARGS_((ClientData dummy,
280 Tcl_Interp *interp, int argc, CONST char **argv));
281 static int TestsetmainloopCmd _ANSI_ARGS_((ClientData dummy,
282 Tcl_Interp *interp, int argc, CONST char **argv));
283 static int TestexitmainloopCmd _ANSI_ARGS_((ClientData dummy,
284 Tcl_Interp *interp, int argc, CONST char **argv));
285 static Tcl_Channel PretendTclpOpenFileChannel _ANSI_ARGS_((
286 Tcl_Interp *interp, CONST char *fileName,
287 CONST char *modeString, int permissions));
288 static Tcl_Channel TestOpenFileChannelProc1 _ANSI_ARGS_((
289 Tcl_Interp *interp, CONST char *fileName,
290 CONST char *modeString, int permissions));
291 static Tcl_Channel TestOpenFileChannelProc2 _ANSI_ARGS_((
292 Tcl_Interp *interp, CONST char *fileName,
293 CONST char *modeString, int permissions));
294 static Tcl_Channel TestOpenFileChannelProc3 _ANSI_ARGS_((
295 Tcl_Interp *interp, CONST char *fileName,
296 CONST char *modeString, int permissions));
297 static int TestpanicCmd _ANSI_ARGS_((ClientData dummy,
298 Tcl_Interp *interp, int argc, CONST char **argv));
299 static int TestparserObjCmd _ANSI_ARGS_((ClientData dummy,
300 Tcl_Interp *interp, int objc,
301 Tcl_Obj *CONST objv[]));
302 static int TestparsevarObjCmd _ANSI_ARGS_((ClientData dummy,
303 Tcl_Interp *interp, int objc,
304 Tcl_Obj *CONST objv[]));
305 static int TestparsevarnameObjCmd _ANSI_ARGS_((ClientData dummy,
306 Tcl_Interp *interp, int objc,
307 Tcl_Obj *CONST objv[]));
308 static int TestregexpObjCmd _ANSI_ARGS_((ClientData dummy,
309 Tcl_Interp *interp, int objc,
310 Tcl_Obj *CONST objv[]));
311 static void TestregexpXflags _ANSI_ARGS_((char *string,
312 int length, int *cflagsPtr, int *eflagsPtr));
313 static int TestsaveresultCmd _ANSI_ARGS_((ClientData dummy,
314 Tcl_Interp *interp, int objc,
315 Tcl_Obj *CONST objv[]));
316 static void TestsaveresultFree _ANSI_ARGS_((char *blockPtr));
317 static int TestsetassocdataCmd _ANSI_ARGS_((ClientData dummy,
318 Tcl_Interp *interp, int argc, CONST char **argv));
319 static int TestsetCmd _ANSI_ARGS_((ClientData dummy,
320 Tcl_Interp *interp, int argc, CONST char **argv));
321 static int TestseterrorcodeCmd _ANSI_ARGS_((ClientData dummy,
322 Tcl_Interp *interp, int argc, CONST char **argv));
323 static int TestsetobjerrorcodeCmd _ANSI_ARGS_((
324 ClientData dummy, Tcl_Interp *interp,
325 int objc, Tcl_Obj *CONST objv[]));
326 static int TestopenfilechannelprocCmd _ANSI_ARGS_((
327 ClientData dummy, Tcl_Interp *interp, int argc,
329 static int TestsetplatformCmd _ANSI_ARGS_((ClientData dummy,
330 Tcl_Interp *interp, int argc, CONST char **argv));
331 static int TeststaticpkgCmd _ANSI_ARGS_((ClientData dummy,
332 Tcl_Interp *interp, int argc, CONST char **argv));
333 static int PretendTclpStat _ANSI_ARGS_((CONST char *path,
335 static int TestStatProc1 _ANSI_ARGS_((CONST char *path,
337 static int TestStatProc2 _ANSI_ARGS_((CONST char *path,
339 static int TestStatProc3 _ANSI_ARGS_((CONST char *path,
341 static int TeststatprocCmd _ANSI_ARGS_((ClientData dummy,
342 Tcl_Interp *interp, int argc, CONST char **argv));
343 static int TesttranslatefilenameCmd _ANSI_ARGS_((ClientData dummy,
344 Tcl_Interp *interp, int argc, CONST char **argv));
345 static int TestupvarCmd _ANSI_ARGS_((ClientData dummy,
346 Tcl_Interp *interp, int argc, CONST char **argv));
347 static int TestWrongNumArgsObjCmd _ANSI_ARGS_((
348 ClientData clientData, Tcl_Interp *interp,
349 int objc, Tcl_Obj *CONST objv[]));
350 static int TestGetIndexFromObjStructObjCmd _ANSI_ARGS_((
351 ClientData clientData, Tcl_Interp *interp,
352 int objc, Tcl_Obj *CONST objv[]));
353 static int TestChannelCmd _ANSI_ARGS_((ClientData clientData,
354 Tcl_Interp *interp, int argc, CONST char **argv));
355 static int TestChannelEventCmd _ANSI_ARGS_((ClientData clientData,
356 Tcl_Interp *interp, int argc, CONST char **argv));
357 /* Filesystem testing */
359 static int TestFilesystemObjCmd _ANSI_ARGS_((ClientData dummy,
360 Tcl_Interp *interp, int objc,
361 Tcl_Obj *CONST objv[]));
362 static int TestSimpleFilesystemObjCmd _ANSI_ARGS_((
363 ClientData dummy, Tcl_Interp *interp, int objc,
364 Tcl_Obj *CONST objv[]));
366 static void TestReport _ANSI_ARGS_ ((CONST char* cmd, Tcl_Obj* arg1,
369 static Tcl_Obj* TestReportGetNativePath _ANSI_ARGS_ ((
370 Tcl_Obj* pathObjPtr));
372 static int TestReportStat _ANSI_ARGS_ ((Tcl_Obj *path,
374 static int TestReportAccess _ANSI_ARGS_ ((Tcl_Obj *path,
376 static Tcl_Channel TestReportOpenFileChannel _ANSI_ARGS_ ((
377 Tcl_Interp *interp, Tcl_Obj *fileName,
378 int mode, int permissions));
379 static int TestReportMatchInDirectory _ANSI_ARGS_ ((
380 Tcl_Interp *interp, Tcl_Obj *resultPtr,
381 Tcl_Obj *dirPtr, CONST char *pattern,
382 Tcl_GlobTypeData *types));
383 static int TestReportChdir _ANSI_ARGS_ ((Tcl_Obj *dirName));
384 static int TestReportLstat _ANSI_ARGS_ ((Tcl_Obj *path,
386 static int TestReportCopyFile _ANSI_ARGS_ ((Tcl_Obj *src,
388 static int TestReportDeleteFile _ANSI_ARGS_ ((Tcl_Obj *path));
389 static int TestReportRenameFile _ANSI_ARGS_ ((Tcl_Obj *src,
391 static int TestReportCreateDirectory _ANSI_ARGS_ ((Tcl_Obj *path));
392 static int TestReportCopyDirectory _ANSI_ARGS_ ((Tcl_Obj *src,
393 Tcl_Obj *dst, Tcl_Obj **errorPtr));
394 static int TestReportRemoveDirectory _ANSI_ARGS_ ((Tcl_Obj *path,
395 int recursive, Tcl_Obj **errorPtr));
396 static int TestReportLoadFile _ANSI_ARGS_ ((Tcl_Interp *interp,
398 Tcl_LoadHandle *handlePtr,
399 Tcl_FSUnloadFileProc **unloadProcPtr));
400 static Tcl_Obj * TestReportLink _ANSI_ARGS_ ((Tcl_Obj *path,
401 Tcl_Obj *to, int linkType));
402 static CONST char** TestReportFileAttrStrings _ANSI_ARGS_ ((
403 Tcl_Obj *fileName, Tcl_Obj **objPtrRef));
404 static int TestReportFileAttrsGet _ANSI_ARGS_ ((Tcl_Interp *interp,
405 int index, Tcl_Obj *fileName, Tcl_Obj **objPtrRef));
406 static int TestReportFileAttrsSet _ANSI_ARGS_ ((Tcl_Interp *interp,
407 int index, Tcl_Obj *fileName, Tcl_Obj *objPtr));
408 static int TestReportUtime _ANSI_ARGS_ ((Tcl_Obj *fileName,
409 struct utimbuf *tval));
410 static int TestReportNormalizePath _ANSI_ARGS_ ((
411 Tcl_Interp *interp, Tcl_Obj *pathPtr,
412 int nextCheckpoint));
413 static int TestReportInFilesystem _ANSI_ARGS_ ((Tcl_Obj *pathPtr, ClientData *clientDataPtr));
414 static void TestReportFreeInternalRep _ANSI_ARGS_ ((ClientData clientData));
415 static ClientData TestReportDupInternalRep _ANSI_ARGS_ ((ClientData clientData));
417 static int SimpleStat _ANSI_ARGS_ ((Tcl_Obj *path,
419 static int SimpleAccess _ANSI_ARGS_ ((Tcl_Obj *path,
421 static Tcl_Channel SimpleOpenFileChannel _ANSI_ARGS_ ((
422 Tcl_Interp *interp, Tcl_Obj *fileName,
423 int mode, int permissions));
424 static Tcl_Obj* SimpleListVolumes _ANSI_ARGS_ ((void));
425 static int SimplePathInFilesystem _ANSI_ARGS_ ((
426 Tcl_Obj *pathPtr, ClientData *clientDataPtr));
427 static Tcl_Obj* SimpleCopy _ANSI_ARGS_ ((Tcl_Obj *pathPtr));
428 static int TestNumUtfCharsCmd _ANSI_ARGS_((ClientData clientData,
429 Tcl_Interp *interp, int objc,
430 Tcl_Obj *CONST objv[]));
432 static Tcl_Filesystem testReportingFilesystem = {
434 sizeof(Tcl_Filesystem),
435 TCL_FILESYSTEM_VERSION_1,
436 &TestReportInFilesystem, /* path in */
437 &TestReportDupInternalRep,
438 &TestReportFreeInternalRep,
439 NULL, /* native to norm */
440 NULL, /* convert to native */
441 &TestReportNormalizePath,
442 NULL, /* path type */
443 NULL, /* separator */
446 &TestReportOpenFileChannel,
447 &TestReportMatchInDirectory,
450 NULL /* list volumes */,
451 &TestReportFileAttrStrings,
452 &TestReportFileAttrsGet,
453 &TestReportFileAttrsSet,
454 &TestReportCreateDirectory,
455 &TestReportRemoveDirectory,
456 &TestReportDeleteFile,
458 &TestReportRenameFile,
459 &TestReportCopyDirectory,
466 static Tcl_Filesystem simpleFilesystem = {
468 sizeof(Tcl_Filesystem),
469 TCL_FILESYSTEM_VERSION_1,
470 &SimplePathInFilesystem,
473 /* No internal to normalized, since we don't create any
474 * pure 'internal' Tcl_Obj path representations */
476 /* No create native rep function, since we don't use it
477 * or 'Tcl_FSNewNativePath' */
479 /* Normalize path isn't needed - we assume paths only have
480 * one representation */
486 &SimpleOpenFileChannel,
489 /* We choose not to support symbolic links inside our vfs's */
498 /* No copy file - fallback will occur at Tcl level */
500 /* No rename file - fallback will occur at Tcl level */
502 /* No copy directory - fallback will occur at Tcl level */
504 /* Use stat for lstat */
506 /* No load - fallback on core implementation */
508 /* We don't need a getcwd or chdir - fallback on Tcl's versions */
515 * External (platform specific) initialization routine, these declarations
516 * explicitly don't use EXTERN since this code does not get compiled
520 extern int TclplatformtestInit _ANSI_ARGS_((Tcl_Interp *interp));
521 extern int TclThread_Init _ANSI_ARGS_((Tcl_Interp *interp));
524 *----------------------------------------------------------------------
528 * This procedure performs application-specific initialization.
529 * Most applications, especially those that incorporate additional
530 * packages, will have their own version of this procedure.
533 * Returns a standard Tcl completion code, and leaves an error
534 * message in the interp's result if an error occurs.
537 * Depends on the startup script.
539 *----------------------------------------------------------------------
544 Tcl_Interp *interp; /* Interpreter for application. */
546 Tcl_ValueType t3ArgTypes[2];
551 static CONST char *specialOptions[] = {
552 "-appinitprocerror", "-appinitprocdeleteinterp",
553 "-appinitprocclosestderr", "-appinitprocsetrcfile", (char *) NULL
557 if (Tcl_PkgProvide(interp, "Tcltest", TCL_VERSION) == TCL_ERROR) {
559 /* TIP #268: Full patchlevel instead of just major.minor */
560 if (Tcl_PkgProvide(interp, "Tcltest", TCL_PATCH_LEVEL) == TCL_ERROR) {
566 * Create additional commands and math functions for testing Tcl.
569 Tcl_CreateCommand(interp, "gettimes", GetTimesCmd, (ClientData) 0,
570 (Tcl_CmdDeleteProc *) NULL);
571 Tcl_CreateCommand(interp, "noop", NoopCmd, (ClientData) 0,
572 (Tcl_CmdDeleteProc *) NULL);
573 Tcl_CreateObjCommand(interp, "noop", NoopObjCmd, (ClientData) 0,
574 (Tcl_CmdDeleteProc *) NULL);
575 Tcl_CreateObjCommand(interp, "testwrongnumargs", TestWrongNumArgsObjCmd,
576 (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
577 Tcl_CreateObjCommand(interp, "testfilesystem", TestFilesystemObjCmd,
578 (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
579 Tcl_CreateObjCommand(interp, "testsimplefilesystem", TestSimpleFilesystemObjCmd,
580 (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
581 Tcl_CreateObjCommand(interp, "testgetindexfromobjstruct",
582 TestGetIndexFromObjStructObjCmd, (ClientData) 0,
583 (Tcl_CmdDeleteProc *) NULL);
584 Tcl_CreateCommand(interp, "testaccessproc", TestaccessprocCmd, (ClientData) 0,
585 (Tcl_CmdDeleteProc *) NULL);
586 Tcl_CreateCommand(interp, "testasync", TestasyncCmd, (ClientData) 0,
587 (Tcl_CmdDeleteProc *) NULL);
588 Tcl_CreateCommand(interp, "testchannel", TestChannelCmd,
589 (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
590 Tcl_CreateCommand(interp, "testchannelevent", TestChannelEventCmd,
591 (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
592 Tcl_CreateCommand(interp, "testcmdtoken", TestcmdtokenCmd, (ClientData) 0,
593 (Tcl_CmdDeleteProc *) NULL);
594 Tcl_CreateCommand(interp, "testcmdinfo", TestcmdinfoCmd, (ClientData) 0,
595 (Tcl_CmdDeleteProc *) NULL);
596 Tcl_CreateCommand(interp, "testcmdtrace", TestcmdtraceCmd,
597 (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
598 Tcl_CreateCommand(interp, "testcreatecommand", TestcreatecommandCmd,
599 (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
600 Tcl_CreateCommand(interp, "testdcall", TestdcallCmd, (ClientData) 0,
601 (Tcl_CmdDeleteProc *) NULL);
602 Tcl_CreateCommand(interp, "testdel", TestdelCmd, (ClientData) 0,
603 (Tcl_CmdDeleteProc *) NULL);
604 Tcl_CreateCommand(interp, "testdelassocdata", TestdelassocdataCmd,
605 (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
606 Tcl_DStringInit(&dstring);
607 Tcl_CreateCommand(interp, "testdstring", TestdstringCmd, (ClientData) 0,
608 (Tcl_CmdDeleteProc *) NULL);
609 Tcl_CreateObjCommand(interp, "testencoding", TestencodingObjCmd, (ClientData) 0,
610 (Tcl_CmdDeleteProc *) NULL);
611 Tcl_CreateObjCommand(interp, "testevalex", TestevalexObjCmd,
612 (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
613 Tcl_CreateObjCommand(interp, "testevalobjv", TestevalobjvObjCmd,
614 (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
615 Tcl_CreateObjCommand( interp, "testevent", TesteventObjCmd,
616 (ClientData) 0, (Tcl_CmdDeleteProc*) NULL );
617 Tcl_CreateCommand(interp, "testexithandler", TestexithandlerCmd,
618 (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
619 Tcl_CreateCommand(interp, "testexprlong", TestexprlongCmd,
620 (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
621 Tcl_CreateObjCommand(interp, "testexprparser", TestexprparserObjCmd,
622 (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
623 Tcl_CreateCommand(interp, "testexprstring", TestexprstringCmd,
624 (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
625 Tcl_CreateCommand(interp, "testfevent", TestfeventCmd, (ClientData) 0,
626 (Tcl_CmdDeleteProc *) NULL);
627 Tcl_CreateObjCommand(interp, "testfilelink", TestfilelinkCmd,
628 (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
629 Tcl_CreateObjCommand(interp, "testfile", TestfileCmd,
630 (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
631 Tcl_CreateCommand(interp, "testgetassocdata", TestgetassocdataCmd,
632 (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
633 Tcl_CreateCommand(interp, "testgetplatform", TestgetplatformCmd,
634 (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
635 Tcl_CreateObjCommand(interp, "testgetvarfullname",
636 TestgetvarfullnameCmd, (ClientData) 0,
637 (Tcl_CmdDeleteProc *) NULL);
638 Tcl_CreateCommand(interp, "testinterpdelete", TestinterpdeleteCmd,
639 (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
640 Tcl_CreateCommand(interp, "testlink", TestlinkCmd, (ClientData) 0,
641 (Tcl_CmdDeleteProc *) NULL);
642 Tcl_CreateObjCommand(interp, "testlocale", TestlocaleCmd, (ClientData) 0,
643 (Tcl_CmdDeleteProc *) NULL);
644 Tcl_CreateCommand(interp, "testopenfilechannelproc",
645 TestopenfilechannelprocCmd, (ClientData) 0,
646 (Tcl_CmdDeleteProc *) NULL);
647 Tcl_CreateCommand(interp, "testpanic", TestpanicCmd, (ClientData) 0,
648 (Tcl_CmdDeleteProc *) NULL);
649 Tcl_CreateObjCommand(interp, "testparser", TestparserObjCmd,
650 (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
651 Tcl_CreateObjCommand(interp, "testparsevar", TestparsevarObjCmd,
652 (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
653 Tcl_CreateObjCommand(interp, "testparsevarname", TestparsevarnameObjCmd,
654 (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
655 Tcl_CreateObjCommand(interp, "testregexp", TestregexpObjCmd,
656 (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
657 Tcl_CreateObjCommand(interp, "testsaveresult", TestsaveresultCmd,
658 (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
659 Tcl_CreateCommand(interp, "testsetassocdata", TestsetassocdataCmd,
660 (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
661 Tcl_CreateCommand(interp, "testsetnoerr", TestsetCmd,
662 (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
663 Tcl_CreateCommand(interp, "testseterr", TestsetCmd,
664 (ClientData) TCL_LEAVE_ERR_MSG, (Tcl_CmdDeleteProc *) NULL);
665 Tcl_CreateCommand(interp, "testseterrorcode", TestseterrorcodeCmd,
666 (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
667 Tcl_CreateObjCommand(interp, "testsetobjerrorcode",
668 TestsetobjerrorcodeCmd, (ClientData) 0,
669 (Tcl_CmdDeleteProc *) NULL);
670 Tcl_CreateObjCommand(interp, "testnumutfchars",
671 TestNumUtfCharsCmd, (ClientData) 0,
672 (Tcl_CmdDeleteProc *) NULL);
673 Tcl_CreateCommand(interp, "testsetplatform", TestsetplatformCmd,
674 (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
675 Tcl_CreateCommand(interp, "teststaticpkg", TeststaticpkgCmd,
676 (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
677 Tcl_CreateCommand(interp, "testtranslatefilename",
678 TesttranslatefilenameCmd, (ClientData) 0,
679 (Tcl_CmdDeleteProc *) NULL);
680 Tcl_CreateCommand(interp, "testupvar", TestupvarCmd, (ClientData) 0,
681 (Tcl_CmdDeleteProc *) NULL);
682 Tcl_CreateMathFunc(interp, "T1", 0, (Tcl_ValueType *) NULL, TestMathFunc,
684 Tcl_CreateMathFunc(interp, "T2", 0, (Tcl_ValueType *) NULL, TestMathFunc,
686 Tcl_CreateCommand(interp, "teststatproc", TeststatprocCmd, (ClientData) 0,
687 (Tcl_CmdDeleteProc *) NULL);
688 Tcl_CreateCommand(interp, "testmainthread", TestmainthreadCmd, (ClientData) 0,
689 (Tcl_CmdDeleteProc *) NULL);
690 Tcl_CreateCommand(interp, "testsetmainloop", TestsetmainloopCmd,
691 (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
692 Tcl_CreateCommand(interp, "testexitmainloop", TestexitmainloopCmd,
693 (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
694 t3ArgTypes[0] = TCL_EITHER;
695 t3ArgTypes[1] = TCL_EITHER;
696 Tcl_CreateMathFunc(interp, "T3", 2, t3ArgTypes, TestMathFunc2,
700 if (TclThread_Init(interp) != TCL_OK) {
706 * Check for special options used in ../tests/main.test
709 listPtr = Tcl_GetVar2Ex(interp, "argv", NULL, TCL_GLOBAL_ONLY);
710 if (listPtr != NULL) {
711 if (Tcl_ListObjGetElements(interp, listPtr, &objc, &objv) != TCL_OK) {
714 if (objc && (Tcl_GetIndexFromObj(NULL, objv[0], specialOptions, NULL,
715 TCL_EXACT, &index) == TCL_OK)) {
721 Tcl_DeleteInterp(interp);
726 Tcl_UnregisterChannel(interp,
727 Tcl_GetChannel(interp, "stderr", &mode));
732 Tcl_SetVar2Ex(interp, "tcl_rcFileName", NULL,
733 objv[1], TCL_GLOBAL_ONLY);
742 * And finally add any platform specific test commands.
745 return TclplatformtestInit(interp);
749 *----------------------------------------------------------------------
753 * This procedure implements the "testasync" command. It is used
754 * to test the asynchronous handler facilities of Tcl.
757 * A standard Tcl result.
760 * Creates, deletes, and invokes handlers.
762 *----------------------------------------------------------------------
767 TestasyncCmd(dummy, interp, argc, argv)
768 ClientData dummy; /* Not used. */
769 Tcl_Interp *interp; /* Current interpreter. */
770 int argc; /* Number of arguments. */
771 CONST char **argv; /* Argument strings. */
773 TestAsyncHandler *asyncPtr, *prevPtr;
775 static int nextId = 1;
776 char buf[TCL_INTEGER_SPACE];
780 Tcl_SetResult(interp, "wrong # args", TCL_STATIC);
783 if (strcmp(argv[1], "create") == 0) {
787 asyncPtr = (TestAsyncHandler *) ckalloc(sizeof(TestAsyncHandler));
788 asyncPtr->id = nextId;
790 asyncPtr->handler = Tcl_AsyncCreate(AsyncHandlerProc,
791 (ClientData) asyncPtr);
792 asyncPtr->command = (char *) ckalloc((unsigned) (strlen(argv[2]) + 1));
793 strcpy(asyncPtr->command, argv[2]);
794 asyncPtr->nextPtr = firstHandler;
795 firstHandler = asyncPtr;
796 TclFormatInt(buf, asyncPtr->id);
797 Tcl_SetResult(interp, buf, TCL_VOLATILE);
798 } else if (strcmp(argv[1], "delete") == 0) {
800 while (firstHandler != NULL) {
801 asyncPtr = firstHandler;
802 firstHandler = asyncPtr->nextPtr;
803 Tcl_AsyncDelete(asyncPtr->handler);
804 ckfree(asyncPtr->command);
805 ckfree((char *) asyncPtr);
812 if (Tcl_GetInt(interp, argv[2], &id) != TCL_OK) {
815 for (prevPtr = NULL, asyncPtr = firstHandler; asyncPtr != NULL;
816 prevPtr = asyncPtr, asyncPtr = asyncPtr->nextPtr) {
817 if (asyncPtr->id != id) {
820 if (prevPtr == NULL) {
821 firstHandler = asyncPtr->nextPtr;
823 prevPtr->nextPtr = asyncPtr->nextPtr;
825 Tcl_AsyncDelete(asyncPtr->handler);
826 ckfree(asyncPtr->command);
827 ckfree((char *) asyncPtr);
830 } else if (strcmp(argv[1], "mark") == 0) {
834 if ((Tcl_GetInt(interp, argv[2], &id) != TCL_OK)
835 || (Tcl_GetInt(interp, argv[4], &code) != TCL_OK)) {
838 for (asyncPtr = firstHandler; asyncPtr != NULL;
839 asyncPtr = asyncPtr->nextPtr) {
840 if (asyncPtr->id == id) {
841 Tcl_AsyncMark(asyncPtr->handler);
845 Tcl_SetResult(interp, (char *)argv[3], TCL_VOLATILE);
848 Tcl_AppendResult(interp, "bad option \"", argv[1],
849 "\": must be create, delete, int, or mark",
857 AsyncHandlerProc(clientData, interp, code)
858 ClientData clientData; /* Pointer to TestAsyncHandler structure. */
859 Tcl_Interp *interp; /* Interpreter in which command was
860 * executed, or NULL. */
861 int code; /* Current return code from command. */
863 TestAsyncHandler *asyncPtr = (TestAsyncHandler *) clientData;
864 CONST char *listArgv[4], *cmd;
865 char string[TCL_INTEGER_SPACE];
867 TclFormatInt(string, code);
868 listArgv[0] = asyncPtr->command;
869 listArgv[1] = Tcl_GetString(Tcl_GetObjResult(interp));
870 listArgv[2] = string;
872 cmd = Tcl_Merge(3, listArgv);
873 if (interp != NULL) {
874 code = Tcl_Eval(interp, cmd);
877 * this should not happen, but by definition of how async
878 * handlers are invoked, it's possible. Better error
879 * checking is needed here.
887 *----------------------------------------------------------------------
891 * This procedure implements the "testcmdinfo" command. It is used
892 * to test Tcl_GetCommandInfo, Tcl_SetCommandInfo, and command creation
896 * A standard Tcl result.
899 * Creates and deletes various commands and modifies their data.
901 *----------------------------------------------------------------------
906 TestcmdinfoCmd(dummy, interp, argc, argv)
907 ClientData dummy; /* Not used. */
908 Tcl_Interp *interp; /* Current interpreter. */
909 int argc; /* Number of arguments. */
910 CONST char **argv; /* Argument strings. */
915 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
916 " option cmdName\"", (char *) NULL);
919 if (strcmp(argv[1], "create") == 0) {
920 Tcl_CreateCommand(interp, argv[2], CmdProc1, (ClientData) "original",
922 } else if (strcmp(argv[1], "delete") == 0) {
923 Tcl_DStringInit(&delString);
924 Tcl_DeleteCommand(interp, argv[2]);
925 Tcl_DStringResult(interp, &delString);
926 } else if (strcmp(argv[1], "get") == 0) {
927 if (Tcl_GetCommandInfo(interp, argv[2], &info) ==0) {
928 Tcl_SetResult(interp, "??", TCL_STATIC);
931 if (info.proc == CmdProc1) {
932 Tcl_AppendResult(interp, "CmdProc1", " ",
933 (char *) info.clientData, (char *) NULL);
934 } else if (info.proc == CmdProc2) {
935 Tcl_AppendResult(interp, "CmdProc2", " ",
936 (char *) info.clientData, (char *) NULL);
938 Tcl_AppendResult(interp, "unknown", (char *) NULL);
940 if (info.deleteProc == CmdDelProc1) {
941 Tcl_AppendResult(interp, " CmdDelProc1", " ",
942 (char *) info.deleteData, (char *) NULL);
943 } else if (info.deleteProc == CmdDelProc2) {
944 Tcl_AppendResult(interp, " CmdDelProc2", " ",
945 (char *) info.deleteData, (char *) NULL);
947 Tcl_AppendResult(interp, " unknown", (char *) NULL);
949 Tcl_AppendResult(interp, " ", info.namespacePtr->fullName,
951 if (info.isNativeObjectProc) {
952 Tcl_AppendResult(interp, " nativeObjectProc", (char *) NULL);
954 Tcl_AppendResult(interp, " stringProc", (char *) NULL);
956 } else if (strcmp(argv[1], "modify") == 0) {
957 info.proc = CmdProc2;
958 info.clientData = (ClientData) "new_command_data";
960 info.objClientData = (ClientData) NULL;
961 info.deleteProc = CmdDelProc2;
962 info.deleteData = (ClientData) "new_delete_data";
963 if (Tcl_SetCommandInfo(interp, argv[2], &info) == 0) {
964 Tcl_SetResult(interp, "0", TCL_STATIC);
966 Tcl_SetResult(interp, "1", TCL_STATIC);
969 Tcl_AppendResult(interp, "bad option \"", argv[1],
970 "\": must be create, delete, get, or modify",
979 CmdProc1(clientData, interp, argc, argv)
980 ClientData clientData; /* String to return. */
981 Tcl_Interp *interp; /* Current interpreter. */
982 int argc; /* Number of arguments. */
983 CONST char **argv; /* Argument strings. */
985 Tcl_AppendResult(interp, "CmdProc1 ", (char *) clientData,
992 CmdProc2(clientData, interp, argc, argv)
993 ClientData clientData; /* String to return. */
994 Tcl_Interp *interp; /* Current interpreter. */
995 int argc; /* Number of arguments. */
996 CONST char **argv; /* Argument strings. */
998 Tcl_AppendResult(interp, "CmdProc2 ", (char *) clientData,
1004 CmdDelProc1(clientData)
1005 ClientData clientData; /* String to save. */
1007 Tcl_DStringInit(&delString);
1008 Tcl_DStringAppend(&delString, "CmdDelProc1 ", -1);
1009 Tcl_DStringAppend(&delString, (char *) clientData, -1);
1013 CmdDelProc2(clientData)
1014 ClientData clientData; /* String to save. */
1016 Tcl_DStringInit(&delString);
1017 Tcl_DStringAppend(&delString, "CmdDelProc2 ", -1);
1018 Tcl_DStringAppend(&delString, (char *) clientData, -1);
1022 *----------------------------------------------------------------------
1024 * TestcmdtokenCmd --
1026 * This procedure implements the "testcmdtoken" command. It is used
1027 * to test Tcl_Command tokens and procedures such as
1028 * Tcl_GetCommandFullName.
1031 * A standard Tcl result.
1034 * Creates and deletes various commands and modifies their data.
1036 *----------------------------------------------------------------------
1041 TestcmdtokenCmd(dummy, interp, argc, argv)
1042 ClientData dummy; /* Not used. */
1043 Tcl_Interp *interp; /* Current interpreter. */
1044 int argc; /* Number of arguments. */
1045 CONST char **argv; /* Argument strings. */
1052 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
1053 " option arg\"", (char *) NULL);
1056 if (strcmp(argv[1], "create") == 0) {
1057 token = Tcl_CreateCommand(interp, argv[2], CmdProc1,
1058 (ClientData) "original", (Tcl_CmdDeleteProc *) NULL);
1059 sprintf(buf, "%p", (VOID *)token);
1060 Tcl_SetResult(interp, buf, TCL_VOLATILE);
1061 } else if (strcmp(argv[1], "name") == 0) {
1064 if (sscanf(argv[2], "%p", &l) != 1) {
1065 Tcl_AppendResult(interp, "bad command token \"", argv[2],
1066 "\"", (char *) NULL);
1070 objPtr = Tcl_NewObj();
1071 Tcl_GetCommandFullName(interp, (Tcl_Command) l, objPtr);
1073 Tcl_AppendElement(interp,
1074 Tcl_GetCommandName(interp, (Tcl_Command) l));
1075 Tcl_AppendElement(interp, Tcl_GetString(objPtr));
1076 Tcl_DecrRefCount(objPtr);
1078 Tcl_AppendResult(interp, "bad option \"", argv[1],
1079 "\": must be create or name", (char *) NULL);
1086 *----------------------------------------------------------------------
1088 * TestcmdtraceCmd --
1090 * This procedure implements the "testcmdtrace" command. It is used
1091 * to test Tcl_CreateTrace and Tcl_DeleteTrace.
1094 * A standard Tcl result.
1097 * Creates and deletes a command trace, and tests the invocation of
1098 * a procedure by the command trace.
1100 *----------------------------------------------------------------------
1105 TestcmdtraceCmd(dummy, interp, argc, argv)
1106 ClientData dummy; /* Not used. */
1107 Tcl_Interp *interp; /* Current interpreter. */
1108 int argc; /* Number of arguments. */
1109 CONST char **argv; /* Argument strings. */
1115 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
1116 " option script\"", (char *) NULL);
1120 if (strcmp(argv[1], "tracetest") == 0) {
1121 Tcl_DStringInit(&buffer);
1122 cmdTrace = Tcl_CreateTrace(interp, 50000,
1123 (Tcl_CmdTraceProc *) CmdTraceProc, (ClientData) &buffer);
1124 result = Tcl_Eval(interp, argv[2]);
1125 if (result == TCL_OK) {
1126 Tcl_ResetResult(interp);
1127 Tcl_AppendResult(interp, Tcl_DStringValue(&buffer), NULL);
1129 Tcl_DeleteTrace(interp, cmdTrace);
1130 Tcl_DStringFree(&buffer);
1131 } else if (strcmp(argv[1], "deletetest") == 0) {
1133 * Create a command trace then eval a script to check whether it is
1134 * called. Note that this trace procedure removes itself as a
1135 * further check of the robustness of the trace proc calling code in
1136 * TclExecuteByteCode.
1139 cmdTrace = Tcl_CreateTrace(interp, 50000,
1140 (Tcl_CmdTraceProc *) CmdTraceDeleteProc, (ClientData) NULL);
1141 Tcl_Eval(interp, argv[2]);
1142 } else if (strcmp(argv[1], "leveltest") == 0) {
1143 Interp *iPtr = (Interp *) interp;
1144 Tcl_DStringInit(&buffer);
1145 cmdTrace = Tcl_CreateTrace(interp, iPtr->numLevels + 4,
1146 (Tcl_CmdTraceProc *) CmdTraceProc, (ClientData) &buffer);
1147 result = Tcl_Eval(interp, argv[2]);
1148 if (result == TCL_OK) {
1149 Tcl_ResetResult(interp);
1150 Tcl_AppendResult(interp, Tcl_DStringValue(&buffer), NULL);
1152 Tcl_DeleteTrace(interp, cmdTrace);
1153 Tcl_DStringFree(&buffer);
1154 } else if ( strcmp(argv[1], "resulttest" ) == 0 ) {
1155 /* Create an object-based trace, then eval a script. This is used
1156 * to test return codes other than TCL_OK from the trace engine.
1158 static int deleteCalled;
1160 cmdTrace = Tcl_CreateObjTrace( interp, 50000,
1161 TCL_ALLOW_INLINE_COMPILATION,
1163 (ClientData) &deleteCalled,
1164 ObjTraceDeleteProc );
1165 result = Tcl_Eval( interp, argv[ 2 ] );
1166 Tcl_DeleteTrace( interp, cmdTrace );
1167 if ( !deleteCalled ) {
1168 Tcl_SetResult( interp, "Delete wasn't called", TCL_STATIC );
1175 Tcl_AppendResult(interp, "bad option \"", argv[1],
1176 "\": must be tracetest, deletetest or resulttest",
1184 CmdTraceProc(clientData, interp, level, command, cmdProc, cmdClientData,
1186 ClientData clientData; /* Pointer to buffer in which the
1187 * command and arguments are appended.
1188 * Accumulates test result. */
1189 Tcl_Interp *interp; /* Current interpreter. */
1190 int level; /* Current trace level. */
1191 char *command; /* The command being traced (after
1192 * substitutions). */
1193 Tcl_CmdProc *cmdProc; /* Points to command's command procedure. */
1194 ClientData cmdClientData; /* Client data associated with command
1196 int argc; /* Number of arguments. */
1197 char **argv; /* Argument strings. */
1199 Tcl_DString *bufPtr = (Tcl_DString *) clientData;
1202 Tcl_DStringAppendElement(bufPtr, command);
1204 Tcl_DStringStartSublist(bufPtr);
1205 for (i = 0; i < argc; i++) {
1206 Tcl_DStringAppendElement(bufPtr, argv[i]);
1208 Tcl_DStringEndSublist(bufPtr);
1212 CmdTraceDeleteProc(clientData, interp, level, command, cmdProc,
1213 cmdClientData, argc, argv)
1214 ClientData clientData; /* Unused. */
1215 Tcl_Interp *interp; /* Current interpreter. */
1216 int level; /* Current trace level. */
1217 char *command; /* The command being traced (after
1218 * substitutions). */
1219 Tcl_CmdProc *cmdProc; /* Points to command's command procedure. */
1220 ClientData cmdClientData; /* Client data associated with command
1222 int argc; /* Number of arguments. */
1223 char **argv; /* Argument strings. */
1226 * Remove ourselves to test whether calling Tcl_DeleteTrace within
1227 * a trace callback causes the for loop in TclExecuteByteCode that
1228 * calls traces to reference freed memory.
1231 Tcl_DeleteTrace(interp, cmdTrace);
1235 ObjTraceProc( clientData, interp, level, command, token, objc, objv )
1236 ClientData clientData; /* unused */
1237 Tcl_Interp* interp; /* Tcl interpreter */
1238 int level; /* Execution level */
1239 CONST char* command; /* Command being executed */
1240 Tcl_Command token; /* Command information */
1241 int objc; /* Parameter count */
1242 Tcl_Obj *CONST objv[]; /* Parameter list */
1244 CONST char* word = Tcl_GetString( objv[ 0 ] );
1245 if ( !strcmp( word, "Error" ) ) {
1246 Tcl_SetObjResult( interp, Tcl_NewStringObj( command, -1 ) );
1248 } else if ( !strcmp( word, "Break" ) ) {
1250 } else if ( !strcmp( word, "Continue" ) ) {
1251 return TCL_CONTINUE;
1252 } else if ( !strcmp( word, "Return" ) ) {
1254 } else if ( !strcmp( word, "OtherStatus" ) ) {
1262 ObjTraceDeleteProc( clientData )
1263 ClientData clientData;
1265 int * intPtr = (int *) clientData;
1266 *intPtr = 1; /* Record that the trace was deleted */
1270 *----------------------------------------------------------------------
1272 * TestcreatecommandCmd --
1274 * This procedure implements the "testcreatecommand" command. It is
1275 * used to test that the Tcl_CreateCommand creates a new command in
1276 * the namespace specified as part of its name, if any. It also
1277 * checks that the namespace code ignore single ":"s in the middle
1278 * or end of a command name.
1281 * A standard Tcl result.
1284 * Creates and deletes two commands ("test_ns_basic::createdcommand"
1287 *----------------------------------------------------------------------
1291 TestcreatecommandCmd(dummy, interp, argc, argv)
1292 ClientData dummy; /* Not used. */
1293 Tcl_Interp *interp; /* Current interpreter. */
1294 int argc; /* Number of arguments. */
1295 CONST char **argv; /* Argument strings. */
1298 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
1299 " option\"", (char *) NULL);
1302 if (strcmp(argv[1], "create") == 0) {
1303 Tcl_CreateCommand(interp, "test_ns_basic::createdcommand",
1304 CreatedCommandProc, (ClientData) NULL,
1305 (Tcl_CmdDeleteProc *) NULL);
1306 } else if (strcmp(argv[1], "delete") == 0) {
1307 Tcl_DeleteCommand(interp, "test_ns_basic::createdcommand");
1308 } else if (strcmp(argv[1], "create2") == 0) {
1309 Tcl_CreateCommand(interp, "value:at:",
1310 CreatedCommandProc2, (ClientData) NULL,
1311 (Tcl_CmdDeleteProc *) NULL);
1312 } else if (strcmp(argv[1], "delete2") == 0) {
1313 Tcl_DeleteCommand(interp, "value:at:");
1315 Tcl_AppendResult(interp, "bad option \"", argv[1],
1316 "\": must be create, delete, create2, or delete2",
1324 CreatedCommandProc(clientData, interp, argc, argv)
1325 ClientData clientData; /* String to return. */
1326 Tcl_Interp *interp; /* Current interpreter. */
1327 int argc; /* Number of arguments. */
1328 CONST char **argv; /* Argument strings. */
1333 found = Tcl_GetCommandInfo(interp, "test_ns_basic::createdcommand",
1336 Tcl_AppendResult(interp, "CreatedCommandProc could not get command info for test_ns_basic::createdcommand",
1340 Tcl_AppendResult(interp, "CreatedCommandProc in ",
1341 info.namespacePtr->fullName, (char *) NULL);
1346 CreatedCommandProc2(clientData, interp, argc, argv)
1347 ClientData clientData; /* String to return. */
1348 Tcl_Interp *interp; /* Current interpreter. */
1349 int argc; /* Number of arguments. */
1350 CONST char **argv; /* Argument strings. */
1355 found = Tcl_GetCommandInfo(interp, "value:at:", &info);
1357 Tcl_AppendResult(interp, "CreatedCommandProc2 could not get command info for test_ns_basic::createdcommand",
1361 Tcl_AppendResult(interp, "CreatedCommandProc2 in ",
1362 info.namespacePtr->fullName, (char *) NULL);
1367 *----------------------------------------------------------------------
1371 * This procedure implements the "testdcall" command. It is used
1372 * to test Tcl_CallWhenDeleted.
1375 * A standard Tcl result.
1378 * Creates and deletes interpreters.
1380 *----------------------------------------------------------------------
1385 TestdcallCmd(dummy, interp, argc, argv)
1386 ClientData dummy; /* Not used. */
1387 Tcl_Interp *interp; /* Current interpreter. */
1388 int argc; /* Number of arguments. */
1389 CONST char **argv; /* Argument strings. */
1393 delInterp = Tcl_CreateInterp();
1394 Tcl_DStringInit(&delString);
1395 for (i = 1; i < argc; i++) {
1396 if (Tcl_GetInt(interp, argv[i], &id) != TCL_OK) {
1400 Tcl_DontCallWhenDeleted(delInterp, DelCallbackProc,
1401 (ClientData) (-id));
1403 Tcl_CallWhenDeleted(delInterp, DelCallbackProc,
1407 Tcl_DeleteInterp(delInterp);
1408 Tcl_DStringResult(interp, &delString);
1413 * The deletion callback used by TestdcallCmd:
1417 DelCallbackProc(clientData, interp)
1418 ClientData clientData; /* Numerical value to append to
1420 Tcl_Interp *interp; /* Interpreter being deleted. */
1422 int id = (int) clientData;
1423 char buffer[TCL_INTEGER_SPACE];
1425 TclFormatInt(buffer, id);
1426 Tcl_DStringAppendElement(&delString, buffer);
1427 if (interp != delInterp) {
1428 Tcl_DStringAppendElement(&delString, "bogus interpreter argument!");
1433 *----------------------------------------------------------------------
1437 * This procedure implements the "testdcall" command. It is used
1438 * to test Tcl_CallWhenDeleted.
1441 * A standard Tcl result.
1444 * Creates and deletes interpreters.
1446 *----------------------------------------------------------------------
1451 TestdelCmd(dummy, interp, argc, argv)
1452 ClientData dummy; /* Not used. */
1453 Tcl_Interp *interp; /* Current interpreter. */
1454 int argc; /* Number of arguments. */
1455 CONST char **argv; /* Argument strings. */
1461 Tcl_SetResult(interp, "wrong # args", TCL_STATIC);
1465 slave = Tcl_GetSlave(interp, argv[1]);
1466 if (slave == NULL) {
1470 dPtr = (DelCmd *) ckalloc(sizeof(DelCmd));
1471 dPtr->interp = interp;
1472 dPtr->deleteCmd = (char *) ckalloc((unsigned) (strlen(argv[3]) + 1));
1473 strcpy(dPtr->deleteCmd, argv[3]);
1475 Tcl_CreateCommand(slave, argv[2], DelCmdProc, (ClientData) dPtr,
1481 DelCmdProc(clientData, interp, argc, argv)
1482 ClientData clientData; /* String result to return. */
1483 Tcl_Interp *interp; /* Current interpreter. */
1484 int argc; /* Number of arguments. */
1485 CONST char **argv; /* Argument strings. */
1487 DelCmd *dPtr = (DelCmd *) clientData;
1489 Tcl_AppendResult(interp, dPtr->deleteCmd, (char *) NULL);
1490 ckfree(dPtr->deleteCmd);
1491 ckfree((char *) dPtr);
1496 DelDeleteProc(clientData)
1497 ClientData clientData; /* String command to evaluate. */
1499 DelCmd *dPtr = (DelCmd *) clientData;
1501 Tcl_Eval(dPtr->interp, dPtr->deleteCmd);
1502 Tcl_ResetResult(dPtr->interp);
1503 ckfree(dPtr->deleteCmd);
1504 ckfree((char *) dPtr);
1508 *----------------------------------------------------------------------
1510 * TestdelassocdataCmd --
1512 * This procedure implements the "testdelassocdata" command. It is used
1513 * to test Tcl_DeleteAssocData.
1516 * A standard Tcl result.
1519 * Deletes an association between a key and associated data from an
1522 *----------------------------------------------------------------------
1526 TestdelassocdataCmd(clientData, interp, argc, argv)
1527 ClientData clientData; /* Not used. */
1528 Tcl_Interp *interp; /* Current interpreter. */
1529 int argc; /* Number of arguments. */
1530 CONST char **argv; /* Argument strings. */
1533 Tcl_AppendResult(interp, "wrong # arguments: should be \"", argv[0],
1534 " data_key\"", (char *) NULL);
1537 Tcl_DeleteAssocData(interp, argv[1]);
1542 *----------------------------------------------------------------------
1546 * This procedure implements the "testdstring" command. It is used
1547 * to test the dynamic string facilities of Tcl.
1550 * A standard Tcl result.
1553 * Creates, deletes, and invokes handlers.
1555 *----------------------------------------------------------------------
1560 TestdstringCmd(dummy, interp, argc, argv)
1561 ClientData dummy; /* Not used. */
1562 Tcl_Interp *interp; /* Current interpreter. */
1563 int argc; /* Number of arguments. */
1564 CONST char **argv; /* Argument strings. */
1570 Tcl_SetResult(interp, "wrong # args", TCL_STATIC);
1573 if (strcmp(argv[1], "append") == 0) {
1577 if (Tcl_GetInt(interp, argv[3], &count) != TCL_OK) {
1580 Tcl_DStringAppend(&dstring, argv[2], count);
1581 } else if (strcmp(argv[1], "element") == 0) {
1585 Tcl_DStringAppendElement(&dstring, argv[2]);
1586 } else if (strcmp(argv[1], "end") == 0) {
1590 Tcl_DStringEndSublist(&dstring);
1591 } else if (strcmp(argv[1], "free") == 0) {
1595 Tcl_DStringFree(&dstring);
1596 } else if (strcmp(argv[1], "get") == 0) {
1600 Tcl_SetResult(interp, Tcl_DStringValue(&dstring), TCL_VOLATILE);
1601 } else if (strcmp(argv[1], "gresult") == 0) {
1605 if (strcmp(argv[2], "staticsmall") == 0) {
1606 Tcl_SetResult(interp, "short", TCL_STATIC);
1607 } else if (strcmp(argv[2], "staticlarge") == 0) {
1608 Tcl_SetResult(interp, "first0 first1 first2 first3 first4 first5 first6 first7 first8 first9\nsecond0 second1 second2 second3 second4 second5 second6 second7 second8 second9\nthird0 third1 third2 third3 third4 third5 third6 third7 third8 third9\nfourth0 fourth1 fourth2 fourth3 fourth4 fourth5 fourth6 fourth7 fourth8 fourth9\nfifth0 fifth1 fifth2 fifth3 fifth4 fifth5 fifth6 fifth7 fifth8 fifth9\nsixth0 sixth1 sixth2 sixth3 sixth4 sixth5 sixth6 sixth7 sixth8 sixth9\nseventh0 seventh1 seventh2 seventh3 seventh4 seventh5 seventh6 seventh7 seventh8 seventh9\n", TCL_STATIC);
1609 } else if (strcmp(argv[2], "free") == 0) {
1610 Tcl_SetResult(interp, (char *) ckalloc(100), TCL_DYNAMIC);
1611 strcpy(interp->result, "This is a malloc-ed string");
1612 } else if (strcmp(argv[2], "special") == 0) {
1613 interp->result = (char *) ckalloc(100);
1614 interp->result += 4;
1615 interp->freeProc = SpecialFree;
1616 strcpy(interp->result, "This is a specially-allocated string");
1618 Tcl_AppendResult(interp, "bad gresult option \"", argv[2],
1619 "\": must be staticsmall, staticlarge, free, or special",
1623 Tcl_DStringGetResult(interp, &dstring);
1624 } else if (strcmp(argv[1], "length") == 0) {
1625 char buf[TCL_INTEGER_SPACE];
1630 TclFormatInt(buf, Tcl_DStringLength(&dstring));
1631 Tcl_SetResult(interp, buf, TCL_VOLATILE);
1632 } else if (strcmp(argv[1], "result") == 0) {
1636 Tcl_DStringResult(interp, &dstring);
1637 } else if (strcmp(argv[1], "trunc") == 0) {
1641 if (Tcl_GetInt(interp, argv[2], &count) != TCL_OK) {
1644 Tcl_DStringTrunc(&dstring, count);
1645 } else if (strcmp(argv[1], "start") == 0) {
1649 Tcl_DStringStartSublist(&dstring);
1651 Tcl_AppendResult(interp, "bad option \"", argv[1],
1652 "\": must be append, element, end, free, get, length, ",
1653 "result, trunc, or start", (char *) NULL);
1660 * The procedure below is used as a special freeProc to test how well
1661 * Tcl_DStringGetResult handles freeProc's other than free.
1664 static void SpecialFree(blockPtr)
1665 char *blockPtr; /* Block to free. */
1667 ckfree(blockPtr - 4);
1671 *----------------------------------------------------------------------
1673 * TestencodingCmd --
1675 * This procedure implements the "testencoding" command. It is used
1676 * to test the encoding package.
1679 * A standard Tcl result.
1684 *----------------------------------------------------------------------
1689 TestencodingObjCmd(dummy, interp, objc, objv)
1690 ClientData dummy; /* Not used. */
1691 Tcl_Interp *interp; /* Current interpreter. */
1692 int objc; /* Number of arguments. */
1693 Tcl_Obj *CONST objv[]; /* Argument objects. */
1695 Tcl_Encoding encoding;
1698 TclEncoding *encodingPtr;
1699 static CONST char *optionStrings[] = {
1700 "create", "delete", "path",
1704 ENC_CREATE, ENC_DELETE, ENC_PATH
1707 if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
1708 &index) != TCL_OK) {
1712 switch ((enum options) index) {
1714 Tcl_EncodingType type;
1719 encodingPtr = (TclEncoding *) ckalloc(sizeof(TclEncoding));
1720 encodingPtr->interp = interp;
1722 string = Tcl_GetStringFromObj(objv[3], &length);
1723 encodingPtr->toUtfCmd = (char *) ckalloc((unsigned) (length + 1));
1724 memcpy(encodingPtr->toUtfCmd, string, (unsigned) length + 1);
1726 string = Tcl_GetStringFromObj(objv[4], &length);
1727 encodingPtr->fromUtfCmd = (char *) ckalloc((unsigned) (length + 1));
1728 memcpy(encodingPtr->fromUtfCmd, string, (unsigned) (length + 1));
1730 string = Tcl_GetStringFromObj(objv[2], &length);
1732 type.encodingName = string;
1733 type.toUtfProc = EncodingToUtfProc;
1734 type.fromUtfProc = EncodingFromUtfProc;
1735 type.freeProc = EncodingFreeProc;
1736 type.clientData = (ClientData) encodingPtr;
1739 Tcl_CreateEncoding(&type);
1746 encoding = Tcl_GetEncoding(NULL, Tcl_GetString(objv[2]));
1747 Tcl_FreeEncoding(encoding);
1748 Tcl_FreeEncoding(encoding);
1753 Tcl_SetObjResult(interp, TclGetLibraryPath());
1755 TclSetLibraryPath(objv[2]);
1763 EncodingToUtfProc(clientData, src, srcLen, flags, statePtr, dst, dstLen,
1764 srcReadPtr, dstWrotePtr, dstCharsPtr)
1765 ClientData clientData; /* TclEncoding structure. */
1766 CONST char *src; /* Source string in specified encoding. */
1767 int srcLen; /* Source string length in bytes. */
1768 int flags; /* Conversion control flags. */
1769 Tcl_EncodingState *statePtr;/* Current state. */
1770 char *dst; /* Output buffer. */
1771 int dstLen; /* The maximum length of output buffer. */
1772 int *srcReadPtr; /* Filled with number of bytes read. */
1773 int *dstWrotePtr; /* Filled with number of bytes stored. */
1774 int *dstCharsPtr; /* Filled with number of chars stored. */
1777 TclEncoding *encodingPtr;
1779 encodingPtr = (TclEncoding *) clientData;
1780 Tcl_GlobalEval(encodingPtr->interp, encodingPtr->toUtfCmd);
1782 len = strlen(Tcl_GetStringResult(encodingPtr->interp));
1786 memcpy(dst, Tcl_GetStringResult(encodingPtr->interp), (unsigned) len);
1787 Tcl_ResetResult(encodingPtr->interp);
1789 *srcReadPtr = srcLen;
1795 EncodingFromUtfProc(clientData, src, srcLen, flags, statePtr, dst, dstLen,
1796 srcReadPtr, dstWrotePtr, dstCharsPtr)
1797 ClientData clientData; /* TclEncoding structure. */
1798 CONST char *src; /* Source string in specified encoding. */
1799 int srcLen; /* Source string length in bytes. */
1800 int flags; /* Conversion control flags. */
1801 Tcl_EncodingState *statePtr;/* Current state. */
1802 char *dst; /* Output buffer. */
1803 int dstLen; /* The maximum length of output buffer. */
1804 int *srcReadPtr; /* Filled with number of bytes read. */
1805 int *dstWrotePtr; /* Filled with number of bytes stored. */
1806 int *dstCharsPtr; /* Filled with number of chars stored. */
1809 TclEncoding *encodingPtr;
1811 encodingPtr = (TclEncoding *) clientData;
1812 Tcl_GlobalEval(encodingPtr->interp, encodingPtr->fromUtfCmd);
1814 len = strlen(Tcl_GetStringResult(encodingPtr->interp));
1818 memcpy(dst, Tcl_GetStringResult(encodingPtr->interp), (unsigned) len);
1819 Tcl_ResetResult(encodingPtr->interp);
1821 *srcReadPtr = srcLen;
1827 EncodingFreeProc(clientData)
1828 ClientData clientData; /* ClientData associated with type. */
1830 TclEncoding *encodingPtr;
1832 encodingPtr = (TclEncoding *) clientData;
1833 ckfree((char *) encodingPtr->toUtfCmd);
1834 ckfree((char *) encodingPtr->fromUtfCmd);
1835 ckfree((char *) encodingPtr);
1839 *----------------------------------------------------------------------
1841 * TestevalexObjCmd --
1843 * This procedure implements the "testevalex" command. It is
1844 * used to test Tcl_EvalEx.
1847 * A standard Tcl result.
1852 *----------------------------------------------------------------------
1856 TestevalexObjCmd(dummy, interp, objc, objv)
1857 ClientData dummy; /* Not used. */
1858 Tcl_Interp *interp; /* Current interpreter. */
1859 int objc; /* Number of arguments. */
1860 Tcl_Obj *CONST objv[]; /* Argument objects. */
1862 Interp *iPtr = (Interp *) interp;
1863 int code, oldFlags, length, flags;
1868 * The command was invoked with no arguments, so just toggle
1869 * the flag that determines whether we use Tcl_EvalEx.
1872 if (iPtr->flags & USE_EVAL_DIRECT) {
1873 iPtr->flags &= ~USE_EVAL_DIRECT;
1874 Tcl_SetResult(interp, "disabling direct evaluation", TCL_STATIC);
1876 iPtr->flags |= USE_EVAL_DIRECT;
1877 Tcl_SetResult(interp, "enabling direct evaluation", TCL_STATIC);
1884 string = Tcl_GetStringFromObj(objv[2], &length);
1885 if (strcmp(string, "global") != 0) {
1886 Tcl_AppendResult(interp, "bad value \"", string,
1887 "\": must be global", (char *) NULL);
1890 flags = TCL_EVAL_GLOBAL;
1891 } else if (objc != 2) {
1892 Tcl_WrongNumArgs(interp, 1, objv, "script ?global?");
1895 Tcl_SetResult(interp, "xxx", TCL_STATIC);
1898 * Note, we have to set the USE_EVAL_DIRECT flag in the interpreter
1899 * in addition to calling Tcl_EvalEx. This is needed so that even nested
1900 * commands are evaluated directly.
1903 oldFlags = iPtr->flags;
1904 iPtr->flags |= USE_EVAL_DIRECT;
1905 string = Tcl_GetStringFromObj(objv[1], &length);
1906 code = Tcl_EvalEx(interp, string, length, flags);
1907 iPtr->flags = (iPtr->flags & ~USE_EVAL_DIRECT)
1908 | (oldFlags & USE_EVAL_DIRECT);
1913 *----------------------------------------------------------------------
1915 * TestevalobjvObjCmd --
1917 * This procedure implements the "testevalobjv" command. It is
1918 * used to test Tcl_EvalObjv.
1921 * A standard Tcl result.
1926 *----------------------------------------------------------------------
1930 TestevalobjvObjCmd(dummy, interp, objc, objv)
1931 ClientData dummy; /* Not used. */
1932 Tcl_Interp *interp; /* Current interpreter. */
1933 int objc; /* Number of arguments. */
1934 Tcl_Obj *CONST objv[]; /* Argument objects. */
1939 Tcl_WrongNumArgs(interp, 1, objv, "global word ?word ...?");
1942 if (Tcl_GetIntFromObj(interp, objv[1], &evalGlobal) != TCL_OK) {
1945 return Tcl_EvalObjv(interp, objc-2, objv+2,
1946 (evalGlobal) ? TCL_EVAL_GLOBAL : 0);
1950 *----------------------------------------------------------------------
1952 * TesteventObjCmd --
1954 * This procedure implements a 'testevent' command. The command
1955 * is used to test event queue management.
1957 * The command takes two forms:
1958 * - testevent queue name position script
1959 * Queues an event at the given position in the queue, and
1960 * associates a given name with it (the same name may be
1961 * associated with multiple events). When the event comes
1962 * to the head of the queue, executes the given script at
1963 * global level in the current interp. The position may be
1964 * one of 'head', 'tail' or 'mark'.
1965 * - testevent delete name
1966 * Deletes any events associated with the given name from
1970 * Returns a standard Tcl result.
1973 * Manipulates the event queue as directed.
1975 *----------------------------------------------------------------------
1979 TesteventObjCmd( ClientData unused, /* Not used */
1980 Tcl_Interp* interp, /* Tcl interpreter */
1981 int objc, /* Parameter count */
1982 Tcl_Obj *CONST objv[] ) /* Parameter vector */
1985 static CONST char* subcommands[] = { /* Possible subcommands */
1990 int subCmdIndex; /* Index of the chosen subcommand */
1991 static CONST char* positions[] = { /* Possible queue positions */
1997 int posIndex; /* Index of the chosen position */
1998 static CONST Tcl_QueuePosition posNum[] = {
1999 /* Interpretation of the chosen position */
2004 TestEvent* ev; /* Event to be queued */
2007 Tcl_WrongNumArgs( interp, 1, objv, "subcommand ?args?" );
2010 if ( Tcl_GetIndexFromObj( interp, objv[1], subcommands, "subcommand",
2011 TCL_EXACT, &subCmdIndex ) != TCL_OK ) {
2014 switch ( subCmdIndex ) {
2017 Tcl_WrongNumArgs( interp, 2, objv, "name position script" );
2020 if ( Tcl_GetIndexFromObj( interp, objv[3], positions,
2021 "position specifier", TCL_EXACT,
2022 &posIndex ) != TCL_OK ) {
2025 ev = (TestEvent*) ckalloc( sizeof( TestEvent ) );
2026 ev->header.proc = TesteventProc;
2027 ev->header.nextPtr = NULL;
2028 ev->interp = interp;
2029 ev->command = objv[ 4 ];
2030 Tcl_IncrRefCount( ev->command );
2031 ev->tag = objv[ 2 ];
2032 Tcl_IncrRefCount( ev->tag );
2033 Tcl_QueueEvent( (Tcl_Event*) ev, posNum[ posIndex ] );
2036 case 1: /* delete */
2038 Tcl_WrongNumArgs( interp, 2, objv, "name" );
2041 Tcl_DeleteEvents( TesteventDeleteProc, objv[ 2 ] );
2050 *----------------------------------------------------------------------
2054 * Delivers a test event to the Tcl interpreter as part of event
2058 * Returns 1 if the event has been serviced, 0 otherwise.
2061 * Evaluates the event's callback script, so has whatever
2062 * side effects the callback has. The return value of the
2063 * callback script becomes the return value of this function.
2064 * If the callback script reports an error, it is reported as
2065 * a background error.
2067 *----------------------------------------------------------------------
2071 TesteventProc( Tcl_Event* event, /* Event to deliver */
2072 int flags ) /* Current flags for Tcl_ServiceEvent */
2074 TestEvent * ev = (TestEvent *) event;
2075 Tcl_Interp* interp = ev->interp;
2076 Tcl_Obj* command = ev->command;
2077 int result = Tcl_EvalObjEx( interp, command,
2078 TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT );
2080 if ( result != TCL_OK ) {
2081 Tcl_AddErrorInfo( interp,
2082 " (command bound to \"testevent\" callback)" );
2083 Tcl_BackgroundError( interp );
2084 return 1; /* Avoid looping on errors */
2086 if ( Tcl_GetBooleanFromObj( interp,
2087 Tcl_GetObjResult( interp ),
2088 &retval ) != TCL_OK ) {
2089 Tcl_AddErrorInfo( interp,
2090 " (return value from \"testevent\" callback)" );
2091 Tcl_BackgroundError( interp );
2095 Tcl_DecrRefCount( ev->tag );
2096 Tcl_DecrRefCount( ev->command );
2103 *----------------------------------------------------------------------
2105 * TesteventDeleteProc --
2107 * Removes some set of events from the queue.
2109 * This procedure is used as part of testing event queue management.
2112 * Returns 1 if a given event should be deleted, 0 otherwise.
2117 *----------------------------------------------------------------------
2121 TesteventDeleteProc( Tcl_Event* event, /* Event to examine */
2122 ClientData clientData ) /* Tcl_Obj containing the name
2123 * of the event(s) to remove */
2125 TestEvent* ev; /* Event to examine */
2127 Tcl_Obj* targetName; /* Name of the event(s) to delete */
2128 char* targetNameStr;
2130 if ( event->proc != TesteventProc ) {
2133 targetName = (Tcl_Obj*) clientData;
2134 targetNameStr = (char*) Tcl_GetStringFromObj( targetName, NULL );
2135 ev = (TestEvent*) event;
2136 evNameStr = Tcl_GetStringFromObj( ev->tag, NULL );
2137 if ( strcmp( evNameStr, targetNameStr ) == 0 ) {
2138 Tcl_DecrRefCount( ev->tag );
2139 Tcl_DecrRefCount( ev->command );
2147 *----------------------------------------------------------------------
2149 * TestexithandlerCmd --
2151 * This procedure implements the "testexithandler" command. It is
2152 * used to test Tcl_CreateExitHandler and Tcl_DeleteExitHandler.
2155 * A standard Tcl result.
2160 *----------------------------------------------------------------------
2164 TestexithandlerCmd(clientData, interp, argc, argv)
2165 ClientData clientData; /* Not used. */
2166 Tcl_Interp *interp; /* Current interpreter. */
2167 int argc; /* Number of arguments. */
2168 CONST char **argv; /* Argument strings. */
2173 Tcl_AppendResult(interp, "wrong # arguments: should be \"", argv[0],
2174 " create|delete value\"", (char *) NULL);
2177 if (Tcl_GetInt(interp, argv[2], &value) != TCL_OK) {
2180 if (strcmp(argv[1], "create") == 0) {
2181 Tcl_CreateExitHandler((value & 1) ? ExitProcOdd : ExitProcEven,
2182 (ClientData) value);
2183 } else if (strcmp(argv[1], "delete") == 0) {
2184 Tcl_DeleteExitHandler((value & 1) ? ExitProcOdd : ExitProcEven,
2185 (ClientData) value);
2187 Tcl_AppendResult(interp, "bad option \"", argv[1],
2188 "\": must be create or delete", (char *) NULL);
2195 ExitProcOdd(clientData)
2196 ClientData clientData; /* Integer value to print. */
2198 char buf[16 + TCL_INTEGER_SPACE];
2200 sprintf(buf, "odd %d\n", (int) clientData);
2201 write(1, buf, strlen(buf));
2205 ExitProcEven(clientData)
2206 ClientData clientData; /* Integer value to print. */
2208 char buf[16 + TCL_INTEGER_SPACE];
2210 sprintf(buf, "even %d\n", (int) clientData);
2211 write(1, buf, strlen(buf));
2215 *----------------------------------------------------------------------
2217 * TestexprlongCmd --
2219 * This procedure verifies that Tcl_ExprLong does not modify the
2220 * interpreter result if there is no error.
2223 * A standard Tcl result.
2228 *----------------------------------------------------------------------
2232 TestexprlongCmd(clientData, interp, argc, argv)
2233 ClientData clientData; /* Not used. */
2234 Tcl_Interp *interp; /* Current interpreter. */
2235 int argc; /* Number of arguments. */
2236 CONST char **argv; /* Argument strings. */
2239 char buf[4 + TCL_INTEGER_SPACE];
2242 Tcl_SetResult(interp, "This is a result", TCL_STATIC);
2243 result = Tcl_ExprLong(interp, "4+1", &exprResult);
2244 if (result != TCL_OK) {
2247 sprintf(buf, ": %ld", exprResult);
2248 Tcl_AppendResult(interp, buf, NULL);
2253 *----------------------------------------------------------------------
2255 * TestexprstringCmd --
2257 * This procedure tests the basic operation of Tcl_ExprString.
2260 * A standard Tcl result.
2265 *----------------------------------------------------------------------
2269 TestexprstringCmd(clientData, interp, argc, argv)
2270 ClientData clientData; /* Not used. */
2271 Tcl_Interp *interp; /* Current interpreter. */
2272 int argc; /* Number of arguments. */
2273 CONST char **argv; /* Argument strings. */
2276 Tcl_AppendResult(interp, "wrong # arguments: should be \"", argv[0],
2277 " expression\"", (char *) NULL);
2280 return Tcl_ExprString(interp, argv[1]);
2284 *----------------------------------------------------------------------
2286 * TestfilelinkCmd --
2288 * This procedure implements the "testfilelink" command. It is used
2289 * to test the effects of creating and manipulating filesystem links
2293 * A standard Tcl result.
2296 * May create a link on disk.
2298 *----------------------------------------------------------------------
2302 TestfilelinkCmd(clientData, interp, objc, objv)
2303 ClientData clientData; /* Not used. */
2304 Tcl_Interp *interp; /* Current interpreter. */
2305 int objc; /* Number of arguments. */
2306 Tcl_Obj *CONST objv[]; /* The argument objects. */
2310 if (objc < 2 || objc > 3) {
2311 Tcl_WrongNumArgs(interp, 1, objv, "source ?target?");
2315 if (Tcl_FSConvertToPathType(interp, objv[1]) != TCL_OK) {
2320 /* Create link from source to target */
2321 contents = Tcl_FSLink(objv[1], objv[2],
2322 TCL_CREATE_SYMBOLIC_LINK|TCL_CREATE_HARD_LINK);
2323 if (contents == NULL) {
2324 Tcl_AppendResult(interp, "could not create link from \"",
2325 Tcl_GetString(objv[1]), "\" to \"",
2326 Tcl_GetString(objv[2]), "\": ",
2327 Tcl_PosixError(interp), (char *) NULL);
2332 contents = Tcl_FSLink(objv[1], NULL, 0);
2333 if (contents == NULL) {
2334 Tcl_AppendResult(interp, "could not read link \"",
2335 Tcl_GetString(objv[1]), "\": ",
2336 Tcl_PosixError(interp), (char *) NULL);
2340 Tcl_SetObjResult(interp, contents);
2343 * If we are creating a link, this will actually just
2344 * be objv[3], and we don't own it
2346 Tcl_DecrRefCount(contents);
2352 *----------------------------------------------------------------------
2354 * TestgetassocdataCmd --
2356 * This procedure implements the "testgetassocdata" command. It is
2357 * used to test Tcl_GetAssocData.
2360 * A standard Tcl result.
2365 *----------------------------------------------------------------------
2369 TestgetassocdataCmd(clientData, interp, argc, argv)
2370 ClientData clientData; /* Not used. */
2371 Tcl_Interp *interp; /* Current interpreter. */
2372 int argc; /* Number of arguments. */
2373 CONST char **argv; /* Argument strings. */
2378 Tcl_AppendResult(interp, "wrong # arguments: should be \"", argv[0],
2379 " data_key\"", (char *) NULL);
2382 res = (char *) Tcl_GetAssocData(interp, argv[1], NULL);
2384 Tcl_AppendResult(interp, res, NULL);
2390 *----------------------------------------------------------------------
2392 * TestgetplatformCmd --
2394 * This procedure implements the "testgetplatform" command. It is
2395 * used to retrievel the value of the tclPlatform global variable.
2398 * A standard Tcl result.
2403 *----------------------------------------------------------------------
2407 TestgetplatformCmd(clientData, interp, argc, argv)
2408 ClientData clientData; /* Not used. */
2409 Tcl_Interp *interp; /* Current interpreter. */
2410 int argc; /* Number of arguments. */
2411 CONST char **argv; /* Argument strings. */
2413 static CONST char *platformStrings[] = { "unix", "mac", "windows" };
2414 TclPlatformType *platform;
2417 platform = TclWinGetPlatform();
2419 platform = &tclPlatform;
2423 Tcl_AppendResult(interp, "wrong # arguments: should be \"", argv[0],
2428 Tcl_AppendResult(interp, platformStrings[*platform], NULL);
2433 *----------------------------------------------------------------------
2435 * TestinterpdeleteCmd --
2437 * This procedure tests the code in tclInterp.c that deals with
2438 * interpreter deletion. It deletes a user-specified interpreter
2439 * from the hierarchy, and subsequent code checks integrity.
2442 * A standard Tcl result.
2445 * Deletes one or more interpreters.
2447 *----------------------------------------------------------------------
2452 TestinterpdeleteCmd(dummy, interp, argc, argv)
2453 ClientData dummy; /* Not used. */
2454 Tcl_Interp *interp; /* Current interpreter. */
2455 int argc; /* Number of arguments. */
2456 CONST char **argv; /* Argument strings. */
2458 Tcl_Interp *slaveToDelete;
2461 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
2462 " path\"", (char *) NULL);
2465 slaveToDelete = Tcl_GetSlave(interp, argv[1]);
2466 if (slaveToDelete == (Tcl_Interp *) NULL) {
2469 Tcl_DeleteInterp(slaveToDelete);
2474 *----------------------------------------------------------------------
2478 * This procedure implements the "testlink" command. It is used
2479 * to test Tcl_LinkVar and related library procedures.
2482 * A standard Tcl result.
2485 * Creates and deletes various variable links, plus returns
2486 * values of the linked variables.
2488 *----------------------------------------------------------------------
2493 TestlinkCmd(dummy, interp, argc, argv)
2494 ClientData dummy; /* Not used. */
2495 Tcl_Interp *interp; /* Current interpreter. */
2496 int argc; /* Number of arguments. */
2497 CONST char **argv; /* Argument strings. */
2499 static int intVar = 43;
2500 static int boolVar = 4;
2501 static double realVar = 1.23;
2502 static Tcl_WideInt wideVar = Tcl_LongAsWide(79);
2503 static char *stringVar = NULL;
2504 static int created = 0;
2505 char buffer[2*TCL_DOUBLE_SPACE];
2510 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
2511 " option ?arg arg arg arg arg?\"", (char *) NULL);
2514 if (strcmp(argv[1], "create") == 0) {
2516 Tcl_AppendResult(interp, "wrong # args: should be \"",
2517 argv[0], " ", argv[1],
2518 " intRO realRO boolRO stringRO wideRO\"", (char *) NULL);
2522 Tcl_UnlinkVar(interp, "int");
2523 Tcl_UnlinkVar(interp, "real");
2524 Tcl_UnlinkVar(interp, "bool");
2525 Tcl_UnlinkVar(interp, "string");
2526 Tcl_UnlinkVar(interp, "wide");
2529 if (Tcl_GetBoolean(interp, argv[2], &writable) != TCL_OK) {
2532 flag = (writable != 0) ? 0 : TCL_LINK_READ_ONLY;
2533 if (Tcl_LinkVar(interp, "int", (char *) &intVar,
2534 TCL_LINK_INT | flag) != TCL_OK) {
2537 if (Tcl_GetBoolean(interp, argv[3], &writable) != TCL_OK) {
2540 flag = (writable != 0) ? 0 : TCL_LINK_READ_ONLY;
2541 if (Tcl_LinkVar(interp, "real", (char *) &realVar,
2542 TCL_LINK_DOUBLE | flag) != TCL_OK) {
2545 if (Tcl_GetBoolean(interp, argv[4], &writable) != TCL_OK) {
2548 flag = (writable != 0) ? 0 : TCL_LINK_READ_ONLY;
2549 if (Tcl_LinkVar(interp, "bool", (char *) &boolVar,
2550 TCL_LINK_BOOLEAN | flag) != TCL_OK) {
2553 if (Tcl_GetBoolean(interp, argv[5], &writable) != TCL_OK) {
2556 flag = (writable != 0) ? 0 : TCL_LINK_READ_ONLY;
2557 if (Tcl_LinkVar(interp, "string", (char *) &stringVar,
2558 TCL_LINK_STRING | flag) != TCL_OK) {
2561 if (Tcl_GetBoolean(interp, argv[6], &writable) != TCL_OK) {
2564 flag = (writable != 0) ? 0 : TCL_LINK_READ_ONLY;
2565 if (Tcl_LinkVar(interp, "wide", (char *) &wideVar,
2566 TCL_LINK_WIDE_INT | flag) != TCL_OK) {
2569 } else if (strcmp(argv[1], "delete") == 0) {
2570 Tcl_UnlinkVar(interp, "int");
2571 Tcl_UnlinkVar(interp, "real");
2572 Tcl_UnlinkVar(interp, "bool");
2573 Tcl_UnlinkVar(interp, "string");
2574 Tcl_UnlinkVar(interp, "wide");
2576 } else if (strcmp(argv[1], "get") == 0) {
2577 TclFormatInt(buffer, intVar);
2578 Tcl_AppendElement(interp, buffer);
2579 Tcl_PrintDouble((Tcl_Interp *) NULL, realVar, buffer);
2580 Tcl_AppendElement(interp, buffer);
2581 TclFormatInt(buffer, boolVar);
2582 Tcl_AppendElement(interp, buffer);
2583 Tcl_AppendElement(interp, (stringVar == NULL) ? "-" : stringVar);
2585 * Wide ints only have an object-based interface.
2587 tmp = Tcl_NewWideIntObj(wideVar);
2588 Tcl_AppendElement(interp, Tcl_GetString(tmp));
2589 Tcl_DecrRefCount(tmp);
2590 } else if (strcmp(argv[1], "set") == 0) {
2592 Tcl_AppendResult(interp, "wrong # args: should be \"",
2593 argv[0], " ", argv[1],
2594 " intValue realValue boolValue stringValue wideValue\"",
2598 if (argv[2][0] != 0) {
2599 if (Tcl_GetInt(interp, argv[2], &intVar) != TCL_OK) {
2603 if (argv[3][0] != 0) {
2604 if (Tcl_GetDouble(interp, argv[3], &realVar) != TCL_OK) {
2608 if (argv[4][0] != 0) {
2609 if (Tcl_GetInt(interp, argv[4], &boolVar) != TCL_OK) {
2613 if (argv[5][0] != 0) {
2614 if (stringVar != NULL) {
2617 if (strcmp(argv[5], "-") == 0) {
2620 stringVar = (char *) ckalloc((unsigned) (strlen(argv[5]) + 1));
2621 strcpy(stringVar, argv[5]);
2624 if (argv[6][0] != 0) {
2625 tmp = Tcl_NewStringObj(argv[6], -1);
2626 if (Tcl_GetWideIntFromObj(interp, tmp, &wideVar) != TCL_OK) {
2627 Tcl_DecrRefCount(tmp);
2630 Tcl_DecrRefCount(tmp);
2632 } else if (strcmp(argv[1], "update") == 0) {
2634 Tcl_AppendResult(interp, "wrong # args: should be \"",
2635 argv[0], " ", argv[1],
2636 "intValue realValue boolValue stringValue wideValue\"",
2640 if (argv[2][0] != 0) {
2641 if (Tcl_GetInt(interp, argv[2], &intVar) != TCL_OK) {
2644 Tcl_UpdateLinkedVar(interp, "int");
2646 if (argv[3][0] != 0) {
2647 if (Tcl_GetDouble(interp, argv[3], &realVar) != TCL_OK) {
2650 Tcl_UpdateLinkedVar(interp, "real");
2652 if (argv[4][0] != 0) {
2653 if (Tcl_GetInt(interp, argv[4], &boolVar) != TCL_OK) {
2656 Tcl_UpdateLinkedVar(interp, "bool");
2658 if (argv[5][0] != 0) {
2659 if (stringVar != NULL) {
2662 if (strcmp(argv[5], "-") == 0) {
2665 stringVar = (char *) ckalloc((unsigned) (strlen(argv[5]) + 1));
2666 strcpy(stringVar, argv[5]);
2668 Tcl_UpdateLinkedVar(interp, "string");
2670 if (argv[6][0] != 0) {
2671 tmp = Tcl_NewStringObj(argv[6], -1);
2672 if (Tcl_GetWideIntFromObj(interp, tmp, &wideVar) != TCL_OK) {
2673 Tcl_DecrRefCount(tmp);
2676 Tcl_DecrRefCount(tmp);
2677 Tcl_UpdateLinkedVar(interp, "wide");
2680 Tcl_AppendResult(interp, "bad option \"", argv[1],
2681 "\": should be create, delete, get, set, or update",
2689 *----------------------------------------------------------------------
2693 * This procedure implements the "testlocale" command. It is used
2694 * to test the effects of setting different locales in Tcl.
2697 * A standard Tcl result.
2700 * Modifies the current C locale.
2702 *----------------------------------------------------------------------
2706 TestlocaleCmd(clientData, interp, objc, objv)
2707 ClientData clientData; /* Not used. */
2708 Tcl_Interp *interp; /* Current interpreter. */
2709 int objc; /* Number of arguments. */
2710 Tcl_Obj *CONST objv[]; /* The argument objects. */
2715 static CONST char *optionStrings[] = {
2716 "ctype", "numeric", "time", "collate", "monetary",
2719 static int lcTypes[] = {
2720 LC_CTYPE, LC_NUMERIC, LC_TIME, LC_COLLATE, LC_MONETARY,
2725 * LC_CTYPE, etc. correspond to the indices for the strings.
2728 if (objc < 2 || objc > 3) {
2729 Tcl_WrongNumArgs(interp, 1, objv, "category ?locale?");
2733 if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
2734 &index) != TCL_OK) {
2739 locale = Tcl_GetString(objv[2]);
2743 locale = setlocale(lcTypes[index], locale);
2745 Tcl_SetStringObj(Tcl_GetObjResult(interp), locale, -1);
2751 *----------------------------------------------------------------------
2755 * This is a user-defined math procedure to test out math procedures
2756 * with no arguments.
2759 * A normal Tcl completion code.
2764 *----------------------------------------------------------------------
2769 TestMathFunc(clientData, interp, args, resultPtr)
2770 ClientData clientData; /* Integer value to return. */
2771 Tcl_Interp *interp; /* Not used. */
2772 Tcl_Value *args; /* Not used. */
2773 Tcl_Value *resultPtr; /* Where to store result. */
2775 resultPtr->type = TCL_INT;
2776 resultPtr->intValue = (int) clientData;
2781 *----------------------------------------------------------------------
2785 * This is a user-defined math procedure to test out math procedures
2786 * that do have arguments, in this case 2.
2789 * A normal Tcl completion code.
2794 *----------------------------------------------------------------------
2799 TestMathFunc2(clientData, interp, args, resultPtr)
2800 ClientData clientData; /* Integer value to return. */
2801 Tcl_Interp *interp; /* Used to report errors. */
2802 Tcl_Value *args; /* Points to an array of two
2803 * Tcl_Value structs for the
2805 Tcl_Value *resultPtr; /* Where to store the result. */
2807 int result = TCL_OK;
2810 * Return the maximum of the two arguments with the correct type.
2813 if (args[0].type == TCL_INT) {
2814 int i0 = args[0].intValue;
2816 if (args[1].type == TCL_INT) {
2817 int i1 = args[1].intValue;
2819 resultPtr->type = TCL_INT;
2820 resultPtr->intValue = ((i0 > i1)? i0 : i1);
2821 } else if (args[1].type == TCL_DOUBLE) {
2823 double d1 = args[1].doubleValue;
2825 resultPtr->type = TCL_DOUBLE;
2826 resultPtr->doubleValue = ((d0 > d1)? d0 : d1);
2827 } else if (args[1].type == TCL_WIDE_INT) {
2828 Tcl_WideInt w0 = Tcl_LongAsWide(i0);
2829 Tcl_WideInt w1 = args[1].wideValue;
2831 resultPtr->type = TCL_WIDE_INT;
2832 resultPtr->wideValue = ((w0 > w1)? w0 : w1);
2834 Tcl_SetResult(interp, "T3: wrong type for arg 2", TCL_STATIC);
2837 } else if (args[0].type == TCL_DOUBLE) {
2838 double d0 = args[0].doubleValue;
2840 if (args[1].type == TCL_INT) {
2841 double d1 = args[1].intValue;
2843 resultPtr->type = TCL_DOUBLE;
2844 resultPtr->doubleValue = ((d0 > d1)? d0 : d1);
2845 } else if (args[1].type == TCL_DOUBLE) {
2846 double d1 = args[1].doubleValue;
2848 resultPtr->type = TCL_DOUBLE;
2849 resultPtr->doubleValue = ((d0 > d1)? d0 : d1);
2850 } else if (args[1].type == TCL_WIDE_INT) {
2851 double d1 = Tcl_WideAsDouble(args[1].wideValue);
2853 resultPtr->type = TCL_DOUBLE;
2854 resultPtr->doubleValue = ((d0 > d1)? d0 : d1);
2856 Tcl_SetResult(interp, "T3: wrong type for arg 2", TCL_STATIC);
2859 } else if (args[0].type == TCL_WIDE_INT) {
2860 Tcl_WideInt w0 = args[0].wideValue;
2862 if (args[1].type == TCL_INT) {
2863 Tcl_WideInt w1 = Tcl_LongAsWide(args[1].intValue);
2865 resultPtr->type = TCL_WIDE_INT;
2866 resultPtr->wideValue = ((w0 > w1)? w0 : w1);
2867 } else if (args[1].type == TCL_DOUBLE) {
2868 double d0 = Tcl_WideAsDouble(w0);
2869 double d1 = args[1].doubleValue;
2871 resultPtr->type = TCL_DOUBLE;
2872 resultPtr->doubleValue = ((d0 > d1)? d0 : d1);
2873 } else if (args[1].type == TCL_WIDE_INT) {
2874 Tcl_WideInt w1 = args[1].wideValue;
2876 resultPtr->type = TCL_WIDE_INT;
2877 resultPtr->wideValue = ((w0 > w1)? w0 : w1);
2879 Tcl_SetResult(interp, "T3: wrong type for arg 2", TCL_STATIC);
2883 Tcl_SetResult(interp, "T3: wrong type for arg 1", TCL_STATIC);
2890 *----------------------------------------------------------------------
2892 * CleanupTestSetassocdataTests --
2894 * This function is called when an interpreter is deleted to clean
2895 * up any data left over from running the testsetassocdata command.
2903 *----------------------------------------------------------------------
2907 CleanupTestSetassocdataTests(clientData, interp)
2908 ClientData clientData; /* Data to be released. */
2909 Tcl_Interp *interp; /* Interpreter being deleted. */
2911 ckfree((char *) clientData);
2915 *----------------------------------------------------------------------
2917 * TestparserObjCmd --
2919 * This procedure implements the "testparser" command. It is
2920 * used for testing the new Tcl script parser in Tcl 8.1.
2923 * A standard Tcl result.
2928 *----------------------------------------------------------------------
2932 TestparserObjCmd(clientData, interp, objc, objv)
2933 ClientData clientData; /* Not used. */
2934 Tcl_Interp *interp; /* Current interpreter. */
2935 int objc; /* Number of arguments. */
2936 Tcl_Obj *CONST objv[]; /* The argument objects. */
2943 Tcl_WrongNumArgs(interp, 1, objv, "script length");
2946 script = Tcl_GetStringFromObj(objv[1], &dummy);
2947 if (Tcl_GetIntFromObj(interp, objv[2], &length)) {
2953 if (Tcl_ParseCommand(interp, script, length, 0, &parse) != TCL_OK) {
2954 Tcl_AddErrorInfo(interp, "\n (remainder of script: \"");
2955 Tcl_AddErrorInfo(interp, parse.term);
2956 Tcl_AddErrorInfo(interp, "\")");
2961 * The parse completed successfully. Just print out the contents
2962 * of the parse structure into the interpreter's result.
2965 PrintParse(interp, &parse);
2966 Tcl_FreeParse(&parse);
2971 *----------------------------------------------------------------------
2973 * TestexprparserObjCmd --
2975 * This procedure implements the "testexprparser" command. It is
2976 * used for testing the new Tcl expression parser in Tcl 8.1.
2979 * A standard Tcl result.
2984 *----------------------------------------------------------------------
2988 TestexprparserObjCmd(clientData, interp, objc, objv)
2989 ClientData clientData; /* Not used. */
2990 Tcl_Interp *interp; /* Current interpreter. */
2991 int objc; /* Number of arguments. */
2992 Tcl_Obj *CONST objv[]; /* The argument objects. */
2999 Tcl_WrongNumArgs(interp, 1, objv, "expr length");
3002 script = Tcl_GetStringFromObj(objv[1], &dummy);
3003 if (Tcl_GetIntFromObj(interp, objv[2], &length)) {
3009 if (Tcl_ParseExpr(interp, script, length, &parse) != TCL_OK) {
3010 Tcl_AddErrorInfo(interp, "\n (remainder of expr: \"");
3011 Tcl_AddErrorInfo(interp, parse.term);
3012 Tcl_AddErrorInfo(interp, "\")");
3017 * The parse completed successfully. Just print out the contents
3018 * of the parse structure into the interpreter's result.
3021 PrintParse(interp, &parse);
3022 Tcl_FreeParse(&parse);
3027 *----------------------------------------------------------------------
3031 * This procedure prints out the contents of a Tcl_Parse structure
3032 * in the result of an interpreter.
3035 * Interp's result is set to a prettily formatted version of the
3036 * contents of parsePtr.
3041 *----------------------------------------------------------------------
3045 PrintParse(interp, parsePtr)
3046 Tcl_Interp *interp; /* Interpreter whose result is to be set to
3047 * the contents of a parse structure. */
3048 Tcl_Parse *parsePtr; /* Parse structure to print out. */
3052 Tcl_Token *tokenPtr;
3055 objPtr = Tcl_GetObjResult(interp);
3056 if (parsePtr->commentSize > 0) {
3057 Tcl_ListObjAppendElement((Tcl_Interp *) NULL, objPtr,
3058 Tcl_NewStringObj(parsePtr->commentStart,
3059 parsePtr->commentSize));
3061 Tcl_ListObjAppendElement((Tcl_Interp *) NULL, objPtr,
3062 Tcl_NewStringObj("-", 1));
3064 Tcl_ListObjAppendElement((Tcl_Interp *) NULL, objPtr,
3065 Tcl_NewStringObj(parsePtr->commandStart, parsePtr->commandSize));
3066 Tcl_ListObjAppendElement((Tcl_Interp *) NULL, objPtr,
3067 Tcl_NewIntObj(parsePtr->numWords));
3068 for (i = 0; i < parsePtr->numTokens; i++) {
3069 tokenPtr = &parsePtr->tokenPtr[i];
3070 switch (tokenPtr->type) {
3071 case TCL_TOKEN_WORD:
3072 typeString = "word";
3074 case TCL_TOKEN_SIMPLE_WORD:
3075 typeString = "simple";
3077 case TCL_TOKEN_TEXT:
3078 typeString = "text";
3081 typeString = "backslash";
3083 case TCL_TOKEN_COMMAND:
3084 typeString = "command";
3086 case TCL_TOKEN_VARIABLE:
3087 typeString = "variable";
3089 case TCL_TOKEN_SUB_EXPR:
3090 typeString = "subexpr";
3092 case TCL_TOKEN_OPERATOR:
3093 typeString = "operator";
3099 Tcl_ListObjAppendElement((Tcl_Interp *) NULL, objPtr,
3100 Tcl_NewStringObj(typeString, -1));
3101 Tcl_ListObjAppendElement((Tcl_Interp *) NULL, objPtr,
3102 Tcl_NewStringObj(tokenPtr->start, tokenPtr->size));
3103 Tcl_ListObjAppendElement((Tcl_Interp *) NULL, objPtr,
3104 Tcl_NewIntObj(tokenPtr->numComponents));
3106 Tcl_ListObjAppendElement((Tcl_Interp *) NULL, objPtr,
3107 Tcl_NewStringObj(parsePtr->commandStart + parsePtr->commandSize,
3112 *----------------------------------------------------------------------
3114 * TestparsevarObjCmd --
3116 * This procedure implements the "testparsevar" command. It is
3117 * used for testing Tcl_ParseVar.
3120 * A standard Tcl result.
3125 *----------------------------------------------------------------------
3129 TestparsevarObjCmd(clientData, interp, objc, objv)
3130 ClientData clientData; /* Not used. */
3131 Tcl_Interp *interp; /* Current interpreter. */
3132 int objc; /* Number of arguments. */
3133 Tcl_Obj *CONST objv[]; /* The argument objects. */
3136 CONST char *name, *termPtr;
3139 Tcl_WrongNumArgs(interp, 1, objv, "varName");
3142 name = Tcl_GetString(objv[1]);
3143 value = Tcl_ParseVar(interp, name, &termPtr);
3144 if (value == NULL) {
3148 Tcl_AppendElement(interp, value);
3149 Tcl_AppendElement(interp, termPtr);
3154 *----------------------------------------------------------------------
3156 * TestparsevarnameObjCmd --
3158 * This procedure implements the "testparsevarname" command. It is
3159 * used for testing the new Tcl script parser in Tcl 8.1.
3162 * A standard Tcl result.
3167 *----------------------------------------------------------------------
3171 TestparsevarnameObjCmd(clientData, interp, objc, objv)
3172 ClientData clientData; /* Not used. */
3173 Tcl_Interp *interp; /* Current interpreter. */
3174 int objc; /* Number of arguments. */
3175 Tcl_Obj *CONST objv[]; /* The argument objects. */
3178 int append, length, dummy;
3182 Tcl_WrongNumArgs(interp, 1, objv, "script length append");
3185 script = Tcl_GetStringFromObj(objv[1], &dummy);
3186 if (Tcl_GetIntFromObj(interp, objv[2], &length)) {
3192 if (Tcl_GetIntFromObj(interp, objv[3], &append)) {
3195 if (Tcl_ParseVarName(interp, script, length, &parse, append) != TCL_OK) {
3196 Tcl_AddErrorInfo(interp, "\n (remainder of script: \"");
3197 Tcl_AddErrorInfo(interp, parse.term);
3198 Tcl_AddErrorInfo(interp, "\")");
3203 * The parse completed successfully. Just print out the contents
3204 * of the parse structure into the interpreter's result.
3207 parse.commentSize = 0;
3208 parse.commandStart = script + parse.tokenPtr->size;
3209 parse.commandSize = 0;
3210 PrintParse(interp, &parse);
3211 Tcl_FreeParse(&parse);
3216 *----------------------------------------------------------------------
3218 * TestregexpObjCmd --
3220 * This procedure implements the "testregexp" command. It is
3221 * used to give a direct interface for regexp flags. It's identical
3222 * to Tcl_RegexpObjCmd except for the -xflags option, and the
3223 * consequences thereof (including the REG_EXPECT kludge).
3226 * A standard Tcl result.
3229 * See the user documentation.
3231 *----------------------------------------------------------------------
3236 TestregexpObjCmd(dummy, interp, objc, objv)
3237 ClientData dummy; /* Not used. */
3238 Tcl_Interp *interp; /* Current interpreter. */
3239 int objc; /* Number of arguments. */
3240 Tcl_Obj *CONST objv[]; /* Argument objects. */
3242 int i, ii, indices, stringLength, match, about;
3243 int hasxflags, cflags, eflags;
3247 Tcl_RegExpInfo info;
3248 static CONST char *options[] = {
3249 "-indices", "-nocase", "-about", "-expanded",
3250 "-line", "-linestop", "-lineanchor",
3255 REGEXP_INDICES, REGEXP_NOCASE, REGEXP_ABOUT, REGEXP_EXPANDED,
3256 REGEXP_MULTI, REGEXP_NOCROSS, REGEXP_NEWL,
3263 cflags = REG_ADVANCED;
3267 for (i = 1; i < objc; i++) {
3271 name = Tcl_GetString(objv[i]);
3272 if (name[0] != '-') {
3275 if (Tcl_GetIndexFromObj(interp, objv[i], options, "switch", TCL_EXACT,
3276 &index) != TCL_OK) {
3279 switch ((enum options) index) {
3280 case REGEXP_INDICES: {
3284 case REGEXP_NOCASE: {
3285 cflags |= REG_ICASE;
3288 case REGEXP_ABOUT: {
3292 case REGEXP_EXPANDED: {
3293 cflags |= REG_EXPANDED;
3296 case REGEXP_MULTI: {
3297 cflags |= REG_NEWLINE;
3300 case REGEXP_NOCROSS: {
3301 cflags |= REG_NLSTOP;
3305 cflags |= REG_NLANCH;
3308 case REGEXP_XFLAGS: {
3320 if (objc - i < hasxflags + 2 - about) {
3321 Tcl_WrongNumArgs(interp, 1, objv,
3322 "?switches? exp string ?matchVar? ?subMatchVar subMatchVar ...?");
3329 string = Tcl_GetStringFromObj(objv[0], &stringLength);
3330 TestregexpXflags(string, stringLength, &cflags, &eflags);
3335 regExpr = Tcl_GetRegExpFromObj(interp, objv[0], cflags);
3336 if (regExpr == NULL) {
3342 if (TclRegAbout(interp, regExpr) < 0) {
3348 match = Tcl_RegExpExecObj(interp, regExpr, objPtr, 0 /* offset */,
3349 objc-2 /* nmatches */, eflags);
3356 * Set the interpreter's object result to an integer object w/
3360 Tcl_SetIntObj(Tcl_GetObjResult(interp), 0);
3361 if (objc > 2 && (cflags®_EXPECT) && indices) {
3365 char resinfo[TCL_INTEGER_SPACE * 2];
3367 varName = Tcl_GetString(objv[2]);
3368 TclRegExpRangeUniChar(regExpr, -1, &start, &end);
3369 sprintf(resinfo, "%d %d", start, end-1);
3370 value = Tcl_SetVar(interp, varName, resinfo, 0);
3371 if (value == NULL) {
3372 Tcl_AppendResult(interp, "couldn't set variable \"",
3373 varName, "\"", (char *) NULL);
3376 } else if (cflags & TCL_REG_CANMATCH) {
3379 char resinfo[TCL_INTEGER_SPACE * 2];
3381 Tcl_RegExpGetInfo(regExpr, &info);
3382 varName = Tcl_GetString(objv[2]);
3383 sprintf(resinfo, "%ld", info.extendStart);
3384 value = Tcl_SetVar(interp, varName, resinfo, 0);
3385 if (value == NULL) {
3386 Tcl_AppendResult(interp, "couldn't set variable \"",
3387 varName, "\"", (char *) NULL);
3395 * If additional variable names have been specified, return
3396 * index information in those variables.
3402 Tcl_RegExpGetInfo(regExpr, &info);
3403 for (i = 0; i < objc; i++) {
3405 Tcl_Obj *newPtr, *varPtr, *valuePtr;
3408 ii = ((cflags®_EXPECT) && i == objc-1) ? -1 : i;
3413 TclRegExpRangeUniChar(regExpr, ii, &start, &end);
3414 } else if (ii > info.nsubs) {
3418 start = info.matches[ii].start;
3419 end = info.matches[ii].end;
3423 * Adjust index so it refers to the last character in the
3424 * match instead of the first character after the match.
3431 objs[0] = Tcl_NewLongObj(start);
3432 objs[1] = Tcl_NewLongObj(end);
3434 newPtr = Tcl_NewListObj(2, objs);
3437 TclRegExpRangeUniChar(regExpr, ii, &start, &end);
3438 newPtr = Tcl_GetRange(objPtr, start, end);
3439 } else if (ii > info.nsubs) {
3440 newPtr = Tcl_NewObj();
3442 newPtr = Tcl_GetRange(objPtr, info.matches[ii].start,
3443 info.matches[ii].end - 1);
3446 Tcl_IncrRefCount(newPtr);
3447 valuePtr = Tcl_ObjSetVar2(interp, varPtr, NULL, newPtr, 0);
3448 Tcl_DecrRefCount(newPtr);
3449 if (valuePtr == NULL) {
3450 Tcl_AppendResult(interp, "couldn't set variable \"",
3451 Tcl_GetString(varPtr), "\"", (char *) NULL);
3457 * Set the interpreter's object result to an integer object w/ value 1.
3460 Tcl_SetIntObj(Tcl_GetObjResult(interp), 1);
3465 *---------------------------------------------------------------------------
3467 * TestregexpXflags --
3469 * Parse a string of extended regexp flag letters, for testing.
3472 * No return value (you're on your own for errors here).
3475 * Modifies *cflagsPtr, a regcomp flags word, and *eflagsPtr, a
3476 * regexec flags word, as appropriate.
3478 *----------------------------------------------------------------------
3482 TestregexpXflags(string, length, cflagsPtr, eflagsPtr)
3483 char *string; /* The string of flags. */
3484 int length; /* The length of the string in bytes. */
3485 int *cflagsPtr; /* compile flags word */
3486 int *eflagsPtr; /* exec flags word */
3492 cflags = *cflagsPtr;
3493 eflags = *eflagsPtr;
3494 for (i = 0; i < length; i++) {
3495 switch (string[i]) {
3501 cflags &= ~REG_ADVANCED;
3505 cflags |= TCL_REG_CANMATCH;
3509 cflags &= ~REG_ADVANCED;
3510 cflags |= REG_EXTENDED;
3514 cflags &= ~REG_ADVANCED;
3515 cflags |= REG_QUOTE;
3518 case 'o': { /* o for opaque */
3519 cflags |= REG_NOSUB;
3522 case 's': { /* s for start */
3523 cflags |= REG_BOSONLY;
3531 cflags |= REG_PROGRESS;
3539 eflags |= REG_MTRACE;
3543 eflags |= REG_FTRACE;
3547 eflags |= REG_NOTBOL;
3551 eflags |= REG_NOTEOL;
3555 cflags |= REG_EXPECT;
3559 eflags |= REG_SMALL;
3565 *cflagsPtr = cflags;
3566 *eflagsPtr = eflags;
3570 *----------------------------------------------------------------------
3572 * TestsetassocdataCmd --
3574 * This procedure implements the "testsetassocdata" command. It is used
3575 * to test Tcl_SetAssocData.
3578 * A standard Tcl result.
3581 * Modifies or creates an association between a key and associated
3582 * data for this interpreter.
3584 *----------------------------------------------------------------------
3588 TestsetassocdataCmd(clientData, interp, argc, argv)
3589 ClientData clientData; /* Not used. */
3590 Tcl_Interp *interp; /* Current interpreter. */
3591 int argc; /* Number of arguments. */
3592 CONST char **argv; /* Argument strings. */
3596 Tcl_InterpDeleteProc *procPtr;
3599 Tcl_AppendResult(interp, "wrong # arguments: should be \"", argv[0],
3600 " data_key data_item\"", (char *) NULL);
3604 buf = ckalloc((unsigned) strlen(argv[2]) + 1);
3605 strcpy(buf, argv[2]);
3608 * If we previously associated a malloced value with the variable,
3609 * free it before associating a new value.
3612 oldData = (char *) Tcl_GetAssocData(interp, argv[1], &procPtr);
3613 if ((oldData != NULL) && (procPtr == CleanupTestSetassocdataTests)) {
3617 Tcl_SetAssocData(interp, argv[1], CleanupTestSetassocdataTests,
3623 *----------------------------------------------------------------------
3625 * TestsetplatformCmd --
3627 * This procedure implements the "testsetplatform" command. It is
3628 * used to change the tclPlatform global variable so all file
3629 * name conversions can be tested on a single platform.
3632 * A standard Tcl result.
3635 * Sets the tclPlatform global variable.
3637 *----------------------------------------------------------------------
3641 TestsetplatformCmd(clientData, interp, argc, argv)
3642 ClientData clientData; /* Not used. */
3643 Tcl_Interp *interp; /* Current interpreter. */
3644 int argc; /* Number of arguments. */
3645 CONST char **argv; /* Argument strings. */
3648 TclPlatformType *platform;
3651 platform = TclWinGetPlatform();
3653 platform = &tclPlatform;
3657 Tcl_AppendResult(interp, "wrong # arguments: should be \"", argv[0],
3658 " platform\"", (char *) NULL);
3662 length = strlen(argv[1]);
3663 if (strncmp(argv[1], "unix", length) == 0) {
3664 *platform = TCL_PLATFORM_UNIX;
3665 } else if (strncmp(argv[1], "mac", length) == 0) {
3666 *platform = TCL_PLATFORM_MAC;
3667 } else if (strncmp(argv[1], "windows", length) == 0) {
3668 *platform = TCL_PLATFORM_WINDOWS;
3670 Tcl_AppendResult(interp, "unsupported platform: should be one of ",
3671 "unix, mac, or windows", (char *) NULL);
3678 *----------------------------------------------------------------------
3680 * TeststaticpkgCmd --
3682 * This procedure implements the "teststaticpkg" command.
3683 * It is used to test the procedure Tcl_StaticPackage.
3686 * A standard Tcl result.
3689 * When the packge given by argv[1] is loaded into an interpeter,
3690 * variable "x" in that interpreter is set to "loaded".
3692 *----------------------------------------------------------------------
3696 TeststaticpkgCmd(dummy, interp, argc, argv)
3697 ClientData dummy; /* Not used. */
3698 Tcl_Interp *interp; /* Current interpreter. */
3699 int argc; /* Number of arguments. */
3700 CONST char **argv; /* Argument strings. */
3705 Tcl_AppendResult(interp, "wrong # arguments: should be \"",
3706 argv[0], " pkgName safe loaded\"", (char *) NULL);
3709 if (Tcl_GetInt(interp, argv[2], &safe) != TCL_OK) {
3712 if (Tcl_GetInt(interp, argv[3], &loaded) != TCL_OK) {
3715 Tcl_StaticPackage((loaded) ? interp : NULL, argv[1], StaticInitProc,
3716 (safe) ? StaticInitProc : NULL);
3721 StaticInitProc(interp)
3722 Tcl_Interp *interp; /* Interpreter in which package
3723 * is supposedly being loaded. */
3725 Tcl_SetVar(interp, "x", "loaded", TCL_GLOBAL_ONLY);
3730 *----------------------------------------------------------------------
3732 * TesttranslatefilenameCmd --
3734 * This procedure implements the "testtranslatefilename" command.
3735 * It is used to test the Tcl_TranslateFileName command.
3738 * A standard Tcl result.
3743 *----------------------------------------------------------------------
3747 TesttranslatefilenameCmd(dummy, interp, argc, argv)
3748 ClientData dummy; /* Not used. */
3749 Tcl_Interp *interp; /* Current interpreter. */
3750 int argc; /* Number of arguments. */
3751 CONST char **argv; /* Argument strings. */
3757 Tcl_AppendResult(interp, "wrong # arguments: should be \"",
3758 argv[0], " path\"", (char *) NULL);
3761 result = Tcl_TranslateFileName(interp, argv[1], &buffer);
3762 if (result == NULL) {
3765 Tcl_AppendResult(interp, result, NULL);
3766 Tcl_DStringFree(&buffer);
3771 *----------------------------------------------------------------------
3775 * This procedure implements the "testupvar2" command. It is used
3776 * to test Tcl_UpVar and Tcl_UpVar2.
3779 * A standard Tcl result.
3782 * Creates or modifies an "upvar" reference.
3784 *----------------------------------------------------------------------
3789 TestupvarCmd(dummy, interp, argc, argv)
3790 ClientData dummy; /* Not used. */
3791 Tcl_Interp *interp; /* Current interpreter. */
3792 int argc; /* Number of arguments. */
3793 CONST char **argv; /* Argument strings. */
3797 if ((argc != 5) && (argc != 6)) {
3798 Tcl_AppendResult(interp, "wrong # arguments: should be \"",
3799 argv[0], " level name ?name2? dest global\"", (char *) NULL);
3804 if (strcmp(argv[4], "global") == 0) {
3805 flags = TCL_GLOBAL_ONLY;
3806 } else if (strcmp(argv[4], "namespace") == 0) {
3807 flags = TCL_NAMESPACE_ONLY;
3809 return Tcl_UpVar(interp, argv[1], argv[2], argv[3], flags);
3811 if (strcmp(argv[5], "global") == 0) {
3812 flags = TCL_GLOBAL_ONLY;
3813 } else if (strcmp(argv[5], "namespace") == 0) {
3814 flags = TCL_NAMESPACE_ONLY;
3816 return Tcl_UpVar2(interp, argv[1], argv[2],
3817 (argv[3][0] == 0) ? (char *) NULL : argv[3], argv[4],
3823 *----------------------------------------------------------------------
3825 * TestseterrorcodeCmd --
3827 * This procedure implements the "testseterrorcodeCmd".
3828 * This tests up to five elements passed to the
3829 * Tcl_SetErrorCode command.
3832 * A standard Tcl result. Always returns TCL_ERROR so that
3833 * the error code can be tested.
3838 *----------------------------------------------------------------------
3843 TestseterrorcodeCmd(dummy, interp, argc, argv)
3844 ClientData dummy; /* Not used. */
3845 Tcl_Interp *interp; /* Current interpreter. */
3846 int argc; /* Number of arguments. */
3847 CONST char **argv; /* Argument strings. */
3850 Tcl_SetResult(interp, "too many args", TCL_STATIC);
3853 Tcl_SetErrorCode(interp, argv[1], argv[2], argv[3], argv[4],
3859 *----------------------------------------------------------------------
3861 * TestsetobjerrorcodeCmd --
3863 * This procedure implements the "testsetobjerrorcodeCmd".
3864 * This tests the Tcl_SetObjErrorCode function.
3867 * A standard Tcl result. Always returns TCL_ERROR so that
3868 * the error code can be tested.
3873 *----------------------------------------------------------------------
3878 TestsetobjerrorcodeCmd(dummy, interp, objc, objv)
3879 ClientData dummy; /* Not used. */
3880 Tcl_Interp *interp; /* Current interpreter. */
3881 int objc; /* Number of arguments. */
3882 Tcl_Obj *CONST objv[]; /* The argument objects. */
3884 Tcl_Obj *listObjPtr;
3887 listObjPtr = Tcl_ConcatObj(objc - 1, objv + 1);
3889 listObjPtr = Tcl_NewObj();
3891 Tcl_IncrRefCount(listObjPtr);
3892 Tcl_SetObjErrorCode(interp, listObjPtr);
3893 Tcl_DecrRefCount(listObjPtr);
3898 *----------------------------------------------------------------------
3902 * This procedure implements the "testfevent" command. It is
3903 * used for testing the "fileevent" command.
3906 * A standard Tcl result.
3909 * Creates and deletes interpreters.
3911 *----------------------------------------------------------------------
3916 TestfeventCmd(clientData, interp, argc, argv)
3917 ClientData clientData; /* Not used. */
3918 Tcl_Interp *interp; /* Current interpreter. */
3919 int argc; /* Number of arguments. */
3920 CONST char **argv; /* Argument strings. */
3922 static Tcl_Interp *interp2 = NULL;
3927 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
3928 " option ?arg arg ...?", (char *) NULL);
3931 if (strcmp(argv[1], "cmd") == 0) {
3933 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
3934 " cmd script", (char *) NULL);
3937 if (interp2 != (Tcl_Interp *) NULL) {
3938 code = Tcl_GlobalEval(interp2, argv[2]);
3939 Tcl_SetObjResult(interp, Tcl_GetObjResult(interp2));
3942 Tcl_AppendResult(interp,
3943 "called \"testfevent code\" before \"testfevent create\"",
3947 } else if (strcmp(argv[1], "create") == 0) {
3948 if (interp2 != NULL) {
3949 Tcl_DeleteInterp(interp2);
3951 interp2 = Tcl_CreateInterp();
3952 return Tcl_Init(interp2);
3953 } else if (strcmp(argv[1], "delete") == 0) {
3954 if (interp2 != NULL) {
3955 Tcl_DeleteInterp(interp2);
3958 } else if (strcmp(argv[1], "share") == 0) {
3959 if (interp2 != NULL) {
3960 chan = Tcl_GetChannel(interp, argv[2], NULL);
3961 if (chan == (Tcl_Channel) NULL) {
3964 Tcl_RegisterChannel(interp2, chan);
3972 *----------------------------------------------------------------------
3976 * Calls the panic routine.
3979 * Always returns TCL_OK.
3982 * May exit application.
3984 *----------------------------------------------------------------------
3988 TestpanicCmd(dummy, interp, argc, argv)
3989 ClientData dummy; /* Not used. */
3990 Tcl_Interp *interp; /* Current interpreter. */
3991 int argc; /* Number of arguments. */
3992 CONST char **argv; /* Argument strings. */
3994 CONST char *argString;
3997 * Put the arguments into a var args structure
3998 * Append all of the arguments together separated by spaces
4001 argString = Tcl_Merge(argc-1, argv+1);
4003 ckfree((char *)argString);
4009 TestfileCmd(dummy, interp, argc, argv)
4010 ClientData dummy; /* Not used. */
4011 Tcl_Interp *interp; /* Current interpreter. */
4012 int argc; /* Number of arguments. */
4013 Tcl_Obj *CONST argv[]; /* The argument objects. */
4015 int force, i, j, result;
4016 Tcl_Obj *error = NULL;
4025 if (strcmp(Tcl_GetString(argv[2]), "-force") == 0) {
4034 for (j = i; j < argc; j++) {
4035 if (Tcl_FSGetNormalizedPath(interp, argv[j]) == NULL) {
4040 subcmd = Tcl_GetString(argv[1]);
4042 if (strcmp(subcmd, "mv") == 0) {
4043 result = TclpObjRenameFile(argv[i], argv[i + 1]);
4044 } else if (strcmp(subcmd, "cp") == 0) {
4045 result = TclpObjCopyFile(argv[i], argv[i + 1]);
4046 } else if (strcmp(subcmd, "rm") == 0) {
4047 result = TclpObjDeleteFile(argv[i]);
4048 } else if (strcmp(subcmd, "mkdir") == 0) {
4049 result = TclpObjCreateDirectory(argv[i]);
4050 } else if (strcmp(subcmd, "cpdir") == 0) {
4051 result = TclpObjCopyDirectory(argv[i], argv[i + 1], &error);
4052 } else if (strcmp(subcmd, "rmdir") == 0) {
4053 result = TclpObjRemoveDirectory(argv[i], force, &error);
4059 if (result != TCL_OK) {
4060 if (error != NULL) {
4061 if (Tcl_GetString(error)[0] != '\0') {
4062 Tcl_AppendResult(interp, Tcl_GetString(error), " ", NULL);
4064 Tcl_DecrRefCount(error);
4066 Tcl_AppendResult(interp, Tcl_ErrnoId(), (char *) NULL);
4075 *----------------------------------------------------------------------
4077 * TestgetvarfullnameCmd --
4079 * Implements the "testgetvarfullname" cmd that is used when testing
4080 * the Tcl_GetVariableFullName procedure.
4083 * A standard Tcl result.
4088 *----------------------------------------------------------------------
4092 TestgetvarfullnameCmd(dummy, interp, objc, objv)
4093 ClientData dummy; /* Not used. */
4094 Tcl_Interp *interp; /* Current interpreter. */
4095 int objc; /* Number of arguments. */
4096 Tcl_Obj *CONST objv[]; /* The argument objects. */
4100 Tcl_Namespace *namespacePtr;
4101 Tcl_CallFrame frame;
4106 Tcl_WrongNumArgs(interp, 1, objv, "name scope");
4110 name = Tcl_GetString(objv[1]);
4112 arg = Tcl_GetString(objv[2]);
4113 if (strcmp(arg, "global") == 0) {
4114 flags = TCL_GLOBAL_ONLY;
4115 } else if (strcmp(arg, "namespace") == 0) {
4116 flags = TCL_NAMESPACE_ONLY;
4120 * This command, like any other created with Tcl_Create[Obj]Command,
4121 * runs in the global namespace. As a "namespace-aware" command that
4122 * needs to run in a particular namespace, it must activate that
4126 if (flags == TCL_NAMESPACE_ONLY) {
4127 namespacePtr = Tcl_FindNamespace(interp, "::test_ns_var",
4128 (Tcl_Namespace *) NULL, TCL_LEAVE_ERR_MSG);
4129 if (namespacePtr == NULL) {
4132 result = Tcl_PushCallFrame(interp, &frame, namespacePtr,
4133 /*isProcCallFrame*/ 0);
4134 if (result != TCL_OK) {
4139 variable = Tcl_FindNamespaceVar(interp, name, (Tcl_Namespace *) NULL,
4140 (flags | TCL_LEAVE_ERR_MSG));
4142 if (flags == TCL_NAMESPACE_ONLY) {
4143 Tcl_PopCallFrame(interp);
4145 if (variable == (Tcl_Var) NULL) {
4148 Tcl_GetVariableFullName(interp, variable, Tcl_GetObjResult(interp));
4153 *----------------------------------------------------------------------
4157 * This procedure implements the "gettimes" command. It is
4158 * used for computing the time needed for various basic operations
4159 * such as reading variables, allocating memory, sprintf, converting
4163 * A standard Tcl result.
4166 * Allocates and frees memory, sets a variable "a" in the interpreter.
4168 *----------------------------------------------------------------------
4172 GetTimesCmd(unused, interp, argc, argv)
4173 ClientData unused; /* Unused. */
4174 Tcl_Interp *interp; /* The current interpreter. */
4175 int argc; /* The number of arguments. */
4176 CONST char **argv; /* The argument strings. */
4178 Interp *iPtr = (Interp *) interp;
4181 Tcl_Time start, stop;
4185 char newString[TCL_INTEGER_SPACE];
4187 /* alloc & free 100000 times */
4188 fprintf(stderr, "alloc & free 100000 6 word items\n");
4189 Tcl_GetTime(&start);
4190 for (i = 0; i < 100000; i++) {
4191 objPtr = (Tcl_Obj *) ckalloc(sizeof(Tcl_Obj));
4192 ckfree((char *) objPtr);
4195 timePer = (stop.sec - start.sec)*1000000 + (stop.usec - start.usec);
4196 fprintf(stderr, " %.3f usec per alloc+free\n", timePer/100000);
4198 /* alloc 5000 times */
4199 fprintf(stderr, "alloc 5000 6 word items\n");
4200 objv = (Tcl_Obj **) ckalloc(5000 * sizeof(Tcl_Obj *));
4201 Tcl_GetTime(&start);
4202 for (i = 0; i < 5000; i++) {
4203 objv[i] = (Tcl_Obj *) ckalloc(sizeof(Tcl_Obj));
4206 timePer = (stop.sec - start.sec)*1000000 + (stop.usec - start.usec);
4207 fprintf(stderr, " %.3f usec per alloc\n", timePer/5000);
4209 /* free 5000 times */
4210 fprintf(stderr, "free 5000 6 word items\n");
4211 Tcl_GetTime(&start);
4212 for (i = 0; i < 5000; i++) {
4213 ckfree((char *) objv[i]);
4216 timePer = (stop.sec - start.sec)*1000000 + (stop.usec - start.usec);
4217 fprintf(stderr, " %.3f usec per free\n", timePer/5000);
4219 /* Tcl_NewObj 5000 times */
4220 fprintf(stderr, "Tcl_NewObj 5000 times\n");
4221 Tcl_GetTime(&start);
4222 for (i = 0; i < 5000; i++) {
4223 objv[i] = Tcl_NewObj();
4226 timePer = (stop.sec - start.sec)*1000000 + (stop.usec - start.usec);
4227 fprintf(stderr, " %.3f usec per Tcl_NewObj\n", timePer/5000);
4229 /* Tcl_DecrRefCount 5000 times */
4230 fprintf(stderr, "Tcl_DecrRefCount 5000 times\n");
4231 Tcl_GetTime(&start);
4232 for (i = 0; i < 5000; i++) {
4234 Tcl_DecrRefCount(objPtr);
4237 timePer = (stop.sec - start.sec)*1000000 + (stop.usec - start.usec);
4238 fprintf(stderr, " %.3f usec per Tcl_DecrRefCount\n", timePer/5000);
4239 ckfree((char *) objv);
4241 /* TclGetString 100000 times */
4242 fprintf(stderr, "TclGetStringFromObj of \"12345\" 100000 times\n");
4243 objPtr = Tcl_NewStringObj("12345", -1);
4244 Tcl_GetTime(&start);
4245 for (i = 0; i < 100000; i++) {
4246 (void) TclGetString(objPtr);
4249 timePer = (stop.sec - start.sec)*1000000 + (stop.usec - start.usec);
4250 fprintf(stderr, " %.3f usec per TclGetStringFromObj of \"12345\"\n",
4253 /* Tcl_GetIntFromObj 100000 times */
4254 fprintf(stderr, "Tcl_GetIntFromObj of \"12345\" 100000 times\n");
4255 Tcl_GetTime(&start);
4256 for (i = 0; i < 100000; i++) {
4257 if (Tcl_GetIntFromObj(interp, objPtr, &n) != TCL_OK) {
4262 timePer = (stop.sec - start.sec)*1000000 + (stop.usec - start.usec);
4263 fprintf(stderr, " %.3f usec per Tcl_GetIntFromObj of \"12345\"\n",
4265 Tcl_DecrRefCount(objPtr);
4267 /* Tcl_GetInt 100000 times */
4268 fprintf(stderr, "Tcl_GetInt of \"12345\" 100000 times\n");
4269 Tcl_GetTime(&start);
4270 for (i = 0; i < 100000; i++) {
4271 if (Tcl_GetInt(interp, "12345", &n) != TCL_OK) {
4276 timePer = (stop.sec - start.sec)*1000000 + (stop.usec - start.usec);
4277 fprintf(stderr, " %.3f usec per Tcl_GetInt of \"12345\"\n",
4280 /* sprintf 100000 times */
4281 fprintf(stderr, "sprintf of 12345 100000 times\n");
4282 Tcl_GetTime(&start);
4283 for (i = 0; i < 100000; i++) {
4284 sprintf(newString, "%d", 12345);
4287 timePer = (stop.sec - start.sec)*1000000 + (stop.usec - start.usec);
4288 fprintf(stderr, " %.3f usec per sprintf of 12345\n",
4291 /* hashtable lookup 100000 times */
4292 fprintf(stderr, "hashtable lookup of \"gettimes\" 100000 times\n");
4293 Tcl_GetTime(&start);
4294 for (i = 0; i < 100000; i++) {
4295 (void) Tcl_FindHashEntry(&iPtr->globalNsPtr->cmdTable, "gettimes");
4298 timePer = (stop.sec - start.sec)*1000000 + (stop.usec - start.usec);
4299 fprintf(stderr, " %.3f usec per hashtable lookup of \"gettimes\"\n",
4302 /* Tcl_SetVar 100000 times */
4303 fprintf(stderr, "Tcl_SetVar of \"12345\" 100000 times\n");
4304 Tcl_GetTime(&start);
4305 for (i = 0; i < 100000; i++) {
4306 s = Tcl_SetVar(interp, "a", "12345", TCL_LEAVE_ERR_MSG);
4312 timePer = (stop.sec - start.sec)*1000000 + (stop.usec - start.usec);
4313 fprintf(stderr, " %.3f usec per Tcl_SetVar of a to \"12345\"\n",
4316 /* Tcl_GetVar 100000 times */
4317 fprintf(stderr, "Tcl_GetVar of a==\"12345\" 100000 times\n");
4318 Tcl_GetTime(&start);
4319 for (i = 0; i < 100000; i++) {
4320 s = Tcl_GetVar(interp, "a", TCL_LEAVE_ERR_MSG);
4326 timePer = (stop.sec - start.sec)*1000000 + (stop.usec - start.usec);
4327 fprintf(stderr, " %.3f usec per Tcl_GetVar of a==\"12345\"\n",
4330 Tcl_ResetResult(interp);
4335 *----------------------------------------------------------------------
4339 * This procedure is just used to time the overhead involved in
4340 * parsing and invoking a command.
4348 *----------------------------------------------------------------------
4352 NoopCmd(unused, interp, argc, argv)
4353 ClientData unused; /* Unused. */
4354 Tcl_Interp *interp; /* The current interpreter. */
4355 int argc; /* The number of arguments. */
4356 CONST char **argv; /* The argument strings. */
4362 *----------------------------------------------------------------------
4366 * This object-based procedure is just used to time the overhead
4367 * involved in parsing and invoking a command.
4370 * Returns the TCL_OK result code.
4375 *----------------------------------------------------------------------
4379 NoopObjCmd(unused, interp, objc, objv)
4380 ClientData unused; /* Not used. */
4381 Tcl_Interp *interp; /* Current interpreter. */
4382 int objc; /* Number of arguments. */
4383 Tcl_Obj *CONST objv[]; /* The argument objects. */
4389 *----------------------------------------------------------------------
4393 * Implements the "testset{err,noerr}" cmds that are used when testing
4394 * Tcl_Set/GetVar C Api with/without TCL_LEAVE_ERR_MSG flag
4397 * A standard Tcl result.
4400 * Variables may be set.
4402 *----------------------------------------------------------------------
4407 TestsetCmd(data, interp, argc, argv)
4408 ClientData data; /* Additional flags for Get/SetVar2. */
4409 register Tcl_Interp *interp; /* Current interpreter. */
4410 int argc; /* Number of arguments. */
4411 CONST char **argv; /* Argument strings. */
4413 int flags = (int) data;
4417 Tcl_SetResult(interp, "before get", TCL_STATIC);
4418 value = Tcl_GetVar2(interp, argv[1], (char *) NULL, flags);
4419 if (value == NULL) {
4422 Tcl_AppendElement(interp, value);
4424 } else if (argc == 3) {
4425 Tcl_SetResult(interp, "before set", TCL_STATIC);
4426 value = Tcl_SetVar2(interp, argv[1], (char *) NULL, argv[2], flags);
4427 if (value == NULL) {
4430 Tcl_AppendElement(interp, value);
4433 Tcl_AppendResult(interp, "wrong # args: should be \"",
4434 argv[0], " varName ?newValue?\"", (char *) NULL);
4440 *----------------------------------------------------------------------
4442 * TestsaveresultCmd --
4444 * Implements the "testsaveresult" cmd that is used when testing
4445 * the Tcl_SaveResult, Tcl_RestoreResult, and
4446 * Tcl_DiscardResult interfaces.
4449 * A standard Tcl result.
4454 *----------------------------------------------------------------------
4459 TestsaveresultCmd(dummy, interp, objc, objv)
4460 ClientData dummy; /* Not used. */
4461 register Tcl_Interp *interp; /* Current interpreter. */
4462 int objc; /* Number of arguments. */
4463 Tcl_Obj *CONST objv[]; /* The argument objects. */
4465 int discard, result, index;
4466 Tcl_SavedResult state;
4468 static CONST char *optionStrings[] = {
4469 "append", "dynamic", "free", "object", "small", NULL
4472 RESULT_APPEND, RESULT_DYNAMIC, RESULT_FREE, RESULT_OBJECT, RESULT_SMALL
4480 Tcl_WrongNumArgs(interp, 1, objv, "type script discard");
4483 if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
4484 &index) != TCL_OK) {
4487 if (Tcl_GetBooleanFromObj(interp, objv[3], &discard) != TCL_OK) {
4491 objPtr = NULL; /* Lint. */
4492 switch ((enum options) index) {
4494 Tcl_SetResult(interp, "small result", TCL_VOLATILE);
4497 Tcl_AppendResult(interp, "append result", NULL);
4500 char *buf = ckalloc(200);
4501 strcpy(buf, "free result");
4502 Tcl_SetResult(interp, buf, TCL_DYNAMIC);
4505 case RESULT_DYNAMIC:
4506 Tcl_SetResult(interp, "dynamic result", TestsaveresultFree);
4509 objPtr = Tcl_NewStringObj("object result", -1);
4510 Tcl_SetObjResult(interp, objPtr);
4515 Tcl_SaveResult(interp, &state);
4517 if (((enum options) index) == RESULT_OBJECT) {
4518 result = Tcl_EvalObjEx(interp, objv[2], 0);
4520 result = Tcl_Eval(interp, Tcl_GetString(objv[2]));
4524 Tcl_DiscardResult(&state);
4526 Tcl_RestoreResult(interp, &state);
4530 switch ((enum options) index) {
4531 case RESULT_DYNAMIC: {
4532 int present = interp->freeProc == TestsaveresultFree;
4533 int called = freeCount;
4534 Tcl_AppendElement(interp, called ? "called" : "notCalled");
4535 Tcl_AppendElement(interp, present ? "present" : "missing");
4539 Tcl_AppendElement(interp, Tcl_GetObjResult(interp) == objPtr
4540 ? "same" : "different");
4549 *----------------------------------------------------------------------
4551 * TestsaveresultFree --
4553 * Special purpose freeProc used by TestsaveresultCmd.
4559 * Increments the freeCount.
4561 *----------------------------------------------------------------------
4565 TestsaveresultFree(blockPtr)
4572 *----------------------------------------------------------------------
4574 * TeststatprocCmd --
4576 * Implements the "testTclStatProc" cmd that is used to test the
4577 * 'TclStatInsertProc' & 'TclStatDeleteProc' C Apis.
4580 * A standard Tcl result.
4585 *----------------------------------------------------------------------
4589 TeststatprocCmd (dummy, interp, argc, argv)
4590 ClientData dummy; /* Not used. */
4591 register Tcl_Interp *interp; /* Current interpreter. */
4592 int argc; /* Number of arguments. */
4593 CONST char **argv; /* Argument strings. */
4599 Tcl_AppendResult(interp, "wrong # args: should be \"",
4600 argv[0], " option arg\"", (char *) NULL);
4604 if (strcmp(argv[2], "TclpStat") == 0) {
4605 proc = PretendTclpStat;
4606 } else if (strcmp(argv[2], "TestStatProc1") == 0) {
4607 proc = TestStatProc1;
4608 } else if (strcmp(argv[2], "TestStatProc2") == 0) {
4609 proc = TestStatProc2;
4610 } else if (strcmp(argv[2], "TestStatProc3") == 0) {
4611 proc = TestStatProc3;
4613 Tcl_AppendResult(interp, "bad arg \"", argv[1], "\": ",
4614 "must be TclpStat, ",
4615 "TestStatProc1, TestStatProc2, or TestStatProc3",
4620 if (strcmp(argv[1], "insert") == 0) {
4621 if (proc == PretendTclpStat) {
4622 Tcl_AppendResult(interp, "bad arg \"", argv[1], "\": ",
4624 "TestStatProc1, TestStatProc2, or TestStatProc3",
4628 retVal = TclStatInsertProc(proc);
4629 } else if (strcmp(argv[1], "delete") == 0) {
4630 retVal = TclStatDeleteProc(proc);
4632 Tcl_AppendResult(interp, "bad option \"", argv[1], "\": ",
4633 "must be insert or delete", (char *) NULL);
4637 if (retVal == TCL_ERROR) {
4638 Tcl_AppendResult(interp, "\"", argv[2], "\": ",
4639 "could not be ", argv[1], "ed", (char *) NULL);
4645 static int PretendTclpStat(path, buf)
4650 Tcl_Obj *pathPtr = Tcl_NewStringObj(path, -1);
4651 #ifdef TCL_WIDE_INT_IS_LONG
4652 Tcl_IncrRefCount(pathPtr);
4653 ret = TclpObjStat(pathPtr, buf);
4654 Tcl_DecrRefCount(pathPtr);
4656 #else /* TCL_WIDE_INT_IS_LONG */
4657 Tcl_StatBuf realBuf;
4658 Tcl_IncrRefCount(pathPtr);
4659 ret = TclpObjStat(pathPtr, &realBuf);
4660 Tcl_DecrRefCount(pathPtr);
4662 # define OUT_OF_RANGE(x) \
4663 (((Tcl_WideInt)(x)) < Tcl_LongAsWide(LONG_MIN) || \
4664 ((Tcl_WideInt)(x)) > Tcl_LongAsWide(LONG_MAX))
4665 #if defined(__GNUC__) && __GNUC__ >= 2
4667 * Workaround gcc warning of "comparison is always false due to limited range of
4668 * data type" in this macro by checking max type size, and when necessary ANDing
4669 * with the complement of ULONG_MAX instead of the comparison:
4671 # define OUT_OF_URANGE(x) \
4672 ((((Tcl_WideUInt)(~ (__typeof__(x)) 0)) > (Tcl_WideUInt)ULONG_MAX) && \
4673 (((Tcl_WideUInt)(x)) & ~(Tcl_WideUInt)ULONG_MAX))
4675 # define OUT_OF_URANGE(x) \
4676 (((Tcl_WideUInt)(x)) > (Tcl_WideUInt)ULONG_MAX)
4680 * Perform the result-buffer overflow check manually.
4682 * Note that ino_t/ino64_t is unsigned...
4685 if (OUT_OF_URANGE(realBuf.st_ino) || OUT_OF_RANGE(realBuf.st_size)
4686 # ifdef HAVE_ST_BLOCKS
4687 || OUT_OF_RANGE(realBuf.st_blocks)
4696 # error "what error should be returned for a value out of range?"
4702 # undef OUT_OF_RANGE
4703 # undef OUT_OF_URANGE
4706 * Copy across all supported fields, with possible type
4707 * coercions on those fields that change between the normal
4708 * and lf64 versions of the stat structure (on Solaris at
4709 * least.) This is slow when the structure sizes coincide,
4710 * but that's what you get for mixing interfaces...
4713 buf->st_mode = realBuf.st_mode;
4714 buf->st_ino = (ino_t) realBuf.st_ino;
4715 buf->st_dev = realBuf.st_dev;
4716 buf->st_rdev = realBuf.st_rdev;
4717 buf->st_nlink = realBuf.st_nlink;
4718 buf->st_uid = realBuf.st_uid;
4719 buf->st_gid = realBuf.st_gid;
4720 buf->st_size = (off_t) realBuf.st_size;
4721 buf->st_atime = realBuf.st_atime;
4722 buf->st_mtime = realBuf.st_mtime;
4723 buf->st_ctime = realBuf.st_ctime;
4724 # ifdef HAVE_ST_BLOCKS
4725 buf->st_blksize = realBuf.st_blksize;
4726 buf->st_blocks = (blkcnt_t) realBuf.st_blocks;
4730 #endif /* TCL_WIDE_INT_IS_LONG */
4733 /* Be careful in the compares in these tests, since the Macintosh puts a
4734 * leading : in the beginning of non-absolute paths before passing them
4735 * into the file command procedures.
4739 TestStatProc1(path, buf)
4743 memset(buf, 0, sizeof(struct stat));
4744 buf->st_size = 1234;
4745 return ((strstr(path, "testStat1%.fil") == NULL) ? -1 : 0);
4750 TestStatProc2(path, buf)
4754 memset(buf, 0, sizeof(struct stat));
4755 buf->st_size = 2345;
4756 return ((strstr(path, "testStat2%.fil") == NULL) ? -1 : 0);
4761 TestStatProc3(path, buf)
4765 memset(buf, 0, sizeof(struct stat));
4766 buf->st_size = 3456;
4767 return ((strstr(path, "testStat3%.fil") == NULL) ? -1 : 0);
4771 *----------------------------------------------------------------------
4773 * TestmainthreadCmd --
4775 * Implements the "testmainthread" cmd that is used to test the
4776 * 'Tcl_GetCurrentThread' API.
4779 * A standard Tcl result.
4784 *----------------------------------------------------------------------
4788 TestmainthreadCmd (dummy, interp, argc, argv)
4789 ClientData dummy; /* Not used. */
4790 register Tcl_Interp *interp; /* Current interpreter. */
4791 int argc; /* Number of arguments. */
4792 CONST char **argv; /* Argument strings. */
4795 Tcl_Obj *idObj = Tcl_NewLongObj((long)Tcl_GetCurrentThread());
4796 Tcl_SetObjResult(interp, idObj);
4799 Tcl_SetResult(interp, "wrong # args", TCL_STATIC);
4805 *----------------------------------------------------------------------
4809 * A main loop set by TestsetmainloopCmd below.
4815 * Event handlers could do anything.
4817 *----------------------------------------------------------------------
4823 while (!exitMainLoop) {
4826 fprintf(stdout,"Exit MainLoop\n");
4831 *----------------------------------------------------------------------
4833 * TestsetmainloopCmd --
4835 * Implements the "testsetmainloop" cmd that is used to test the
4836 * 'Tcl_SetMainLoop' API.
4839 * A standard Tcl result.
4844 *----------------------------------------------------------------------
4848 TestsetmainloopCmd (dummy, interp, argc, argv)
4849 ClientData dummy; /* Not used. */
4850 register Tcl_Interp *interp; /* Current interpreter. */
4851 int argc; /* Number of arguments. */
4852 CONST char **argv; /* Argument strings. */
4855 Tcl_SetMainLoop(MainLoop);
4860 *----------------------------------------------------------------------
4862 * TestexitmainloopCmd --
4864 * Implements the "testexitmainloop" cmd that is used to test the
4865 * 'Tcl_SetMainLoop' API.
4868 * A standard Tcl result.
4873 *----------------------------------------------------------------------
4877 TestexitmainloopCmd (dummy, interp, argc, argv)
4878 ClientData dummy; /* Not used. */
4879 register Tcl_Interp *interp; /* Current interpreter. */
4880 int argc; /* Number of arguments. */
4881 CONST char **argv; /* Argument strings. */
4888 *----------------------------------------------------------------------
4890 * TestaccessprocCmd --
4892 * Implements the "testTclAccessProc" cmd that is used to test the
4893 * 'TclAccessInsertProc' & 'TclAccessDeleteProc' C Apis.
4896 * A standard Tcl result.
4901 *----------------------------------------------------------------------
4905 TestaccessprocCmd (dummy, interp, argc, argv)
4906 ClientData dummy; /* Not used. */
4907 register Tcl_Interp *interp; /* Current interpreter. */
4908 int argc; /* Number of arguments. */
4909 CONST char **argv; /* Argument strings. */
4911 TclAccessProc_ *proc;
4915 Tcl_AppendResult(interp, "wrong # args: should be \"",
4916 argv[0], " option arg\"", (char *) NULL);
4920 if (strcmp(argv[2], "TclpAccess") == 0) {
4921 proc = PretendTclpAccess;
4922 } else if (strcmp(argv[2], "TestAccessProc1") == 0) {
4923 proc = TestAccessProc1;
4924 } else if (strcmp(argv[2], "TestAccessProc2") == 0) {
4925 proc = TestAccessProc2;
4926 } else if (strcmp(argv[2], "TestAccessProc3") == 0) {
4927 proc = TestAccessProc3;
4929 Tcl_AppendResult(interp, "bad arg \"", argv[1], "\": ",
4930 "must be TclpAccess, ",
4931 "TestAccessProc1, TestAccessProc2, or TestAccessProc3",
4936 if (strcmp(argv[1], "insert") == 0) {
4937 if (proc == PretendTclpAccess) {
4938 Tcl_AppendResult(interp, "bad arg \"", argv[1], "\": ",
4940 "TestAccessProc1, TestAccessProc2, or TestAccessProc3",
4944 retVal = TclAccessInsertProc(proc);
4945 } else if (strcmp(argv[1], "delete") == 0) {
4946 retVal = TclAccessDeleteProc(proc);
4948 Tcl_AppendResult(interp, "bad option \"", argv[1], "\": ",
4949 "must be insert or delete", (char *) NULL);
4953 if (retVal == TCL_ERROR) {
4954 Tcl_AppendResult(interp, "\"", argv[2], "\": ",
4955 "could not be ", argv[1], "ed", (char *) NULL);
4961 static int PretendTclpAccess(path, mode)
4966 Tcl_Obj *pathPtr = Tcl_NewStringObj(path, -1);
4967 Tcl_IncrRefCount(pathPtr);
4968 ret = TclpObjAccess(pathPtr, mode);
4969 Tcl_DecrRefCount(pathPtr);
4974 TestAccessProc1(path, mode)
4978 return ((strstr(path, "testAccess1%.fil") == NULL) ? -1 : 0);
4983 TestAccessProc2(path, mode)
4987 return ((strstr(path, "testAccess2%.fil") == NULL) ? -1 : 0);
4992 TestAccessProc3(path, mode)
4996 return ((strstr(path, "testAccess3%.fil") == NULL) ? -1 : 0);
5000 *----------------------------------------------------------------------
5002 * TestopenfilechannelprocCmd --
5004 * Implements the "testTclOpenFileChannelProc" cmd that is used to test the
5005 * 'TclOpenFileChannelInsertProc' & 'TclOpenFileChannelDeleteProc' C Apis.
5008 * A standard Tcl result.
5013 *----------------------------------------------------------------------
5017 TestopenfilechannelprocCmd (dummy, interp, argc, argv)
5018 ClientData dummy; /* Not used. */
5019 register Tcl_Interp *interp; /* Current interpreter. */
5020 int argc; /* Number of arguments. */
5021 CONST char **argv; /* Argument strings. */
5023 TclOpenFileChannelProc_ *proc;
5027 Tcl_AppendResult(interp, "wrong # args: should be \"",
5028 argv[0], " option arg\"", (char *) NULL);
5032 if (strcmp(argv[2], "TclpOpenFileChannel") == 0) {
5033 proc = PretendTclpOpenFileChannel;
5034 } else if (strcmp(argv[2], "TestOpenFileChannelProc1") == 0) {
5035 proc = TestOpenFileChannelProc1;
5036 } else if (strcmp(argv[2], "TestOpenFileChannelProc2") == 0) {
5037 proc = TestOpenFileChannelProc2;
5038 } else if (strcmp(argv[2], "TestOpenFileChannelProc3") == 0) {
5039 proc = TestOpenFileChannelProc3;
5041 Tcl_AppendResult(interp, "bad arg \"", argv[1], "\": ",
5042 "must be TclpOpenFileChannel, ",
5043 "TestOpenFileChannelProc1, TestOpenFileChannelProc2, or ",
5044 "TestOpenFileChannelProc3",
5049 if (strcmp(argv[1], "insert") == 0) {
5050 if (proc == PretendTclpOpenFileChannel) {
5051 Tcl_AppendResult(interp, "bad arg \"", argv[1], "\": ",
5053 "TestOpenFileChannelProc1, TestOpenFileChannelProc2, or ",
5054 "TestOpenFileChannelProc3",
5058 retVal = TclOpenFileChannelInsertProc(proc);
5059 } else if (strcmp(argv[1], "delete") == 0) {
5060 retVal = TclOpenFileChannelDeleteProc(proc);
5062 Tcl_AppendResult(interp, "bad option \"", argv[1], "\": ",
5063 "must be insert or delete", (char *) NULL);
5067 if (retVal == TCL_ERROR) {
5068 Tcl_AppendResult(interp, "\"", argv[2], "\": ",
5069 "could not be ", argv[1], "ed", (char *) NULL);
5076 PretendTclpOpenFileChannel(interp, fileName, modeString, permissions)
5077 Tcl_Interp *interp; /* Interpreter for error reporting;
5079 CONST char *fileName; /* Name of file to open. */
5080 CONST char *modeString; /* A list of POSIX open modes or
5081 * a string such as "rw". */
5082 int permissions; /* If the open involves creating a
5083 * file, with what modes to create
5089 mode = TclGetOpenMode(interp, modeString, &seekFlag);
5093 pathPtr = Tcl_NewStringObj(fileName, -1);
5094 Tcl_IncrRefCount(pathPtr);
5095 ret = TclpOpenFileChannel(interp, pathPtr, mode, permissions);
5096 Tcl_DecrRefCount(pathPtr);
5099 if (Tcl_Seek(ret, (Tcl_WideInt)0, SEEK_END) < (Tcl_WideInt)0) {
5100 if (interp != (Tcl_Interp *) NULL) {
5101 Tcl_AppendResult(interp,
5102 "could not seek to end of file while opening \"",
5104 Tcl_PosixError(interp), (char *) NULL);
5106 Tcl_Close(NULL, ret);
5115 TestOpenFileChannelProc1(interp, fileName, modeString, permissions)
5116 Tcl_Interp *interp; /* Interpreter for error reporting;
5118 CONST char *fileName; /* Name of file to open. */
5119 CONST char *modeString; /* A list of POSIX open modes or
5120 * a string such as "rw". */
5121 int permissions; /* If the open involves creating a
5122 * file, with what modes to create
5125 CONST char *expectname="testOpenFileChannel1%.fil";
5128 Tcl_DStringInit(&ds);
5129 Tcl_JoinPath(1, &expectname, &ds);
5131 if (!strcmp(Tcl_DStringValue(&ds), fileName)) {
5132 Tcl_DStringFree(&ds);
5133 return (PretendTclpOpenFileChannel(interp, "__testOpenFileChannel1%__.fil",
5134 modeString, permissions));
5136 Tcl_DStringFree(&ds);
5143 TestOpenFileChannelProc2(interp, fileName, modeString, permissions)
5144 Tcl_Interp *interp; /* Interpreter for error reporting;
5146 CONST char *fileName; /* Name of file to open. */
5147 CONST char *modeString; /* A list of POSIX open modes or
5148 * a string such as "rw". */
5149 int permissions; /* If the open involves creating a
5150 * file, with what modes to create
5153 CONST char *expectname="testOpenFileChannel2%.fil";
5156 Tcl_DStringInit(&ds);
5157 Tcl_JoinPath(1, &expectname, &ds);
5159 if (!strcmp(Tcl_DStringValue(&ds), fileName)) {
5160 Tcl_DStringFree(&ds);
5161 return (PretendTclpOpenFileChannel(interp, "__testOpenFileChannel2%__.fil",
5162 modeString, permissions));
5164 Tcl_DStringFree(&ds);
5171 TestOpenFileChannelProc3(interp, fileName, modeString, permissions)
5172 Tcl_Interp *interp; /* Interpreter for error reporting;
5174 CONST char *fileName; /* Name of file to open. */
5175 CONST char *modeString; /* A list of POSIX open modes or
5176 * a string such as "rw". */
5177 int permissions; /* If the open involves creating a
5178 * file, with what modes to create
5181 CONST char *expectname="testOpenFileChannel3%.fil";
5184 Tcl_DStringInit(&ds);
5185 Tcl_JoinPath(1, &expectname, &ds);
5187 if (!strcmp(Tcl_DStringValue(&ds), fileName)) {
5188 Tcl_DStringFree(&ds);
5189 return (PretendTclpOpenFileChannel(interp, "__testOpenFileChannel3%__.fil",
5190 modeString, permissions));
5192 Tcl_DStringFree(&ds);
5198 *----------------------------------------------------------------------
5202 * Implements the Tcl "testchannel" debugging command and its
5203 * subcommands. This is part of the testing environment.
5206 * A standard Tcl result.
5211 *----------------------------------------------------------------------
5216 TestChannelCmd(clientData, interp, argc, argv)
5217 ClientData clientData; /* Not used. */
5218 Tcl_Interp *interp; /* Interpreter for result. */
5219 int argc; /* Count of additional args. */
5220 CONST char **argv; /* Additional arg strings. */
5222 CONST char *cmdName; /* Sub command. */
5223 Tcl_HashTable *hTblPtr; /* Hash table of channels. */
5224 Tcl_HashSearch hSearch; /* Search variable. */
5225 Tcl_HashEntry *hPtr; /* Search variable. */
5226 Channel *chanPtr; /* The actual channel. */
5227 ChannelState *statePtr; /* state info for channel */
5228 Tcl_Channel chan; /* The opaque type. */
5229 size_t len; /* Length of subcommand string. */
5230 int IOQueued; /* How much IO is queued inside channel? */
5231 ChannelBuffer *bufPtr; /* For iterating over queued IO. */
5232 char buf[TCL_INTEGER_SPACE];/* For sprintf. */
5233 int mode; /* rw mode of the channel */
5236 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
5237 " subcommand ?additional args..?\"", (char *) NULL);
5241 len = strlen(cmdName);
5243 chanPtr = (Channel *) NULL;
5246 chan = Tcl_GetChannel(interp, argv[2], &mode);
5247 if (chan == (Tcl_Channel) NULL) {
5250 chanPtr = (Channel *) chan;
5251 statePtr = chanPtr->state;
5252 chanPtr = statePtr->topChanPtr;
5253 chan = (Tcl_Channel) chanPtr;
5260 if ((cmdName[0] == 'c') && (strncmp(cmdName, "cut", len) == 0)) {
5262 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
5263 " cut channelName\"", (char *) NULL);
5266 Tcl_CutChannel(chan);
5270 if ((cmdName[0] == 'c') &&
5271 (strncmp(cmdName, "clearchannelhandlers", len) == 0)) {
5273 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
5274 " clearchannelhandlers channelName\"", (char *) NULL);
5277 Tcl_ClearChannelHandlers(chan);
5281 if ((cmdName[0] == 'i') && (strncmp(cmdName, "info", len) == 0)) {
5283 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
5284 " info channelName\"", (char *) NULL);
5287 Tcl_AppendElement(interp, argv[2]);
5288 Tcl_AppendElement(interp, Tcl_ChannelName(chanPtr->typePtr));
5289 if (statePtr->flags & TCL_READABLE) {
5290 Tcl_AppendElement(interp, "read");
5292 Tcl_AppendElement(interp, "");
5294 if (statePtr->flags & TCL_WRITABLE) {
5295 Tcl_AppendElement(interp, "write");
5297 Tcl_AppendElement(interp, "");
5299 if (statePtr->flags & CHANNEL_NONBLOCKING) {
5300 Tcl_AppendElement(interp, "nonblocking");
5302 Tcl_AppendElement(interp, "blocking");
5304 if (statePtr->flags & CHANNEL_LINEBUFFERED) {
5305 Tcl_AppendElement(interp, "line");
5306 } else if (statePtr->flags & CHANNEL_UNBUFFERED) {
5307 Tcl_AppendElement(interp, "none");
5309 Tcl_AppendElement(interp, "full");
5311 if (statePtr->flags & BG_FLUSH_SCHEDULED) {
5312 Tcl_AppendElement(interp, "async_flush");
5314 Tcl_AppendElement(interp, "");
5316 if (statePtr->flags & CHANNEL_EOF) {
5317 Tcl_AppendElement(interp, "eof");
5319 Tcl_AppendElement(interp, "");
5321 if (statePtr->flags & CHANNEL_BLOCKED) {
5322 Tcl_AppendElement(interp, "blocked");
5324 Tcl_AppendElement(interp, "unblocked");
5326 if (statePtr->inputTranslation == TCL_TRANSLATE_AUTO) {
5327 Tcl_AppendElement(interp, "auto");
5328 if (statePtr->flags & INPUT_SAW_CR) {
5329 Tcl_AppendElement(interp, "saw_cr");
5331 Tcl_AppendElement(interp, "");
5333 } else if (statePtr->inputTranslation == TCL_TRANSLATE_LF) {
5334 Tcl_AppendElement(interp, "lf");
5335 Tcl_AppendElement(interp, "");
5336 } else if (statePtr->inputTranslation == TCL_TRANSLATE_CR) {
5337 Tcl_AppendElement(interp, "cr");
5338 Tcl_AppendElement(interp, "");
5339 } else if (statePtr->inputTranslation == TCL_TRANSLATE_CRLF) {
5340 Tcl_AppendElement(interp, "crlf");
5341 if (statePtr->flags & INPUT_SAW_CR) {
5342 Tcl_AppendElement(interp, "queued_cr");
5344 Tcl_AppendElement(interp, "");
5347 if (statePtr->outputTranslation == TCL_TRANSLATE_AUTO) {
5348 Tcl_AppendElement(interp, "auto");
5349 } else if (statePtr->outputTranslation == TCL_TRANSLATE_LF) {
5350 Tcl_AppendElement(interp, "lf");
5351 } else if (statePtr->outputTranslation == TCL_TRANSLATE_CR) {
5352 Tcl_AppendElement(interp, "cr");
5353 } else if (statePtr->outputTranslation == TCL_TRANSLATE_CRLF) {
5354 Tcl_AppendElement(interp, "crlf");
5356 for (IOQueued = 0, bufPtr = statePtr->inQueueHead;
5357 bufPtr != (ChannelBuffer *) NULL;
5358 bufPtr = bufPtr->nextPtr) {
5359 IOQueued += bufPtr->nextAdded - bufPtr->nextRemoved;
5361 TclFormatInt(buf, IOQueued);
5362 Tcl_AppendElement(interp, buf);
5365 if (statePtr->curOutPtr != (ChannelBuffer *) NULL) {
5366 IOQueued = statePtr->curOutPtr->nextAdded -
5367 statePtr->curOutPtr->nextRemoved;
5369 for (bufPtr = statePtr->outQueueHead;
5370 bufPtr != (ChannelBuffer *) NULL;
5371 bufPtr = bufPtr->nextPtr) {
5372 IOQueued += (bufPtr->nextAdded - bufPtr->nextRemoved);
5374 TclFormatInt(buf, IOQueued);
5375 Tcl_AppendElement(interp, buf);
5377 TclFormatInt(buf, (int)Tcl_Tell((Tcl_Channel) chanPtr));
5378 Tcl_AppendElement(interp, buf);
5380 TclFormatInt(buf, statePtr->refCount);
5381 Tcl_AppendElement(interp, buf);
5386 if ((cmdName[0] == 'i') &&
5387 (strncmp(cmdName, "inputbuffered", len) == 0)) {
5389 Tcl_AppendResult(interp, "channel name required",
5394 for (IOQueued = 0, bufPtr = statePtr->inQueueHead;
5395 bufPtr != (ChannelBuffer *) NULL;
5396 bufPtr = bufPtr->nextPtr) {
5397 IOQueued += bufPtr->nextAdded - bufPtr->nextRemoved;
5399 TclFormatInt(buf, IOQueued);
5400 Tcl_AppendResult(interp, buf, (char *) NULL);
5404 if ((cmdName[0] == 'i') && (strncmp(cmdName, "isshared", len) == 0)) {
5406 Tcl_AppendResult(interp, "channel name required", (char *) NULL);
5410 TclFormatInt(buf, Tcl_IsChannelShared(chan));
5411 Tcl_AppendResult(interp, buf, (char *) NULL);
5415 if ((cmdName[0] == 'i') && (strncmp(cmdName, "isstandard", len) == 0)) {
5417 Tcl_AppendResult(interp, "channel name required", (char *) NULL);
5421 TclFormatInt(buf, Tcl_IsStandardChannel(chan));
5422 Tcl_AppendResult(interp, buf, (char *) NULL);
5426 if ((cmdName[0] == 'm') && (strncmp(cmdName, "mode", len) == 0)) {
5428 Tcl_AppendResult(interp, "channel name required",
5433 if (statePtr->flags & TCL_READABLE) {
5434 Tcl_AppendElement(interp, "read");
5436 Tcl_AppendElement(interp, "");
5438 if (statePtr->flags & TCL_WRITABLE) {
5439 Tcl_AppendElement(interp, "write");
5441 Tcl_AppendElement(interp, "");
5446 if ((cmdName[0] == 'm') && (strncmp(cmdName, "mthread", len) == 0)) {
5448 Tcl_AppendResult(interp, "channel name required",
5453 TclFormatInt(buf, (long) Tcl_GetChannelThread(chan));
5454 Tcl_AppendResult(interp, buf, (char *) NULL);
5458 if ((cmdName[0] == 'n') && (strncmp(cmdName, "name", len) == 0)) {
5460 Tcl_AppendResult(interp, "channel name required",
5464 Tcl_AppendResult(interp, statePtr->channelName, (char *) NULL);
5468 if ((cmdName[0] == 'o') && (strncmp(cmdName, "open", len) == 0)) {
5469 hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL);
5470 if (hTblPtr == (Tcl_HashTable *) NULL) {
5473 for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch);
5474 hPtr != (Tcl_HashEntry *) NULL;
5475 hPtr = Tcl_NextHashEntry(&hSearch)) {
5476 Tcl_AppendElement(interp, Tcl_GetHashKey(hTblPtr, hPtr));
5481 if ((cmdName[0] == 'o') &&
5482 (strncmp(cmdName, "outputbuffered", len) == 0)) {
5484 Tcl_AppendResult(interp, "channel name required",
5490 if (statePtr->curOutPtr != (ChannelBuffer *) NULL) {
5491 IOQueued = statePtr->curOutPtr->nextAdded -
5492 statePtr->curOutPtr->nextRemoved;
5494 for (bufPtr = statePtr->outQueueHead;
5495 bufPtr != (ChannelBuffer *) NULL;
5496 bufPtr = bufPtr->nextPtr) {
5497 IOQueued += (bufPtr->nextAdded - bufPtr->nextRemoved);
5499 TclFormatInt(buf, IOQueued);
5500 Tcl_AppendResult(interp, buf, (char *) NULL);
5504 if ((cmdName[0] == 'q') &&
5505 (strncmp(cmdName, "queuedcr", len) == 0)) {
5507 Tcl_AppendResult(interp, "channel name required",
5512 Tcl_AppendResult(interp,
5513 (statePtr->flags & INPUT_SAW_CR) ? "1" : "0",
5518 if ((cmdName[0] == 'r') && (strncmp(cmdName, "readable", len) == 0)) {
5519 hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL);
5520 if (hTblPtr == (Tcl_HashTable *) NULL) {
5523 for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch);
5524 hPtr != (Tcl_HashEntry *) NULL;
5525 hPtr = Tcl_NextHashEntry(&hSearch)) {
5526 chanPtr = (Channel *) Tcl_GetHashValue(hPtr);
5527 statePtr = chanPtr->state;
5528 if (statePtr->flags & TCL_READABLE) {
5529 Tcl_AppendElement(interp, Tcl_GetHashKey(hTblPtr, hPtr));
5535 if ((cmdName[0] == 'r') && (strncmp(cmdName, "refcount", len) == 0)) {
5537 Tcl_AppendResult(interp, "channel name required",
5542 TclFormatInt(buf, statePtr->refCount);
5543 Tcl_AppendResult(interp, buf, (char *) NULL);
5547 if ((cmdName[0] == 's') && (strncmp(cmdName, "splice", len) == 0)) {
5549 Tcl_AppendResult(interp, "channel name required", (char *) NULL);
5553 Tcl_SpliceChannel(chan);
5557 if ((cmdName[0] == 't') && (strncmp(cmdName, "type", len) == 0)) {
5559 Tcl_AppendResult(interp, "channel name required",
5563 Tcl_AppendResult(interp, Tcl_ChannelName(chanPtr->typePtr),
5568 if ((cmdName[0] == 'w') && (strncmp(cmdName, "writable", len) == 0)) {
5569 hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL);
5570 if (hTblPtr == (Tcl_HashTable *) NULL) {
5573 for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch);
5574 hPtr != (Tcl_HashEntry *) NULL;
5575 hPtr = Tcl_NextHashEntry(&hSearch)) {
5576 chanPtr = (Channel *) Tcl_GetHashValue(hPtr);
5577 statePtr = chanPtr->state;
5578 if (statePtr->flags & TCL_WRITABLE) {
5579 Tcl_AppendElement(interp, Tcl_GetHashKey(hTblPtr, hPtr));
5585 if ((cmdName[0] == 't') && (strncmp(cmdName, "transform", len) == 0)) {
5587 * Syntax: transform channel -command command
5591 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
5592 " transform channelId -command cmd\"", (char *) NULL);
5595 if (strcmp(argv[3], "-command") != 0) {
5596 Tcl_AppendResult(interp, "bad argument \"", argv[3],
5597 "\": should be \"-command\"", (char *) NULL);
5601 return TclChannelTransform(interp, chan,
5602 Tcl_NewStringObj(argv[4], -1));
5605 if ((cmdName[0] == 'u') && (strncmp(cmdName, "unstack", len) == 0)) {
5607 * Syntax: unstack channel
5611 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
5612 " unstack channel\"", (char *) NULL);
5615 return Tcl_UnstackChannel(interp, chan);
5618 Tcl_AppendResult(interp, "bad option \"", cmdName, "\": should be ",
5619 "cut, clearchannelhandlers, info, isshared, mode, open, "
5620 "readable, splice, writable, transform, unstack",
5626 *----------------------------------------------------------------------
5628 * TestChannelEventCmd --
5630 * This procedure implements the "testchannelevent" command. It is
5631 * used to test the Tcl channel event mechanism.
5634 * A standard Tcl result.
5637 * Creates, deletes and returns channel event handlers.
5639 *----------------------------------------------------------------------
5644 TestChannelEventCmd(dummy, interp, argc, argv)
5645 ClientData dummy; /* Not used. */
5646 Tcl_Interp *interp; /* Current interpreter. */
5647 int argc; /* Number of arguments. */
5648 CONST char **argv; /* Argument strings. */
5650 Tcl_Obj *resultListPtr;
5652 ChannelState *statePtr; /* state info for channel */
5653 EventScriptRecord *esPtr, *prevEsPtr, *nextEsPtr;
5655 int index, i, mask, len;
5657 if ((argc < 3) || (argc > 5)) {
5658 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
5659 " channelName cmd ?arg1? ?arg2?\"", (char *) NULL);
5662 chanPtr = (Channel *) Tcl_GetChannel(interp, argv[1], NULL);
5663 if (chanPtr == (Channel *) NULL) {
5666 statePtr = chanPtr->state;
5670 if ((cmd[0] == 'a') && (strncmp(cmd, "add", (unsigned) len) == 0)) {
5672 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
5673 " channelName add eventSpec script\"", (char *) NULL);
5676 if (strcmp(argv[3], "readable") == 0) {
5677 mask = TCL_READABLE;
5678 } else if (strcmp(argv[3], "writable") == 0) {
5679 mask = TCL_WRITABLE;
5680 } else if (strcmp(argv[3], "none") == 0) {
5683 Tcl_AppendResult(interp, "bad event name \"", argv[3],
5684 "\": must be readable, writable, or none", (char *) NULL);
5688 esPtr = (EventScriptRecord *) ckalloc((unsigned)
5689 sizeof(EventScriptRecord));
5690 esPtr->nextPtr = statePtr->scriptRecordPtr;
5691 statePtr->scriptRecordPtr = esPtr;
5693 esPtr->chanPtr = chanPtr;
5694 esPtr->interp = interp;
5696 esPtr->scriptPtr = Tcl_NewStringObj(argv[4], -1);
5697 Tcl_IncrRefCount(esPtr->scriptPtr);
5699 Tcl_CreateChannelHandler((Tcl_Channel) chanPtr, mask,
5700 TclChannelEventScriptInvoker, (ClientData) esPtr);
5705 if ((cmd[0] == 'd') && (strncmp(cmd, "delete", (unsigned) len) == 0)) {
5707 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
5708 " channelName delete index\"", (char *) NULL);
5711 if (Tcl_GetInt(interp, argv[3], &index) == TCL_ERROR) {
5715 Tcl_AppendResult(interp, "bad event index: ", argv[3],
5716 ": must be nonnegative", (char *) NULL);
5719 for (i = 0, esPtr = statePtr->scriptRecordPtr;
5720 (i < index) && (esPtr != (EventScriptRecord *) NULL);
5721 i++, esPtr = esPtr->nextPtr) {
5722 /* Empty loop body. */
5724 if (esPtr == (EventScriptRecord *) NULL) {
5725 Tcl_AppendResult(interp, "bad event index ", argv[3],
5726 ": out of range", (char *) NULL);
5729 if (esPtr == statePtr->scriptRecordPtr) {
5730 statePtr->scriptRecordPtr = esPtr->nextPtr;
5732 for (prevEsPtr = statePtr->scriptRecordPtr;
5733 (prevEsPtr != (EventScriptRecord *) NULL) &&
5734 (prevEsPtr->nextPtr != esPtr);
5735 prevEsPtr = prevEsPtr->nextPtr) {
5736 /* Empty loop body. */
5738 if (prevEsPtr == (EventScriptRecord *) NULL) {
5739 panic("TestChannelEventCmd: damaged event script list");
5741 prevEsPtr->nextPtr = esPtr->nextPtr;
5743 Tcl_DeleteChannelHandler((Tcl_Channel) chanPtr,
5744 TclChannelEventScriptInvoker, (ClientData) esPtr);
5745 Tcl_DecrRefCount(esPtr->scriptPtr);
5746 ckfree((char *) esPtr);
5751 if ((cmd[0] == 'l') && (strncmp(cmd, "list", (unsigned) len) == 0)) {
5753 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
5754 " channelName list\"", (char *) NULL);
5757 resultListPtr = Tcl_GetObjResult(interp);
5758 for (esPtr = statePtr->scriptRecordPtr;
5759 esPtr != (EventScriptRecord *) NULL;
5760 esPtr = esPtr->nextPtr) {
5762 Tcl_ListObjAppendElement(interp, resultListPtr, Tcl_NewStringObj(
5763 (esPtr->mask == TCL_READABLE) ? "readable" : "writable", -1));
5765 Tcl_ListObjAppendElement(interp, resultListPtr,
5766 Tcl_NewStringObj("none", -1));
5768 Tcl_ListObjAppendElement(interp, resultListPtr, esPtr->scriptPtr);
5770 Tcl_SetObjResult(interp, resultListPtr);
5774 if ((cmd[0] == 'r') && (strncmp(cmd, "removeall", (unsigned) len) == 0)) {
5776 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
5777 " channelName removeall\"", (char *) NULL);
5780 for (esPtr = statePtr->scriptRecordPtr;
5781 esPtr != (EventScriptRecord *) NULL;
5782 esPtr = nextEsPtr) {
5783 nextEsPtr = esPtr->nextPtr;
5784 Tcl_DeleteChannelHandler((Tcl_Channel) chanPtr,
5785 TclChannelEventScriptInvoker, (ClientData) esPtr);
5786 Tcl_DecrRefCount(esPtr->scriptPtr);
5787 ckfree((char *) esPtr);
5789 statePtr->scriptRecordPtr = (EventScriptRecord *) NULL;
5793 if ((cmd[0] == 's') && (strncmp(cmd, "set", (unsigned) len) == 0)) {
5795 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
5796 " channelName delete index event\"", (char *) NULL);
5799 if (Tcl_GetInt(interp, argv[3], &index) == TCL_ERROR) {
5803 Tcl_AppendResult(interp, "bad event index: ", argv[3],
5804 ": must be nonnegative", (char *) NULL);
5807 for (i = 0, esPtr = statePtr->scriptRecordPtr;
5808 (i < index) && (esPtr != (EventScriptRecord *) NULL);
5809 i++, esPtr = esPtr->nextPtr) {
5810 /* Empty loop body. */
5812 if (esPtr == (EventScriptRecord *) NULL) {
5813 Tcl_AppendResult(interp, "bad event index ", argv[3],
5814 ": out of range", (char *) NULL);
5818 if (strcmp(argv[4], "readable") == 0) {
5819 mask = TCL_READABLE;
5820 } else if (strcmp(argv[4], "writable") == 0) {
5821 mask = TCL_WRITABLE;
5822 } else if (strcmp(argv[4], "none") == 0) {
5825 Tcl_AppendResult(interp, "bad event name \"", argv[4],
5826 "\": must be readable, writable, or none", (char *) NULL);
5830 Tcl_CreateChannelHandler((Tcl_Channel) chanPtr, mask,
5831 TclChannelEventScriptInvoker, (ClientData) esPtr);
5834 Tcl_AppendResult(interp, "bad command ", cmd, ", must be one of ",
5835 "add, delete, list, set, or removeall", (char *) NULL);
5840 *----------------------------------------------------------------------
5842 * TestWrongNumArgsObjCmd --
5844 * Test the Tcl_WrongNumArgs function.
5847 * Standard Tcl result.
5850 * Sets interpreter result.
5852 *----------------------------------------------------------------------
5856 TestWrongNumArgsObjCmd(dummy, interp, objc, objv)
5857 ClientData dummy; /* Not used. */
5858 Tcl_Interp *interp; /* Current interpreter. */
5859 int objc; /* Number of arguments. */
5860 Tcl_Obj *CONST objv[]; /* Argument objects. */
5867 * Don't use Tcl_WrongNumArgs here, as that is the function
5870 Tcl_SetResult(interp, "insufficient arguments", TCL_STATIC);
5874 if (Tcl_GetIntFromObj(interp, objv[1], &i) != TCL_OK) {
5878 msg = Tcl_GetStringFromObj(objv[2], &length);
5885 * Asked for more arguments than were given.
5887 Tcl_SetResult(interp, "insufficient arguments", TCL_STATIC);
5891 Tcl_WrongNumArgs(interp, i, &(objv[3]), msg);
5896 *----------------------------------------------------------------------
5898 * TestGetIndexFromObjStructObjCmd --
5900 * Test the Tcl_GetIndexFromObjStruct function.
5903 * Standard Tcl result.
5906 * Sets interpreter result.
5908 *----------------------------------------------------------------------
5912 TestGetIndexFromObjStructObjCmd(dummy, interp, objc, objv)
5913 ClientData dummy; /* Not used. */
5914 Tcl_Interp *interp; /* Current interpreter. */
5915 int objc; /* Number of arguments. */
5916 Tcl_Obj *CONST objv[]; /* Argument objects. */
5919 "a", "b", "c", "d", "e", "f", (char *)NULL,(char *)NULL
5924 Tcl_WrongNumArgs(interp, 1, objv, "argument targetvalue");
5927 if (Tcl_GetIndexFromObjStruct(interp, objv[1], ary, 2*sizeof(char *),
5928 "dummy", 0, &idx) != TCL_OK) {
5931 if (Tcl_GetIntFromObj(interp, objv[2], &target) != TCL_OK) {
5934 if (idx != target) {
5936 sprintf(buffer, "%d", idx);
5937 Tcl_AppendResult(interp, "index value comparison failed: got ",
5939 sprintf(buffer, "%d", target);
5940 Tcl_AppendResult(interp, " when ", buffer, " expected", NULL);
5943 Tcl_WrongNumArgs(interp, 3, objv, NULL);
5948 *----------------------------------------------------------------------
5950 * TestFilesystemObjCmd --
5952 * This procedure implements the "testfilesystem" command. It is
5953 * used to test Tcl_FSRegister, Tcl_FSUnregister, and can be used
5954 * to test that the pluggable filesystem works.
5957 * A standard Tcl result.
5960 * Inserts or removes a filesystem from Tcl's stack.
5962 *----------------------------------------------------------------------
5966 TestFilesystemObjCmd(dummy, interp, objc, objv)
5970 Tcl_Obj *CONST objv[];
5976 Tcl_WrongNumArgs(interp, 1, objv, "boolean");
5979 if (Tcl_GetBooleanFromObj(interp, objv[1], &boolVal) != TCL_OK) {
5983 res = Tcl_FSRegister((ClientData)interp, &testReportingFilesystem);
5984 msg = (res == TCL_OK) ? "registered" : "failed";
5986 res = Tcl_FSUnregister(&testReportingFilesystem);
5987 msg = (res == TCL_OK) ? "unregistered" : "failed";
5989 Tcl_SetResult(interp, msg, TCL_VOLATILE);
5994 TestReportInFilesystem(Tcl_Obj *pathPtr, ClientData *clientDataPtr)
5996 static Tcl_Obj* lastPathPtr = NULL;
5998 if (pathPtr == lastPathPtr) {
5999 /* Reject all files second time around */
6002 Tcl_Obj * newPathPtr;
6003 /* Try to claim all files first time around */
6005 newPathPtr = Tcl_DuplicateObj(pathPtr);
6006 lastPathPtr = newPathPtr;
6007 Tcl_IncrRefCount(newPathPtr);
6008 if (Tcl_FSGetFileSystemForPath(newPathPtr) == NULL) {
6009 /* Nothing claimed it. Therefore we don't either */
6010 Tcl_DecrRefCount(newPathPtr);
6015 *clientDataPtr = (ClientData) newPathPtr;
6022 * Simple helper function to extract the native vfs representation of a
6023 * path object, or NULL if no such representation exists.
6026 TestReportGetNativePath(Tcl_Obj* pathObjPtr) {
6027 return (Tcl_Obj*) Tcl_FSGetInternalRep(pathObjPtr, &testReportingFilesystem);
6031 TestReportFreeInternalRep(ClientData clientData) {
6032 Tcl_Obj *nativeRep = (Tcl_Obj*)clientData;
6033 if (nativeRep != NULL) {
6035 Tcl_DecrRefCount(nativeRep);
6040 TestReportDupInternalRep(ClientData clientData) {
6041 Tcl_Obj *original = (Tcl_Obj*)clientData;
6042 Tcl_IncrRefCount(original);
6047 TestReport(cmd, path, arg2)
6052 Tcl_Interp* interp = (Tcl_Interp*) Tcl_FSData(&testReportingFilesystem);
6053 if (interp == NULL) {
6054 /* This is bad, but not much we can do about it */
6057 * No idea why I decided to program this up using the
6058 * old string-based API, but there you go. We should
6059 * convert it to objects.
6061 Tcl_SavedResult savedResult;
6063 Tcl_DStringInit(&ds);
6064 Tcl_DStringAppend(&ds, "lappend filesystemReport ",-1);
6065 Tcl_DStringStartSublist(&ds);
6066 Tcl_DStringAppendElement(&ds, cmd);
6068 Tcl_DStringAppendElement(&ds, Tcl_GetString(path));
6071 Tcl_DStringAppendElement(&ds, Tcl_GetString(arg2));
6073 Tcl_DStringEndSublist(&ds);
6074 Tcl_SaveResult(interp, &savedResult);
6075 Tcl_Eval(interp, Tcl_DStringValue(&ds));
6076 Tcl_DStringFree(&ds);
6077 Tcl_RestoreResult(interp, &savedResult);
6082 TestReportStat(path, buf)
6083 Tcl_Obj *path; /* Path of file to stat (in current CP). */
6084 Tcl_StatBuf *buf; /* Filled with results of stat call. */
6086 TestReport("stat",path, NULL);
6087 return Tcl_FSStat(TestReportGetNativePath(path),buf);
6090 TestReportLstat(path, buf)
6091 Tcl_Obj *path; /* Path of file to stat (in current CP). */
6092 Tcl_StatBuf *buf; /* Filled with results of stat call. */
6094 TestReport("lstat",path, NULL);
6095 return Tcl_FSLstat(TestReportGetNativePath(path),buf);
6098 TestReportAccess(path, mode)
6099 Tcl_Obj *path; /* Path of file to access (in current CP). */
6100 int mode; /* Permission setting. */
6102 TestReport("access",path,NULL);
6103 return Tcl_FSAccess(TestReportGetNativePath(path),mode);
6106 TestReportOpenFileChannel(interp, fileName, mode, permissions)
6107 Tcl_Interp *interp; /* Interpreter for error reporting;
6109 Tcl_Obj *fileName; /* Name of file to open. */
6110 int mode; /* POSIX open mode. */
6111 int permissions; /* If the open involves creating a
6112 * file, with what modes to create
6115 TestReport("open",fileName, NULL);
6116 return TclpOpenFileChannel(interp, TestReportGetNativePath(fileName),
6121 TestReportMatchInDirectory(interp, resultPtr, dirPtr, pattern, types)
6122 Tcl_Interp *interp; /* Interpreter to receive results. */
6123 Tcl_Obj *resultPtr; /* Object to lappend results. */
6124 Tcl_Obj *dirPtr; /* Contains path to directory to search. */
6125 CONST char *pattern; /* Pattern to match against. */
6126 Tcl_GlobTypeData *types; /* Object containing list of acceptable types.
6129 if (types != NULL && types->type & TCL_GLOB_TYPE_MOUNT) {
6130 TestReport("matchmounts",dirPtr, NULL);
6133 TestReport("matchindirectory",dirPtr, NULL);
6134 return Tcl_FSMatchInDirectory(interp, resultPtr,
6135 TestReportGetNativePath(dirPtr), pattern,
6140 TestReportChdir(dirName)
6143 TestReport("chdir",dirName,NULL);
6144 return Tcl_FSChdir(TestReportGetNativePath(dirName));
6147 TestReportLoadFile(interp, fileName,
6148 handlePtr, unloadProcPtr)
6149 Tcl_Interp *interp; /* Used for error reporting. */
6150 Tcl_Obj *fileName; /* Name of the file containing the desired
6152 Tcl_LoadHandle *handlePtr; /* Filled with token for dynamically loaded
6153 * file which will be passed back to
6154 * (*unloadProcPtr)() to unload the file. */
6155 Tcl_FSUnloadFileProc **unloadProcPtr;
6156 /* Filled with address of Tcl_FSUnloadFileProc
6157 * function which should be used for
6160 TestReport("loadfile",fileName,NULL);
6161 return Tcl_FSLoadFile(interp, TestReportGetNativePath(fileName), NULL, NULL,
6162 NULL, NULL, handlePtr, unloadProcPtr);
6165 TestReportLink(path, to, linkType)
6166 Tcl_Obj *path; /* Path of file to readlink or link */
6167 Tcl_Obj *to; /* Path of file to link to, or NULL */
6170 TestReport("link",path,to);
6171 return Tcl_FSLink(TestReportGetNativePath(path), to, linkType);
6174 TestReportRenameFile(src, dst)
6175 Tcl_Obj *src; /* Pathname of file or dir to be renamed
6177 Tcl_Obj *dst; /* New pathname of file or directory
6180 TestReport("renamefile",src,dst);
6181 return Tcl_FSRenameFile(TestReportGetNativePath(src),
6182 TestReportGetNativePath(dst));
6185 TestReportCopyFile(src, dst)
6186 Tcl_Obj *src; /* Pathname of file to be copied (UTF-8). */
6187 Tcl_Obj *dst; /* Pathname of file to copy to (UTF-8). */
6189 TestReport("copyfile",src,dst);
6190 return Tcl_FSCopyFile(TestReportGetNativePath(src),
6191 TestReportGetNativePath(dst));
6194 TestReportDeleteFile(path)
6195 Tcl_Obj *path; /* Pathname of file to be removed (UTF-8). */
6197 TestReport("deletefile",path,NULL);
6198 return Tcl_FSDeleteFile(TestReportGetNativePath(path));
6201 TestReportCreateDirectory(path)
6202 Tcl_Obj *path; /* Pathname of directory to create (UTF-8). */
6204 TestReport("createdirectory",path,NULL);
6205 return Tcl_FSCreateDirectory(TestReportGetNativePath(path));
6208 TestReportCopyDirectory(src, dst, errorPtr)
6209 Tcl_Obj *src; /* Pathname of directory to be copied
6211 Tcl_Obj *dst; /* Pathname of target directory (UTF-8). */
6212 Tcl_Obj **errorPtr; /* If non-NULL, to be filled with UTF-8 name
6213 * of file causing error. */
6215 TestReport("copydirectory",src,dst);
6216 return Tcl_FSCopyDirectory(TestReportGetNativePath(src),
6217 TestReportGetNativePath(dst), errorPtr);
6220 TestReportRemoveDirectory(path, recursive, errorPtr)
6221 Tcl_Obj *path; /* Pathname of directory to be removed
6223 int recursive; /* If non-zero, removes directories that
6224 * are nonempty. Otherwise, will only remove
6225 * empty directories. */
6226 Tcl_Obj **errorPtr; /* If non-NULL, to be filled with UTF-8 name
6227 * of file causing error. */
6229 TestReport("removedirectory",path,NULL);
6230 return Tcl_FSRemoveDirectory(TestReportGetNativePath(path), recursive,
6234 TestReportFileAttrStrings(fileName, objPtrRef)
6236 Tcl_Obj** objPtrRef;
6238 TestReport("fileattributestrings",fileName,NULL);
6239 return Tcl_FSFileAttrStrings(TestReportGetNativePath(fileName), objPtrRef);
6242 TestReportFileAttrsGet(interp, index, fileName, objPtrRef)
6243 Tcl_Interp *interp; /* The interpreter for error reporting. */
6244 int index; /* index of the attribute command. */
6245 Tcl_Obj *fileName; /* filename we are operating on. */
6246 Tcl_Obj **objPtrRef; /* for output. */
6248 TestReport("fileattributesget",fileName,NULL);
6249 return Tcl_FSFileAttrsGet(interp, index,
6250 TestReportGetNativePath(fileName), objPtrRef);
6253 TestReportFileAttrsSet(interp, index, fileName, objPtr)
6254 Tcl_Interp *interp; /* The interpreter for error reporting. */
6255 int index; /* index of the attribute command. */
6256 Tcl_Obj *fileName; /* filename we are operating on. */
6257 Tcl_Obj *objPtr; /* for input. */
6259 TestReport("fileattributesset",fileName,objPtr);
6260 return Tcl_FSFileAttrsSet(interp, index,
6261 TestReportGetNativePath(fileName), objPtr);
6264 TestReportUtime (fileName, tval)
6266 struct utimbuf *tval;
6268 TestReport("utime",fileName,NULL);
6269 return Tcl_FSUtime(TestReportGetNativePath(fileName), tval);
6272 TestReportNormalizePath(interp, pathPtr, nextCheckpoint)
6277 TestReport("normalizepath",pathPtr,NULL);
6278 return nextCheckpoint;
6282 SimplePathInFilesystem(Tcl_Obj *pathPtr, ClientData *clientDataPtr) {
6283 CONST char *str = Tcl_GetString(pathPtr);
6284 if (strncmp(str,"simplefs:/",10)) {
6291 * Since TclCopyChannel insists on an interpreter, we use this
6292 * to simplify our test scripts. Would be better if it could
6293 * copy without an interp
6295 static Tcl_Interp *simpleInterpPtr = NULL;
6296 /* We use this to ensure we clean up after ourselves */
6297 static Tcl_Obj *tempFile = NULL;
6300 * This is a very 'hacky' filesystem which is used just to
6301 * test two important features of the vfs code: (1) that
6302 * you can load a shared library from a vfs, (2) that when
6303 * copying files from one fs to another, the 'mtime' is
6306 * It treats any file in 'simplefs:/' as a file, and
6307 * artificially creates a real file on the fly which it uses
6308 * to extract information from. The real file it uses is
6309 * whatever follows the trailing '/' (e.g. 'foo' in 'simplefs:/foo'),
6310 * and that file is assumed to exist in the native pwd, and is
6311 * copied over to the native temporary directory where it is
6314 * Please do not consider this filesystem a model of how
6315 * things are to be done. It is quite the opposite! But, it
6316 * does allow us to test two important features.
6318 * Finally: this fs can only be used from one interpreter.
6321 TestSimpleFilesystemObjCmd(dummy, interp, objc, objv)
6325 Tcl_Obj *CONST objv[];
6331 Tcl_WrongNumArgs(interp, 1, objv, "boolean");
6334 if (Tcl_GetBooleanFromObj(interp, objv[1], &boolVal) != TCL_OK) {
6338 res = Tcl_FSRegister((ClientData)interp, &simpleFilesystem);
6339 msg = (res == TCL_OK) ? "registered" : "failed";
6340 simpleInterpPtr = interp;
6342 if (tempFile != NULL) {
6343 Tcl_FSDeleteFile(tempFile);
6344 Tcl_DecrRefCount(tempFile);
6347 res = Tcl_FSUnregister(&simpleFilesystem);
6348 msg = (res == TCL_OK) ? "unregistered" : "failed";
6349 simpleInterpPtr = NULL;
6351 Tcl_SetResult(interp, msg, TCL_VOLATILE);
6356 * Treats a file name 'simplefs:/foo' by copying the file 'foo'
6357 * in the current (native) directory to a temporary native file,
6358 * and then returns that native file.
6362 Tcl_Obj *pathPtr; /* Name of file to copy. */
6369 tempPtr = TclpTempFileName();
6370 Tcl_IncrRefCount(tempPtr);
6373 * We assume the same name in the current directory is ok.
6375 str = Tcl_GetString(pathPtr);
6376 origPtr = Tcl_NewStringObj(str+10,-1);
6377 Tcl_IncrRefCount(origPtr);
6379 res = TclCrossFilesystemCopy(simpleInterpPtr, origPtr, tempPtr);
6380 Tcl_DecrRefCount(origPtr);
6382 if (res != TCL_OK) {
6383 Tcl_FSDeleteFile(tempPtr);
6384 Tcl_DecrRefCount(tempPtr);
6391 SimpleOpenFileChannel(interp, pathPtr, mode, permissions)
6392 Tcl_Interp *interp; /* Interpreter for error reporting;
6394 Tcl_Obj *pathPtr; /* Name of file to open. */
6395 int mode; /* POSIX open mode. */
6396 int permissions; /* If the open involves creating a
6397 * file, with what modes to create
6403 if ((mode != 0) && !(mode & O_RDONLY)) {
6404 Tcl_AppendResult(interp, "read-only",
6409 tempPtr = SimpleCopy(pathPtr);
6411 if (tempPtr == NULL) {
6415 chan = Tcl_FSOpenFileChannel(interp, tempPtr, "r", permissions);
6417 if (tempFile != NULL) {
6418 Tcl_FSDeleteFile(tempFile);
6419 Tcl_DecrRefCount(tempFile);
6423 * Store file pointer in this global variable so we can delete
6431 SimpleAccess(pathPtr, mode)
6432 Tcl_Obj *pathPtr; /* Path of file to access (in current CP). */
6433 int mode; /* Permission setting. */
6435 /* All files exist */
6440 SimpleStat(pathPtr, bufPtr)
6441 Tcl_Obj *pathPtr; /* Path of file to stat (in current CP). */
6442 Tcl_StatBuf *bufPtr; /* Filled with results of stat call. */
6444 Tcl_Obj *tempPtr = SimpleCopy(pathPtr);
6445 if (tempPtr == NULL) {
6446 /* We just pretend the file exists anyway */
6449 int res = Tcl_FSStat(tempPtr, bufPtr);
6450 Tcl_FSDeleteFile(tempPtr);
6451 Tcl_DecrRefCount(tempPtr);
6457 SimpleListVolumes(void)
6459 /* Add one new volume */
6462 retVal = Tcl_NewStringObj("simplefs:/",-1);
6463 Tcl_IncrRefCount(retVal);
6468 * Used to check correct string-length determining in Tcl_NumUtfChars
6471 TestNumUtfCharsCmd(clientData, interp, objc, objv)
6472 ClientData clientData;
6475 Tcl_Obj *CONST objv[];
6480 (void) Tcl_GetStringFromObj(objv[1], &len);
6482 len = Tcl_NumUtfChars(Tcl_GetString(objv[1]), len);
6483 Tcl_SetObjResult(interp, Tcl_NewIntObj(len));