home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume18 / perl / part17 < prev    next >
Internet Message Format  |  1991-04-16  |  52KB

  1. From: lwall@netlabs.com (Larry Wall)
  2. Newsgroups: comp.sources.misc
  3. Subject: v18i035:  perl - The perl programming language, Part17/36
  4. Message-ID: <1991Apr16.185449.931@sparky.IMD.Sterling.COM>
  5. Date: 16 Apr 91 18:54:49 GMT
  6. Approved: kent@sparky.imd.sterling.com
  7. X-Checksum-Snefru: d636a17b 9d9bfb8c 10b58cd4 517fca7f
  8.  
  9. Submitted-by: Larry Wall <lwall@netlabs.com>
  10. Posting-number: Volume 18, Issue 35
  11. Archive-name: perl/part17
  12.  
  13. [There are 36 kits for perl version 4.0.]
  14.  
  15. #! /bin/sh
  16.  
  17. # Make a new directory for the perl sources, cd to it, and run kits 1
  18. # thru 36 through sh.  When all 36 kits have been run, read README.
  19.  
  20. echo "This is perl 4.0 kit 17 (of 36).  If kit 17 is complete, the line"
  21. echo '"'"End of kit 17 (of 36)"'" will echo at the end.'
  22. echo ""
  23. export PATH || (echo "You didn't use sh, you clunch." ; kill $$)
  24. mkdir lib 2>/dev/null
  25. echo Extracting util.c
  26. sed >util.c <<'!STUFFY!FUNK!' -e 's/X//'
  27. X/* $RCSfile: util.c,v $$Revision: 4.0.1.1 $$Date: 91/04/12 09:19:25 $
  28. X *
  29. X *    Copyright (c) 1989, Larry Wall
  30. X *
  31. X *    You may distribute under the terms of the GNU General Public License
  32. X *    as specified in the README file that comes with the perl 3.0 kit.
  33. X *
  34. X * $Log:    util.c,v $
  35. X * Revision 4.0.1.1  91/04/12  09:19:25  lwall
  36. X * patch1: random cleanup in cpp namespace
  37. X * 
  38. X * Revision 4.0  91/03/20  01:56:39  lwall
  39. X * 4.0 baseline.
  40. X * 
  41. X */
  42. X
  43. X#include "EXTERN.h"
  44. X#include "perl.h"
  45. X
  46. X#if !defined(NSIG) || defined(M_UNIX) || defined(M_XENIX)
  47. X#include <signal.h>
  48. X#endif
  49. X
  50. X#ifdef I_VFORK
  51. X#  include <vfork.h>
  52. X#endif
  53. X
  54. X#ifdef I_VARARGS
  55. X#  include <varargs.h>
  56. X#endif
  57. X
  58. X#ifdef I_FCNTL
  59. X#  include <fcntl.h>
  60. X#endif
  61. X#ifdef I_SYS_FILE
  62. X#  include <sys/file.h>
  63. X#endif
  64. X
  65. X#define FLUSH
  66. X
  67. Xstatic char nomem[] = "Out of memory!\n";
  68. X
  69. X/* paranoid version of malloc */
  70. X
  71. X#ifdef DEBUGGING
  72. Xstatic int an = 0;
  73. X#endif
  74. X
  75. X/* NOTE:  Do not call the next three routines directly.  Use the macros
  76. X * in handy.h, so that we can easily redefine everything to do tracking of
  77. X * allocated hunks back to the original New to track down any memory leaks.
  78. X */
  79. X
  80. Xchar *
  81. Xsafemalloc(size)
  82. X#ifdef MSDOS
  83. Xunsigned long size;
  84. X#else
  85. XMEM_SIZE size;
  86. X#endif /* MSDOS */
  87. X{
  88. X    char *ptr;
  89. X#ifndef __STDC__
  90. X    char *malloc();
  91. X#endif /* ! __STDC__ */
  92. X
  93. X#ifdef MSDOS
  94. X    if (size > 0xffff) {
  95. X        fprintf(stderr, "Allocation too large: %lx\n", size) FLUSH;
  96. X        exit(1);
  97. X    }
  98. X#endif /* MSDOS */
  99. X#ifdef DEBUGGING
  100. X    if ((long)size < 0)
  101. X    fatal("panic: malloc");
  102. X#endif
  103. X    ptr = malloc(size?size:1);    /* malloc(0) is NASTY on our system */
  104. X#ifdef DEBUGGING
  105. X#  ifndef I286
  106. X    if (debug & 128)
  107. X    fprintf(stderr,"0x%x: (%05d) malloc %d bytes\n",ptr,an++,size);
  108. X#  else
  109. X    if (debug & 128)
  110. X    fprintf(stderr,"0x%lx: (%05d) malloc %d bytes\n",ptr,an++,size);
  111. X#  endif
  112. X#endif
  113. X    if (ptr != Nullch)
  114. X    return ptr;
  115. X    else {
  116. X    fputs(nomem,stderr) FLUSH;
  117. X    exit(1);
  118. X    }
  119. X    /*NOTREACHED*/
  120. X#ifdef lint
  121. X    return ptr;
  122. X#endif
  123. X}
  124. X
  125. X/* paranoid version of realloc */
  126. X
  127. Xchar *
  128. Xsaferealloc(where,size)
  129. Xchar *where;
  130. X#ifndef MSDOS
  131. XMEM_SIZE size;
  132. X#else
  133. Xunsigned long size;
  134. X#endif /* MSDOS */
  135. X{
  136. X    char *ptr;
  137. X#ifndef __STDC__
  138. X    char *realloc();
  139. X#endif /* ! __STDC__ */
  140. X
  141. X#ifdef MSDOS
  142. X    if (size > 0xffff) {
  143. X        fprintf(stderr, "Reallocation too large: %lx\n", size) FLUSH;
  144. X        exit(1);
  145. X    }
  146. X#endif /* MSDOS */
  147. X    if (!where)
  148. X    fatal("Null realloc");
  149. X#ifdef DEBUGGING
  150. X    if ((long)size < 0)
  151. X    fatal("panic: realloc");
  152. X#endif
  153. X    ptr = realloc(where,size?size:1);    /* realloc(0) is NASTY on our system */
  154. X#ifdef DEBUGGING
  155. X#  ifndef I286
  156. X    if (debug & 128) {
  157. X    fprintf(stderr,"0x%x: (%05d) rfree\n",where,an++);
  158. X    fprintf(stderr,"0x%x: (%05d) realloc %d bytes\n",ptr,an++,size);
  159. X    }
  160. X#  else
  161. X    if (debug & 128) {
  162. X    fprintf(stderr,"0x%lx: (%05d) rfree\n",where,an++);
  163. X    fprintf(stderr,"0x%lx: (%05d) realloc %d bytes\n",ptr,an++,size);
  164. X    }
  165. X#  endif
  166. X#endif
  167. X    if (ptr != Nullch)
  168. X    return ptr;
  169. X    else {
  170. X    fputs(nomem,stderr) FLUSH;
  171. X    exit(1);
  172. X    }
  173. X    /*NOTREACHED*/
  174. X#ifdef lint
  175. X    return ptr;
  176. X#endif
  177. X}
  178. X
  179. X/* safe version of free */
  180. X
  181. Xvoid
  182. Xsafefree(where)
  183. Xchar *where;
  184. X{
  185. X#ifdef DEBUGGING
  186. X#  ifndef I286
  187. X    if (debug & 128)
  188. X    fprintf(stderr,"0x%x: (%05d) free\n",where,an++);
  189. X#  else
  190. X    if (debug & 128)
  191. X    fprintf(stderr,"0x%lx: (%05d) free\n",where,an++);
  192. X#  endif
  193. X#endif
  194. X    if (where) {
  195. X    free(where);
  196. X    }
  197. X}
  198. X
  199. X#ifdef LEAKTEST
  200. X
  201. X#define ALIGN sizeof(long)
  202. X
  203. Xchar *
  204. Xsafexmalloc(x,size)
  205. Xint x;
  206. XMEM_SIZE size;
  207. X{
  208. X    register char *where;
  209. X
  210. X    where = safemalloc(size + ALIGN);
  211. X    xcount[x]++;
  212. X    where[0] = x % 100;
  213. X    where[1] = x / 100;
  214. X    return where + ALIGN;
  215. X}
  216. X
  217. Xchar *
  218. Xsafexrealloc(where,size)
  219. Xchar *where;
  220. XMEM_SIZE size;
  221. X{
  222. X    return saferealloc(where - ALIGN, size + ALIGN) + ALIGN;
  223. X}
  224. X
  225. Xvoid
  226. Xsafexfree(where)
  227. Xchar *where;
  228. X{
  229. X    int x;
  230. X
  231. X    if (!where)
  232. X    return;
  233. X    where -= ALIGN;
  234. X    x = where[0] + 100 * where[1];
  235. X    xcount[x]--;
  236. X    safefree(where);
  237. X}
  238. X
  239. Xxstat()
  240. X{
  241. X    register int i;
  242. X
  243. X    for (i = 0; i < MAXXCOUNT; i++) {
  244. X    if (xcount[i] != lastxcount[i]) {
  245. X        fprintf(stderr,"%2d %2d\t%ld\n", i / 100, i % 100, xcount[i]);
  246. X        lastxcount[i] = xcount[i];
  247. X    }
  248. X    }
  249. X}
  250. X
  251. X#endif /* LEAKTEST */
  252. X
  253. X/* copy a string up to some (non-backslashed) delimiter, if any */
  254. X
  255. Xchar *
  256. Xcpytill(to,from,fromend,delim,retlen)
  257. Xregister char *to;
  258. Xregister char *from;
  259. Xregister char *fromend;
  260. Xregister int delim;
  261. Xint *retlen;
  262. X{
  263. X    char *origto = to;
  264. X
  265. X    for (; from < fromend; from++,to++) {
  266. X    if (*from == '\\') {
  267. X        if (from[1] == delim)
  268. X        from++;
  269. X        else if (from[1] == '\\')
  270. X        *to++ = *from++;
  271. X    }
  272. X    else if (*from == delim)
  273. X        break;
  274. X    *to = *from;
  275. X    }
  276. X    *to = '\0';
  277. X    *retlen = to - origto;
  278. X    return from;
  279. X}
  280. X
  281. X/* return ptr to little string in big string, NULL if not found */
  282. X/* This routine was donated by Corey Satten. */
  283. X
  284. Xchar *
  285. Xinstr(big, little)
  286. Xregister char *big;
  287. Xregister char *little;
  288. X{
  289. X    register char *s, *x;
  290. X    register int first;
  291. X
  292. X    if (!little)
  293. X    return big;
  294. X    first = *little++;
  295. X    if (!first)
  296. X    return big;
  297. X    while (*big) {
  298. X    if (*big++ != first)
  299. X        continue;
  300. X    for (x=big,s=little; *s; /**/ ) {
  301. X        if (!*x)
  302. X        return Nullch;
  303. X        if (*s++ != *x++) {
  304. X        s--;
  305. X        break;
  306. X        }
  307. X    }
  308. X    if (!*s)
  309. X        return big-1;
  310. X    }
  311. X    return Nullch;
  312. X}
  313. X
  314. X/* same as instr but allow embedded nulls */
  315. X
  316. Xchar *
  317. Xninstr(big, bigend, little, lend)
  318. Xregister char *big;
  319. Xregister char *bigend;
  320. Xchar *little;
  321. Xchar *lend;
  322. X{
  323. X    register char *s, *x;
  324. X    register int first = *little;
  325. X    register char *littleend = lend;
  326. X
  327. X    if (!first && little > littleend)
  328. X    return big;
  329. X    bigend -= littleend - little++;
  330. X    while (big <= bigend) {
  331. X    if (*big++ != first)
  332. X        continue;
  333. X    for (x=big,s=little; s < littleend; /**/ ) {
  334. X        if (*s++ != *x++) {
  335. X        s--;
  336. X        break;
  337. X        }
  338. X    }
  339. X    if (s >= littleend)
  340. X        return big-1;
  341. X    }
  342. X    return Nullch;
  343. X}
  344. X
  345. X/* reverse of the above--find last substring */
  346. X
  347. Xchar *
  348. Xrninstr(big, bigend, little, lend)
  349. Xregister char *big;
  350. Xchar *bigend;
  351. Xchar *little;
  352. Xchar *lend;
  353. X{
  354. X    register char *bigbeg;
  355. X    register char *s, *x;
  356. X    register int first = *little;
  357. X    register char *littleend = lend;
  358. X
  359. X    if (!first && little > littleend)
  360. X    return bigend;
  361. X    bigbeg = big;
  362. X    big = bigend - (littleend - little++);
  363. X    while (big >= bigbeg) {
  364. X    if (*big-- != first)
  365. X        continue;
  366. X    for (x=big+2,s=little; s < littleend; /**/ ) {
  367. X        if (*s++ != *x++) {
  368. X        s--;
  369. X        break;
  370. X        }
  371. X    }
  372. X    if (s >= littleend)
  373. X        return big+1;
  374. X    }
  375. X    return Nullch;
  376. X}
  377. X
  378. Xunsigned char fold[] = {
  379. X    0,    1,    2,    3,    4,    5,    6,    7,
  380. X    8,    9,    10,    11,    12,    13,    14,    15,
  381. X    16,    17,    18,    19,    20,    21,    22,    23,
  382. X    24,    25,    26,    27,    28,    29,    30,    31,
  383. X    32,    33,    34,    35,    36,    37,    38,    39,
  384. X    40,    41,    42,    43,    44,    45,    46,    47,
  385. X    48,    49,    50,    51,    52,    53,    54,    55,
  386. X    56,    57,    58,    59,    60,    61,    62,    63,
  387. X    64,    'a',    'b',    'c',    'd',    'e',    'f',    'g',
  388. X    'h',    'i',    'j',    'k',    'l',    'm',    'n',    'o',
  389. X    'p',    'q',    'r',    's',    't',    'u',    'v',    'w',
  390. X    'x',    'y',    'z',    91,    92,    93,    94,    95,
  391. X    96,    'A',    'B',    'C',    'D',    'E',    'F',    'G',
  392. X    'H',    'I',    'J',    'K',    'L',    'M',    'N',    'O',
  393. X    'P',    'Q',    'R',    'S',    'T',    'U',    'V',    'W',
  394. X    'X',    'Y',    'Z',    123,    124,    125,    126,    127,
  395. X    128,    129,    130,    131,    132,    133,    134,    135,
  396. X    136,    137,    138,    139,    140,    141,    142,    143,
  397. X    144,    145,    146,    147,    148,    149,    150,    151,
  398. X    152,    153,    154,    155,    156,    157,    158,    159,
  399. X    160,    161,    162,    163,    164,    165,    166,    167,
  400. X    168,    169,    170,    171,    172,    173,    174,    175,
  401. X    176,    177,    178,    179,    180,    181,    182,    183,
  402. X    184,    185,    186,    187,    188,    189,    190,    191,
  403. X    192,    193,    194,    195,    196,    197,    198,    199,
  404. X    200,    201,    202,    203,    204,    205,    206,    207,
  405. X    208,    209,    210,    211,    212,    213,    214,    215,
  406. X    216,    217,    218,    219,    220,    221,    222,    223,    
  407. X    224,    225,    226,    227,    228,    229,    230,    231,
  408. X    232,    233,    234,    235,    236,    237,    238,    239,
  409. X    240,    241,    242,    243,    244,    245,    246,    247,
  410. X    248,    249,    250,    251,    252,    253,    254,    255
  411. X};
  412. X
  413. Xstatic unsigned char freq[] = {
  414. X    1,    2,    84,    151,    154,    155,    156,    157,
  415. X    165,    246,    250,    3,    158,    7,    18,    29,
  416. X    40,    51,    62,    73,    85,    96,    107,    118,
  417. X    129,    140,    147,    148,    149,    150,    152,    153,
  418. X    255,    182,    224,    205,    174,    176,    180,    217,
  419. X    233,    232,    236,    187,    235,    228,    234,    226,
  420. X    222,    219,    211,    195,    188,    193,    185,    184,
  421. X    191,    183,    201,    229,    181,    220,    194,    162,
  422. X    163,    208,    186,    202,    200,    218,    198,    179,
  423. X    178,    214,    166,    170,    207,    199,    209,    206,
  424. X    204,    160,    212,    216,    215,    192,    175,    173,
  425. X    243,    172,    161,    190,    203,    189,    164,    230,
  426. X    167,    248,    227,    244,    242,    255,    241,    231,
  427. X    240,    253,    169,    210,    245,    237,    249,    247,
  428. X    239,    168,    252,    251,    254,    238,    223,    221,
  429. X    213,    225,    177,    197,    171,    196,    159,    4,
  430. X    5,    6,    8,    9,    10,    11,    12,    13,
  431. X    14,    15,    16,    17,    19,    20,    21,    22,
  432. X    23,    24,    25,    26,    27,    28,    30,    31,
  433. X    32,    33,    34,    35,    36,    37,    38,    39,
  434. X    41,    42,    43,    44,    45,    46,    47,    48,
  435. X    49,    50,    52,    53,    54,    55,    56,    57,
  436. X    58,    59,    60,    61,    63,    64,    65,    66,
  437. X    67,    68,    69,    70,    71,    72,    74,    75,
  438. X    76,    77,    78,    79,    80,    81,    82,    83,
  439. X    86,    87,    88,    89,    90,    91,    92,    93,
  440. X    94,    95,    97,    98,    99,    100,    101,    102,
  441. X    103,    104,    105,    106,    108,    109,    110,    111,
  442. X    112,    113,    114,    115,    116,    117,    119,    120,
  443. X    121,    122,    123,    124,    125,    126,    127,    128,
  444. X    130,    131,    132,    133,    134,    135,    136,    137,
  445. X    138,    139,    141,    142,    143,    144,    145,    146
  446. X};
  447. X
  448. Xvoid
  449. Xfbmcompile(str, iflag)
  450. XSTR *str;
  451. Xint iflag;
  452. X{
  453. X    register unsigned char *s;
  454. X    register unsigned char *table;
  455. X    register int i;
  456. X    register int len = str->str_cur;
  457. X    int rarest = 0;
  458. X    unsigned int frequency = 256;
  459. X
  460. X    Str_Grow(str,len+258);
  461. X#ifndef lint
  462. X    table = (unsigned char*)(str->str_ptr + len + 1);
  463. X#else
  464. X    table = Null(unsigned char*);
  465. X#endif
  466. X    s = table - 2;
  467. X    for (i = 0; i < 256; i++) {
  468. X    table[i] = len;
  469. X    }
  470. X    i = 0;
  471. X#ifndef lint
  472. X    while (s >= (unsigned char*)(str->str_ptr))
  473. X#endif
  474. X    {
  475. X    if (table[*s] == len) {
  476. X#ifndef pdp11
  477. X        if (iflag)
  478. X        table[*s] = table[fold[*s]] = i;
  479. X#else
  480. X        if (iflag) {
  481. X        int j;
  482. X        j = fold[*s];
  483. X        table[j] = i;
  484. X        table[*s] = i;
  485. X        }
  486. X#endif /* pdp11 */
  487. X        else
  488. X        table[*s] = i;
  489. X    }
  490. X    s--,i++;
  491. X    }
  492. X    str->str_pok |= SP_FBM;        /* deep magic */
  493. X
  494. X#ifndef lint
  495. X    s = (unsigned char*)(str->str_ptr);        /* deeper magic */
  496. X#else
  497. X    s = Null(unsigned char*);
  498. X#endif
  499. X    if (iflag) {
  500. X    register unsigned int tmp, foldtmp;
  501. X    str->str_pok |= SP_CASEFOLD;
  502. X    for (i = 0; i < len; i++) {
  503. X        tmp=freq[s[i]];
  504. X        foldtmp=freq[fold[s[i]]];
  505. X        if (tmp < frequency && foldtmp < frequency) {
  506. X        rarest = i;
  507. X        /* choose most frequent among the two */
  508. X        frequency = (tmp > foldtmp) ? tmp : foldtmp;
  509. X        }
  510. X    }
  511. X    }
  512. X    else {
  513. X    for (i = 0; i < len; i++) {
  514. X        if (freq[s[i]] < frequency) {
  515. X        rarest = i;
  516. X        frequency = freq[s[i]];
  517. X        }
  518. X    }
  519. X    }
  520. X    str->str_rare = s[rarest];
  521. X    str->str_state = rarest;
  522. X#ifdef DEBUGGING
  523. X    if (debug & 512)
  524. X    fprintf(stderr,"rarest char %c at %d\n",str->str_rare, str->str_state);
  525. X#endif
  526. X}
  527. X
  528. Xchar *
  529. Xfbminstr(big, bigend, littlestr)
  530. Xunsigned char *big;
  531. Xregister unsigned char *bigend;
  532. XSTR *littlestr;
  533. X{
  534. X    register unsigned char *s;
  535. X    register int tmp;
  536. X    register int littlelen;
  537. X    register unsigned char *little;
  538. X    register unsigned char *table;
  539. X    register unsigned char *olds;
  540. X    register unsigned char *oldlittle;
  541. X
  542. X#ifndef lint
  543. X    if (!(littlestr->str_pok & SP_FBM))
  544. X    return ninstr((char*)big,(char*)bigend,
  545. X        littlestr->str_ptr, littlestr->str_ptr + littlestr->str_cur);
  546. X#endif
  547. X
  548. X    littlelen = littlestr->str_cur;
  549. X#ifndef lint
  550. X    if (littlestr->str_pok & SP_TAIL && !multiline) {    /* tail anchored? */
  551. X    if (littlelen > bigend - big)
  552. X        return Nullch;
  553. X    little = (unsigned char*)littlestr->str_ptr;
  554. X    if (littlestr->str_pok & SP_CASEFOLD) {    /* oops, fake it */
  555. X        big = bigend - littlelen;        /* just start near end */
  556. X        if (bigend[-1] == '\n' && little[littlelen-1] != '\n')
  557. X        big--;
  558. X    }
  559. X    else {
  560. X        s = bigend - littlelen;
  561. X        if (*s == *little && bcmp(s,little,littlelen)==0)
  562. X        return (char*)s;        /* how sweet it is */
  563. X        else if (bigend[-1] == '\n' && little[littlelen-1] != '\n'
  564. X          && s > big) {
  565. X            s--;
  566. X        if (*s == *little && bcmp(s,little,littlelen)==0)
  567. X            return (char*)s;
  568. X        }
  569. X        return Nullch;
  570. X    }
  571. X    }
  572. X    table = (unsigned char*)(littlestr->str_ptr + littlelen + 1);
  573. X#else
  574. X    table = Null(unsigned char*);
  575. X#endif
  576. X    if (--littlelen >= bigend - big)
  577. X    return Nullch;
  578. X    s = big + littlelen;
  579. X    oldlittle = little = table - 2;
  580. X    if (littlestr->str_pok & SP_CASEFOLD) {    /* case insensitive? */
  581. X    if (s < bigend) {
  582. X      top1:
  583. X        if (tmp = table[*s]) {
  584. X#ifdef POINTERRIGOR
  585. X        if (bigend - s > tmp) {
  586. X            s += tmp;
  587. X            goto top1;
  588. X        }
  589. X#else
  590. X        if ((s += tmp) < bigend)
  591. X            goto top1;
  592. X#endif
  593. X        return Nullch;
  594. X        }
  595. X        else {
  596. X        tmp = littlelen;    /* less expensive than calling strncmp() */
  597. X        olds = s;
  598. X        while (tmp--) {
  599. X            if (*--s == *--little || fold[*s] == *little)
  600. X            continue;
  601. X            s = olds + 1;    /* here we pay the price for failure */
  602. X            little = oldlittle;
  603. X            if (s < bigend)    /* fake up continue to outer loop */
  604. X            goto top1;
  605. X            return Nullch;
  606. X        }
  607. X#ifndef lint
  608. X        return (char *)s;
  609. X#endif
  610. X        }
  611. X    }
  612. X    }
  613. X    else {
  614. X    if (s < bigend) {
  615. X      top2:
  616. X        if (tmp = table[*s]) {
  617. X#ifdef POINTERRIGOR
  618. X        if (bigend - s > tmp) {
  619. X            s += tmp;
  620. X            goto top2;
  621. X        }
  622. X#else
  623. X        if ((s += tmp) < bigend)
  624. X            goto top2;
  625. X#endif
  626. X        return Nullch;
  627. X        }
  628. X        else {
  629. X        tmp = littlelen;    /* less expensive than calling strncmp() */
  630. X        olds = s;
  631. X        while (tmp--) {
  632. X            if (*--s == *--little)
  633. X            continue;
  634. X            s = olds + 1;    /* here we pay the price for failure */
  635. X            little = oldlittle;
  636. X            if (s < bigend)    /* fake up continue to outer loop */
  637. X            goto top2;
  638. X            return Nullch;
  639. X        }
  640. X#ifndef lint
  641. X        return (char *)s;
  642. X#endif
  643. X        }
  644. X    }
  645. X    }
  646. X    return Nullch;
  647. X}
  648. X
  649. Xchar *
  650. Xscreaminstr(bigstr, littlestr)
  651. XSTR *bigstr;
  652. XSTR *littlestr;
  653. X{
  654. X    register unsigned char *s, *x;
  655. X    register unsigned char *big;
  656. X    register int pos;
  657. X    register int previous;
  658. X    register int first;
  659. X    register unsigned char *little;
  660. X    register unsigned char *bigend;
  661. X    register unsigned char *littleend;
  662. X
  663. X    if ((pos = screamfirst[littlestr->str_rare]) < 0) 
  664. X    return Nullch;
  665. X#ifndef lint
  666. X    little = (unsigned char *)(littlestr->str_ptr);
  667. X#else
  668. X    little = Null(unsigned char *);
  669. X#endif
  670. X    littleend = little + littlestr->str_cur;
  671. X    first = *little++;
  672. X    previous = littlestr->str_state;
  673. X#ifndef lint
  674. X    big = (unsigned char *)(bigstr->str_ptr);
  675. X#else
  676. X    big = Null(unsigned char*);
  677. X#endif
  678. X    bigend = big + bigstr->str_cur;
  679. X    big -= previous;
  680. X    while (pos < previous) {
  681. X#ifndef lint
  682. X    if (!(pos += screamnext[pos]))
  683. X#endif
  684. X        return Nullch;
  685. X    }
  686. X    if (littlestr->str_pok & SP_CASEFOLD) {    /* case insignificant? */
  687. X    do {
  688. X        if (big[pos] != first && big[pos] != fold[first])
  689. X        continue;
  690. X        for (x=big+pos+1,s=little; s < littleend; /**/ ) {
  691. X        if (x >= bigend)
  692. X            return Nullch;
  693. X        if (*s++ != *x++ && fold[*(s-1)] != *(x-1)) {
  694. X            s--;
  695. X            break;
  696. X        }
  697. X        }
  698. X        if (s == littleend)
  699. X#ifndef lint
  700. X        return (char *)(big+pos);
  701. X#else
  702. X        return Nullch;
  703. X#endif
  704. X    } while (
  705. X#ifndef lint
  706. X        pos += screamnext[pos]    /* does this goof up anywhere? */
  707. X#else
  708. X        pos += screamnext[0]
  709. X#endif
  710. X        );
  711. X    }
  712. X    else {
  713. X    do {
  714. X        if (big[pos] != first)
  715. X        continue;
  716. X        for (x=big+pos+1,s=little; s < littleend; /**/ ) {
  717. X        if (x >= bigend)
  718. X            return Nullch;
  719. X        if (*s++ != *x++) {
  720. X            s--;
  721. X            break;
  722. X        }
  723. X        }
  724. X        if (s == littleend)
  725. X#ifndef lint
  726. X        return (char *)(big+pos);
  727. X#else
  728. X        return Nullch;
  729. X#endif
  730. X    } while (
  731. X#ifndef lint
  732. X        pos += screamnext[pos]
  733. X#else
  734. X        pos += screamnext[0]
  735. X#endif
  736. X        );
  737. X    }
  738. X    return Nullch;
  739. X}
  740. X
  741. X/* copy a string to a safe spot */
  742. X
  743. Xchar *
  744. Xsavestr(str)
  745. Xchar *str;
  746. X{
  747. X    register char *newaddr;
  748. X
  749. X    New(902,newaddr,strlen(str)+1,char);
  750. X    (void)strcpy(newaddr,str);
  751. X    return newaddr;
  752. X}
  753. X
  754. X/* same thing but with a known length */
  755. X
  756. Xchar *
  757. Xnsavestr(str, len)
  758. Xchar *str;
  759. Xregister int len;
  760. X{
  761. X    register char *newaddr;
  762. X
  763. X    New(903,newaddr,len+1,char);
  764. X    (void)bcopy(str,newaddr,len);    /* might not be null terminated */
  765. X    newaddr[len] = '\0';        /* is now */
  766. X    return newaddr;
  767. X}
  768. X
  769. X/* grow a static string to at least a certain length */
  770. X
  771. Xvoid
  772. Xgrowstr(strptr,curlen,newlen)
  773. Xchar **strptr;
  774. Xint *curlen;
  775. Xint newlen;
  776. X{
  777. X    if (newlen > *curlen) {        /* need more room? */
  778. X    if (*curlen)
  779. X        Renew(*strptr,newlen,char);
  780. X    else
  781. X        New(905,*strptr,newlen,char);
  782. X    *curlen = newlen;
  783. X    }
  784. X}
  785. X
  786. X#ifndef I_VARARGS
  787. X/*VARARGS1*/
  788. Xmess(pat,a1,a2,a3,a4)
  789. Xchar *pat;
  790. Xlong a1, a2, a3, a4;
  791. X{
  792. X    char *s;
  793. X
  794. X    s = buf;
  795. X    (void)sprintf(s,pat,a1,a2,a3,a4);
  796. X    s += strlen(s);
  797. X    if (s[-1] != '\n') {
  798. X    if (curcmd->c_line) {
  799. X        (void)sprintf(s," at %s line %ld",
  800. X          stab_val(curcmd->c_filestab)->str_ptr, (long)curcmd->c_line);
  801. X        s += strlen(s);
  802. X    }
  803. X    if (last_in_stab &&
  804. X        stab_io(last_in_stab) &&
  805. X        stab_io(last_in_stab)->lines ) {
  806. X        (void)sprintf(s,", <%s> line %ld",
  807. X          last_in_stab == argvstab ? "" : stab_name(last_in_stab),
  808. X          (long)stab_io(last_in_stab)->lines);
  809. X        s += strlen(s);
  810. X    }
  811. X    (void)strcpy(s,".\n");
  812. X    }
  813. X}
  814. X
  815. X/*VARARGS1*/
  816. Xfatal(pat,a1,a2,a3,a4)
  817. Xchar *pat;
  818. Xlong a1, a2, a3, a4;
  819. X{
  820. X    extern FILE *e_fp;
  821. X    extern char *e_tmpname;
  822. X    char *tmps;
  823. X
  824. X    mess(pat,a1,a2,a3,a4);
  825. X    if (in_eval) {
  826. X    str_set(stab_val(stabent("@",TRUE)),buf);
  827. X    tmps = "_EVAL_";
  828. X    while (loop_ptr >= 0 && (!loop_stack[loop_ptr].loop_label ||
  829. X      strNE(tmps,loop_stack[loop_ptr].loop_label) )) {
  830. X#ifdef DEBUGGING
  831. X        if (debug & 4) {
  832. X        deb("(Skipping label #%d %s)\n",loop_ptr,
  833. X            loop_stack[loop_ptr].loop_label);
  834. X        }
  835. X#endif
  836. X        loop_ptr--;
  837. X    }
  838. X#ifdef DEBUGGING
  839. X    if (debug & 4) {
  840. X        deb("(Found label #%d %s)\n",loop_ptr,
  841. X        loop_stack[loop_ptr].loop_label);
  842. X    }
  843. X#endif
  844. X    if (loop_ptr < 0) {
  845. X        in_eval = 0;
  846. X        fatal("Bad label: %s", tmps);
  847. X    }
  848. X    longjmp(loop_stack[loop_ptr].loop_env, 1);
  849. X    }
  850. X    fputs(buf,stderr);
  851. X    (void)fflush(stderr);
  852. X    if (e_fp)
  853. X    (void)UNLINK(e_tmpname);
  854. X    statusvalue >>= 8;
  855. X    exit((int)((errno&255)?errno:((statusvalue&255)?statusvalue:255)));
  856. X}
  857. X
  858. X/*VARARGS1*/
  859. Xwarn(pat,a1,a2,a3,a4)
  860. Xchar *pat;
  861. Xlong a1, a2, a3, a4;
  862. X{
  863. X    mess(pat,a1,a2,a3,a4);
  864. X    fputs(buf,stderr);
  865. X#ifdef LEAKTEST
  866. X#ifdef DEBUGGING
  867. X    if (debug & 4096)
  868. X    xstat();
  869. X#endif
  870. X#endif
  871. X    (void)fflush(stderr);
  872. X}
  873. X#else
  874. X/*VARARGS0*/
  875. Xmess(args)
  876. Xva_list args;
  877. X{
  878. X    char *pat;
  879. X    char *s;
  880. X#ifdef CHARVSPRINTF
  881. X    char *vsprintf();
  882. X#else
  883. X    int vsprintf();
  884. X#endif
  885. X
  886. X    s = buf;
  887. X#ifdef lint
  888. X    pat = Nullch;
  889. X#else
  890. X    pat = va_arg(args, char *);
  891. X#endif
  892. X    (void) vsprintf(s,pat,args);
  893. X
  894. X    s += strlen(s);
  895. X    if (s[-1] != '\n') {
  896. X    if (curcmd->c_line) {
  897. X        (void)sprintf(s," at %s line %ld",
  898. X          stab_val(curcmd->c_filestab)->str_ptr, (long)curcmd->c_line);
  899. X        s += strlen(s);
  900. X    }
  901. X    if (last_in_stab &&
  902. X        stab_io(last_in_stab) &&
  903. X        stab_io(last_in_stab)->lines ) {
  904. X        (void)sprintf(s,", <%s> line %ld",
  905. X          last_in_stab == argvstab ? "" : last_in_stab->str_magic->str_ptr,
  906. X          (long)stab_io(last_in_stab)->lines);
  907. X        s += strlen(s);
  908. X    }
  909. X    (void)strcpy(s,".\n");
  910. X    }
  911. X}
  912. X
  913. X/*VARARGS0*/
  914. Xfatal(va_alist)
  915. Xva_dcl
  916. X{
  917. X    va_list args;
  918. X    extern FILE *e_fp;
  919. X    extern char *e_tmpname;
  920. X    char *tmps;
  921. X
  922. X#ifndef lint
  923. X    va_start(args);
  924. X#else
  925. X    args = 0;
  926. X#endif
  927. X    mess(args);
  928. X    va_end(args);
  929. X    if (in_eval) {
  930. X    str_set(stab_val(stabent("@",TRUE)),buf);
  931. X    tmps = "_EVAL_";
  932. X    while (loop_ptr >= 0 && (!loop_stack[loop_ptr].loop_label ||
  933. X      strNE(tmps,loop_stack[loop_ptr].loop_label) )) {
  934. X#ifdef DEBUGGING
  935. X        if (debug & 4) {
  936. X        deb("(Skipping label #%d %s)\n",loop_ptr,
  937. X            loop_stack[loop_ptr].loop_label);
  938. X        }
  939. X#endif
  940. X        loop_ptr--;
  941. X    }
  942. X#ifdef DEBUGGING
  943. X    if (debug & 4) {
  944. X        deb("(Found label #%d %s)\n",loop_ptr,
  945. X        loop_stack[loop_ptr].loop_label);
  946. X    }
  947. X#endif
  948. X    if (loop_ptr < 0) {
  949. X        in_eval = 0;
  950. X        fatal("Bad label: %s", tmps);
  951. X    }
  952. X    longjmp(loop_stack[loop_ptr].loop_env, 1);
  953. X    }
  954. X    fputs(buf,stderr);
  955. X    (void)fflush(stderr);
  956. X    if (e_fp)
  957. X    (void)UNLINK(e_tmpname);
  958. X    statusvalue >>= 8;
  959. X    exit((int)((errno&255)?errno:((statusvalue&255)?statusvalue:255)));
  960. X}
  961. X
  962. X/*VARARGS0*/
  963. Xwarn(va_alist)
  964. Xva_dcl
  965. X{
  966. X    va_list args;
  967. X
  968. X#ifndef lint
  969. X    va_start(args);
  970. X#else
  971. X    args = 0;
  972. X#endif
  973. X    mess(args);
  974. X    va_end(args);
  975. X
  976. X    fputs(buf,stderr);
  977. X#ifdef LEAKTEST
  978. X#ifdef DEBUGGING
  979. X    if (debug & 4096)
  980. X    xstat();
  981. X#endif
  982. X#endif
  983. X    (void)fflush(stderr);
  984. X}
  985. X#endif
  986. X
  987. Xvoid
  988. Xsetenv(nam,val)
  989. Xchar *nam, *val;
  990. X{
  991. X    register int i=envix(nam);        /* where does it go? */
  992. X
  993. X    if (environ == origenviron) {    /* need we copy environment? */
  994. X    int j;
  995. X    int max;
  996. X    char **tmpenv;
  997. X
  998. X    for (max = i; environ[max]; max++) ;
  999. X    New(901,tmpenv, max+2, char*);
  1000. X    for (j=0; j<max; j++)        /* copy environment */
  1001. X        tmpenv[j] = savestr(environ[j]);
  1002. X    tmpenv[max] = Nullch;
  1003. X    environ = tmpenv;        /* tell exec where it is now */
  1004. X    }
  1005. X    if (!val) {
  1006. X    while (environ[i]) {
  1007. X        environ[i] = environ[i+1];
  1008. X        i++;
  1009. X    }
  1010. X    return;
  1011. X    }
  1012. X    if (!environ[i]) {            /* does not exist yet */
  1013. X    Renew(environ, i+2, char*);    /* just expand it a bit */
  1014. X    environ[i+1] = Nullch;    /* make sure it's null terminated */
  1015. X    }
  1016. X    else
  1017. X    Safefree(environ[i]);
  1018. X    New(904, environ[i], strlen(nam) + strlen(val) + 2, char);
  1019. X#ifndef MSDOS
  1020. X    (void)sprintf(environ[i],"%s=%s",nam,val);/* all that work just for this */
  1021. X#else
  1022. X    /* MS-DOS requires environment variable names to be in uppercase */
  1023. X    /* [Tom Dinger, 27 August 1990: Well, it doesn't _require_ it, but
  1024. X     * some utilities and applications may break because they only look
  1025. X     * for upper case strings. (Fixed strupr() bug here.)]
  1026. X     */
  1027. X    strcpy(environ[i],nam); strupr(environ[i]);
  1028. X    (void)sprintf(environ[i] + strlen(nam),"=%s",val);
  1029. X#endif /* MSDOS */
  1030. X}
  1031. X
  1032. Xint
  1033. Xenvix(nam)
  1034. Xchar *nam;
  1035. X{
  1036. X    register int i, len = strlen(nam);
  1037. X
  1038. X    for (i = 0; environ[i]; i++) {
  1039. X    if (strnEQ(environ[i],nam,len) && environ[i][len] == '=')
  1040. X        break;            /* strnEQ must come first to avoid */
  1041. X    }                    /* potential SEGV's */
  1042. X    return i;
  1043. X}
  1044. X
  1045. X#ifdef EUNICE
  1046. Xunlnk(f)    /* unlink all versions of a file */
  1047. Xchar *f;
  1048. X{
  1049. X    int i;
  1050. X
  1051. X    for (i = 0; unlink(f) >= 0; i++) ;
  1052. X    return i ? 0 : -1;
  1053. X}
  1054. X#endif
  1055. X
  1056. X#ifndef HAS_MEMCPY
  1057. X#ifndef HAS_BCOPY
  1058. Xchar *
  1059. Xbcopy(from,to,len)
  1060. Xregister char *from;
  1061. Xregister char *to;
  1062. Xregister int len;
  1063. X{
  1064. X    char *retval = to;
  1065. X
  1066. X    while (len--)
  1067. X    *to++ = *from++;
  1068. X    return retval;
  1069. X}
  1070. X#endif
  1071. X
  1072. X#ifndef HAS_BZERO
  1073. Xchar *
  1074. Xbzero(loc,len)
  1075. Xregister char *loc;
  1076. Xregister int len;
  1077. X{
  1078. X    char *retval = loc;
  1079. X
  1080. X    while (len--)
  1081. X    *loc++ = 0;
  1082. X    return retval;
  1083. X}
  1084. X#endif
  1085. X#endif
  1086. X
  1087. X#ifdef I_VARARGS
  1088. X#ifndef HAS_VPRINTF
  1089. X
  1090. X#ifdef CHARVSPRINTF
  1091. Xchar *
  1092. X#else
  1093. Xint
  1094. X#endif
  1095. Xvsprintf(dest, pat, args)
  1096. Xchar *dest, *pat, *args;
  1097. X{
  1098. X    FILE fakebuf;
  1099. X
  1100. X    fakebuf._ptr = dest;
  1101. X    fakebuf._cnt = 32767;
  1102. X#ifndef _IOSTRG
  1103. X#define _IOSTRG 0
  1104. X#endif
  1105. X    fakebuf._flag = _IOWRT|_IOSTRG;
  1106. X    _doprnt(pat, args, &fakebuf);    /* what a kludge */
  1107. X    (void)putc('\0', &fakebuf);
  1108. X#ifdef CHARVSPRINTF
  1109. X    return(dest);
  1110. X#else
  1111. X    return 0;        /* perl doesn't use return value */
  1112. X#endif
  1113. X}
  1114. X
  1115. X#ifdef DEBUGGING
  1116. Xint
  1117. Xvfprintf(fd, pat, args)
  1118. XFILE *fd;
  1119. Xchar *pat, *args;
  1120. X{
  1121. X    _doprnt(pat, args, fd);
  1122. X    return 0;        /* wrong, but perl doesn't use the return value */
  1123. X}
  1124. X#endif
  1125. X#endif /* HAS_VPRINTF */
  1126. X#endif /* I_VARARGS */
  1127. X
  1128. X#ifdef MYSWAP
  1129. X#if BYTEORDER != 0x4321
  1130. Xshort
  1131. Xmy_swap(s)
  1132. Xshort s;
  1133. X{
  1134. X#if (BYTEORDER & 1) == 0
  1135. X    short result;
  1136. X
  1137. X    result = ((s & 255) << 8) + ((s >> 8) & 255);
  1138. X    return result;
  1139. X#else
  1140. X    return s;
  1141. X#endif
  1142. X}
  1143. X
  1144. Xlong
  1145. Xhtonl(l)
  1146. Xregister long l;
  1147. X{
  1148. X    union {
  1149. X    long result;
  1150. X    char c[sizeof(long)];
  1151. X    } u;
  1152. X
  1153. X#if BYTEORDER == 0x1234
  1154. X    u.c[0] = (l >> 24) & 255;
  1155. X    u.c[1] = (l >> 16) & 255;
  1156. X    u.c[2] = (l >> 8) & 255;
  1157. X    u.c[3] = l & 255;
  1158. X    return u.result;
  1159. X#else
  1160. X#if ((BYTEORDER - 0x1111) & 0x444) || !(BYTEORDER & 0xf)
  1161. X    fatal("Unknown BYTEORDER\n");
  1162. X#else
  1163. X    register int o;
  1164. X    register int s;
  1165. X
  1166. X    for (o = BYTEORDER - 0x1111, s = 0; s < (sizeof(long)*8); o >>= 4, s += 8) {
  1167. X    u.c[o & 0xf] = (l >> s) & 255;
  1168. X    }
  1169. X    return u.result;
  1170. X#endif
  1171. X#endif
  1172. X}
  1173. X
  1174. Xlong
  1175. Xntohl(l)
  1176. Xregister long l;
  1177. X{
  1178. X    union {
  1179. X    long l;
  1180. X    char c[sizeof(long)];
  1181. X    } u;
  1182. X
  1183. X#if BYTEORDER == 0x1234
  1184. X    u.c[0] = (l >> 24) & 255;
  1185. X    u.c[1] = (l >> 16) & 255;
  1186. X    u.c[2] = (l >> 8) & 255;
  1187. X    u.c[3] = l & 255;
  1188. X    return u.l;
  1189. X#else
  1190. X#if ((BYTEORDER - 0x1111) & 0x444) || !(BYTEORDER & 0xf)
  1191. X    fatal("Unknown BYTEORDER\n");
  1192. X#else
  1193. X    register int o;
  1194. X    register int s;
  1195. X
  1196. X    u.l = l;
  1197. X    l = 0;
  1198. X    for (o = BYTEORDER - 0x1111, s = 0; s < (sizeof(long)*8); o >>= 4, s += 8) {
  1199. X    l |= (u.c[o & 0xf] & 255) << s;
  1200. X    }
  1201. X    return l;
  1202. X#endif
  1203. X#endif
  1204. X}
  1205. X
  1206. X#endif /* BYTEORDER != 0x4321 */
  1207. X#endif /* HAS_HTONS */
  1208. X
  1209. X#ifndef MSDOS
  1210. XFILE *
  1211. Xmypopen(cmd,mode)
  1212. Xchar    *cmd;
  1213. Xchar    *mode;
  1214. X{
  1215. X    int p[2];
  1216. X    register int this, that;
  1217. X    register int pid;
  1218. X    STR *str;
  1219. X    int doexec = strNE(cmd,"-");
  1220. X
  1221. X    if (pipe(p) < 0)
  1222. X    return Nullfp;
  1223. X    this = (*mode == 'w');
  1224. X    that = !this;
  1225. X    while ((pid = (doexec?vfork():fork())) < 0) {
  1226. X    if (errno != EAGAIN) {
  1227. X        close(p[this]);
  1228. X        if (!doexec)
  1229. X        fatal("Can't fork");
  1230. X        return Nullfp;
  1231. X    }
  1232. X    sleep(5);
  1233. X    }
  1234. X    if (pid == 0) {
  1235. X#define THIS that
  1236. X#define THAT this
  1237. X    close(p[THAT]);
  1238. X    if (p[THIS] != (*mode == 'r')) {
  1239. X        dup2(p[THIS], *mode == 'r');
  1240. X        close(p[THIS]);
  1241. X    }
  1242. X    if (doexec) {
  1243. X#if !defined(I_FCNTL) || !defined(F_SETFD)
  1244. X        int fd;
  1245. X
  1246. X#ifndef NOFILE
  1247. X#define NOFILE 20
  1248. X#endif
  1249. X        for (fd = 3; fd < NOFILE; fd++)
  1250. X        close(fd);
  1251. X#endif
  1252. X        do_exec(cmd);    /* may or may not use the shell */
  1253. X        _exit(1);
  1254. X    }
  1255. X    if (tmpstab = stabent("$",allstabs))
  1256. X        str_numset(STAB_STR(tmpstab),(double)getpid());
  1257. X    forkprocess = 0;
  1258. X    hclear(pidstatus, FALSE);    /* we have no children */
  1259. X    return Nullfp;
  1260. X#undef THIS
  1261. X#undef THAT
  1262. X    }
  1263. X    do_execfree();    /* free any memory malloced by child on vfork */
  1264. X    close(p[that]);
  1265. X    if (p[that] < p[this]) {
  1266. X    dup2(p[this], p[that]);
  1267. X    close(p[this]);
  1268. X    p[this] = p[that];
  1269. X    }
  1270. X    str = afetch(fdpid,p[this],TRUE);
  1271. X    str->str_u.str_useful = pid;
  1272. X    forkprocess = pid;
  1273. X    return fdopen(p[this], mode);
  1274. X}
  1275. X#endif /* !MSDOS */
  1276. X
  1277. X#ifdef NOTDEF
  1278. Xdumpfds(s)
  1279. Xchar *s;
  1280. X{
  1281. X    int fd;
  1282. X    struct stat tmpstatbuf;
  1283. X
  1284. X    fprintf(stderr,"%s", s);
  1285. X    for (fd = 0; fd < 32; fd++) {
  1286. X    if (fstat(fd,&tmpstatbuf) >= 0)
  1287. X        fprintf(stderr," %d",fd);
  1288. X    }
  1289. X    fprintf(stderr,"\n");
  1290. X}
  1291. X#endif
  1292. X
  1293. X#ifndef HAS_DUP2
  1294. Xdup2(oldfd,newfd)
  1295. Xint oldfd;
  1296. Xint newfd;
  1297. X{
  1298. X#if defined(HAS_FCNTL) && defined(F_DUPFD)
  1299. X    close(newfd);
  1300. X    fcntl(oldfd, F_DUPFD, newfd);
  1301. X#else
  1302. X    int fdtmp[20];
  1303. X    int fdx = 0;
  1304. X    int fd;
  1305. X
  1306. X    if (oldfd == newfd)
  1307. X    return 0;
  1308. X    close(newfd);
  1309. X    while ((fd = dup(oldfd)) != newfd)    /* good enough for low fd's */
  1310. X    fdtmp[fdx++] = fd;
  1311. X    while (fdx > 0)
  1312. X    close(fdtmp[--fdx]);
  1313. X#endif
  1314. X}
  1315. X#endif
  1316. X
  1317. X#ifndef MSDOS
  1318. Xint
  1319. Xmypclose(ptr)
  1320. XFILE *ptr;
  1321. X{
  1322. X#ifdef VOIDSIG
  1323. X    void (*hstat)(), (*istat)(), (*qstat)();
  1324. X#else
  1325. X    int (*hstat)(), (*istat)(), (*qstat)();
  1326. X#endif
  1327. X    int status;
  1328. X    STR *str;
  1329. X    int pid;
  1330. X
  1331. X    str = afetch(fdpid,fileno(ptr),TRUE);
  1332. X    astore(fdpid,fileno(ptr),Nullstr);
  1333. X    fclose(ptr);
  1334. X    pid = (int)str->str_u.str_useful;
  1335. X    hstat = signal(SIGHUP, SIG_IGN);
  1336. X    istat = signal(SIGINT, SIG_IGN);
  1337. X    qstat = signal(SIGQUIT, SIG_IGN);
  1338. X    pid = wait4pid(pid, &status, 0);
  1339. X    signal(SIGHUP, hstat);
  1340. X    signal(SIGINT, istat);
  1341. X    signal(SIGQUIT, qstat);
  1342. X    return(pid < 0 ? pid : status);
  1343. X}
  1344. X
  1345. Xint
  1346. Xwait4pid(pid,statusp,flags)
  1347. Xint pid;
  1348. Xint *statusp;
  1349. Xint flags;
  1350. X{
  1351. X    int result;
  1352. X    STR *str;
  1353. X    char spid[16];
  1354. X
  1355. X    if (!pid)
  1356. X    return -1;
  1357. X#ifdef HAS_WAIT4
  1358. X    return wait4((pid==-1)?0:pid,statusp,flags,Null(struct rusage *));
  1359. X#else
  1360. X#ifdef HAS_WAITPID
  1361. X    return waitpid(pid,statusp,flags);
  1362. X#else
  1363. X    if (pid > 0) {
  1364. X    sprintf(spid, "%d", pid);
  1365. X    str = hfetch(pidstatus,spid,strlen(spid),FALSE);
  1366. X    if (str != &str_undef) {
  1367. X        *statusp = (int)str->str_u.str_useful;
  1368. X        hdelete(pidstatus,spid,strlen(spid));
  1369. X        return pid;
  1370. X    }
  1371. X    }
  1372. X    else {
  1373. X    HENT *entry;
  1374. X
  1375. X    hiterinit(pidstatus);
  1376. X    if (entry = hiternext(pidstatus)) {
  1377. X        pid = atoi(hiterkey(entry,statusp));
  1378. X        str = hiterval(entry);
  1379. X        *statusp = (int)str->str_u.str_useful;
  1380. X        sprintf(spid, "%d", pid);
  1381. X        hdelete(pidstatus,spid,strlen(spid));
  1382. X        return pid;
  1383. X    }
  1384. X    }
  1385. X    if (flags)
  1386. X    fatal("Can't do waitpid with flags");
  1387. X    else {
  1388. X    while ((result = wait(statusp)) != pid && pid > 0 && result >= 0)
  1389. X        pidgone(result,*statusp);
  1390. X    if (result < 0)
  1391. X        *statusp = -1;
  1392. X    }
  1393. X    return result;
  1394. X#endif
  1395. X#endif
  1396. X}
  1397. X
  1398. Xpidgone(pid,status)
  1399. Xint pid;
  1400. Xint status;
  1401. X{
  1402. X#if defined(HAS_WAIT4) || defined(HAS_WAITPID)
  1403. X#else
  1404. X    register STR *str;
  1405. X    char spid[16];
  1406. X
  1407. X    sprintf(spid, "%d", pid);
  1408. X    str = hfetch(pidstatus,spid,strlen(spid),TRUE);
  1409. X    str->str_u.str_useful = status;
  1410. X#endif
  1411. X    return;
  1412. X}
  1413. X#endif /* !MSDOS */
  1414. X
  1415. X#ifndef HAS_MEMCMP
  1416. Xmemcmp(s1,s2,len)
  1417. Xregister unsigned char *s1;
  1418. Xregister unsigned char *s2;
  1419. Xregister int len;
  1420. X{
  1421. X    register int tmp;
  1422. X
  1423. X    while (len--) {
  1424. X    if (tmp = *s1++ - *s2++)
  1425. X        return tmp;
  1426. X    }
  1427. X    return 0;
  1428. X}
  1429. X#endif /* HAS_MEMCMP */
  1430. X
  1431. Xvoid
  1432. Xrepeatcpy(to,from,len,count)
  1433. Xregister char *to;
  1434. Xregister char *from;
  1435. Xint len;
  1436. Xregister int count;
  1437. X{
  1438. X    register int todo;
  1439. X    register char *frombase = from;
  1440. X
  1441. X    if (len == 1) {
  1442. X    todo = *from;
  1443. X    while (count-- > 0)
  1444. X        *to++ = todo;
  1445. X    return;
  1446. X    }
  1447. X    while (count-- > 0) {
  1448. X    for (todo = len; todo > 0; todo--) {
  1449. X        *to++ = *from++;
  1450. X    }
  1451. X    from = frombase;
  1452. X    }
  1453. X}
  1454. X
  1455. X#ifndef CASTNEGFLOAT
  1456. Xunsigned long
  1457. Xcastulong(f)
  1458. Xdouble f;
  1459. X{
  1460. X    long along;
  1461. X
  1462. X#if CASTFLAGS & 2
  1463. X#   define BIGDOUBLE 2147483648.0
  1464. X    if (f >= BIGDOUBLE)
  1465. X    return (unsigned long)(f-(long)(f/BIGDOUBLE)*BIGDOUBLE)|0x80000000;
  1466. X#endif
  1467. X    if (f >= 0.0)
  1468. X    return (unsigned long)f;
  1469. X    along = (long)f;
  1470. X    return (unsigned long)along;
  1471. X}
  1472. X#endif
  1473. X
  1474. X#ifndef HAS_RENAME
  1475. Xint
  1476. Xsame_dirent(a,b)
  1477. Xchar *a;
  1478. Xchar *b;
  1479. X{
  1480. X    char *fa = rindex(a,'/');
  1481. X    char *fb = rindex(b,'/');
  1482. X    struct stat tmpstatbuf1;
  1483. X    struct stat tmpstatbuf2;
  1484. X#ifndef MAXPATHLEN
  1485. X#define MAXPATHLEN 1024
  1486. X#endif
  1487. X    char tmpbuf[MAXPATHLEN+1];
  1488. X
  1489. X    if (fa)
  1490. X    fa++;
  1491. X    else
  1492. X    fa = a;
  1493. X    if (fb)
  1494. X    fb++;
  1495. X    else
  1496. X    fb = b;
  1497. X    if (strNE(a,b))
  1498. X    return FALSE;
  1499. X    if (fa == a)
  1500. X    strcpy(tmpbuf,".");
  1501. X    else
  1502. X    strncpy(tmpbuf, a, fa - a);
  1503. X    if (stat(tmpbuf, &tmpstatbuf1) < 0)
  1504. X    return FALSE;
  1505. X    if (fb == b)
  1506. X    strcpy(tmpbuf,".");
  1507. X    else
  1508. X    strncpy(tmpbuf, b, fb - b);
  1509. X    if (stat(tmpbuf, &tmpstatbuf2) < 0)
  1510. X    return FALSE;
  1511. X    return tmpstatbuf1.st_dev == tmpstatbuf2.st_dev &&
  1512. X       tmpstatbuf1.st_ino == tmpstatbuf2.st_ino;
  1513. X}
  1514. X#endif /* !HAS_RENAME */
  1515. X
  1516. Xunsigned long
  1517. Xscanoct(start, len, retlen)
  1518. Xchar *start;
  1519. Xint len;
  1520. Xint *retlen;
  1521. X{
  1522. X    register char *s = start;
  1523. X    register unsigned long retval = 0;
  1524. X
  1525. X    while (len-- && *s >= '0' && *s <= '7') {
  1526. X    retval <<= 3;
  1527. X    retval |= *s++ - '0';
  1528. X    }
  1529. X    *retlen = s - start;
  1530. X    return retval;
  1531. X}
  1532. X
  1533. Xunsigned long
  1534. Xscanhex(start, len, retlen)
  1535. Xchar *start;
  1536. Xint len;
  1537. Xint *retlen;
  1538. X{
  1539. X    register char *s = start;
  1540. X    register unsigned long retval = 0;
  1541. X    char *tmp;
  1542. X
  1543. X    while (len-- && *s && (tmp = index(hexdigit, *s))) {
  1544. X    retval <<= 4;
  1545. X    retval |= (tmp - hexdigit) & 15;
  1546. X    s++;
  1547. X    }
  1548. X    *retlen = s - start;
  1549. X    return retval;
  1550. X}
  1551. !STUFFY!FUNK!
  1552. echo Extracting PACKINGLIST@3
  1553. sed >PACKINGLIST@3 <<'!STUFFY!FUNK!' -e 's/X//'
  1554. XAfter all the perl kits are run you should have the following files:
  1555. X
  1556. XFilename        Kit Description
  1557. X--------        --- -----------
  1558. XConfigure:AA             7 Run this first
  1559. XConfigure:AB            14 
  1560. XCopying                 15 The GNU General Public License
  1561. XEXTERN.h                36 Included before foreign .h files
  1562. XINTERN.h                36 Included before domestic .h files
  1563. XMANIFEST                27 This list of files
  1564. XMakefile.SH             28 Precursor to Makefile
  1565. XPACKINGLIST             17 Which files came from which kits
  1566. XREADME                   1 The Instructions
  1567. XREADME.uport             1 Special instructions for Microports
  1568. XREADME.xenix             1 Special instructions for Xenix
  1569. XWishlist                36 Some things that may or may not happen
  1570. Xarg.h                   20 Public declarations for the above
  1571. Xarray.c                 30 Numerically subscripted arrays
  1572. Xarray.h                 36 Public declarations for the above
  1573. Xcflags.SH               34 A script that emits C compilation flags per file
  1574. Xclient                  36 A client to test sockets
  1575. Xcmd.c                   19 Command interpreter
  1576. Xcmd.h                   31 Public declarations for the above
  1577. Xconfig.H                25 Sample config.h
  1578. Xconfig_h.SH             23 Produces config.h
  1579. Xcons.c                  13 Routines to construct cmd nodes of a parse tree
  1580. Xconsarg.c               20 Routines to construct arg nodes of a parse tree
  1581. Xdoarg.c                 12 Scalar expression evaluation
  1582. Xdoio.c:AA                3 I/O operations
  1583. Xdoio.c:AB               28 
  1584. Xdolist.c                11 Array expression evaluation
  1585. Xdump.c                  29 Debugging output
  1586. Xeg/ADB                  36 An adb wrapper to put in your crash dir
  1587. Xeg/README                1 Intro to example perl scripts
  1588. Xeg/changes              35 A program to list recently changed files
  1589. Xeg/down                 36 A program to do things to subdirectories
  1590. Xeg/dus                  36 A program to do du -s on non-mounted dirs
  1591. Xeg/findcp               35 A find wrapper that implements a -cp switch
  1592. Xeg/findtar              22 A find wrapper that pumps out a tar file
  1593. Xeg/g/gcp                33 A program to do a global rcp
  1594. Xeg/g/gcp.man            34 Manual page for gcp
  1595. Xeg/g/ged                36 A program to do a global edit
  1596. Xeg/g/ghosts             35 A sample /etc/ghosts file
  1597. Xeg/g/gsh                33 A program to do a global rsh
  1598. Xeg/g/gsh.man            33 Manual page for gsh
  1599. Xeg/muck                 26 A program to find missing make dependencies
  1600. Xeg/muck.man             36 Manual page for muck
  1601. Xeg/myrup                35 A program to find lightly loaded machines
  1602. Xeg/nih                  10 Script to insert #! workaround
  1603. Xeg/relink               33 A program to change symbolic links
  1604. Xeg/rename               34 A program to rename files
  1605. Xeg/rmfrom               36 A program to feed doomed filenames to
  1606. Xeg/scan/scan_df         34 Scan for filesystem anomalies
  1607. Xeg/scan/scan_last       34 Scan for login anomalies
  1608. Xeg/scan/scan_messages   30 Scan for console message anomalies
  1609. Xeg/scan/scan_passwd     35 Scan for passwd file anomalies
  1610. Xeg/scan/scan_ps         18 Scan for process anomalies
  1611. Xeg/scan/scan_sudo       35 Scan for sudo anomalies
  1612. Xeg/scan/scan_suid       33 Scan for setuid anomalies
  1613. Xeg/scan/scanner         34 An anomaly reporter
  1614. Xeg/shmkill              36 A program to remove unused shared memory
  1615. Xeg/sysvipc/README        1 Intro to Sys V IPC examples
  1616. Xeg/sysvipc/ipcmsg       35 Example of SYS V IPC message queues
  1617. Xeg/sysvipc/ipcsem       35 Example of Sys V IPC semaphores
  1618. Xeg/sysvipc/ipcshm       35 Example of Sys V IPC shared memory
  1619. Xeg/travesty             35 A program to print travesties of its input text
  1620. Xeg/van/empty            35 A program to empty the trashcan
  1621. Xeg/van/unvanish         34 A program to undo what vanish does
  1622. Xeg/van/vanexp           36 A program to expire vanished files
  1623. Xeg/van/vanish           34 A program to put files in a trashcan
  1624. Xeg/who                  36 A sample who program
  1625. Xemacs/perl-mode.el      21 Emacs major mode for perl
  1626. Xemacs/perldb.el         18 Emacs debugging
  1627. Xemacs/perldb.pl         16 Emacs debugging
  1628. Xemacs/tedstuff          27 Some optional patches
  1629. Xeval.c:AA                6 The expression evaluator
  1630. Xeval.c:AB               23 
  1631. Xform.c                  28 Format processing
  1632. Xform.h                  35 Public declarations for the above
  1633. Xgettest                 36 A little script to test the get* routines
  1634. Xh2ph.SH                 11 A thing to turn C .h file into perl .ph files
  1635. Xh2pl/README              1 How to turn .ph files into .pl files
  1636. Xh2pl/cbreak.pl          36 cbreak routines using .ph
  1637. Xh2pl/cbreak2.pl         36 cbreak routines using .pl
  1638. Xh2pl/eg/sizeof.ph       36 Sample sizeof array initialization
  1639. Xh2pl/eg/sys/errno.pl    34 Sample translated errno.pl
  1640. Xh2pl/eg/sys/ioctl.pl    31 Sample translated ioctl.pl
  1641. Xh2pl/eg/sysexits.pl     36 Sample translated sysexits.pl
  1642. Xh2pl/getioctlsizes      36 Program to extract types from ioctl.h
  1643. Xh2pl/mksizes            35 Program to make %sizeof array.
  1644. Xh2pl/mkvars             35 Program to make .pl from .ph files
  1645. Xh2pl/tcbreak            36 cbreak test routine using .ph
  1646. Xh2pl/tcbreak2           25 cbreak test routine using .pl
  1647. Xhandy.h                 32 Handy definitions
  1648. Xhash.c                  26 Associative arrays
  1649. Xhash.h                  34 Public declarations for the above
  1650. Xhints/3b2.sh            36 
  1651. Xhints/aix_rs.sh         36 
  1652. Xhints/aix_rt.sh         36 
  1653. Xhints/apollo_C6_7.sh    36 
  1654. Xhints/aux.sh            36 
  1655. Xhints/dnix.sh           36 
  1656. Xhints/dynix.sh          36 
  1657. Xhints/fps.sh            36 
  1658. Xhints/genix.sh          36 
  1659. Xhints/hp9000_300.sh     36 
  1660. Xhints/hp9000_400.sh     36 
  1661. Xhints/hpux.sh           36 
  1662. Xhints/i386.sh           36 
  1663. Xhints/mips.sh           36 
  1664. Xhints/ncr_tower.sh      36 
  1665. Xhints/next.sh           36 
  1666. Xhints/osf_1.sh          36 
  1667. Xhints/sco_2_3_0.sh      36 
  1668. Xhints/sco_2_3_1.sh      36 
  1669. Xhints/sco_2_3_2.sh      36 
  1670. Xhints/sco_2_3_3.sh      36 
  1671. Xhints/sco_3.sh          36 
  1672. Xhints/sgi.sh            36 
  1673. Xhints/sunos_3_4.sh      36 
  1674. Xhints/sunos_3_5.sh      36 
  1675. Xhints/sunos_4_0_1.sh    36 
  1676. Xhints/sunos_4_0_2.sh    36 
  1677. Xhints/ultrix_3.sh       36 
  1678. Xhints/ultrix_4.sh       36 
  1679. Xhints/uts.sh            35 
  1680. Xinstallperl             31 Perl script to do "make install" dirty work
  1681. Xioctl.pl                32 Sample ioctl.pl
  1682. Xlib/abbrev.pl           36 An abbreviation table builder
  1683. Xlib/bigfloat.pl         29 An arbitrary precision floating point package
  1684. Xlib/bigint.pl           29 An arbitrary precision integer arithmetic package
  1685. Xlib/bigrat.pl           31 An arbitrary precision rational arithmetic package
  1686. Xlib/cacheout.pl         28 Manages output filehandles when you need too many
  1687. Xlib/complete.pl         34 A command completion subroutine
  1688. Xlib/ctime.pl            23 A ctime workalike
  1689. Xlib/dumpvar.pl          35 A variable dumper
  1690. Xlib/flush.pl            36 Routines to do single flush
  1691. Xlib/getopt.pl           35 Perl library supporting option parsing
  1692. Xlib/getopts.pl          35 Perl library supporting option parsing
  1693. Xlib/importenv.pl        36 Perl routine to get environment into variables
  1694. Xlib/look.pl             35 A "look" equivalent
  1695. Xlib/perldb.pl           26 Perl debugging routines
  1696. Xlib/pwd.pl              35 Routines to keep track of PWD environment variable
  1697. Xlib/stat.pl             17 Perl library supporting stat function
  1698. Xlib/syslog.pl           30 Perl library supporting syslogging
  1699. Xlib/termcap.pl          32 Perl library supporting termcap usage
  1700. Xlib/timelocal.pl        31 Perl library supporting inverse of localtime, gmtime
  1701. Xlib/validate.pl         32 Perl library supporting wholesale file mode validation
  1702. Xmakedepend.SH           30 Precursor to makedepend
  1703. Xmakedir.SH              34 Precursor to makedir
  1704. Xmalloc.c                12 A version of malloc you might not want
  1705. Xmsdos/Changes.dds       13 Expanation of MS-DOS patches by Diomidis Spinellis
  1706. Xmsdos/Makefile          24 MS-DOS makefile
  1707. Xmsdos/README.msdos       1 Compiling and usage information
  1708. Xmsdos/Wishlist.dds      35 My wishlist
  1709. Xmsdos/chdir.c           32 A chdir that can change drives
  1710. Xmsdos/config.h          22 Definitions for msdos
  1711. Xmsdos/dir.h             34 MS-DOS header for directory access functions
  1712. Xmsdos/directory.c       32 MS-DOS directory access functions.
  1713. Xmsdos/eg/crlf.bat       35 Convert files from unix to MS-DOS line termination
  1714. Xmsdos/eg/drives.bat     35 List the system drives and their characteristics
  1715. Xmsdos/eg/lf.bat         35 Convert files from MS-DOS to Unix line termination
  1716. Xmsdos/glob.c            36 A command equivalent to csh glob
  1717. Xmsdos/msdos.c           30 MS-DOS ioctl, sleep, gete?[gu]if, spawn, aspawn
  1718. Xmsdos/popen.c           32 My_popen and my_pclose for MS-DOS
  1719. Xmsdos/usage.c           34 How to invoke perl under MS-DOS
  1720. Xos2/Makefile            33 Makefile for OS/2
  1721. Xos2/README.OS2           1 Notes for OS/2
  1722. Xos2/a2p.cs              36 Compiler script for a2p
  1723. Xos2/a2p.def             36 Linker defs for a2p
  1724. Xos2/alarm.c             31 An implementation of alarm()
  1725. Xos2/alarm.h             36 Header file for same
  1726. Xos2/config.h            25 Configuration file for OS/2
  1727. Xos2/dir.h               34 Directory header
  1728. Xos2/director.c          30 Directory routines
  1729. Xos2/eg/alarm.pl         36 Example of alarm code
  1730. Xos2/eg/os2.pl           34 Sample script for OS/2
  1731. Xos2/eg/syscalls.pl      36 Example of syscall on OS/2
  1732. Xos2/glob.c              34 Globbing routines
  1733. Xos2/makefile            33 Make file
  1734. Xos2/mktemp.c            36 Mktemp() using TMP
  1735. Xos2/os2.c               30 Unix compatibility functions
  1736. Xos2/perl.bad            36 names of protect-only API calls for BIND
  1737. Xos2/perl.cs             36 Compiler script for perl
  1738. Xos2/perl.def            36 Linker defs for perl
  1739. Xos2/perldb.dif          35 Changes to make the debugger work
  1740. Xos2/perlglob.bad        36 names of protect-only API calls for BIND
  1741. Xos2/perlglob.cs         36 Compiler script for perlglob
  1742. Xos2/perlglob.def        36 Linker defs for perlglob
  1743. Xos2/perlsh.cmd          36 Poor man's shell for os2
  1744. Xos2/popen.c             25 Code for opening pipes
  1745. Xos2/s2p.cmd             28 s2p as command file
  1746. Xos2/selfrun.bat         36 A self running perl script for DOS
  1747. Xos2/selfrun.cmd         36 Example of extproc feature
  1748. Xos2/suffix.c            29 Code for creating backup filenames
  1749. Xpatchlevel.h            19 The current patch level of perl
  1750. Xperl.c                  16 main()
  1751. Xperl.h                  19 Global declarations
  1752. Xperl.man:AA              2 The manual page(s)
  1753. Xperl.man:AB              5 
  1754. Xperl.man:AC              8 
  1755. Xperl.man:AD             10 
  1756. Xperlsh                  16 A poor man's perl shell
  1757. Xperly.fixer             32 A program to remove yacc stack limitations
  1758. Xperly.y                 22 Yacc grammar for perl
  1759. Xregcomp.c               18 Regular expression compiler
  1760. Xregcomp.h               29 Private declarations for above
  1761. Xregexec.c               21 Regular expression evaluator
  1762. Xregexp.h                35 Public declarations for the above
  1763. Xserver                  36 A server to test sockets
  1764. Xspat.h                  34 Search pattern declarations
  1765. Xstab.c                  24 Symbol table stuff
  1766. Xstab.h                  32 Public declarations for the above
  1767. Xstr.c                   15 String handling package
  1768. Xstr.h                   31 Public declarations for the above
  1769. Xt/README                 1 Instructions for regression tests
  1770. Xt/TEST                  34 The regression tester
  1771. Xt/base/cond.t           36 See if conditionals work
  1772. Xt/base/if.t             36 See if if works
  1773. Xt/base/lex.t            35 See if lexical items work
  1774. Xt/base/pat.t            36 See if pattern matching works
  1775. Xt/base/term.t           35 See if various terms work
  1776. Xt/cmd/elsif.t           36 See if else-if works
  1777. Xt/cmd/for.t             35 See if for loops work
  1778. Xt/cmd/mod.t             36 See if statement modifiers work
  1779. Xt/cmd/subval.t          32 See if subroutine values work
  1780. Xt/cmd/switch.t          15 See if switch optimizations work
  1781. Xt/cmd/while.t           33 See if while loops work
  1782. Xt/comp/cmdopt.t         33 See if command optimization works
  1783. Xt/comp/cpp.t            36 See if C preprocessor works
  1784. Xt/comp/decl.t           36 See if declarations work
  1785. Xt/comp/multiline.t      35 See if multiline strings work
  1786. Xt/comp/package.t        36 See if packages work
  1787. Xt/comp/script.t         36 See if script invokation works
  1788. Xt/comp/term.t           34 See if more terms work
  1789. Xt/io/argv.t             35 See if ARGV stuff works
  1790. Xt/io/dup.t              36 See if >& works right
  1791. Xt/io/fs.t               33 See if directory manipulations work
  1792. Xt/io/inplace.t          36 See if inplace editing works
  1793. Xt/io/pipe.t             35 See if secure pipes work
  1794. Xt/io/print.t            36 See if print commands work
  1795. Xt/io/tell.t             35 See if file seeking works
  1796. Xt/lib/big.t             31 See if lib/bigint.pl works
  1797. Xt/op/append.t           36 See if . works
  1798. Xt/op/array.t            31 See if array operations work
  1799. Xt/op/auto.t             33 See if autoincrement et all work
  1800. Xt/op/chop.t             36 See if chop works
  1801. Xt/op/cond.t             36 See if conditional expressions work
  1802. Xt/op/dbm.t              33 See if dbm binding works
  1803. Xt/op/delete.t           14 See if delete works
  1804. Xt/op/do.t               35 See if subroutines work
  1805. Xt/op/each.t             35 See if associative iterators work
  1806. Xt/op/eval.t             35 See if eval operator works
  1807. Xt/op/exec.t             36 See if exec and system work
  1808. Xt/op/exp.t              36 See if math functions work
  1809. Xt/op/flip.t             36 See if range operator works
  1810. Xt/op/fork.t             12 See if fork works
  1811. Xt/op/glob.t             36 See if <*> works
  1812. Xt/op/goto.t             36 See if goto works
  1813. Xt/op/groups.t           36 See if $( works
  1814. Xt/op/index.t            34 See if index works
  1815. Xt/op/int.t              36 See if int works
  1816. Xt/op/join.t             36 See if join works
  1817. Xt/op/list.t             33 See if array lists work
  1818. Xt/op/local.t            35 See if local works
  1819. Xt/op/magic.t            35 See if magic variables work
  1820. Xt/op/mkdir.t            36 See if mkdir works
  1821. Xt/op/oct.t              36 See if oct and hex work
  1822. Xt/op/ord.t              36 See if ord works
  1823. Xt/op/pack.t             36 See if pack and unpack work
  1824. Xt/op/pat.t              32 See if esoteric patterns work
  1825. Xt/op/push.t             35 See if push and pop work
  1826. Xt/op/range.t            35 See if .. works
  1827. Xt/op/re_tests           33 Input file for op.regexp
  1828. Xt/op/read.t             21 See if read() works
  1829. Xt/op/regexp.t           35 See if regular expressions work
  1830. Xt/op/repeat.t           34 See if x operator works
  1831. Xt/op/s.t                31 See if substitutions work
  1832. Xt/op/sleep.t            36 See if sleep works
  1833. Xt/op/sort.t             27 See if sort works
  1834. Xt/op/split.t            34 See if split works
  1835. Xt/op/sprintf.t          36 See if sprintf works
  1836. Xt/op/stat.t             30 See if stat works
  1837. Xt/op/study.t             1 See if study works
  1838. Xt/op/substr.t           34 See if substr works
  1839. Xt/op/time.t             35 See if time functions work
  1840. Xt/op/undef.t            34 See if undef works
  1841. Xt/op/unshift.t          36 See if unshift works
  1842. Xt/op/vec.t              35 See if vectors work
  1843. Xt/op/write.t            34 See if write works
  1844. Xtoke.c:AA                4 The tokener
  1845. Xtoke.c:AB               28 
  1846. Xusersub.c               32 User supplied (possibly proprietary) subroutines
  1847. Xusub/Makefile           36 Makefile for curseperl
  1848. Xusub/README              1 Instructions for user supplied subroutines
  1849. Xusub/curses.mus         14 Glue routines for BSD curses
  1850. Xusub/man2mus            34 A manual page to .mus translator
  1851. Xusub/mus                33 A .mus to .c translator
  1852. Xusub/pager              32 A sample pager in curseperl
  1853. Xusub/usersub.c          36 An initialization file to call curses glue routines
  1854. Xutil.c                  17 Utility routines
  1855. Xutil.h                  35 Public declarations for the above
  1856. Xx2p/EXTERN.h            36 Same as above
  1857. Xx2p/INTERN.h            36 Same as above
  1858. Xx2p/Makefile.SH         33 Precursor to Makefile
  1859. Xx2p/a2p.h               29 Global declarations
  1860. Xx2p/a2p.man             29 Manual page for awk to perl translator
  1861. Xx2p/a2p.y               27 A yacc grammer for awk
  1862. Xx2p/a2py.c              24 Awk compiler, sort of
  1863. Xx2p/find2perl.SH        26 A find to perl translator
  1864. Xx2p/handy.h             35 Handy definitions
  1865. Xx2p/hash.c              31 Associative arrays again
  1866. Xx2p/hash.h              34 Public declarations for the above
  1867. Xx2p/s2p.SH              27 Sed to perl translator
  1868. Xx2p/s2p.man             33 Manual page for sed to perl translator
  1869. Xx2p/str.c               13 String handling package
  1870. Xx2p/str.h               35 Public declarations for the above
  1871. Xx2p/util.c              30 Utility routines
  1872. Xx2p/util.h              35 Public declarations for the above
  1873. Xx2p/walk.c               9 Parse tree walker
  1874. !STUFFY!FUNK!
  1875. echo Extracting lib/stat.pl
  1876. sed >lib/stat.pl <<'!STUFFY!FUNK!' -e 's/X//'
  1877. X;# $Header: stat.pl,v 4.0 91/03/20 01:26:16 lwall Locked $
  1878. X
  1879. X;# Usage:
  1880. X;#    require 'stat.pl';
  1881. X;#    @ary = stat(foo);
  1882. X;#    $st_dev = @ary[$ST_DEV];
  1883. X;#
  1884. X$ST_DEV =    0 + $[;
  1885. X$ST_INO =    1 + $[;
  1886. X$ST_MODE =    2 + $[;
  1887. X$ST_NLINK =    3 + $[;
  1888. X$ST_UID =    4 + $[;
  1889. X$ST_GID =    5 + $[;
  1890. X$ST_RDEV =    6 + $[;
  1891. X$ST_SIZE =    7 + $[;
  1892. X$ST_ATIME =    8 + $[;
  1893. X$ST_MTIME =    9 + $[;
  1894. X$ST_CTIME =    10 + $[;
  1895. X$ST_BLKSIZE =    11 + $[;
  1896. X$ST_BLOCKS =    12 + $[;
  1897. X
  1898. X;# Usage:
  1899. X;#    require 'stat.pl';
  1900. X;#    do Stat('foo');        # sets st_* as a side effect
  1901. X;#
  1902. Xsub Stat {
  1903. X    ($st_dev,$st_ino,$st_mode,$st_nlink,$st_uid,$st_gid,$st_rdev,$st_size,
  1904. X    $st_atime,$st_mtime,$st_ctime,$st_blksize,$st_blocks) = stat(shift(@_));
  1905. X}
  1906. X
  1907. X1;
  1908. !STUFFY!FUNK!
  1909. echo " "
  1910. echo "End of kit 17 (of 36)"
  1911. cat /dev/null >kit17isdone
  1912. run=''
  1913. config=''
  1914. for iskit 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 34 35 36; do
  1915.     if test -f kit${iskit}isdone; then
  1916.     run="$run $iskit"
  1917.     else
  1918.     todo="$todo $iskit"
  1919.     fi
  1920. done
  1921. case $todo in
  1922.     '')
  1923.     echo "You have run all your kits.  Please read README and then type Configure."
  1924.     for combo in *:AA; do
  1925.         if test -f "$combo"; then
  1926.         realfile=`basename $combo :AA`
  1927.         cat $realfile:[A-Z][A-Z] >$realfile
  1928.         rm -rf $realfile:[A-Z][A-Z]
  1929.         fi
  1930.     done
  1931.     rm -rf kit*isdone
  1932.     chmod 755 Configure
  1933.     ;;
  1934.     *)  echo "You have run$run."
  1935.     echo "You still need to run$todo."
  1936.     ;;
  1937. esac
  1938. : Someone might mail this, so...
  1939. exit
  1940.  
  1941. exit 0 # Just in case...
  1942. -- 
  1943. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  1944. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  1945. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  1946. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  1947.