home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume25 / tcl / part20 < prev    next >
Encoding:
Text File  |  1991-11-15  |  31.9 KB  |  1,197 lines

  1. Newsgroups: comp.sources.misc
  2. From: karl@sugar.neosoft.com (Karl Lehenbauer)
  3. Subject:  v25i088:  tcl - tool command language, version 6.1, Part20/33
  4. Message-ID: <1991Nov15.224922.20998@sparky.imd.sterling.com>
  5. X-Md4-Signature: 622600ff92f14e7f0e366ae3380f4c4d
  6. Date: Fri, 15 Nov 1991 22:49:22 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: karl@sugar.neosoft.com (Karl Lehenbauer)
  10. Posting-number: Volume 25, Issue 88
  11. Archive-name: tcl/part20
  12. Environment: UNIX
  13.  
  14. #! /bin/sh
  15. # This is a shell archive.  Remove anything before this line, then unpack
  16. # it by saving it into a file and typing "sh file".  To overwrite existing
  17. # files, type "sh file -c".  You can also feed this as standard input via
  18. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  19. # will see the following message at the end:
  20. #        "End of archive 20 (of 33)."
  21. # Contents:  tcl6.1/tclCmdIL.c
  22. # Wrapped by karl@one on Tue Nov 12 19:44:27 1991
  23. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  24. if test -f 'tcl6.1/tclCmdIL.c' -a "${1}" != "-c" ; then 
  25.   echo shar: Will not clobber existing file \"'tcl6.1/tclCmdIL.c'\"
  26. else
  27. echo shar: Extracting \"'tcl6.1/tclCmdIL.c'\" \(29320 characters\)
  28. sed "s/^X//" >'tcl6.1/tclCmdIL.c' <<'END_OF_FILE'
  29. X/* 
  30. X * tclCmdIL.c --
  31. X *
  32. X *    This file contains the top-level command routines for most of
  33. X *    the Tcl built-in commands whose names begin with the letters
  34. X *    I through L.  It contains only commands in the generic core
  35. X *    (i.e. those that don't depend much upon UNIX facilities).
  36. X *
  37. X * Copyright 1987-1991 Regents of the University of California
  38. X * Permission to use, copy, modify, and distribute this
  39. X * software and its documentation for any purpose and without
  40. X * fee is hereby granted, provided that the above copyright
  41. X * notice appear in all copies.  The University of California
  42. X * makes no representations about the suitability of this
  43. X * software for any purpose.  It is provided "as is" without
  44. X * express or implied warranty.
  45. X */
  46. X
  47. X#ifndef lint
  48. Xstatic char rcsid[] = "$Header: /user6/ouster/tcl/RCS/tclCmdIL.c,v 1.82 91/10/31 16:41:50 ouster Exp $ SPRITE (Berkeley)";
  49. X#endif
  50. X
  51. X#include "tclInt.h"
  52. X
  53. X/*
  54. X * Forward declarations for procedures defined in this file:
  55. X */
  56. X
  57. Xstatic int        SortCompareProc _ANSI_ARGS_((CONST char *first,
  58. X                CONST char *second));
  59. X
  60. X/*
  61. X *----------------------------------------------------------------------
  62. X *
  63. X * Tcl_IfCmd --
  64. X *
  65. X *    This procedure is invoked to process the "if" Tcl command.
  66. X *    See the user documentation for details on what it does.
  67. X *
  68. X * Results:
  69. X *    A standard Tcl result.
  70. X *
  71. X * Side effects:
  72. X *    See the user documentation.
  73. X *
  74. X *----------------------------------------------------------------------
  75. X */
  76. X
  77. X    /* ARGSUSED */
  78. Xint
  79. XTcl_IfCmd(dummy, interp, argc, argv)
  80. X    ClientData dummy;            /* Not used. */
  81. X    Tcl_Interp *interp;            /* Current interpreter. */
  82. X    int argc;                /* Number of arguments. */
  83. X    char **argv;            /* Argument strings. */
  84. X{
  85. X    char *condition, *ifPart, *elsePart, *cmd, *name;
  86. X    char *clause;
  87. X    int result, value;
  88. X
  89. X    name = argv[0];
  90. X    if (argc < 3) {
  91. X    ifSyntax:
  92. X    Tcl_AppendResult(interp, "wrong # args: should be \"", name,
  93. X        " bool ?then? command ?else? ?command?\"", (char *) NULL);
  94. X    return TCL_ERROR;
  95. X    }
  96. X    condition = argv[1];
  97. X    argc -= 2;
  98. X    argv += 2;
  99. X    if ((**argv == 't') && (strncmp(*argv, "then", strlen(*argv)) == 0)) {
  100. X    argc--;
  101. X    argv++;
  102. X    }
  103. X    if (argc < 1) {
  104. X    goto ifSyntax;
  105. X    }
  106. X    ifPart = *argv;
  107. X    argv++;
  108. X    argc--;
  109. X    if (argc == 0) {
  110. X    elsePart = "";
  111. X    } else {
  112. X    if ((**argv == 'e') && (strncmp(*argv, "else", strlen(*argv)) == 0)) {
  113. X        argc--;
  114. X        argv++;
  115. X    }
  116. X    if (argc != 1) {
  117. X        goto ifSyntax;
  118. X    }
  119. X    elsePart = *argv;
  120. X    }
  121. X
  122. X    cmd = ifPart;
  123. X    clause = "\"then\" clause";
  124. X    result = Tcl_ExprBoolean(interp, condition, &value);
  125. X    if (result != TCL_OK) {
  126. X    if (result == TCL_ERROR) {
  127. X        char msg[60];
  128. X        sprintf(msg, "\n    (\"if\" test line %d)", interp->errorLine);
  129. X        Tcl_AddErrorInfo(interp, msg);
  130. X    }
  131. X    return result;
  132. X    }
  133. X    if (value == 0) {
  134. X    cmd = elsePart;
  135. X    clause = "\"else\" clause";
  136. X    }
  137. X    if (*cmd == 0) {
  138. X    return TCL_OK;
  139. X    }
  140. X    result = Tcl_Eval(interp, cmd, 0, (char **) NULL);
  141. X    if (result == TCL_ERROR) {
  142. X    char msg[60];
  143. X    sprintf(msg, "\n    (%s line %d)", clause, interp->errorLine);
  144. X    Tcl_AddErrorInfo(interp, msg);
  145. X    }
  146. X    return result;
  147. X}
  148. X
  149. X/*
  150. X *----------------------------------------------------------------------
  151. X *
  152. X * Tcl_IncrCmd --
  153. X *
  154. X *    This procedure is invoked to process the "incr" Tcl command.
  155. X *    See the user documentation for details on what it does.
  156. X *
  157. X * Results:
  158. X *    A standard Tcl result.
  159. X *
  160. X * Side effects:
  161. X *    See the user documentation.
  162. X *
  163. X *----------------------------------------------------------------------
  164. X */
  165. X
  166. X    /* ARGSUSED */
  167. Xint
  168. XTcl_IncrCmd(dummy, interp, argc, argv)
  169. X    ClientData dummy;            /* Not used. */
  170. X    Tcl_Interp *interp;            /* Current interpreter. */
  171. X    int argc;                /* Number of arguments. */
  172. X    char **argv;            /* Argument strings. */
  173. X{
  174. X    int value;
  175. X    char *oldString, *result;
  176. X    char newString[30];
  177. X
  178. X    if ((argc != 2) && (argc != 3)) {
  179. X    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
  180. X        " varName ?increment?\"", (char *) NULL);
  181. X    return TCL_ERROR;
  182. X    }
  183. X
  184. X    oldString = Tcl_GetVar(interp, argv[1], TCL_LEAVE_ERR_MSG);
  185. X    if (oldString == NULL) {
  186. X    return TCL_ERROR;
  187. X    }
  188. X    if (Tcl_GetInt(interp, oldString, &value) != TCL_OK) {
  189. X    Tcl_AddErrorInfo(interp,
  190. X        "\n    (reading value of variable to increment)");
  191. X    return TCL_ERROR;
  192. X    }
  193. X    if (argc == 2) {
  194. X    value += 1;
  195. X    } else {
  196. X    int increment;
  197. X
  198. X    if (Tcl_GetInt(interp, argv[2], &increment) != TCL_OK) {
  199. X        Tcl_AddErrorInfo(interp,
  200. X            "\n    (reading increment)");
  201. X        return TCL_ERROR;
  202. X    }
  203. X    value += increment;
  204. X    }
  205. X    sprintf(newString, "%d", value);
  206. X    result = Tcl_SetVar(interp, argv[1], newString, TCL_LEAVE_ERR_MSG);
  207. X    if (result == NULL) {
  208. X    return TCL_ERROR;
  209. X    }
  210. X    interp->result = result;
  211. X    return TCL_OK; 
  212. X}
  213. X
  214. X/*
  215. X *----------------------------------------------------------------------
  216. X *
  217. X * Tcl_InfoCmd --
  218. X *
  219. X *    This procedure is invoked to process the "info" Tcl command.
  220. X *    See the user documentation for details on what it does.
  221. X *
  222. X * Results:
  223. X *    A standard Tcl result.
  224. X *
  225. X * Side effects:
  226. X *    See the user documentation.
  227. X *
  228. X *----------------------------------------------------------------------
  229. X */
  230. X
  231. X    /* ARGSUSED */
  232. Xint
  233. XTcl_InfoCmd(dummy, interp, argc, argv)
  234. X    ClientData dummy;            /* Not used. */
  235. X    Tcl_Interp *interp;            /* Current interpreter. */
  236. X    int argc;                /* Number of arguments. */
  237. X    char **argv;            /* Argument strings. */
  238. X{
  239. X    register Interp *iPtr = (Interp *) interp;
  240. X    int length;
  241. X    char c;
  242. X    Arg *argPtr;
  243. X    Proc *procPtr;
  244. X    Var *varPtr;
  245. X    Command *cmdPtr;
  246. X    Tcl_HashEntry *hPtr;
  247. X    Tcl_HashSearch search;
  248. X
  249. X    if (argc < 2) {
  250. X    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
  251. X        " option ?arg arg ...?\"", (char *) NULL);
  252. X    return TCL_ERROR;
  253. X    }
  254. X    c = argv[1][0];
  255. X    length = strlen(argv[1]);
  256. X    if ((c == 'a') && (strncmp(argv[1], "args", length)) == 0) {
  257. X    if (argc != 3) {
  258. X        Tcl_AppendResult(interp, "wrong # args: should be \"",
  259. X            argv[0], " args procname\"", (char *) NULL);
  260. X        return TCL_ERROR;
  261. X    }
  262. X    procPtr = TclFindProc(iPtr, argv[2]);
  263. X    if (procPtr == NULL) {
  264. X        infoNoSuchProc:
  265. X        Tcl_AppendResult(interp, "\"", argv[2],
  266. X            "\" isn't a procedure", (char *) NULL);
  267. X        return TCL_ERROR;
  268. X    }
  269. X    for (argPtr = procPtr->argPtr; argPtr != NULL;
  270. X        argPtr = argPtr->nextPtr) {
  271. X        Tcl_AppendElement(interp, argPtr->name, 0);
  272. X    }
  273. X    return TCL_OK;
  274. X    } else if ((c == 'b') && (strncmp(argv[1], "body", length)) == 0) {
  275. X    if (argc != 3) {
  276. X        Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
  277. X            " body procname\"", (char *) NULL);
  278. X        return TCL_ERROR;
  279. X    }
  280. X    procPtr = TclFindProc(iPtr, argv[2]);
  281. X    if (procPtr == NULL) {
  282. X        goto infoNoSuchProc;
  283. X    }
  284. X    iPtr->result = procPtr->command;
  285. X    return TCL_OK;
  286. X    } else if ((c == 'c') && (strncmp(argv[1], "cmdcount", length) == 0)
  287. X        && (length >= 2)) {
  288. X    if (argc != 2) {
  289. X        Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
  290. X            " cmdcount\"", (char *) NULL);
  291. X        return TCL_ERROR;
  292. X    }
  293. X    sprintf(iPtr->result, "%d", iPtr->cmdCount);
  294. X    return TCL_OK;
  295. X    } else if ((c == 'c') && (strncmp(argv[1], "commands", length) == 0)
  296. X        && (length >= 2)){
  297. X    if (argc > 3) {
  298. X        Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
  299. X            " commands [pattern]\"", (char *) NULL);
  300. X        return TCL_ERROR;
  301. X    }
  302. X    for (hPtr = Tcl_FirstHashEntry(&iPtr->commandTable, &search);
  303. X        hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
  304. X        char *name = Tcl_GetHashKey(&iPtr->commandTable, hPtr);
  305. X        if ((argc == 3) && !Tcl_StringMatch(name, argv[2])) {
  306. X        continue;
  307. X        }
  308. X        Tcl_AppendElement(interp, name, 0);
  309. X    }
  310. X    return TCL_OK;
  311. X    } else if ((c == 'd') && (strncmp(argv[1], "default", length)) == 0) {
  312. X    if (argc != 5) {
  313. X        Tcl_AppendResult(interp, "wrong # args: should be \"",
  314. X            argv[0], " default procname arg varname\"",
  315. X            (char *) NULL);
  316. X        return TCL_ERROR;
  317. X    }
  318. X    procPtr = TclFindProc(iPtr, argv[2]);
  319. X    if (procPtr == NULL) {
  320. X        goto infoNoSuchProc;
  321. X    }
  322. X    for (argPtr = procPtr->argPtr; ; argPtr = argPtr->nextPtr) {
  323. X        if (argPtr == NULL) {
  324. X        Tcl_AppendResult(interp, "procedure \"", argv[2],
  325. X            "\" doesn't have an argument \"", argv[3],
  326. X            "\"", (char *) NULL);
  327. X        return TCL_ERROR;
  328. X        }
  329. X        if (strcmp(argv[3], argPtr->name) == 0) {
  330. X        if (argPtr->defValue != NULL) {
  331. X            if (Tcl_SetVar((Tcl_Interp *) iPtr, argv[4],
  332. X                argPtr->defValue, 0) == NULL) {
  333. X            defStoreError:
  334. X            Tcl_AppendResult(interp,
  335. X                "couldn't store default value in variable \"",
  336. X                argv[4], "\"", (char *) NULL);
  337. X            return TCL_ERROR;
  338. X            }
  339. X            iPtr->result = "1";
  340. X        } else {
  341. X            if (Tcl_SetVar((Tcl_Interp *) iPtr, argv[4], "", 0)
  342. X                == NULL) {
  343. X            goto defStoreError;
  344. X            }
  345. X            iPtr->result = "0";
  346. X        }
  347. X        return TCL_OK;
  348. X        }
  349. X    }
  350. X    } else if ((c == 'e') && (strncmp(argv[1], "exists", length) == 0)) {
  351. X    char *p;
  352. X    if (argc != 3) {
  353. X        Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
  354. X            " exists varName\"", (char *) NULL);
  355. X        return TCL_ERROR;
  356. X    }
  357. X    p = Tcl_GetVar((Tcl_Interp *) iPtr, argv[2], 0);
  358. X
  359. X    /*
  360. X     * The code below handles the special case where the name is for
  361. X     * an array:  Tcl_GetVar will reject this since you can't read
  362. X     * an array variable without an index.
  363. X     */
  364. X
  365. X    if (p == NULL) {
  366. X        Tcl_HashEntry *hPtr;
  367. X        Var *varPtr;
  368. X
  369. X        if (strchr(argv[2], '(') != NULL) {
  370. X        noVar:
  371. X        iPtr->result = "0";
  372. X        return TCL_OK;
  373. X        }
  374. X        if (iPtr->varFramePtr == NULL) {
  375. X        hPtr = Tcl_FindHashEntry(&iPtr->globalTable, argv[2]);
  376. X        } else {
  377. X        hPtr = Tcl_FindHashEntry(&iPtr->varFramePtr->varTable, argv[2]);
  378. X        }
  379. X        if (hPtr == NULL) {
  380. X        goto noVar;
  381. X        }
  382. X        varPtr = (Var *) Tcl_GetHashValue(hPtr);
  383. X        if (varPtr->flags & VAR_UPVAR) {
  384. X        varPtr = (Var *) Tcl_GetHashValue(varPtr->value.upvarPtr);
  385. X        }
  386. X        if (!(varPtr->flags & VAR_ARRAY)) {
  387. X        goto noVar;
  388. X        }
  389. X    }
  390. X    iPtr->result = "1";
  391. X    return TCL_OK;
  392. X    } else if ((c == 'g') && (strncmp(argv[1], "globals", length) == 0)) {
  393. X    char *name;
  394. X
  395. X    if (argc > 3) {
  396. X        Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
  397. X            " globals [pattern]\"", (char *) NULL);
  398. X        return TCL_ERROR;
  399. X    }
  400. X    for (hPtr = Tcl_FirstHashEntry(&iPtr->globalTable, &search);
  401. X        hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
  402. X        varPtr = (Var *) Tcl_GetHashValue(hPtr);
  403. X        if (varPtr->flags & VAR_UNDEFINED) {
  404. X        continue;
  405. X        }
  406. X        name = Tcl_GetHashKey(&iPtr->globalTable, hPtr);
  407. X        if ((argc == 3) && !Tcl_StringMatch(name, argv[2])) {
  408. X        continue;
  409. X        }
  410. X        Tcl_AppendElement(interp, name, 0);
  411. X    }
  412. X    return TCL_OK;
  413. X    } else if ((c == 'l') && (strncmp(argv[1], "level", length) == 0)
  414. X        && (length >= 2)) {
  415. X    if (argc == 2) {
  416. X        if (iPtr->varFramePtr == NULL) {
  417. X        iPtr->result = "0";
  418. X        } else {
  419. X        sprintf(iPtr->result, "%d", iPtr->varFramePtr->level);
  420. X        }
  421. X        return TCL_OK;
  422. X    } else if (argc == 3) {
  423. X        int level;
  424. X        CallFrame *framePtr;
  425. X
  426. X        if (Tcl_GetInt(interp, argv[2], &level) != TCL_OK) {
  427. X        return TCL_ERROR;
  428. X        }
  429. X        if (level <= 0) {
  430. X        if (iPtr->varFramePtr == NULL) {
  431. X            levelError:
  432. X            Tcl_AppendResult(interp, "bad level \"", argv[2],
  433. X                "\"", (char *) NULL);
  434. X            return TCL_ERROR;
  435. X        }
  436. X        level += iPtr->varFramePtr->level;
  437. X        }
  438. X        for (framePtr = iPtr->varFramePtr; framePtr != NULL;
  439. X            framePtr = framePtr->callerVarPtr) {
  440. X        if (framePtr->level == level) {
  441. X            break;
  442. X        }
  443. X        }
  444. X        if (framePtr == NULL) {
  445. X        goto levelError;
  446. X        }
  447. X        iPtr->result = Tcl_Merge(framePtr->argc, framePtr->argv);
  448. X        iPtr->freeProc = (Tcl_FreeProc *) free;
  449. X        return TCL_OK;
  450. X    }
  451. X    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
  452. X        " level [number]\"", (char *) NULL);
  453. X    return TCL_ERROR;
  454. X    } else if ((c == 'l') && (strncmp(argv[1], "library", length) == 0)
  455. X        && (length >= 2)) {
  456. X    if (argc != 2) {
  457. X        Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
  458. X            " library\"", (char *) NULL);
  459. X        return TCL_ERROR;
  460. X    }
  461. X#ifdef TCL_LIBRARY
  462. X    interp->result = TCL_LIBRARY;
  463. X    return TCL_OK;
  464. X#else
  465. X    interp->result = "there is no Tcl library at this installation";
  466. X    return TCL_ERROR;
  467. X#endif
  468. X    } else if ((c == 'l') && (strncmp(argv[1], "locals", length) == 0)
  469. X        && (length >= 2)) {
  470. X    char *name;
  471. X
  472. X    if (argc > 3) {
  473. X        Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
  474. X            " locals [pattern]\"", (char *) NULL);
  475. X        return TCL_ERROR;
  476. X    }
  477. X    if (iPtr->varFramePtr == NULL) {
  478. X        return TCL_OK;
  479. X    }
  480. X    for (hPtr = Tcl_FirstHashEntry(&iPtr->varFramePtr->varTable, &search);
  481. X        hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
  482. X        varPtr = (Var *) Tcl_GetHashValue(hPtr);
  483. X        if (varPtr->flags & (VAR_UNDEFINED|VAR_UPVAR)) {
  484. X        continue;
  485. X        }
  486. X        name = Tcl_GetHashKey(&iPtr->varFramePtr->varTable, hPtr);
  487. X        if ((argc == 3) && !Tcl_StringMatch(name, argv[2])) {
  488. X        continue;
  489. X        }
  490. X        Tcl_AppendElement(interp, name, 0);
  491. X    }
  492. X    return TCL_OK;
  493. X    } else if ((c == 'p') && (strncmp(argv[1], "procs", length)) == 0) {
  494. X    if (argc > 3) {
  495. X        Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
  496. X            " procs [pattern]\"", (char *) NULL);
  497. X        return TCL_ERROR;
  498. X    }
  499. X    for (hPtr = Tcl_FirstHashEntry(&iPtr->commandTable, &search);
  500. X        hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
  501. X        char *name = Tcl_GetHashKey(&iPtr->commandTable, hPtr);
  502. X
  503. X        cmdPtr = (Command *) Tcl_GetHashValue(hPtr);
  504. X        if (!TclIsProc(cmdPtr)) {
  505. X        continue;
  506. X        }
  507. X        if ((argc == 3) && !Tcl_StringMatch(name, argv[2])) {
  508. X        continue;
  509. X        }
  510. X        Tcl_AppendElement(interp, name, 0);
  511. X    }
  512. X    return TCL_OK;
  513. X    } else if ((c == 's') && (strncmp(argv[1], "script", length) == 0)) {
  514. X    if (argc != 2) {
  515. X        Tcl_AppendResult(interp, "wrong # args: should be \"",
  516. X            argv[0], " script\"", (char *) NULL);
  517. X        return TCL_ERROR;
  518. X    }
  519. X    if (iPtr->scriptFile != NULL) {
  520. X        interp->result = iPtr->scriptFile;
  521. X    }
  522. X    return TCL_OK;
  523. X    } else if ((c == 't') && (strncmp(argv[1], "tclversion", length) == 0)) {
  524. X    if (argc != 2) {
  525. X        Tcl_AppendResult(interp, "wrong # args: should be \"",
  526. X            argv[0], " tclversion\"", (char *) NULL);
  527. X        return TCL_ERROR;
  528. X    }
  529. X
  530. X    /*
  531. X     * Note:  TCL_VERSION below is expected to be set with a "-D"
  532. X     * switch in the Makefile.
  533. X     */
  534. X
  535. X    strcpy(iPtr->result, TCL_VERSION);
  536. X    return TCL_OK;
  537. X    } else if ((c == 'v') && (strncmp(argv[1], "vars", length)) == 0) {
  538. X    Tcl_HashTable *tablePtr;
  539. X    char *name;
  540. X
  541. X    if (argc > 3) {
  542. X        Tcl_AppendResult(interp, "wrong # args: should be \"",
  543. X            argv[0], " vars [pattern]\"", (char *) NULL);
  544. X        return TCL_ERROR;
  545. X    }
  546. X    if (iPtr->varFramePtr == NULL) {
  547. X        tablePtr = &iPtr->globalTable;
  548. X    } else {
  549. X        tablePtr = &iPtr->varFramePtr->varTable;
  550. X    }
  551. X    for (hPtr = Tcl_FirstHashEntry(tablePtr, &search);
  552. X        hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
  553. X        varPtr = (Var *) Tcl_GetHashValue(hPtr);
  554. X        if (varPtr->flags & VAR_UNDEFINED) {
  555. X        continue;
  556. X        }
  557. X        name = Tcl_GetHashKey(tablePtr, hPtr);
  558. X        if ((argc == 3) && !Tcl_StringMatch(name, argv[2])) {
  559. X        continue;
  560. X        }
  561. X        Tcl_AppendElement(interp, name, 0);
  562. X    }
  563. X    return TCL_OK;
  564. X    } else {
  565. X    Tcl_AppendResult(interp, "bad option \"", argv[1],
  566. X        "\": should be args, body, commands, cmdcount, default, ",
  567. X        "exists, globals, level, library, locals, procs, ",
  568. X        "script, tclversion, or vars",
  569. X        (char *) NULL);
  570. X    return TCL_ERROR;
  571. X    }
  572. X}
  573. X
  574. X/*
  575. X *----------------------------------------------------------------------
  576. X *
  577. X * Tcl_JoinCmd --
  578. X *
  579. X *    This procedure is invoked to process the "join" Tcl command.
  580. X *    See the user documentation for details on what it does.
  581. X *
  582. X * Results:
  583. X *    A standard Tcl result.
  584. X *
  585. X * Side effects:
  586. X *    See the user documentation.
  587. X *
  588. X *----------------------------------------------------------------------
  589. X */
  590. X
  591. X    /* ARGSUSED */
  592. Xint
  593. XTcl_JoinCmd(dummy, interp, argc, argv)
  594. X    ClientData dummy;            /* Not used. */
  595. X    Tcl_Interp *interp;            /* Current interpreter. */
  596. X    int argc;                /* Number of arguments. */
  597. X    char **argv;            /* Argument strings. */
  598. X{
  599. X    char *joinString;
  600. X    char **listArgv;
  601. X    int listArgc, i;
  602. X
  603. X    if (argc == 2) {
  604. X    joinString = " ";
  605. X    } else if (argc == 3) {
  606. X    joinString = argv[2];
  607. X    } else {
  608. X    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
  609. X        " list ?joinString?\"", (char *) NULL);
  610. X    return TCL_ERROR;
  611. X    }
  612. X
  613. X    if (Tcl_SplitList(interp, argv[1], &listArgc, &listArgv) != TCL_OK) {
  614. X    return TCL_ERROR;
  615. X    }
  616. X    for (i = 0; i < listArgc; i++) {
  617. X    if (i == 0) {
  618. X        Tcl_AppendResult(interp, listArgv[0], (char *) NULL);
  619. X    } else  {
  620. X        Tcl_AppendResult(interp, joinString, listArgv[i], (char *) NULL);
  621. X    }
  622. X    }
  623. X    ckfree((char *) listArgv);
  624. X    return TCL_OK;
  625. X}
  626. X
  627. X/*
  628. X *----------------------------------------------------------------------
  629. X *
  630. X * Tcl_LindexCmd --
  631. X *
  632. X *    This procedure is invoked to process the "lindex" Tcl command.
  633. X *    See the user documentation for details on what it does.
  634. X *
  635. X * Results:
  636. X *    A standard Tcl result.
  637. X *
  638. X * Side effects:
  639. X *    See the user documentation.
  640. X *
  641. X *----------------------------------------------------------------------
  642. X */
  643. X
  644. X    /* ARGSUSED */
  645. Xint
  646. XTcl_LindexCmd(dummy, interp, argc, argv)
  647. X    ClientData dummy;            /* Not used. */
  648. X    Tcl_Interp *interp;            /* Current interpreter. */
  649. X    int argc;                /* Number of arguments. */
  650. X    char **argv;            /* Argument strings. */
  651. X{
  652. X    char *p, *element;
  653. X    int index, size, parenthesized, result;
  654. X
  655. X    if (argc != 3) {
  656. X    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
  657. X        " list index\"", (char *) NULL);
  658. X    return TCL_ERROR;
  659. X    }
  660. X    if (Tcl_GetInt(interp, argv[2], &index) != TCL_OK) {
  661. X    return TCL_ERROR;
  662. X    }
  663. X    if (index < 0) {
  664. X    return TCL_OK;
  665. X    }
  666. X    for (p = argv[1] ; index >= 0; index--) {
  667. X    result = TclFindElement(interp, p, &element, &p, &size,
  668. X        &parenthesized);
  669. X    if (result != TCL_OK) {
  670. X        return result;
  671. X    }
  672. X    }
  673. X    if (size == 0) {
  674. X    return TCL_OK;
  675. X    }
  676. X    if (size >= TCL_RESULT_SIZE) {
  677. X    interp->result = (char *) ckalloc((unsigned) size+1);
  678. X    interp->freeProc = (Tcl_FreeProc *) free;
  679. X    }
  680. X    if (parenthesized) {
  681. X    memcpy((VOID *) interp->result, (VOID *) element, size);
  682. X    interp->result[size] = 0;
  683. X    } else {
  684. X    TclCopyAndCollapse(size, element, interp->result);
  685. X    }
  686. X    return TCL_OK;
  687. X}
  688. X
  689. X/*
  690. X *----------------------------------------------------------------------
  691. X *
  692. X * Tcl_LinsertCmd --
  693. X *
  694. X *    This procedure is invoked to process the "linsert" Tcl command.
  695. X *    See the user documentation for details on what it does.
  696. X *
  697. X * Results:
  698. X *    A standard Tcl result.
  699. X *
  700. X * Side effects:
  701. X *    See the user documentation.
  702. X *
  703. X *----------------------------------------------------------------------
  704. X */
  705. X
  706. X    /* ARGSUSED */
  707. Xint
  708. XTcl_LinsertCmd(dummy, interp, argc, argv)
  709. X    ClientData dummy;            /* Not used. */
  710. X    Tcl_Interp *interp;            /* Current interpreter. */
  711. X    int argc;                /* Number of arguments. */
  712. X    char **argv;            /* Argument strings. */
  713. X{
  714. X    char *p, *element, savedChar;
  715. X    int i, index, count, result, size, brace;
  716. X
  717. X    if (argc < 4) {
  718. X    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
  719. X        " list index element ?element ...?\"", (char *) NULL);
  720. X    return TCL_ERROR;
  721. X    }
  722. X    if (Tcl_GetInt(interp, argv[2], &index) != TCL_OK) {
  723. X    return TCL_ERROR;
  724. X    }
  725. X
  726. X    /*
  727. X     * Skip over the first "index" elements of the list, then add
  728. X     * all of those elements to the result.
  729. X     */
  730. X
  731. X    size = 0;
  732. X    brace = 0;
  733. X    element = argv[1];
  734. X    for (count = 0, p = argv[1]; (count < index) && (*p != 0); count++) {
  735. X    result = TclFindElement(interp, p, &element, &p, &size, &brace);
  736. X    if (result != TCL_OK) {
  737. X        return result;
  738. X    }
  739. X    }
  740. X    if (*p == 0) {
  741. X    Tcl_AppendResult(interp, argv[1], (char *) NULL);
  742. X    } else {
  743. X    char *end;
  744. X
  745. X    end = element+size;
  746. X    if (brace) {
  747. X        end++;
  748. X    }
  749. X    savedChar = *end;
  750. X    *end = 0;
  751. X    Tcl_AppendResult(interp, argv[1], (char *) NULL);
  752. X    *end = savedChar;
  753. X    }
  754. X
  755. X    /*
  756. X     * Add the new list elements.
  757. X     */
  758. X
  759. X    for (i = 3; i < argc; i++) {
  760. X    Tcl_AppendElement(interp, argv[i], 0);
  761. X    }
  762. X
  763. X    /*
  764. X     * Append the remainder of the original list.
  765. X     */
  766. X
  767. X    if (*p != 0) {
  768. X    Tcl_AppendResult(interp, " ", p, (char *) NULL);
  769. X    }
  770. X    return TCL_OK;
  771. X}
  772. X
  773. X/*
  774. X *----------------------------------------------------------------------
  775. X *
  776. X * Tcl_ListCmd --
  777. X *
  778. X *    This procedure is invoked to process the "list" Tcl command.
  779. X *    See the user documentation for details on what it does.
  780. X *
  781. X * Results:
  782. X *    A standard Tcl result.
  783. X *
  784. X * Side effects:
  785. X *    See the user documentation.
  786. X *
  787. X *----------------------------------------------------------------------
  788. X */
  789. X
  790. X    /* ARGSUSED */
  791. Xint
  792. XTcl_ListCmd(dummy, interp, argc, argv)
  793. X    ClientData dummy;            /* Not used. */
  794. X    Tcl_Interp *interp;            /* Current interpreter. */
  795. X    int argc;                /* Number of arguments. */
  796. X    char **argv;            /* Argument strings. */
  797. X{
  798. X    if (argc < 2) {
  799. X    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
  800. X        " arg ?arg ...?\"", (char *) NULL);
  801. X    return TCL_ERROR;
  802. X    }
  803. X    interp->result = Tcl_Merge(argc-1, argv+1);
  804. X    interp->freeProc = (Tcl_FreeProc *) free;
  805. X    return TCL_OK;
  806. X}
  807. X
  808. X/*
  809. X *----------------------------------------------------------------------
  810. X *
  811. X * Tcl_LlengthCmd --
  812. X *
  813. X *    This procedure is invoked to process the "llength" Tcl command.
  814. X *    See the user documentation for details on what it does.
  815. X *
  816. X * Results:
  817. X *    A standard Tcl result.
  818. X *
  819. X * Side effects:
  820. X *    See the user documentation.
  821. X *
  822. X *----------------------------------------------------------------------
  823. X */
  824. X
  825. X    /* ARGSUSED */
  826. Xint
  827. XTcl_LlengthCmd(dummy, interp, argc, argv)
  828. X    ClientData dummy;            /* Not used. */
  829. X    Tcl_Interp *interp;            /* Current interpreter. */
  830. X    int argc;                /* Number of arguments. */
  831. X    char **argv;            /* Argument strings. */
  832. X{
  833. X    int count, result;
  834. X    char *element, *p;
  835. X
  836. X    if (argc != 2) {
  837. X    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
  838. X        " list\"", (char *) NULL);
  839. X    return TCL_ERROR;
  840. X    }
  841. X    for (count = 0, p = argv[1]; *p != 0 ; count++) {
  842. X    result = TclFindElement(interp, p, &element, &p, (int *) NULL,
  843. X        (int *) NULL);
  844. X    if (result != TCL_OK) {
  845. X        return result;
  846. X    }
  847. X    if (*element == 0) {
  848. X        break;
  849. X    }
  850. X    }
  851. X    sprintf(interp->result, "%d", count);
  852. X    return TCL_OK;
  853. X}
  854. X
  855. X/*
  856. X *----------------------------------------------------------------------
  857. X *
  858. X * Tcl_LrangeCmd --
  859. X *
  860. X *    This procedure is invoked to process the "lrange" Tcl command.
  861. X *    See the user documentation for details on what it does.
  862. X *
  863. X * Results:
  864. X *    A standard Tcl result.
  865. X *
  866. X * Side effects:
  867. X *    See the user documentation.
  868. X *
  869. X *----------------------------------------------------------------------
  870. X */
  871. X
  872. X    /* ARGSUSED */
  873. Xint
  874. XTcl_LrangeCmd(notUsed, interp, argc, argv)
  875. X    ClientData notUsed;            /* Not used. */
  876. X    Tcl_Interp *interp;            /* Current interpreter. */
  877. X    int argc;                /* Number of arguments. */
  878. X    char **argv;            /* Argument strings. */
  879. X{
  880. X    int first, last, result;
  881. X    char *begin, *end, c, *dummy;
  882. X    int count;
  883. X
  884. X    if (argc != 4) {
  885. X    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
  886. X        " list first last\"", (char *) NULL);
  887. X    return TCL_ERROR;
  888. X    }
  889. X    if (Tcl_GetInt(interp, argv[2], &first) != TCL_OK) {
  890. X    return TCL_ERROR;
  891. X    }
  892. X    if (first < 0) {
  893. X    first = 0;
  894. X    }
  895. X    if ((*argv[3] == 'e') && (strncmp(argv[3], "end", strlen(argv[3])) == 0)) {
  896. X    last = 1000000;
  897. X    } else {
  898. X    if (Tcl_GetInt(interp, argv[3], &last) != TCL_OK) {
  899. X        Tcl_ResetResult(interp);
  900. X        Tcl_AppendResult(interp,
  901. X            "expected integer or \"end\" but got \"",
  902. X            argv[3], "\"", (char *) NULL);
  903. X        return TCL_ERROR;
  904. X    }
  905. X    }
  906. X    if (first > last) {
  907. X    return TCL_OK;
  908. X    }
  909. X
  910. X    /*
  911. X     * Extract a range of fields.
  912. X     */
  913. X
  914. X    for (count = 0, begin = argv[1]; count < first; count++) {
  915. X    result = TclFindElement(interp, begin, &dummy, &begin, (int *) NULL,
  916. X        (int *) NULL);
  917. X    if (result != TCL_OK) {
  918. X        return result;
  919. X    }
  920. X    if (*begin == 0) {
  921. X        break;
  922. X    }
  923. X    }
  924. X    for (count = first, end = begin; (count <= last) && (*end != 0);
  925. X        count++) {
  926. X    result = TclFindElement(interp, end, &dummy, &end, (int *) NULL,
  927. X        (int *) NULL);
  928. X    if (result != TCL_OK) {
  929. X        return result;
  930. X    }
  931. X    }
  932. X
  933. X    /*
  934. X     * Chop off trailing spaces.
  935. X     */
  936. X
  937. X    while (isspace(end[-1])) {
  938. X    end--;
  939. X    }
  940. X    c = *end;
  941. X    *end = 0;
  942. X    Tcl_SetResult(interp, begin, TCL_VOLATILE);
  943. X    *end = c;
  944. X    return TCL_OK;
  945. X}
  946. X
  947. X/*
  948. X *----------------------------------------------------------------------
  949. X *
  950. X * Tcl_LreplaceCmd --
  951. X *
  952. X *    This procedure is invoked to process the "lreplace" Tcl command.
  953. X *    See the user documentation for details on what it does.
  954. X *
  955. X * Results:
  956. X *    A standard Tcl result.
  957. X *
  958. X * Side effects:
  959. X *    See the user documentation.
  960. X *
  961. X *----------------------------------------------------------------------
  962. X */
  963. X
  964. X    /* ARGSUSED */
  965. Xint
  966. XTcl_LreplaceCmd(notUsed, interp, argc, argv)
  967. X    ClientData notUsed;            /* Not used. */
  968. X    Tcl_Interp *interp;            /* Current interpreter. */
  969. X    int argc;                /* Number of arguments. */
  970. X    char **argv;            /* Argument strings. */
  971. X{
  972. X    char *p1, *p2, *element, savedChar, *dummy;
  973. X    int i, first, last, count, result, size, brace;
  974. X
  975. X    if (argc < 4) {
  976. X    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
  977. X        " list first last ?element element ...?\"", (char *) NULL);
  978. X    return TCL_ERROR;
  979. X    }
  980. X    if (Tcl_GetInt(interp, argv[2], &first) != TCL_OK) {
  981. X    return TCL_ERROR;
  982. X    }
  983. X    if (TclGetListIndex(interp, argv[3], &last) != TCL_OK) {
  984. X    return TCL_ERROR;
  985. X    }
  986. X    if (first < 0) {
  987. X    first = 0;
  988. X    }
  989. X    if (last < 0) {
  990. X    last = 0;
  991. X    }
  992. X    if (first > last) {
  993. X    Tcl_AppendResult(interp, "first index must not be greater than second",
  994. X        (char *) NULL);
  995. X    return TCL_ERROR;
  996. X    }
  997. X
  998. X    /*
  999. X     * Skip over the elements of the list before "first".
  1000. X     */
  1001. X
  1002. X    size = 0;
  1003. X    brace = 0;
  1004. X    element = argv[1];
  1005. X    for (count = 0, p1 = argv[1]; (count < first) && (*p1 != 0); count++) {
  1006. X    result = TclFindElement(interp, p1, &element, &p1, &size, &brace);
  1007. X    if (result != TCL_OK) {
  1008. X        return result;
  1009. X    }
  1010. X    }
  1011. X    if (*p1 == 0) {
  1012. X    Tcl_AppendResult(interp, "list doesn't contain element ",
  1013. X        argv[2], (char *) NULL);
  1014. X    return TCL_ERROR;
  1015. X    }
  1016. X
  1017. X    /*
  1018. X     * Skip over the elements of the list up through "last".
  1019. X     */
  1020. X
  1021. X    for (p2 = p1 ; (count <= last) && (*p2 != 0); count++) {
  1022. X    result = TclFindElement(interp, p2, &dummy, &p2, (int *) NULL,
  1023. X        (int *) NULL);
  1024. X    if (result != TCL_OK) {
  1025. X        return result;
  1026. X    }
  1027. X    }
  1028. X
  1029. X    /*
  1030. X     * Add the elements up through "first" to the result.
  1031. X     */
  1032. X
  1033. X    p1 = element+size;
  1034. X    if (brace) {
  1035. X    p1++;
  1036. X    }
  1037. X    savedChar = *p1;
  1038. X    *p1 = 0;
  1039. X    Tcl_AppendResult(interp, argv[1], (char *) NULL);
  1040. X    *p1 = savedChar;
  1041. X
  1042. X    /*
  1043. X     * Add the new list elements.
  1044. X     */
  1045. X
  1046. X    for (i = 4; i < argc; i++) {
  1047. X    Tcl_AppendElement(interp, argv[i], 0);
  1048. X    }
  1049. X
  1050. X    /*
  1051. X     * Append the remainder of the original list.
  1052. X     */
  1053. X
  1054. X    if (*p2 != 0) {
  1055. X    if (*interp->result == 0) {
  1056. X        Tcl_SetResult(interp, p2, TCL_VOLATILE);
  1057. X    } else {
  1058. X        Tcl_AppendResult(interp, " ", p2, (char *) NULL);
  1059. X    }
  1060. X    }
  1061. X    return TCL_OK;
  1062. X}
  1063. X
  1064. X/*
  1065. X *----------------------------------------------------------------------
  1066. X *
  1067. X * Tcl_LsearchCmd --
  1068. X *
  1069. X *    This procedure is invoked to process the "lsearch" Tcl command.
  1070. X *    See the user documentation for details on what it does.
  1071. X *
  1072. X * Results:
  1073. X *    A standard Tcl result.
  1074. X *
  1075. X * Side effects:
  1076. X *    See the user documentation.
  1077. X *
  1078. X *----------------------------------------------------------------------
  1079. X */
  1080. X
  1081. X    /* ARGSUSED */
  1082. Xint
  1083. XTcl_LsearchCmd(notUsed, interp, argc, argv)
  1084. X    ClientData notUsed;            /* Not used. */
  1085. X    Tcl_Interp *interp;            /* Current interpreter. */
  1086. X    int argc;                /* Number of arguments. */
  1087. X    char **argv;            /* Argument strings. */
  1088. X{
  1089. X    int listArgc;
  1090. X    char **listArgv;
  1091. X    int i, match;
  1092. X
  1093. X    if (argc != 3) {
  1094. X    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
  1095. X        " list pattern\"", (char *) NULL);
  1096. X    return TCL_ERROR;
  1097. X    }
  1098. X    if (Tcl_SplitList(interp, argv[1], &listArgc, &listArgv) != TCL_OK) {
  1099. X    return TCL_ERROR;
  1100. X    }
  1101. X    match = -1;
  1102. X    for (i = 0; i < listArgc; i++) {
  1103. X    if (Tcl_StringMatch(listArgv[i], argv[2])) {
  1104. X        match = i;
  1105. X        break;
  1106. X    }
  1107. X    }
  1108. X    sprintf(interp->result, "%d", match);
  1109. X    ckfree((char *) listArgv);
  1110. X    return TCL_OK;
  1111. X}
  1112. X
  1113. X/*
  1114. X *----------------------------------------------------------------------
  1115. X *
  1116. X * Tcl_LsortCmd --
  1117. X *
  1118. X *    This procedure is invoked to process the "lsort" Tcl command.
  1119. X *    See the user documentation for details on what it does.
  1120. X *
  1121. X * Results:
  1122. X *    A standard Tcl result.
  1123. X *
  1124. X * Side effects:
  1125. X *    See the user documentation.
  1126. X *
  1127. X *----------------------------------------------------------------------
  1128. X */
  1129. X
  1130. X    /* ARGSUSED */
  1131. Xint
  1132. XTcl_LsortCmd(notUsed, interp, argc, argv)
  1133. X    ClientData notUsed;            /* Not used. */
  1134. X    Tcl_Interp *interp;            /* Current interpreter. */
  1135. X    int argc;                /* Number of arguments. */
  1136. X    char **argv;            /* Argument strings. */
  1137. X{
  1138. X    int listArgc;
  1139. X    char **listArgv;
  1140. X
  1141. X    if (argc != 2) {
  1142. X    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
  1143. X        " list\"", (char *) NULL);
  1144. X    return TCL_ERROR;
  1145. X    }
  1146. X    if (Tcl_SplitList(interp, argv[1], &listArgc, &listArgv) != TCL_OK) {
  1147. X    return TCL_ERROR;
  1148. X    }
  1149. X    qsort((char *) listArgv, listArgc, sizeof (char *), SortCompareProc);
  1150. X    interp->result = Tcl_Merge(listArgc, listArgv);
  1151. X    interp->freeProc = (Tcl_FreeProc *) free;
  1152. X    ckfree((char *) listArgv);
  1153. X    return TCL_OK;
  1154. X}
  1155. X
  1156. X/*
  1157. X * The procedure below is called back by qsort to determine
  1158. X * the proper ordering between two elements.
  1159. X */
  1160. X
  1161. Xstatic int
  1162. XSortCompareProc(first, second)
  1163. X    CONST char *first, *second;        /* Elements to be compared. */
  1164. X{
  1165. X    return strcmp(*((char **) first), *((char **) second));
  1166. X}
  1167. END_OF_FILE
  1168. if test 29320 -ne `wc -c <'tcl6.1/tclCmdIL.c'`; then
  1169.     echo shar: \"'tcl6.1/tclCmdIL.c'\" unpacked with wrong size!
  1170. fi
  1171. # end of 'tcl6.1/tclCmdIL.c'
  1172. fi
  1173. echo shar: End of archive 20 \(of 33\).
  1174. cp /dev/null ark20isdone
  1175. MISSING=""
  1176. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 ; do
  1177.     if test ! -f ark${I}isdone ; then
  1178.     MISSING="${MISSING} ${I}"
  1179.     fi
  1180. done
  1181. if test "${MISSING}" = "" ; then
  1182.     echo You have unpacked all 33 archives.
  1183.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1184. else
  1185.     echo You still need to unpack the following archives:
  1186.     echo "        " ${MISSING}
  1187. fi
  1188. ##  End of shell archive.
  1189. exit 0
  1190.  
  1191. exit 0 # Just in case...
  1192. -- 
  1193. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  1194. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  1195. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  1196. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  1197.