home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume26 / tclx / part10 < prev    next >
Encoding:
Text File  |  1991-11-19  |  46.8 KB  |  1,409 lines

  1. Newsgroups: comp.sources.misc
  2. From: karl@sugar.neosoft.com (Karl Lehenbauer)
  3. Subject:  v26i010:  tclx - extensions and on-line help for tcl 6.1, Part10/23
  4. Message-ID: <1991Nov19.005553.8926@sparky.imd.sterling.com>
  5. X-Md4-Signature: d29f799aa78025252413ac906f222e4e
  6. Date: Tue, 19 Nov 1991 00:55:53 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: karl@sugar.neosoft.com (Karl Lehenbauer)
  10. Posting-number: Volume 26, Issue 10
  11. Archive-name: tclx/part10
  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 10 (of 23)."
  21. # Contents:  extended/ossupport/strftime.c extended/src/tclExtdInt.h
  22. #   extended/tcllib/help/commands/history
  23. #   extended/tcllib/help/commands/info extended/tclsrc/help.tcl
  24. #   extended/tests/iocmds.test
  25. # Wrapped by karl@one on Wed Nov 13 21:50:22 1991
  26. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  27. if test -f 'extended/ossupport/strftime.c' -a "${1}" != "-c" ; then 
  28.   echo shar: Will not clobber existing file \"'extended/ossupport/strftime.c'\"
  29. else
  30. echo shar: Extracting \"'extended/ossupport/strftime.c'\" \(6767 characters\)
  31. sed "s/^X//" >'extended/ossupport/strftime.c' <<'END_OF_FILE'
  32. X/*
  33. X * strftime.c
  34. X *
  35. X * Public-domain relatively quick-and-dirty implemenation of
  36. X * ANSI library routine for System V Unix systems.
  37. X *
  38. X * It's written in old-style C for maximal portability.
  39. X *
  40. X * The code for %c, %x, and %X is my best guess as to what's "appropriate".
  41. X * This version ignores LOCALE information.
  42. X * It also doesn't worry about multi-byte characters.
  43. X * So there.
  44. X *
  45. X * Arnold Robbins
  46. X * January, February, 1991
  47. X *
  48. X * Fixes from ado@elsie.nci.nih.gov
  49. X * February 1991
  50. X */
  51. X
  52. X/*
  53. X * To avoid Unix version problems, this code has been simplified to avoid
  54. X * const and size_t, however this can cause an incompatible definition on
  55. X * ansi-C systems, so a game is played with defines to ignore a strftime
  56. X * declaration in time.h
  57. X */
  58. X
  59. X#define strftime ___srtftime
  60. X
  61. X#include <stdio.h>
  62. X#include <string.h>
  63. X#include <time.h>
  64. X#include <sys/types.h>
  65. X
  66. X#undef strftime
  67. X
  68. Xextern void tzset();
  69. Xextern char *strchr();
  70. Xstatic int weeknumber();
  71. X
  72. X#ifndef TCL_HAS_TM_ZONE
  73. Xextern char *tzname[2];
  74. Xextern int daylight;
  75. X#endif
  76. X
  77. X/* strftime --- produce formatted time */
  78. X
  79. Xint
  80. Xstrftime(s, maxsize, format, timeptr)
  81. X    char            *s;
  82. X    int              maxsize;
  83. X    char            *format;
  84. X    struct tm       *timeptr;
  85. X{
  86. X    char *endp = s + maxsize;
  87. X    char *start = s;
  88. X    char tbuf[100];
  89. X    int i;
  90. X    static short first = 1;
  91. X
  92. X    /* various tables, useful in North America */
  93. X    static char *days_a[] = {
  94. X        "Sun", "Mon", "Tue", "Wed",
  95. X        "Thu", "Fri", "Sat",
  96. X    };
  97. X    static char *days_l[] = {
  98. X        "Sunday", "Monday", "Tuesday", "Wednesday",
  99. X        "Thursday", "Friday", "Saturday",
  100. X    };
  101. X    static char *months_a[] = {
  102. X        "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  103. X        "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
  104. X    };
  105. X    static char *months_l[] = {
  106. X        "January", "February", "March", "April",
  107. X        "May", "June", "July", "August", "September",
  108. X        "October", "November", "December",
  109. X    };
  110. X    static char *ampm[] = { "AM", "PM", };
  111. X
  112. X    if (s == NULL || format == NULL || timeptr == NULL || maxsize == 0)
  113. X        return 0;
  114. X
  115. X    if (strchr(format, '%') == NULL && strlen(format) + 1 >= maxsize)
  116. X        return 0;
  117. X
  118. X    if (first) {
  119. X        tzset();
  120. X        first = 0;
  121. X    }
  122. X
  123. X    for (; *format && s < endp - 1; format++) {
  124. X        tbuf[0] = '\0';
  125. X        if (*format != '%') {
  126. X            *s++ = *format;
  127. X            continue;
  128. X        }
  129. X        switch (*++format) {
  130. X        case '\0':
  131. X            *s++ = '%';
  132. X            goto out;
  133. X
  134. X        case '%':
  135. X            *s++ = '%';
  136. X            continue;
  137. X
  138. X        case 'a':    /* abbreviated weekday name */
  139. X            if (timeptr->tm_wday < 0 || timeptr->tm_wday > 6)
  140. X                strcpy(tbuf, "?");
  141. X            else
  142. X                strcpy(tbuf, days_a[timeptr->tm_wday]);
  143. X            break;
  144. X
  145. X        case 'A':    /* full weekday name */
  146. X            if (timeptr->tm_wday < 0 || timeptr->tm_wday > 6)
  147. X                strcpy(tbuf, "?");
  148. X            else
  149. X                strcpy(tbuf, days_l[timeptr->tm_wday]);
  150. X            break;
  151. X
  152. X        case 'h':    /* abbreviated month name */
  153. X        case 'b':    /* abbreviated month name */
  154. X            if (timeptr->tm_mon < 0 || timeptr->tm_mon > 11)
  155. X                strcpy(tbuf, "?");
  156. X            else
  157. X                strcpy(tbuf, months_a[timeptr->tm_mon]);
  158. X            break;
  159. X
  160. X        case 'B':    /* full month name */
  161. X            if (timeptr->tm_mon < 0 || timeptr->tm_mon > 11)
  162. X                strcpy(tbuf, "?");
  163. X            else
  164. X                strcpy(tbuf, months_l[timeptr->tm_mon]);
  165. X            break;
  166. X
  167. X        case 'c':    /* appropriate date and time representation */
  168. X            sprintf(tbuf, "%s %s %2d %02d:%02d:%02d %d",
  169. X                days_a[timeptr->tm_wday],
  170. X                months_a[timeptr->tm_mon],
  171. X                timeptr->tm_mday,
  172. X                timeptr->tm_hour,
  173. X                timeptr->tm_min,
  174. X                timeptr->tm_sec,
  175. X                timeptr->tm_year + 1900);
  176. X            break;
  177. X
  178. X        case 'd':    /* day of the month, 01 - 31 */
  179. X            sprintf(tbuf, "%02d", timeptr->tm_mday);
  180. X            break;
  181. X
  182. X        case 'H':    /* hour, 24-hour clock, 00 - 23 */
  183. X            sprintf(tbuf, "%02d", timeptr->tm_hour);
  184. X            break;
  185. X
  186. X        case 'I':    /* hour, 12-hour clock, 01 - 12 */
  187. X            i = timeptr->tm_hour;
  188. X            if (i == 0)
  189. X                i = 12;
  190. X            else if (i > 12)
  191. X                i -= 12;
  192. X            sprintf(tbuf, "%02d", i);
  193. X            break;
  194. X
  195. X        case 'j':    /* day of the year, 001 - 366 */
  196. X            sprintf(tbuf, "%03d", timeptr->tm_yday + 1);
  197. X            break;
  198. X
  199. X        case 'm':    /* month, 01 - 12 */
  200. X            sprintf(tbuf, "%02d", timeptr->tm_mon + 1);
  201. X            break;
  202. X
  203. X        case 'M':    /* minute, 00 - 59 */
  204. X            sprintf(tbuf, "%02d", timeptr->tm_min);
  205. X            break;
  206. X
  207. X        case 'p':    /* am or pm based on 12-hour clock */
  208. X            if (timeptr->tm_hour < 12)
  209. X                strcpy(tbuf, ampm[0]);
  210. X            else
  211. X                strcpy(tbuf, ampm[1]);
  212. X            break;
  213. X
  214. X        case 'S':    /* second, 00 - 61 */
  215. X            sprintf(tbuf, "%02d", timeptr->tm_sec);
  216. X            break;
  217. X
  218. X        case 'U':    /* week of year, Sunday is first day of week */
  219. X            sprintf(tbuf, "%d", weeknumber(timeptr, 0));
  220. X            break;
  221. X
  222. X        case 'w':    /* weekday, Sunday == 0, 0 - 6 */
  223. X            sprintf(tbuf, "%d", timeptr->tm_wday);
  224. X            break;
  225. X
  226. X        case 'W':    /* week of year, Monday is first day of week */
  227. X            sprintf(tbuf, "%d", weeknumber(timeptr, 1));
  228. X            break;
  229. X
  230. X        case 'x':    /* appropriate date representation */
  231. X            sprintf(tbuf, "%s %s %2d %d",
  232. X                days_a[timeptr->tm_wday],
  233. X                months_a[timeptr->tm_mon],
  234. X                timeptr->tm_mday,
  235. X                timeptr->tm_year + 1900);
  236. X            break;
  237. X
  238. X        case 'X':    /* appropriate time representation */
  239. X            sprintf(tbuf, "%02d:%02d:%02d",
  240. X                timeptr->tm_hour,
  241. X                timeptr->tm_min,
  242. X                timeptr->tm_sec);
  243. X            break;
  244. X
  245. X        case 'y':    /* year without a century, 00 - 99 */
  246. X            i = timeptr->tm_year % 100;
  247. X            sprintf(tbuf, "%d", i);
  248. X            break;
  249. X
  250. X        case 'Y':    /* year with century */
  251. X            sprintf(tbuf, "%d", 1900 + timeptr->tm_year);
  252. X            break;
  253. X
  254. X        case 'Z':    /* time zone name or abbrevation */
  255. X#ifdef TCL_HAS_TM_ZONE
  256. X                        strcpy(tbuf, timeptr->tm_zone);
  257. X#else
  258. X            i = 0;
  259. X            if (daylight && timeptr->tm_isdst)
  260. X                i = 1;
  261. X            strcpy(tbuf, tzname[i]);
  262. X#endif
  263. X            break;
  264. X
  265. X        case 'n':    /* same as \n */
  266. X            tbuf[0] = '\n';
  267. X            tbuf[1] = '\0';
  268. X            break;
  269. X
  270. X        case 't':    /* same as \t */
  271. X            tbuf[0] = '\t';
  272. X            tbuf[1] = '\0';
  273. X            break;
  274. X
  275. X        case 'D':    /* date as %m/%d/%y */
  276. X            strftime(tbuf, sizeof tbuf, "%m/%d/%y", timeptr);
  277. X            break;
  278. X
  279. X        case 'e':    /* day of month, blank padded */
  280. X            sprintf(tbuf, "%2d", timeptr->tm_mday);
  281. X            break;
  282. X
  283. X        case 'r':    /* time as %I:%M:%S %p */
  284. X            strftime(tbuf, sizeof tbuf, "%I:%M:%S %p", timeptr);
  285. X            break;
  286. X
  287. X        case 'R':    /* time as %H:%M */
  288. X            strftime(tbuf, sizeof tbuf, "%H:%M", timeptr);
  289. X            break;
  290. X
  291. X        case 'T':    /* time as %H:%M:%S */
  292. X            strftime(tbuf, sizeof tbuf, "%H:%M:%S", timeptr);
  293. X            break;
  294. X
  295. X        default:
  296. X            tbuf[0] = '%';
  297. X            tbuf[1] = *format;
  298. X            tbuf[2] = '\0';
  299. X            break;
  300. X        }
  301. X        i = strlen(tbuf);
  302. X        if (i)
  303. X            if (s + i < endp - 1) {
  304. X                strcpy(s, tbuf);
  305. X                s += i;
  306. X            } else
  307. X                return 0;
  308. X    }
  309. Xout:
  310. X    if (s < endp && *format == '\0') {
  311. X        *s = '\0';
  312. X        return (s - start);
  313. X    } else
  314. X        return 0;
  315. X}
  316. X
  317. X/* weeknumber --- figure how many weeks into the year */
  318. X
  319. X/* With thanks and tip of the hatlo to ado@elsie.nci.nih.gov */
  320. X
  321. Xstatic int
  322. Xweeknumber(timeptr, firstweekday)
  323. X    struct tm *timeptr;
  324. X    int        firstweekday;
  325. X{
  326. X    if (firstweekday == 0)
  327. X        return (timeptr->tm_yday + 7 - timeptr->tm_wday) / 7;
  328. X    else
  329. X        return (timeptr->tm_yday + 7 -
  330. X            (timeptr->tm_wday ? (timeptr->tm_wday - 1) : 6)) / 7;
  331. X}
  332. END_OF_FILE
  333. if test 6767 -ne `wc -c <'extended/ossupport/strftime.c'`; then
  334.     echo shar: \"'extended/ossupport/strftime.c'\" unpacked with wrong size!
  335. fi
  336. # end of 'extended/ossupport/strftime.c'
  337. fi
  338. if test -f 'extended/src/tclExtdInt.h' -a "${1}" != "-c" ; then 
  339.   echo shar: Will not clobber existing file \"'extended/src/tclExtdInt.h'\"
  340. else
  341. echo shar: Extracting \"'extended/src/tclExtdInt.h'\" \(6363 characters\)
  342. sed "s/^X//" >'extended/src/tclExtdInt.h' <<'END_OF_FILE'
  343. X/*
  344. X * tclExtdInt.h
  345. X *
  346. X * Standard internal include file for Extended Tcl library..
  347. X *---------------------------------------------------------------------------
  348. X * Copyright 1991 Karl Lehenbauer and Mark Diekhans.
  349. X *
  350. X * Permission to use, copy, modify, and distribute this software and its
  351. X * documentation for any purpose and without fee is hereby granted, provided
  352. X * that the above copyright notice appear in all copies.  Karl Lehenbauer and
  353. X * Mark Diekhans make no representations about the suitability of this
  354. X * software for any purpose.  It is provided "as is" without express or
  355. X * implied warranty.
  356. X */
  357. X
  358. X#ifndef TCLEXTDINT_H
  359. X#define TCLEXTDINT_H
  360. X
  361. X#include "tclExtend.h"
  362. X#include "tclInt.h"
  363. X#include "tclUnix.h"
  364. X
  365. X#include <values.h>
  366. X#include <grp.h>
  367. X/*
  368. X * If sys/times.h was not included by tclUnix.h, then include it.  On some
  369. X * systems, it cann't be double included.
  370. X */
  371. X#if TCL_GETTOD
  372. X#   include <sys/times.h>
  373. X#endif
  374. X
  375. X/*
  376. X * On some systems this is not included by tclUnix.h.
  377. X */
  378. X#include <sys/param.h>
  379. X#ifndef CLK_TCK
  380. X#    ifdef HZ
  381. X#        define CLK_TCK HZ
  382. X#    else
  383. X#        define CLK_TCK 60
  384. X#    endif
  385. X#endif
  386. X
  387. X
  388. X
  389. X#ifndef MAXINT
  390. X#    define BITSPERBYTE   8
  391. X#    define BITS(type)    (BITSPERBYTE * (int)sizeof(type))
  392. X#    define HIBITI        (1 << BITS(int) - 1)
  393. X#    define MAXINT        (~HIBITI)
  394. X#endif
  395. X
  396. X#ifndef MININT
  397. X#    define MININT (-MAXINT)-1
  398. X#endif
  399. X
  400. X#ifndef TRUE
  401. X#    define TRUE   (1)
  402. X#    define FALSE  (0)
  403. X#endif
  404. X
  405. X/*
  406. X * Structure to hold a regular expression, plus a Boyer-Moore compiled
  407. X * pattern.
  408. X */
  409. X
  410. Xtypedef struct regexp_t {
  411. X    regexp *progPtr;
  412. X    char   *boyerMoorePtr;
  413. X    int     noCase;
  414. X    } regexp_t;
  415. Xtypedef regexp_t *regexp_pt;
  416. X/*
  417. X * Flags used by RegExpCompile:
  418. X */
  419. X#define REXP_NO_CASE         1   /* Do matching regardless of case    */
  420. X#define REXP_BOTH_ALGORITHMS 2   /* Use boyer-moore along with regexp */
  421. X
  422. X/*
  423. X * Data structure to control a dynamic buffer.  These buffers are primarly
  424. X * used for reading things from files, were the maximum size is not known
  425. X * in advance, and the buffer must grow.  These are used in the case were
  426. X * the value is not to be returned as the interpreter result.
  427. X */
  428. X
  429. X#define INIT_DYN_BUFFER_SIZE 256
  430. X
  431. Xtypedef struct dynamicBuf_t {
  432. X    char  buf [INIT_DYN_BUFFER_SIZE];   /* Initial buffer area.              */
  433. X    char *ptr;                          /* Pointer to buffer area.           */
  434. X    int   size;                         /* Current size of buffer.           */
  435. X    int   used;                         /* Current amount used, include '\0' */
  436. X    } dynamicBuf_t;
  437. X
  438. X/*
  439. X * Macros to do string compares.  They pre-check the first character before
  440. X * checking of the strings are equal.
  441. X */
  442. X
  443. X#define STREQU(str1, str2) \
  444. X        ((str1[0] == str2[0]) && (strcmp (str1, str2) == 0))
  445. X#define STRNEQU(str1, str2, cnt) \
  446. X        ((str1[0] == str2[0]) && (strncmp (str1, str2, cnt) == 0))
  447. X
  448. Xvoid
  449. XTcl_DynBufInit _ANSI_ARGS_((dynamicBuf_t *dynBufPtr));
  450. X
  451. Xvoid
  452. XTcl_DynBufFree _ANSI_ARGS_((dynamicBuf_t *dynBufPtr));
  453. X
  454. Xvoid
  455. XTcl_DynBufReturn _ANSI_ARGS_((Tcl_Interp    *interp,
  456. X                              dynamicBuf_t *dynBufPtr));
  457. X
  458. Xvoid
  459. XTcl_DynBufAppend _ANSI_ARGS_((dynamicBuf_t *dynBufPtr,
  460. X                              char         *newStr));
  461. X
  462. Xint
  463. XTcl_DynamicFgets _ANSI_ARGS_((dynamicBuf_t *dynBufPtr,
  464. X                              FILE         *filePtr));
  465. X
  466. Xint
  467. XTcl_ConvertFileHandle _ANSI_ARGS_((Tcl_Interp *interp,
  468. X                                  char       *handle));
  469. X
  470. Xint
  471. XTcl_ProcessSignal _ANSI_ARGS_((Tcl_Interp *interp,
  472. X                               int         cmdResultCode));
  473. X
  474. Xvoid
  475. XTcl_RegExpClean _ANSI_ARGS_((regexp_pt regExpPtr));
  476. X
  477. Xint
  478. XTcl_RegExpCompile _ANSI_ARGS_((Tcl_Interp  *interp,
  479. X                               regexp_pt    regExpPtr,
  480. X                               char        *expression,
  481. X                               int          flags));
  482. X
  483. Xint
  484. XTcl_RegExpExecute _ANSI_ARGS_((Tcl_Interp  *interp,
  485. X                               regexp_pt    regExpPtr,
  486. X                               char        *matchStrIn,
  487. X                               char        *matchStrLower));
  488. Xvoid
  489. XTcl_ResetSignals ();
  490. X
  491. X/*
  492. X * Definitions required to initialize all extended commands.  These are either
  493. X * the command executors or initialization routines that do the command
  494. X * initialization.  The initialization routines are used when there is more
  495. X * to initializing the command that just binding the command name to the
  496. X * executor.  Usually, this means initializing some command local data via
  497. X * the ClientData mechanism.
  498. X */
  499. X
  500. X/*
  501. X * from chmod.c
  502. X */
  503. Xextern Tcl_CmdProc  Tcl_ChmodCmd, Tcl_ChownCmd, Tcl_ChgrpCmd;
  504. X
  505. X/*
  506. X * from clock.c
  507. X */
  508. Xextern Tcl_CmdProc  Tcl_GetclockCmd, Tcl_FmtclockCmd;
  509. X
  510. X/*
  511. X * from cmdloop.c
  512. X */
  513. Xextern Tcl_CmdProc  Tcl_CommandloopCmd;
  514. X
  515. X/*
  516. X * from debug.c
  517. X */
  518. Xvoid
  519. XTcl_InitDebug _ANSI_ARGS_((Tcl_Interp *interp));
  520. X
  521. X/*
  522. X * from filescan.c
  523. X */
  524. Xvoid
  525. XTcl_InitFilescan _ANSI_ARGS_((Tcl_Interp *interp));
  526. X
  527. X/*
  528. X * from fmath.c
  529. X */
  530. Xextern Tcl_CmdProc  Tcl_AcosCmd, Tcl_AsinCmd, Tcl_AtanCmd,  Tcl_CosCmd,
  531. X                    Tcl_SinCmd,  Tcl_TanCmd,  Tcl_CoshCmd,  Tcl_SinhCmd,
  532. X                    Tcl_TanhCmd, Tcl_ExpCmd,  Tcl_LogCmd,   Tcl_Log10Cmd,
  533. X                    Tcl_SqrtCmd, Tcl_FabsCmd, Tcl_FloorCmd, Tcl_CeilCmd,
  534. X                    Tcl_FmodCmd, Tcl_PowCmd;
  535. X
  536. X/*
  537. X * from general.c
  538. X */
  539. Xextern Tcl_CmdProc  Tcl_EchoCmd, Tcl_InfoxCmd, Tcl_LoopCmd;
  540. X
  541. X/*
  542. X * from id.c
  543. X */
  544. Xextern Tcl_CmdProc  Tcl_IdCmd;
  545. X
  546. X/*
  547. X * from iocmds.c
  548. X */
  549. Xextern Tcl_CmdProc  Tcl_BsearchCmd, Tcl_DupCmd, Tcl_PipeCmd, Tcl_CopyfileCmd,
  550. X                    Tcl_FstatCmd,   Tcl_FcntlCmd, Tcl_SelectCmd;
  551. X
  552. X/*
  553. X * from list.c
  554. X */
  555. Xextern Tcl_CmdProc  Tcl_LvarpopCmd, Tcl_LemptyCmd, Tcl_KeyldelCmd,
  556. X                    Tcl_KeylgetCmd, Tcl_KeylsetCmd;
  557. X
  558. X/*
  559. X * from math.c
  560. X */
  561. Xextern Tcl_CmdProc  Tcl_MaxCmd, Tcl_MinCmd, Tcl_RandomCmd;
  562. X
  563. X/*
  564. X * from signal.c
  565. X */
  566. Xvoid
  567. XTcl_InitSignalHandling _ANSI_ARGS_((Tcl_Interp *interp));
  568. X
  569. X/*
  570. X * from string.c
  571. X */
  572. Xextern Tcl_CmdProc  Tcl_CindexCmd,     Tcl_ClengthCmd,   Tcl_CrangeCmd,
  573. X                    Tcl_ReplicateCmd,  Tcl_TranslitCmd,  Tcl_CtypeCmd;
  574. X
  575. X
  576. X/*
  577. X * from unixcmds.c
  578. X */
  579. Xextern Tcl_CmdProc  Tcl_ExecvpCmd, Tcl_ForkCmd,   Tcl_KillCmd,  Tcl_AlarmCmd,
  580. X                    Tcl_SleepCmd,  Tcl_SystemCmd, Tcl_TimesCmd, Tcl_UmaskCmd,
  581. X                    Tcl_LinkCmd,   Tcl_UnlinkCmd, Tcl_MkdirCmd, Tcl_RmdirCmd,
  582. X                    Tcl_WaitCmd;
  583. X
  584. X
  585. X#endif
  586. END_OF_FILE
  587. if test 6363 -ne `wc -c <'extended/src/tclExtdInt.h'`; then
  588.     echo shar: \"'extended/src/tclExtdInt.h'\" unpacked with wrong size!
  589. fi
  590. # end of 'extended/src/tclExtdInt.h'
  591. fi
  592. if test -f 'extended/tcllib/help/commands/history' -a "${1}" != "-c" ; then 
  593.   echo shar: Will not clobber existing file \"'extended/tcllib/help/commands/history'\"
  594. else
  595. echo shar: Extracting \"'extended/tcllib/help/commands/history'\" \(8154 characters\)
  596. sed "s/^X//" >'extended/tcllib/help/commands/history' <<'END_OF_FILE'
  597. X          history ?option? ?arg arg ...?
  598. X               Note:  this command may not be available  in  all  Tcl-
  599. X               based applications.  Typically, only those that receive
  600. X               command  input  in  a  typescript  form  will   support
  601. X               history.   The  history command performs one of several
  602. X               operations  related   to   recently-executed   commands
  603. X               recorded  in  a  history  list.  Each of these recorded
  604. X               commands  is  referred  to  as  an   ``event''.    When
  605. X               specifying   an  event  to  the  history  command,  the
  606. X               following forms may be used:
  607. X
  608. X               [1]  A number:  if positive, it  refers  to  the  event
  609. X                    with that number (all events are numbered starting
  610. X                    at 1).  If the number is negative, it  selects  an
  611. X                    event  relative to the current event (-1 refers to
  612. X                    the previous event, -2 to the one before that, and
  613. X                    so on).
  614. X
  615. X               [2]  A string:  selects  the  most  recent  event  that
  616. X                    matches  the  string.   An  event is considered to
  617. X                    match the string either if the string is the  same
  618. X                    as  the  first  characters of the event, or if the
  619. X                    string matches the  event  in  the  sense  of  the
  620. X                    string match command.
  621. X
  622. X               The history command  can  take  any  of  the  following
  623. X               forms:
  624. X
  625. X               history
  626. X                    Same as history info, described below.
  627. X
  628. X               history add command ?exec?
  629. X                    Add the command argument to the history list as  a
  630. X                    new  event.  If exec is specified (or abbreviated)
  631. X                    then the command is also executed and  its  result
  632. X                    is  returned.   If  exec  isn't  specified then an
  633. X                    empty string is returned as result.
  634. X
  635. X               history change newValue ?event?
  636. X                    Replace the  value  recorded  for  an  event  with
  637. X                    newValue.   Event  specifies the event to replace,
  638. X                    and defaults to the current event (not event  -1).
  639. X                    This  command is intended for use in commands that
  640. X                    implement new forms of  history  substitution  and
  641. X                    wish  to  replace the current event (which invokes
  642. X                    the substitution) with the command created through
  643. X                    substitution.    The  return  value  is  an  empty
  644. X                    string.
  645. X
  646. X               history event ?event?
  647. X                    Returns the value of the  event  given  by  event.
  648. X                    Event defaults to -1.  This command causes history
  649. X                    revision to occur: see below for details.
  650. X
  651. X               history info ?count?
  652. X                    Returns a formatted string (intended for humans to
  653. X                    read)  giving  the  event  number and contents for
  654. X                    each of the events in the history list except  the
  655. X                    current  event.   If  count is specified then only
  656. X                    the most recent count events are returned.
  657. X
  658. X               history keep count
  659. X                    This command may be used to change the size of the
  660. X                    history  list  to  count  events.   Initially,  20
  661. X                    events are retained in  the  history  list.   This
  662. X                    command returns an empty string.
  663. X
  664. X               history nextid
  665. X                    Returns  the  number  of  the  next  event  to  be
  666. X                    recorded  in  the  history list.  It is useful for
  667. X                    things like printing the event number in  command-
  668. X                    line prompts.
  669. X
  670. X               history redo ?event?
  671. X                    Re-execute the  command  indicated  by  event  and
  672. X                    return  its  result.   Event defaults to -1.  This
  673. X                    command results in history  revision:   see  below
  674. X                    for details.
  675. X
  676. X               history substitute old new ?event?
  677. X                    Retrieve  the  command  given  by  event  (-1   by
  678. X                    default), replace any occurrences of old by new in
  679. X                    the command (only  simple  character  equality  is
  680. X                    supported;  no  wild cards), execute the resulting
  681. X                    command, and return the result of that  execution.
  682. X                    This  command  results  in  history revision:  see
  683. X                    below for details.
  684. X
  685. X               history words selector ?event?
  686. X                    Retrieve from the command given by  event  (-1  by
  687. X                    default)  the  words given by selector, and return
  688. X                    those words in a string separated by spaces.   The
  689. X                    selector  argument  has  three  forms.  If it is a
  690. X                    single number then it selects the  word  given  by
  691. X                    that  number  (0  for  the command name, 1 for its
  692. X                    first argument, and so on).  If it consists of two
  693. X                    numbers  separated  by a dash, then it selects all
  694. X                    the  arguments  between  those   two.    Otherwise
  695. X                    selector  is  treated  as  a  pattern;  all  words
  696. X                    matching that pattern  (in  the  sense  of  string
  697. X                    match)  are  returned.  In the numeric forms $ may
  698. X                    be used to select the last word of a command.  For
  699. X                    example,  suppose  the  most recent command in the
  700. X                    history list is
  701. X
  702. X                      format  {%s is %d years old} Alice [expr $ageInMonths/12]
  703. X
  704. X                    Below are some history commands  and  the  results
  705. X                    they would produce:
  706. X
  707. X
  708. X                         history words $ 
  709. X                                 [expr $ageInMonths/12]
  710. X                         history words 1-2
  711. X                                 {%s is %d years  old} Alice
  712. X                         history words *a*o*
  713. X                                 {%s is %d years old} [expr $ageInMonths/12]
  714. X                    History words results in  history  revision:   see
  715. X                    below for details.
  716. X
  717. X               The history options event, redo, substitute, and  words
  718. X               result  in  ``history  revision''.   When  one of these
  719. X               options is invoked then the current event  is  modified
  720. X               to  eliminate  the  history command and replace it with
  721. X               the  result  of  the  history  command.   For  example,
  722. X               suppose  that  the  most  recent command in the history
  723. X               list is
  724. X
  725. X                    set a [expr $b+2]
  726. X
  727. X               and suppose that the next command invoked is one of the
  728. X               ones  on the left side of the table below.  The command
  729. X               actually recorded in the  history  event  will  be  the
  730. X               corresponding one on the right side of the table.
  731. X
  732. X
  733. X                    history                set a [expr $b+2]
  734. X                    history s a b          set b [expr $b+2]
  735. X                    set c [history w 2]    set c [expr $b+2]
  736. X
  737. X               History revision is  needed  because  event  specifiers
  738. X               like -1 are only valid at a particular time:  once more
  739. X               events have been added to the history list a  different
  740. X               event  specifier  would  be  needed.   History revision
  741. X               occurs even when history is invoked indirectly from the
  742. X               current event (e.g. a user types a command that invokes
  743. X               a Tcl procedure that invokes history):   the  top-level
  744. X               command   whose  execution  eventually  resulted  in  a
  745. X               history command is replaced.  If  you  wish  to  invoke
  746. X               commands  like  history words without history revision,
  747. X               you can use history event to save the  current  history
  748. X               event and then use history change to restore it later.
  749. END_OF_FILE
  750. if test 8154 -ne `wc -c <'extended/tcllib/help/commands/history'`; then
  751.     echo shar: \"'extended/tcllib/help/commands/history'\" unpacked with wrong size!
  752. fi
  753. # end of 'extended/tcllib/help/commands/history'
  754. fi
  755. if test -f 'extended/tcllib/help/commands/info' -a "${1}" != "-c" ; then 
  756.   echo shar: Will not clobber existing file \"'extended/tcllib/help/commands/info'\"
  757. else
  758. echo shar: Extracting \"'extended/tcllib/help/commands/info'\" \(6394 characters\)
  759. sed "s/^X//" >'extended/tcllib/help/commands/info' <<'END_OF_FILE'
  760. X          info option ?arg arg ...?
  761. X               Provide information about various internals to the  Tcl
  762. X               interpreter.    The   legal   option's  (which  may  be
  763. X               abbreviated) are:
  764. X
  765. X               info args procname
  766. X                    Returns  a  list  containing  the  names  of   the
  767. X                    arguments   to   procedure   procname,  in  order.
  768. X                    Procname  must  be  the  name  of  a  Tcl  command
  769. X                    procedure.
  770. X
  771. X               info body procname
  772. X                    Returns the body of procedure procname.   Procname
  773. X                    must be the name of a Tcl command procedure.
  774. X
  775. X               info cmdcount
  776. X                    Returns a count of the total  number  of  commands
  777. X                    that have been invoked in this interpreter.
  778. X
  779. X               info commands ?pattern?
  780. X                    If pattern isn't  specified,  returns  a  list  of
  781. X                    names  of all the Tcl commands, including both the
  782. X                    built-in commands written in  C  and  the  command
  783. X                    procedures  defined  using  the  proc command.  If
  784. X                    pattern is specified, only  those  names  matching
  785. X                    pattern  are  returned.   Matching  is  determined
  786. X                    using the same rules as for string match.
  787. X
  788. X               info default procname arg varname
  789. X                    Procname  must  be  the  name  of  a  Tcl  command
  790. X                    procedure  and arg must be the name of an argument
  791. X                    to that procedure.  If arg doesn't have a  default
  792. X                    value  then  the  command returns 0.  Otherwise it
  793. X                    returns 1 and places the default value of arg into
  794. X                    variable varname.
  795. X
  796. X               info exists varName
  797. X                    Returns 1 if the variable named varName exists  in
  798. X                    the  current  context (either as a global or local
  799. X                    variable), returns 0 otherwise.
  800. X
  801. X               info globals ?pattern?
  802. X                    If pattern isn't specified, returns a list of  all
  803. X                    the  names  of currently-defined global variables.
  804. X                    If pattern is specified, only those names matching
  805. X                    pattern  are  returned.   Matching  is  determined
  806. X                    using the same rules as for string match.
  807. X
  808. X               info level ?number?
  809. X                    If number is not specified, this command returns a
  810. X                    number  giving  the  stack  level  of the invoking
  811. X                    procedure, or 0 if the command is invoked at  top-
  812. X                    level.  If number is specified, then the result is
  813. X                    a list consisting of the name  and  arguments  for
  814. X                    the  procedure  call at level number on the stack.
  815. X                    If number is positive then it selects a particular
  816. X                    stack  level  (1  refers  to  the  top-most active
  817. X                    procedure, 2 to the procedure it  called,  and  so
  818. X                    on);  otherwise  it  gives a level relative to the
  819. X                    current level (0 refers to the current  procedure,
  820. X                    -1  to  its  caller,  and so on).  See the uplevel
  821. X                    command for more information on what stack  levels
  822. X                    mean.
  823. X
  824. X               info library
  825. X                    Returns the name of the library directory in which
  826. X                    standard  Tcl  scripts are stored.  If there is no
  827. X                    such   directory   defined   for    the    current
  828. X                    installation  then an error is generated.  See the
  829. X                    library manual entry for details of the facilities
  830. X                    provided by the Tcl script library.  Normally each
  831. X                    application will have its own application-specific
  832. X                    library  in  addition  to  the Tcl script library;
  833. X                    the location of the  application-specific  library
  834. X                    should be kept in the $appLibrary global variable.
  835. X
  836. X               info locals ?pattern?
  837. X                    If pattern isn't specified, returns a list of  all
  838. X                    the  names  of  currently-defined local variables,
  839. X                    including arguments to the current  procedure,  if
  840. X                    any.   Variables defined with the global and upvar
  841. X                    commands will not  be  returned.   If  pattern  is
  842. X                    specified,  only  those names matching pattern are
  843. X                    returned.  Matching is determined using  the  same
  844. X                    rules as for string match.
  845. X
  846. X               info procs ?pattern?
  847. X                    If pattern isn't specified, returns a list of  all
  848. X                    the  names  of Tcl command procedures.  If pattern
  849. X                    is specified, only those  names  matching  pattern
  850. X                    are  returned.   Matching  is determined using the
  851. X                    same rules as for string match.
  852. X
  853. X               info script
  854. X                    If a Tcl script file is currently being  evaluated
  855. X                    (i.e.  there  is  a call to Tcl_EvalFile active or
  856. X                    there  is  an  active  invocation  of  the  source
  857. X                    command),  then  this  command returns the name of
  858. X                    the innermost file being processed.  Otherwise the
  859. X                    command returns an empty string.
  860. X
  861. X               info tclversion
  862. X                    Returns the version number for this version of Tcl
  863. X                    in  the  form  x.y,  where  changes to x represent
  864. X                    major changes with probable incompatibilities  and
  865. X                    changes  to y represent small enhancements and bug
  866. X                    fixes that retain backward compatibility.
  867. X
  868. X               info vars ?pattern?
  869. X                    If pattern isn't specified, returns a list of  all
  870. X                    the    names   of   currently-visible   variables,
  871. X                    including  both   locals   and   currently-visible
  872. X                    globals.   If  pattern  is  specified,  only those
  873. X                    names matching pattern are returned.  Matching  is
  874. X                    determined  using  the  same  rules  as for string
  875. X                    match.
  876. END_OF_FILE
  877. if test 6394 -ne `wc -c <'extended/tcllib/help/commands/info'`; then
  878.     echo shar: \"'extended/tcllib/help/commands/info'\" unpacked with wrong size!
  879. fi
  880. # end of 'extended/tcllib/help/commands/info'
  881. fi
  882. if test -f 'extended/tclsrc/help.tcl' -a "${1}" != "-c" ; then 
  883.   echo shar: Will not clobber existing file \"'extended/tclsrc/help.tcl'\"
  884. else
  885. echo shar: Extracting \"'extended/tclsrc/help.tcl'\" \(7490 characters\)
  886. sed "s/^X//" >'extended/tclsrc/help.tcl' <<'END_OF_FILE'
  887. X#@package: help help helpcd helppwd apropos
  888. X
  889. X#==============================================================================
  890. X# help.tcl --
  891. X#     Tcl help command. (see Tcl shell manual)
  892. X#==============================================================================
  893. X
  894. X#------------------------------------------------------------------------------
  895. X# Take a path name which might have . and .. elements and flatten them out.
  896. X
  897. Xproc help:flattenPath {pathName} {
  898. X    set newPath {}
  899. X    foreach element [split $pathName /] {
  900. X        if {"$element" == "."} {
  901. X           continue
  902. X        }
  903. X        if {"$element" == ".."} {
  904. X            if {[llength [join $newPath /]] == 0} {
  905. X                error "Help: name goes above subject directory root"}
  906. X            lvarpop newPath [expr [llength $newPath]-1]
  907. X            continue
  908. X        }
  909. X        lappend newPath $element
  910. X    }
  911. X    set newPath [join $newPath /]
  912. X    
  913. X    # Take care of the case where we started with something line "/" or "/."
  914. X
  915. X    if {("$newPath" == "") && [string match "/*" $pathName]} {
  916. X        set newPath "/"}
  917. X        
  918. X    return $newPath
  919. X}
  920. X
  921. X#------------------------------------------------------------------------------
  922. X# Take the help current directory and a path and evaluate it into a help root-
  923. X# based path name.
  924. X
  925. Xproc help:EvalPath {pathName} {
  926. X    global TCLENV
  927. X
  928. X    if {![string match "/*" $pathName]} {
  929. X        if {"$pathName" == ""} {
  930. X            return $TCLENV(help:curDir)}
  931. X        if {"$TCLENV(help:curDir)" == "/"} {
  932. X            set pathName "/$pathName"
  933. X        } else {
  934. X            set pathName "$TCLENV(help:curDir)/$pathName"
  935. X        }
  936. X    }
  937. X    set pathName [help:flattenPath $pathName]
  938. X    if {[string match "*/" $pathName] && ($pathName != "/")} {
  939. X        set pathName [csubstr $pathName 0 [expr [length $pathName]-1]]}
  940. X
  941. X    return $pathName    
  942. X}
  943. X
  944. X#------------------------------------------------------------------------------
  945. X# Display a line of output, pausing waiting for input before displaying if the
  946. X# screen size has been reached.  Return 1 if output is to continue, return
  947. X# 0 if no more should be outputed, indicated by input other than return.
  948. X#
  949. X
  950. Xproc help:Display {line} {
  951. X    global TCLENV
  952. X    if {$TCLENV(help:lineCnt) >= 23} {
  953. X        set TCLENV(help:lineCnt) 0
  954. X        puts stdout ":" nonewline
  955. X        flush stdout
  956. X        gets stdin response
  957. X        if {![lempty $response]} {
  958. X            return 0}
  959. X    }
  960. X    puts stdout $line
  961. X    incr TCLENV(help:lineCnt)
  962. X}
  963. X
  964. X#------------------------------------------------------------------------------
  965. X# Display a file.
  966. X
  967. Xproc help:DisplayFile {filepath} {
  968. X
  969. X    set inFH [open $filepath r]
  970. X    while {[gets $inFH fileBuf] >= 0} {
  971. X        if {![help:Display $fileBuf]} {
  972. X            break}
  973. X    }
  974. X    close $inFH
  975. X
  976. X}    
  977. X
  978. X#------------------------------------------------------------------------------
  979. X# Procedure to return contents of a directory.  A list is returned, consisting
  980. X# of two lists.  The first list are all the directories (subjects) in the
  981. X# specified directory.  The second is all of the help files.  Eash sub-list
  982. X# is sorted in alphabetical order.
  983. X#
  984. X
  985. Xproc help:ListDir {dirPath} {
  986. X    set dirList {}
  987. X    set fileList {}
  988. X    if {[catch {set dirFiles [glob $dirPath/*]}] != 0} {
  989. X        error "No files in subject directory: $dirPath"}
  990. X    foreach fileName $dirFiles {
  991. X        if [file isdirectory $fileName] {
  992. X            lappend dirList "[file tail $fileName]/"
  993. X        } else {
  994. X            lappend fileList [file tail $fileName]
  995. X        }
  996. X    }
  997. X   return [list [lsort $dirList] [lsort $fileList]]
  998. X}
  999. X
  1000. X#------------------------------------------------------------------------------
  1001. X# Display a list of file names in a column format. This use columns of 14 
  1002. X# characters 3 blanks.
  1003. X
  1004. Xproc help:DisplayColumns {nameList} {
  1005. X    set count 0
  1006. X    set outLine ""
  1007. X    foreach name $nameList {
  1008. X        if {$count == 0} {
  1009. X            append outLine "   "}
  1010. X        append outLine $name
  1011. X        if {[incr count] < 4} {
  1012. X            set padLen [expr 17-[clength $name]]
  1013. X            if {$padLen < 3} {
  1014. X               set padLen 3}
  1015. X            append outLine [replicate " " $padLen]
  1016. X        } else {
  1017. X           if {![help:Display $outLine]} {
  1018. X               return}
  1019. X           set outLine ""
  1020. X           set count 0
  1021. X        }
  1022. X    }
  1023. X    if {$count != 0} {
  1024. X        help:Display $outLine}
  1025. X    return
  1026. X}
  1027. X
  1028. X
  1029. X#------------------------------------------------------------------------------
  1030. X# Help command main.
  1031. X
  1032. Xproc help {args} {
  1033. X    global TCLENV
  1034. X
  1035. X    if {[llength $args] > 1} {
  1036. X        error "Help: too many arguments"}
  1037. X
  1038. X    set TCLENV(help:lineCnt) 0
  1039. X
  1040. X    # Special case "help help", so we can get it at any level.
  1041. X
  1042. X    if {("$args" == "help") || ("$args" == "?")} {
  1043. X        help:DisplayFile "$TCLENV(help:root)/help"
  1044. X        return
  1045. X    }
  1046. X
  1047. X    set request [help:EvalPath $args]
  1048. X    set requestPath "$TCLENV(help:root)$request"
  1049. X
  1050. X    if {![file exists $requestPath]} {
  1051. X        error "Help:\"$request\" does not exist"}
  1052. X    
  1053. X    if [file isdirectory $requestPath] {
  1054. X        set dirList [help:ListDir $requestPath]
  1055. X        set subList  [lindex $dirList 0]
  1056. X        set fileList [lindex $dirList 1]
  1057. X        if {[llength $subList] != 0} {
  1058. X            help:Display "\nSubjects available in $request:"
  1059. X            help:DisplayColumns $subList
  1060. X        }
  1061. X        if {[llength $fileList] != 0} {
  1062. X            help:Display "\nHelp files available in $request:"
  1063. X            help:DisplayColumns $fileList
  1064. X        }
  1065. X    } else {
  1066. X        help:DisplayFile $requestPath
  1067. X    }
  1068. X    return
  1069. X}
  1070. X
  1071. X
  1072. X#------------------------------------------------------------------------------
  1073. X# Helpcd main.
  1074. X#   
  1075. X# The name of the new current directory is assembled from the current 
  1076. X# directory and the argument.  The name will be flatten and any trailing
  1077. X# "/" will be removed, unless the name is just "/".
  1078. X
  1079. Xproc helpcd {args} {
  1080. X    global TCLENV
  1081. X
  1082. X    if [lempty $args] {
  1083. X        set args "/"
  1084. X    } else {
  1085. X        if {[llength $args] > 1} {
  1086. X            error "Helpcd: too many arugments"}
  1087. X    }
  1088. X    
  1089. X    set request [help:EvalPath $args]
  1090. X    set requestPath "$TCLENV(help:root)$request"
  1091. X
  1092. X    if {![file exists $requestPath]} {
  1093. X        error "Helpcd: \"$request\" does not exist"}
  1094. X    
  1095. X    if {![file isdirectory $requestPath]} {
  1096. X        error "Helpcd: \"$request\" is not a directory"}
  1097. X
  1098. X    set TCLENV(help:curDir) $request
  1099. X    return    
  1100. X}
  1101. X
  1102. X#------------------------------------------------------------------------------
  1103. X# Helpcd main.
  1104. X
  1105. Xproc helppwd {} {
  1106. X        global TCLENV
  1107. X        echo "Current help subject directory: $TCLENV(help:curDir)"
  1108. X}
  1109. X
  1110. X#==============================================================================
  1111. X#     Tcl apropos command.  (see Tcl shell manual)
  1112. X#------------------------------------------------------------------------------
  1113. X
  1114. Xproc apropos {name} {
  1115. X    global TCLENV
  1116. X
  1117. X    set TCLENV(help:lineCnt) 0
  1118. X
  1119. X    set aproposCT [scancontext create]
  1120. X    scanmatch -nocase $aproposCT $name {
  1121. X        set path [lindex $matchInfo(line) 0]
  1122. X        set desc [lrange $matchInfo(line) 1 end]
  1123. X        if {![help:Display [format "%s - %s" $path $desc]]} {
  1124. X            return}
  1125. X    }
  1126. X    set briefFH [open $TCLENV(help:root)/brief]
  1127. X
  1128. X    scanfile $aproposCT $briefFH
  1129. X
  1130. X    scancontext delete $aproposCT
  1131. X    close $briefFH
  1132. X}
  1133. X
  1134. X#------------------------------------------------------------------------------
  1135. X# One time initialization done when the file is sourced.
  1136. X#
  1137. Xglobal TCLENV TCLPATH
  1138. X
  1139. Xset TCLENV(help:root) [searchpath $TCLPATH help]
  1140. Xset TCLENV(help:curDir) "/"
  1141. Xset TCLENV(help:outBuf) {}
  1142. END_OF_FILE
  1143. if test 7490 -ne `wc -c <'extended/tclsrc/help.tcl'`; then
  1144.     echo shar: \"'extended/tclsrc/help.tcl'\" unpacked with wrong size!
  1145. fi
  1146. # end of 'extended/tclsrc/help.tcl'
  1147. fi
  1148. if test -f 'extended/tests/iocmds.test' -a "${1}" != "-c" ; then 
  1149.   echo shar: Will not clobber existing file \"'extended/tests/iocmds.test'\"
  1150. else
  1151. echo shar: Extracting \"'extended/tests/iocmds.test'\" \(6451 characters\)
  1152. sed "s/^X//" >'extended/tests/iocmds.test' <<'END_OF_FILE'
  1153. X#
  1154. X# iocmds.test
  1155. X#
  1156. X# Tests for the bsearch, dup, copyfile, pipe, and fcntl commands.
  1157. X#---------------------------------------------------------------------------
  1158. X# Copyright 1991 Karl Lehenbauer and Mark Diekhans.
  1159. X#
  1160. X# Permission to use, copy, modify, and distribute this software and its
  1161. X# documentation for any purpose and without fee is hereby granted, provided
  1162. X# that the above copyright notice appear in all copies.  Karl Lehenbauer and
  1163. X# Mark Diekhans make no representations about the suitability of this
  1164. X# software for any purpose.  It is provided "as is" without express or
  1165. X# implied warranty.
  1166. X#
  1167. X
  1168. Xglobal ModuleName
  1169. Xset ModuleName "Unix I/O"
  1170. Xsource testutil.tcl
  1171. Xif {[info procs test] != "test"} then {source defs}
  1172. X
  1173. X# Genenerate a unique file record that can be verified.  The record has 
  1174. X# grows quite large to test the dynamic buffering in the file I/O.
  1175. X
  1176. Xproc GenRec {id} {
  1177. X    return [format "Key:%04d {This is a test of file I/O (%d)} KeyX:%04d %s" \
  1178. X                    $id $id $id [replicate :@@@@@@@@: $id]]
  1179. X}
  1180. X
  1181. X# Create a test file
  1182. X
  1183. Xcatch {unlink {IOTEST.TMP IOTEST2.TMP}}
  1184. X
  1185. Xset testFH [open IOTEST.TMP w]
  1186. Xfor {set cnt 0} {$cnt < 100} {incr cnt} {
  1187. X     puts $testFH [GenRec $cnt]
  1188. X}
  1189. Xclose $testFH
  1190. X
  1191. X# Test bsearch
  1192. X
  1193. Xproc BsearchTestCmp {key line} {
  1194. X    set linekey [lindex $line 2]
  1195. X    return [string compare $key $linekey]
  1196. X}
  1197. X
  1198. Xset testFH [open IOTEST.TMP r]
  1199. Xset toggle 0
  1200. Xfor {set cnt 0} {$cnt < 100} {incr cnt} {
  1201. X    set key1 [format "Key:%04d" $cnt]
  1202. X    set key2 [format "KeyX:%04d" $cnt]
  1203. X    if {($cnt % 6) == 0} {
  1204. X        if {$toggle} {
  1205. X            set rec1 [bsearch $testFH $key1]
  1206. X            set rec2 [bsearch $testFH $key2 {} BsearchTestCmp]
  1207. X        } else {
  1208. X            check [bsearch $testFH $key1 rec1] 1                          1.1
  1209. X            check [bsearch $testFH $key2 rec2 BsearchTestCmp] 1           1.2
  1210. X        }
  1211. X        set expect [GenRec $cnt]
  1212. X        check $rec1 $expect                                              1.3
  1213. X        check $rec2 $expect                                              1.4
  1214. X        set toggle [expr !$toggle]
  1215. X    }
  1216. X}
  1217. Xclose $testFH
  1218. X
  1219. X# Test dup, including redirection of stdin/stdout in a child process.
  1220. X
  1221. Xset testFH [open IOTEST.TMP]
  1222. Xset testFH2 [dup $testFH]
  1223. Xgets $testFH2 testRec
  1224. Xcheck $testRec [GenRec 0]                                               2.1
  1225. Xclose $testFH
  1226. Xclose $testFH2
  1227. X
  1228. Xset data {{now is the time}    {for all good programmers} 
  1229. X          {to come to the aid} {of their software}}
  1230. Xset inFH [open INCMDS.TMP w]
  1231. Xcatch {unlink OUTPUT.TMP}
  1232. Xforeach line $data {
  1233. X    puts $inFH "puts stdout \"$line\""
  1234. X}
  1235. Xputs $inFH {flush stdout}
  1236. Xputs $inFH {exit 0}
  1237. Xclose $inFH
  1238. X
  1239. Xif {[set childPid [fork]] == 0} {
  1240. X    set inFH  [open INCMDS.TMP r]
  1241. X    set outFH [open OUTPUT.TMP w]
  1242. X
  1243. X    close stdin
  1244. X    dup $inFH stdin
  1245. X    close $inFH
  1246. X
  1247. X    close stdout
  1248. X    dup $outFH stdout
  1249. X    close $outFH
  1250. X        
  1251. X    execvp ../tcl -qc {commandloop {return ""} {return ""}}
  1252. X    error "Should never make it here"
  1253. X}
  1254. X
  1255. Xcheck [wait $childPid] "$childPid EXIT 0"                               2.3
  1256. X
  1257. Xset outFH [open OUTPUT.TMP r]
  1258. Xforeach line $data {
  1259. X    check [gets $outFH] $line                                           2.4
  1260. X}
  1261. Xclose $outFH
  1262. X
  1263. X
  1264. X# Test copyfile
  1265. X
  1266. Xset testFH [open IOTEST.TMP r]
  1267. Xset testFH2 [open IOTEST2.TMP w]
  1268. Xcopyfile $testFH $testFH2
  1269. Xclose $testFH
  1270. Xclose $testFH2
  1271. Xset retVal [system "diff IOTEST.TMP IOTEST2.TMP >/dev/null 2>&1"]
  1272. Xcheck $retVal 0                                                         3.1
  1273. X
  1274. Xset testFH [open IOTEST.TMP w]
  1275. Xset testFH2 [open IOTEST2.TMP w]
  1276. Xdo1cmd {copyfile $testFH $testFH2} msg                                  3.2
  1277. Xcheck $msg {Source file is not open for read access}                    3.3
  1278. Xclose $testFH
  1279. Xclose $testFH2
  1280. X
  1281. Xset testFH [open IOTEST.TMP r]
  1282. Xset testFH2 [open IOTEST2.TMP r]
  1283. Xdo1cmd {copyfile $testFH $testFH2} msg                                  3.4
  1284. Xcheck $msg {Target file is not open for write access}                   3.5
  1285. Xclose $testFH
  1286. Xclose $testFH2
  1287. X
  1288. Xdo1cmd {copyfile $testFH $testFH2}  msg                                 3.6
  1289. Xcheck $msg "file \"$testFH\" isn't open"                                3.7
  1290. Xdo1cmd {copyfile} msg                                                   3.8
  1291. Xcheck $msg {wrong # args: copyfile fromfilehandle tofilehandle}         3.9
  1292. X
  1293. X# Test the pipe command.
  1294. X
  1295. Xpipe readPF writePF
  1296. X
  1297. Xflush stdout  ;# Not going to exec, must clean up the buffers.
  1298. Xflush stderr
  1299. Xset sonPid [fork]
  1300. X
  1301. Xif {$sonPid == 0} {
  1302. X    for {set cnt 0} {$cnt < 50} {incr cnt} {
  1303. X        if {![gets $readPF msgBuf]} {
  1304. X            check "Premature eof on pipe" ""                            4.1
  1305. X        }
  1306. X        check $msgBuf [GenRec $cnt]                                     4.2
  1307. X    }
  1308. X    close $readPF
  1309. X    exit 0
  1310. X}
  1311. X
  1312. Xfor {set cnt 0} {$cnt < 50} {incr cnt} {
  1313. X    puts $writePF [GenRec $cnt]
  1314. X}
  1315. Xflush $writePF
  1316. Xcheck [wait $sonPid] "$sonPid EXIT 0"                                  4.3
  1317. Xclose $readPF
  1318. Xclose $writePF
  1319. X
  1320. X# Test fcntl.
  1321. X
  1322. Xset testFH [open IOTEST.TMP r+]
  1323. X
  1324. Xcheck [fcntl $testFH] {RDWR}                 5.1
  1325. X
  1326. Xfcntl $testFH CLEXEC 1
  1327. Xcheck [fcntl $testFH] {RDWR CLEXEC}          5.2
  1328. X
  1329. Xfcntl $testFH CLEXEC 0
  1330. Xcheck [fcntl $testFH] {RDWR}                 5.3
  1331. X
  1332. Xfcntl $testFH NDELAY 1
  1333. Xcheck [fcntl $testFH] {RDWR NDELAY}          5.4
  1334. X
  1335. Xfcntl $testFH append 1
  1336. Xcheck [fcntl $testFH] {RDWR NDELAY APPEND}   5.5
  1337. X
  1338. Xfcntl $testFH APPEND 0
  1339. Xcheck [fcntl $testFH] {RDWR NDELAY}          5.6
  1340. X
  1341. Xfcntl $testFH ndelay 0
  1342. Xcheck [fcntl $testFH] {RDWR}                 5.7
  1343. X
  1344. Xfcntl $testFH NOBUF 1
  1345. Xcheck [fcntl $testFH] {RDWR NOBUF}           5.7.1
  1346. X
  1347. Xdo1cmd "fcntl $testFH NOBUF 0" msg           5.7.2
  1348. Xcheck $msg {NOBUF flag may not be cleared}   5.7.3
  1349. X
  1350. Xclose $testFH
  1351. Xset testFH [open IOTEST.TMP r+]  ;# Reopen, can not have both nobuf and linebuf
  1352. X
  1353. Xfcntl $testFH LINEBUF 1
  1354. Xcheck [fcntl $testFH] {RDWR LINEBUF}         5.7.4
  1355. X
  1356. Xdo1cmd "fcntl $testFH LINEBUF 0" msg         5.7.5
  1357. Xcheck $msg {LINEBUF flag may not be cleared} 5.7.6
  1358. X
  1359. X
  1360. Xdo1cmd "fcntl $testFH FOO" msg               5.8
  1361. Xcheck $msg {wrong # args: fcntl handle [attribute value]}  5.9
  1362. X
  1363. Xdo1cmd "fcntl $testFH BAZ 1" msg             5.10
  1364. Xcheck $msg {unknown attribute name "BAZ", expected one of: APPEND, CLEXEC, NDELAY, NOBUF, LINEBUF}         5.12
  1365. X
  1366. Xdo1cmd "fcntl $testFH APPEND FOO" msg        5.13
  1367. Xcheck $msg {expected boolean value but got "FOO"}         5.14
  1368. X
  1369. Xclose $testFH
  1370. X
  1371. Xdo1cmd "fcntl $testFH" msg                   5.15
  1372. Xcheck $msg "file \"$testFH\" isn't open"     5.16
  1373. X
  1374. Xunlink {IOTEST.TMP IOTEST2.TMP OUTPUT.TMP INCMDS.TMP}
  1375. Xrename GenRec {}
  1376. X
  1377. X
  1378. END_OF_FILE
  1379. if test 6451 -ne `wc -c <'extended/tests/iocmds.test'`; then
  1380.     echo shar: \"'extended/tests/iocmds.test'\" unpacked with wrong size!
  1381. fi
  1382. # end of 'extended/tests/iocmds.test'
  1383. fi
  1384. echo shar: End of archive 10 \(of 23\).
  1385. cp /dev/null ark10isdone
  1386. MISSING=""
  1387. 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 ; do
  1388.     if test ! -f ark${I}isdone ; then
  1389.     MISSING="${MISSING} ${I}"
  1390.     fi
  1391. done
  1392. if test "${MISSING}" = "" ; then
  1393.     echo You have unpacked all 23 archives.
  1394.     echo "Now cd to "extended", edit the makefile, then do a "make""
  1395.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1396. else
  1397.     echo You still need to unpack the following archives:
  1398.     echo "        " ${MISSING}
  1399. fi
  1400. ##  End of shell archive.
  1401. exit 0
  1402.  
  1403. exit 0 # Just in case...
  1404. -- 
  1405. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  1406. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  1407. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  1408. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  1409.