home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume22 / debug_malloc / part02 < prev    next >
Encoding:
Internet Message Format  |  1990-10-09  |  44.9 KB

  1. Subject:  v22i113:  Debugging malloc() library, Part02/02
  2. Newsgroups: comp.sources.unix
  3. Approved: rsalz@uunet.UU.NET
  4. X-Checksum-Snefru: 781b16f7 302faa92 8449794f 3a8d14ed
  5.  
  6. Submitted-by: "Conor P. Cahill" <virtech!cpcahil@uunet.uu.net>
  7. Posting-number: Volume 22, Issue 113
  8. Archive-name: debug_malloc/part02
  9.  
  10. #!/bin/sh
  11. # This is part 02 of Malloclib
  12. if touch 2>&1 | fgrep '[-amc]' > /dev/null
  13.  then TOUCH=touch
  14.  else TOUCH=true
  15. fi
  16. # ============= malloc.h ==============
  17. if test X"$1" != X"-c" -a -f 'malloc.h'; then
  18.     echo "File already exists: skipping 'malloc.h'"
  19. else
  20. echo "x - extracting malloc.h (Text)"
  21. sed 's/^X//' << 'SHAR_EOF' > malloc.h &&
  22. X/*
  23. X * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).  
  24. X * You may copy, distribute, and use this software as long as this
  25. X * copyright statement is not removed.
  26. X */
  27. X/*
  28. X * $Id: malloc.h,v 1.3 90/05/11 11:04:10 cpcahil Exp $
  29. X */
  30. Xstruct mlist
  31. X{
  32. X    struct mlist    * next;            /* next entry in chain    */
  33. X    struct mlist    * prev;            /* prev entry in chain    */
  34. X    int           flag;            /* inuse flag        */
  35. X    unsigned int      r_size;        /* requested size    */
  36. X    union
  37. X    {
  38. X        unsigned int      size;        /* actual size        */
  39. X        double          unused_just_for_alignment;
  40. X    } s;
  41. X    char          data[4];
  42. X};
  43. X
  44. X#define M_SIZE        ((int)(char *)((struct mlist *)0)->data)
  45. X#define M_RND        0x08
  46. X
  47. X#define M_INUSE     0x01
  48. X#define M_MAGIC     0x03156100
  49. X
  50. X#define M_BLOCKSIZE    (1024*8)
  51. X
  52. X#define M_FILL        '\01'
  53. X#define M_FREE_FILL    '\02'
  54. X
  55. X#define M_ROUNDUP(size)    {\
  56. X                if( size & (M_RND-1) ) \
  57. X                { \
  58. X                    size &= ~(M_RND-1); \
  59. X                    size += M_RND; \
  60. X                } \
  61. X            }
  62. X
  63. X/*
  64. X * Malloc warning/fatal error handler defines...
  65. X */
  66. X#define M_HANDLE_DUMP    0x80  /* 128 */
  67. X#define M_HANDLE_IGNORE    0
  68. X#define M_HANDLE_ABORT    1
  69. X#define M_HANDLE_EXIT    2
  70. X#define M_HANDLE_CORE    3
  71. X    
  72. X/*
  73. X * Mallopt commands and defaults
  74. X */
  75. X
  76. X#define MALLOC_WARN    1        /* set malloc warning handling    */
  77. X#define MALLOC_FATAL    2        /* set malloc fatal handling    */
  78. X#define MALLOC_ERRFILE    3        /* specify malloc error file    */
  79. X#define MALLOC_CKCHAIN    4        /* turn on chain checking    */
  80. X
  81. X
  82. X/*
  83. X * Malloc warning/fatal error codes
  84. X */
  85. X
  86. X#define M_CODE_CHAIN_BROKE    1    /* malloc chain is broken    */
  87. X#define M_CODE_NO_END        2    /* chain end != endptr        */
  88. X#define M_CODE_BAD_PTR        3    /* pointer not in malloc area    */
  89. X#define M_CODE_BAD_MAGIC    4    /* bad magic number in header    */
  90. X#define M_CODE_BAD_CONNECT    5    /* chain poingers corrupt    */
  91. X#define M_CODE_OVERRUN        6    /* data overrun in malloc seg    */
  92. X#define M_CODE_REUSE        7    /* reuse of freed area        */
  93. X#define M_CODE_NOT_INUSE    8    /* pointer is not in use    */
  94. X#define M_CODE_NOMORE_MEM    9    /* no more memory available    */
  95. X#define M_CODE_OUTOF_BOUNDS    10    /* gone beyound bounds         */
  96. X
  97. Xvoid malloc_warning();
  98. Xvoid malloc_fatal();
  99. Xvoid malloc_check_data();
  100. Xvoid malloc_check_str();
  101. Xvoid malloc_verify();
  102. X
  103. X/*
  104. X * $Log:    malloc.h,v $
  105. X * Revision 1.3  90/05/11  11:04:10  cpcahil
  106. X * took out some extraneous lines
  107. X * 
  108. X * Revision 1.2  90/05/11  00:13:09  cpcahil
  109. X * added copyright statment
  110. X * 
  111. X * Revision 1.1  90/02/23  07:09:03  cpcahil
  112. X * Initial revision
  113. X * 
  114. X */
  115. SHAR_EOF
  116. $TOUCH -am 0511110490 malloc.h &&
  117. chmod 0444 malloc.h ||
  118. echo "restore of malloc.h failed"
  119. set `wc -c malloc.h`;Wc_c=$1
  120. if test "$Wc_c" != "2346"; then
  121.     echo original size 2346, current size $Wc_c
  122. fi
  123. fi
  124. # ============= malloc_chk.c ==============
  125. if test X"$1" != X"-c" -a -f 'malloc_chk.c'; then
  126.     echo "File already exists: skipping 'malloc_chk.c'"
  127. else
  128. echo "x - extracting malloc_chk.c (Text)"
  129. sed 's/^X//' << 'SHAR_EOF' > malloc_chk.c &&
  130. X/*
  131. X * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).  
  132. X * You may copy, distribute, and use this software as long as this
  133. X * copyright statement is not removed.
  134. X */
  135. X
  136. X#include <stdio.h>
  137. X#include "malloc.h"
  138. X#include "debug.h"
  139. X
  140. X#ifndef lint
  141. Xstatic
  142. Xchar rcs_hdr[] = "$Id: malloc_chk.c,v 1.4 90/05/11 00:13:09 cpcahil Exp $";
  143. X#endif
  144. X
  145. Xextern struct mlist      malloc_start;
  146. Xextern struct mlist    * malloc_end;
  147. Xextern char        * malloc_data_start;
  148. Xextern char        * malloc_data_end;
  149. X
  150. X/*
  151. X * Function:    malloc_in_arena()
  152. X *
  153. X * Purpose:    to verify address is within malloc arena.
  154. X *
  155. X * Arguments:    ptr    - pointer to verify
  156. X *
  157. X * Returns:    TRUE    - if pointer is within malloc area
  158. X *        FALSE    - otherwise
  159. X *
  160. X * Narrative:
  161. X *   IF pointer is >= malloc area start AND <= malloc area end
  162. X *      return TRUE
  163. X *   ELSE
  164. X *      return FALSE
  165. X *
  166. X * Mod History:    
  167. X *   90/01/24    cpcahil        Initial revision.
  168. X */
  169. Xint
  170. Xmalloc_in_arena(ptr)
  171. X    char    * ptr;
  172. X{
  173. X    extern char    * malloc_data_start;
  174. X    extern char    * malloc_data_end;
  175. X    int          rtn = 0;
  176. X
  177. X    if( ptr >= malloc_data_start && ptr <= malloc_data_end )
  178. X    {
  179. X        rtn = 1;
  180. X    }
  181. X    
  182. X    return(rtn);
  183. X}
  184. X
  185. X/*
  186. X * Function:    malloc_check_str()
  187. X *
  188. X * Arguments:    func    - name of function calling this routine
  189. X *        str    - pointer to area to check
  190. X *
  191. X * Purpose:    to verify that if str is within the malloc arena, the data 
  192. X *        it points to does not extend beyond the applicable region.
  193. X *
  194. X * Returns:    Nothing of any use (function is void).
  195. X *
  196. X * Narrative:
  197. X *   IF pointer is within malloc arena
  198. X *      determin length of string
  199. X *      call malloc_verify() to verify data is withing applicable region
  200. X *   return 
  201. X *
  202. X * Mod History:    
  203. X *   90/01/24    cpcahil        Initial revision.
  204. X *   90/01/29    cpcahil        Added code to ignore recursive calls.
  205. X */
  206. Xvoid
  207. Xmalloc_check_str(func,str)
  208. X    char        * func;
  209. X    char        * str;
  210. X{
  211. X    static int      layers;
  212. X    register char    * s;
  213. X
  214. X    if( (layers++ == 0) &&  malloc_in_arena(str) )
  215. X    {
  216. X        for( s=str; *s; s++)
  217. X        {
  218. X        }
  219. X        
  220. X        malloc_verify(func,str,s-str+1);
  221. X    }
  222. X
  223. X    layers--;
  224. X}
  225. X
  226. X/*
  227. X * Function:    malloc_check_data()
  228. X *
  229. X * Arguments:    func    - name of function calling this routine
  230. X *        ptr    - pointer to area to check
  231. X *        len     - length to verify
  232. X *
  233. X * Purpose:    to verify that if ptr is within the malloc arena, the data 
  234. X *        it points to does not extend beyond the applicable region.
  235. X *
  236. X * Returns:    Nothing of any use (function is void).
  237. X *
  238. X * Narrative:
  239. X *   IF pointer is within malloc arena
  240. X *      call malloc_verify() to verify data is withing applicable region
  241. X *   return 
  242. X *
  243. X * Mod History:    
  244. X *   90/01/24    cpcahil        Initial revision.
  245. X *   90/01/29    cpcahil        Added code to ignore recursive calls.
  246. X */
  247. Xvoid
  248. Xmalloc_check_data(func,ptr,len)
  249. X    char        * func;
  250. X    char        * ptr;
  251. X    int          len;
  252. X{
  253. X    static int      layers;
  254. X
  255. X    if( layers++ == 0 )
  256. X    {
  257. X        DEBUG3(40,"malloc_check_data(%s,0x%x,%d) called...",
  258. X            func,ptr,len);
  259. X        if( malloc_in_arena(ptr) )
  260. X        {
  261. X            DEBUG0(10,"pointer in malloc arena, verifying...");
  262. X            malloc_verify(func,ptr,len);
  263. X        }
  264. X    }
  265. X
  266. X    layers--;
  267. X}
  268. X
  269. X/*
  270. X * Function:    malloc_verify()
  271. X *
  272. X * Arguments:    func    - name of function calling the malloc check routines
  273. X *        ptr    - pointer to area to check
  274. X *        len     - length to verify
  275. X *
  276. X * Purpose:    to verify that the data ptr points to does not extend beyond
  277. X *        the applicable malloc region.  This function is only called 
  278. X *        if it has been determined that ptr points into the malloc arena.
  279. X *
  280. X * Returns:    Nothing of any use (function is void).
  281. X *
  282. X * Narrative:
  283. X *
  284. X * Mod History:    
  285. X *   90/01/24    cpcahil        Initial revision.
  286. X */
  287. Xvoid
  288. Xmalloc_verify(func,ptr,len)
  289. X    char        * func;
  290. X    char        * ptr;
  291. X    int          len;
  292. X{
  293. X    extern struct mlist    * malloc_end;
  294. X    extern int          malloc_errno;
  295. X    extern struct mlist       malloc_start;
  296. X    struct mlist        * mptr;
  297. X    
  298. X    DEBUG3(40,"malloc_verify(%s,0x%x,%d) called...", func,ptr,len);
  299. X    /*
  300. X     * Find the malloc block that includes this pointer
  301. X     */
  302. X    mptr = &malloc_start;
  303. X    while( mptr && 
  304. X        ! (((char *)mptr < ptr) && ((mptr->data+mptr->s.size) > ptr) ) )
  305. X    {
  306. X        mptr = mptr->next;
  307. X    }
  308. X
  309. X    /*
  310. X     * if ptr was not in a malloc block, it must be part of
  311. X     *    some direct sbrk() stuff, so just return.
  312. X     */
  313. X    if( ! mptr )
  314. X    {
  315. X        DEBUG1(10,"ptr (0x%x) not found in malloc search", ptr);
  316. X        return;
  317. X    }
  318. X    
  319. X    /*
  320. X      * Now we have a valid malloc block that contains the indicated
  321. X     * pointer.  We must verify that it is withing the requested block
  322. X     * size (as opposed to the real block size which is rounded up to
  323. X     * allow for correct alignment).
  324. X     */
  325. X
  326. X    DEBUG4(60,"Checking  0x%x-0x%x, 0x%x-0x%x",
  327. X            ptr, ptr+len, mptr->data, mptr->data+mptr->r_size);
  328. X    
  329. X    if( (ptr < mptr->data) || ((ptr+len) > (mptr->data+mptr->r_size)) )
  330. X    {
  331. X        DEBUG4(0,"pointer not within region 0x%x-0x%x, 0x%x-0x%x",
  332. X            ptr, ptr+len, mptr->data, mptr->data+mptr->r_size);
  333. X
  334. X        malloc_errno = M_CODE_OUTOF_BOUNDS;
  335. X        malloc_warning(func);
  336. X    }
  337. X
  338. X    return;
  339. X}
  340. X
  341. X/*
  342. X * $Log:    malloc_chk.c,v $
  343. X * Revision 1.4  90/05/11  00:13:09  cpcahil
  344. X * added copyright statment
  345. X * 
  346. X * Revision 1.3  90/02/24  21:50:22  cpcahil
  347. X * lots of lint fixes
  348. X * 
  349. X * Revision 1.2  90/02/24  17:29:38  cpcahil
  350. X * changed $Header to $Id so full path wouldnt be included as part of rcs 
  351. X * id string
  352. X * 
  353. X * Revision 1.1  90/02/24  14:57:03  cpcahil
  354. X * Initial revision
  355. X * 
  356. X */
  357. SHAR_EOF
  358. $TOUCH -am 0511001490 malloc_chk.c &&
  359. chmod 0444 malloc_chk.c ||
  360. echo "restore of malloc_chk.c failed"
  361. set `wc -c malloc_chk.c`;Wc_c=$1
  362. if test "$Wc_c" != "5125"; then
  363.     echo original size 5125, current size $Wc_c
  364. fi
  365. fi
  366. # ============= malloc_chn.c ==============
  367. if test X"$1" != X"-c" -a -f 'malloc_chn.c'; then
  368.     echo "File already exists: skipping 'malloc_chn.c'"
  369. else
  370. echo "x - extracting malloc_chn.c (Text)"
  371. sed 's/^X//' << 'SHAR_EOF' > malloc_chn.c &&
  372. X/*
  373. X * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).  
  374. X * You may copy, distribute, and use this software as long as this
  375. X * copyright statement is not removed.
  376. X */
  377. X#include <stdio.h>
  378. X#include <fcntl.h>
  379. X#include "malloc.h"
  380. X
  381. X/*
  382. X * Function:    malloc_chain_check()
  383. X *
  384. X * Purpose:    to verify malloc chain is intact
  385. X *
  386. X * Arguments:    todo    - 0 - just check and return status
  387. X *              1 - call malloc_warn if error detected
  388. X *
  389. X * Returns:    0    - malloc chain intact & no overflows
  390. X *        other    - problems detected in malloc chain
  391. X *
  392. X * Narrative:
  393. X *
  394. X * Notes:    If todo is non-zero the malloc_warn function, when called
  395. X *        may not return (i.e. it may exit)
  396. X *
  397. X */
  398. X#ifndef lint
  399. Xstatic
  400. Xchar rcs_hdr[] = "$Id: malloc_chn.c,v 1.4 90/05/11 00:13:09 cpcahil Exp $";
  401. X#endif
  402. X
  403. X
  404. Xint
  405. Xmalloc_chain_check(todo)
  406. X    int          todo;
  407. X{
  408. X    char            * func = "malloc_chain_check";
  409. X    int              i;
  410. X    extern char        * malloc_data_start;
  411. X    extern char        * malloc_data_end;
  412. X    extern struct mlist     * malloc_end;
  413. X    extern int          malloc_errno;
  414. X    extern struct mlist      malloc_start;
  415. X    struct mlist        * oldptr;
  416. X    struct mlist        * ptr;
  417. X    int              rtn = 0;
  418. X
  419. X    oldptr = &malloc_start;
  420. X    for(ptr = malloc_start.next; ; ptr = ptr->next)
  421. X    {
  422. X        /*
  423. X         * Since the malloc chain is a forward only chain, any
  424. X         * pointer that we get should always be positioned in 
  425. X         * memory following the previous pointer.  If this is not
  426. X         * so, we must have a corrupted chain.
  427. X         */
  428. X        if( ptr )
  429. X        {
  430. X            if(ptr < oldptr )
  431. X            {
  432. X                malloc_errno = M_CODE_CHAIN_BROKE;
  433. X                if( todo )
  434. X                {
  435. X                    malloc_fatal(func);
  436. X                }
  437. X                rtn++;
  438. X                break;
  439. X            }
  440. X            oldptr = ptr;
  441. X        }
  442. X        else
  443. X        {
  444. X            if( oldptr != malloc_end )
  445. X            {
  446. X                /*
  447. X                 * This should never happen.  If it does, then
  448. X                 * we got a real problem.
  449. X                 */
  450. X                malloc_errno = M_CODE_NO_END;
  451. X                if( todo )
  452. X                {
  453. X                    malloc_fatal(func);
  454. X                }
  455. X                rtn++;
  456. X            }
  457. X            break;
  458. X        }
  459. X        
  460. X        /*
  461. X         * verify that ptr is within the malloc region...
  462. X         * since we started within the malloc chain this should never
  463. X         * happen.
  464. X         */
  465. X
  466. X        if( ((char *)ptr < malloc_data_start) ||
  467. X            ((char *)ptr > malloc_data_end) )
  468. X        {
  469. X            malloc_errno = M_CODE_BAD_PTR;
  470. X            if( todo )
  471. X            {
  472. X                malloc_fatal(func);
  473. X            }
  474. X            rtn++;
  475. X            break;
  476. X        }
  477. X
  478. X        /* 
  479. X         * verify magic flag is set
  480. X         */
  481. X        
  482. X        if( (ptr->flag&M_MAGIC) != M_MAGIC )
  483. X        {
  484. X            malloc_errno = M_CODE_BAD_MAGIC;
  485. X            if( todo )
  486. X            {
  487. X                malloc_warning(func);
  488. X            }
  489. X            rtn++;
  490. X            continue;
  491. X        }
  492. X
  493. X        /* 
  494. X         * verify segments are correctly linked together
  495. X         */
  496. X        
  497. X        if( (ptr->prev && (ptr->prev->next != ptr) ) ||
  498. X            (ptr->next && (ptr->next->prev != ptr) ) ||
  499. X            ((ptr->next == NULL) && (ptr->prev == NULL)) )
  500. X        {
  501. X            malloc_errno = M_CODE_BAD_CONNECT;
  502. X            if( todo )
  503. X            {
  504. X                malloc_warning(func);
  505. X            }
  506. X            rtn++;
  507. X            continue;
  508. X        }
  509. X
  510. X        /*
  511. X         * If this segment is allocated
  512. X         */
  513. X
  514. X        if( (ptr->flag & M_INUSE) != 0 )
  515. X        {
  516. X            /*
  517. X             * verify no overflow of data area
  518. X             */
  519. X
  520. X            for(i=ptr->r_size; i < ptr->s.size; i++)
  521. X            {
  522. X                if( ptr->data[i] != M_FILL )
  523. X                {
  524. X                    malloc_errno = M_CODE_OVERRUN;
  525. X                    if( todo )
  526. X                    {
  527. X                        malloc_warning(func);
  528. X                    }
  529. X                    rtn++;
  530. X                    break;
  531. X                }
  532. X            }
  533. X        }
  534. X        else /* it's not allocated so */
  535. X        {
  536. X            /*
  537. X             * verify no reuse of freed data blocks
  538. X             */
  539. X
  540. X            for(i=0; i < ptr->s.size; i++)
  541. X            {
  542. X                if( ptr->data[i] != M_FREE_FILL )
  543. X                {
  544. X                    malloc_errno = M_CODE_REUSE;
  545. X                    if( todo )
  546. X                    {
  547. X                        malloc_warning(func);
  548. X                    }
  549. X                    rtn++;
  550. X                    break;
  551. X                }
  552. X            }
  553. X        }
  554. X
  555. X    } /* for(... */
  556. X
  557. X    return(rtn);
  558. X
  559. X} /* malloc_chain_check(... */
  560. SHAR_EOF
  561. $TOUCH -am 0511001490 malloc_chn.c &&
  562. chmod 0444 malloc_chn.c ||
  563. echo "restore of malloc_chn.c failed"
  564. set `wc -c malloc_chn.c`;Wc_c=$1
  565. if test "$Wc_c" != "3449"; then
  566.     echo original size 3449, current size $Wc_c
  567. fi
  568. fi
  569. # ============= mallopt.c ==============
  570. if test X"$1" != X"-c" -a -f 'mallopt.c'; then
  571.     echo "File already exists: skipping 'mallopt.c'"
  572. else
  573. echo "x - extracting mallopt.c (Text)"
  574. sed 's/^X//' << 'SHAR_EOF' > mallopt.c &&
  575. X/*
  576. X * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).  
  577. X * You may copy, distribute, and use this software as long as this
  578. X * copyright statement is not removed.
  579. X */
  580. X#include <stdio.h>
  581. X#include <fcntl.h>
  582. X#include "malloc.h"
  583. X
  584. X/*
  585. X * Function:    mallopt()
  586. X *
  587. X * Purpose:    to set options for the malloc debugging library
  588. X *
  589. X * Arguments:    none
  590. X *
  591. X * Returns:    nothing of any value
  592. X *
  593. X * Narrative:    
  594. X *
  595. X */
  596. X
  597. X#ifndef lint
  598. Xstatic
  599. Xchar rcs_hdr[] = "$Id: mallopt.c,v 1.4 90/05/11 00:13:10 cpcahil Exp $";
  600. X#endif
  601. X
  602. Xunion val
  603. X{
  604. X    int      i;
  605. X    char    * str;
  606. X};
  607. X
  608. Xint
  609. Xmallopt(cmd,value)
  610. X    int              cmd;
  611. X    union val          value;
  612. X{
  613. X    int              i;
  614. X    extern int          malloc_checking;
  615. X    extern char        * malloc_data_start;
  616. X    extern int          malloc_errfd;
  617. X    extern int          malloc_fatal_level;
  618. X    void              malloc_init();
  619. X    extern int          malloc_warn_level;
  620. X    register char        * s;
  621. X
  622. X    /*
  623. X      * If not initialized...
  624. X     */
  625. X    if( malloc_data_start == (char *) 0)
  626. X    {
  627. X        malloc_init();
  628. X    }
  629. X
  630. X
  631. X    switch(cmd)
  632. X    {
  633. X        case MALLOC_WARN:
  634. X            malloc_warn_level = value.i;
  635. X            break;
  636. X
  637. X        case MALLOC_FATAL:
  638. X            malloc_fatal_level = value.i;
  639. X            break;
  640. X
  641. X        case MALLOC_CKCHAIN:
  642. X            malloc_checking = value.i;
  643. X            break;
  644. X
  645. X        case MALLOC_ERRFILE:
  646. X            
  647. X            i = open(value.str,O_CREAT|O_APPEND|O_WRONLY,0666);
  648. X            if( i == -1 )
  649. X            {
  650. X                (void) write(2,
  651. X                      "Unable to open malloc error file: ",
  652. X                      (unsigned) 34);
  653. X                for(s=value.str; *s; s++)
  654. X                {
  655. X                    /* do nothing */;
  656. X                }
  657. X                (void) write(2,value.str,
  658. X                         (unsigned)(s-value.str));
  659. X                (void) write(2,"\n",(unsigned)1);
  660. X            }
  661. X            else
  662. X            {
  663. X                if( malloc_errfd != 2 )
  664. X                {
  665. X                    (void) close(malloc_errfd);
  666. X                }
  667. X            }
  668. X            
  669. X            break;
  670. X
  671. X        default:
  672. X            return(1);
  673. X            break;
  674. X    }
  675. X
  676. X    return(0);
  677. X}
  678. X
  679. X/*
  680. X * $Log:    mallopt.c,v $
  681. X * Revision 1.4  90/05/11  00:13:10  cpcahil
  682. X * added copyright statment
  683. X * 
  684. X * Revision 1.3  90/02/25  11:03:26  cpcahil
  685. X * changed to return int so that it agrees with l libmalloc.a's mallopt()
  686. X * 
  687. X * Revision 1.2  90/02/25  11:01:21  cpcahil
  688. X * added support for malloc chain checking.
  689. X * 
  690. X * Revision 1.1  90/02/24  21:50:24  cpcahil
  691. X * Initial revision
  692. X * 
  693. X * Revision 1.1  90/02/24  17:10:53  cpcahil
  694. X * Initial revision
  695. X * 
  696. X */
  697. SHAR_EOF
  698. $TOUCH -am 0511001490 mallopt.c &&
  699. chmod 0444 mallopt.c ||
  700. echo "restore of mallopt.c failed"
  701. set `wc -c mallopt.c`;Wc_c=$1
  702. if test "$Wc_c" != "2128"; then
  703.     echo original size 2128, current size $Wc_c
  704. fi
  705. fi
  706. # ============= memory.c ==============
  707. if test X"$1" != X"-c" -a -f 'memory.c'; then
  708.     echo "File already exists: skipping 'memory.c'"
  709. else
  710. echo "x - extracting memory.c (Text)"
  711. sed 's/^X//' << 'SHAR_EOF' > memory.c &&
  712. X/*
  713. X * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).  
  714. X * You may copy, distribute, and use this software as long as this
  715. X * copyright statement is not removed.
  716. X */
  717. X
  718. X#ifndef lint
  719. Xstatic
  720. Xchar rcs_hdr[] = "$Id: memory.c,v 1.5 90/05/11 15:39:36 cpcahil Exp $";
  721. X#endif
  722. X
  723. Xchar *
  724. Xmemccpy(ptr1, ptr2, ch, len)
  725. X    register char    * ptr1;
  726. X    register char    * ptr2;
  727. X    int          len;
  728. X    int          ch;
  729. X{
  730. X    int          check;
  731. X    register int      i;
  732. X    char        * rtn;
  733. X
  734. X    /*
  735. X     * I know that the assignment could be done in the following, but
  736. X     * I wanted to perform a check before any assignment, so first I 
  737. X     * determine the length, check the pointers and then do the assignment.
  738. X     */
  739. X    for( i=0; (i < len) && (ptr2[i] != ch); i++)
  740. X    {
  741. X    }
  742. X    if( ptr2[i] == ch )
  743. X    {
  744. X        check = i+1;
  745. X    }
  746. X
  747. X    malloc_check_data("memccpy", ptr1, check);
  748. X    malloc_check_data("memccpy", ptr2, check);
  749. X
  750. X    /*
  751. X     * if we found the character...
  752. X      */
  753. X
  754. X    if( i < len )
  755. X    {
  756. X        rtn = ptr1+i+1;
  757. X        i++;
  758. X    }
  759. X    else
  760. X    {
  761. X        rtn = (char *) 0;
  762. X    }
  763. X
  764. X     while( i-- )
  765. X    {
  766. X        *(ptr1++) = *(ptr2++);
  767. X    }
  768. X    
  769. X    return(rtn);
  770. X}
  771. X
  772. Xchar *
  773. Xmemchr(ptr1,ch,len)
  774. X    register char    * ptr1;
  775. X    register int      ch;
  776. X    int          len;
  777. X{
  778. X    int          i;
  779. X
  780. X    for( i=0; (i < len) && (ptr1[i] != ch); i++)
  781. X    {
  782. X    }
  783. X
  784. X    malloc_check_data("memchr", ptr1, i);
  785. X
  786. X    if( i < len )
  787. X    {
  788. X        return( ptr1+i );
  789. X    }
  790. X    else
  791. X    {
  792. X        return( (char *) 0);    
  793. X    }
  794. X}
  795. X
  796. Xchar *
  797. Xmemcpy(ptr1, ptr2, len)
  798. X    register char    * ptr1;
  799. X    register char    * ptr2;
  800. X    register int      len;
  801. X{
  802. X    char        * rtn = ptr1;
  803. X
  804. X    malloc_check_data("memcpy", ptr1, len);
  805. X    malloc_check_data("memcpy", ptr2, len);
  806. X    
  807. X    while( len-- )
  808. X    {
  809. X        *(ptr1++) = *(ptr2++);
  810. X    }
  811. X    return(rtn);
  812. X}
  813. X
  814. Xint
  815. Xmemcmp(ptr1, ptr2, len)
  816. X    register char    * ptr1;
  817. X    register char    * ptr2;
  818. X    register int      len;
  819. X{
  820. X    malloc_check_data("memcpy", ptr1, len);
  821. X    malloc_check_data("memcpy", ptr2, len);
  822. X
  823. X    while( --len && (*ptr1 == *ptr2) )
  824. X    {
  825. X        ptr1++;
  826. X        ptr2++;
  827. X    }
  828. X    return( *ptr1 - *ptr2 );
  829. X}
  830. X
  831. Xchar * 
  832. Xmemset(ptr1, ch, len)
  833. X    register char    * ptr1;
  834. X    register int      ch;
  835. X    register int      len;
  836. X{
  837. X    char        * rtn = ptr1;
  838. X
  839. X    malloc_check_data("memcpy", ptr1, len);
  840. X
  841. X    while( len-- )
  842. X    {
  843. X        *(ptr1++) = ch;
  844. X    }
  845. X
  846. X    return(rtn);
  847. X}
  848. X
  849. Xchar *
  850. Xbcopy(ptr2,ptr1,len)
  851. X    char        * ptr2;
  852. X    char        * ptr1;
  853. X    int          len;
  854. X{
  855. X    return(memcpy(ptr1,ptr2,len));
  856. X}
  857. X
  858. Xchar *
  859. Xbzero(ptr1,len)
  860. X    char        * ptr1;
  861. X    int          len;
  862. X{
  863. X    return(memset(ptr1,'\0',len));
  864. X}
  865. X
  866. Xint
  867. Xbcmp(ptr2, ptr1, len)
  868. X    char        * ptr1;
  869. X    char        * ptr2;
  870. X    int          len;
  871. X{
  872. X    return( memcmp(ptr1,ptr2,len) );
  873. X}
  874. X
  875. X/*
  876. X * $Log:    memory.c,v $
  877. X * Revision 1.5  90/05/11  15:39:36  cpcahil
  878. X * fixed bug in memccpy().
  879. X * 
  880. X * Revision 1.4  90/05/11  00:13:10  cpcahil
  881. X * added copyright statment
  882. X * 
  883. X * Revision 1.3  90/02/24  21:50:29  cpcahil
  884. X * lots of lint fixes
  885. X * 
  886. X * Revision 1.2  90/02/24  17:29:41  cpcahil
  887. X * changed $Header to $Id so full path wouldnt be included as part of rcs 
  888. X * id string
  889. X * 
  890. X * Revision 1.1  90/02/22  23:17:43  cpcahil
  891. X * Initial revision
  892. X * 
  893. X */
  894. SHAR_EOF
  895. $TOUCH -am 0511153990 memory.c &&
  896. chmod 0444 memory.c ||
  897. echo "restore of memory.c failed"
  898. set `wc -c memory.c`;Wc_c=$1
  899. if test "$Wc_c" != "2817"; then
  900.     echo original size 2817, current size $Wc_c
  901. fi
  902. fi
  903. # ============= realloc.c ==============
  904. if test X"$1" != X"-c" -a -f 'realloc.c'; then
  905.     echo "File already exists: skipping 'realloc.c'"
  906. else
  907. echo "x - extracting realloc.c (Text)"
  908. sed 's/^X//' << 'SHAR_EOF' > realloc.c &&
  909. X/*
  910. X * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).  
  911. X * You may copy, distribute, and use this software as long as this
  912. X * copyright statement is not removed.
  913. X */
  914. X#include <stdio.h>
  915. X#include "malloc.h"
  916. X
  917. X/*
  918. X * Function:    realloc()
  919. X *
  920. X * Purpose:    to re-allocate a data area.
  921. X *
  922. X * Arguments:    cptr    - pointer to area to reallocate
  923. X *        size    - size to change area to
  924. X *
  925. X * Returns:    pointer to new area (may be same area)
  926. X *
  927. X * Narrative:    verify pointer is within malloc region
  928. X *        obtain mlist pointer from cptr
  929. X *        verify magic number is correct
  930. X *        verify inuse flag is set
  931. X *        verify connection to adjoining segments is correct
  932. X *        save requested size
  933. X *        round-up size to appropriate boundry
  934. X *        IF size is bigger than what is in this segment
  935. X *            try to join next segment to this segment
  936. X *        IF size is less than what is is this segment
  937. X *            determine leftover amount of space
  938. X *        ELSE
  939. X *            allocate new segment of size bites
  940. X *            IF allocation failed
  941. X *                return NULL
  942. X *            copy previous data to new segment
  943. X *            free previous segment
  944. X *            return new pointer
  945. X *        split of extra space in this segment (if any)
  946. X *        clear bytes beyound what they had before
  947. X *        return pointer to data 
  948. X */
  949. X#ifndef lint
  950. Xstatic
  951. Xchar rcs_hdr[] = "$Id: realloc.c,v 1.7 90/05/11 00:13:10 cpcahil Exp $";
  952. X#endif
  953. X
  954. Xchar *
  955. Xrealloc(cptr,size)
  956. X    char            * cptr;
  957. X    unsigned int          size;
  958. X{
  959. X    void              free();
  960. X    char            * func = "realloc";
  961. X    int              i;
  962. X    char            * malloc();
  963. X    extern int          malloc_checking;
  964. X    extern struct mlist     * malloc_end;
  965. X    extern int          malloc_errno;
  966. X    extern char        * malloc_data_end;
  967. X    extern char        * malloc_data_start;
  968. X    char            * memcpy();
  969. X    char            * new_cptr;
  970. X    struct mlist        * ptr;
  971. X    int              r_size;
  972. X
  973. X    /*
  974. X     * IF malloc chain checking is on, go do it.
  975. X     */
  976. X    if( malloc_checking )
  977. X    {
  978. X        (void) malloc_chain_check(1);
  979. X    }
  980. X
  981. X    /*
  982. X     * verify that cptr is within the malloc region...
  983. X     */
  984. X    if( cptr < malloc_data_start || cptr > malloc_data_end )
  985. X    {
  986. X        malloc_errno = M_CODE_BAD_PTR;
  987. X        malloc_warning(func);
  988. X        return (NULL);
  989. X    }
  990. X
  991. X    /* 
  992. X     * convert pointer to mlist struct pointer.  To do this we must 
  993. X     * move the pointer backwards the correct number of bytes...
  994. X     */
  995. X    
  996. X    ptr = (struct mlist *) (cptr - M_SIZE);
  997. X    
  998. X    if( (ptr->flag&M_MAGIC) != M_MAGIC )
  999. X    {
  1000. X        malloc_errno = M_CODE_BAD_MAGIC;
  1001. X        malloc_warning(func);
  1002. X        return(NULL);
  1003. X    }
  1004. X
  1005. X    if( ! (ptr->flag & M_INUSE) )
  1006. X    {
  1007. X        malloc_errno = M_CODE_NOT_INUSE ;
  1008. X        malloc_warning(func);
  1009. X        return(NULL);
  1010. X    }
  1011. X
  1012. X     if( (ptr->prev && (ptr->prev->next != ptr) ) ||
  1013. X        (ptr->next && (ptr->next->prev != ptr) ) ||
  1014. X        ((ptr->next == NULL) && (ptr->prev == NULL)) )
  1015. X    {
  1016. X        malloc_errno = M_CODE_BAD_CONNECT;
  1017. X        malloc_warning(func);
  1018. X        return(NULL);
  1019. X    }
  1020. X
  1021. X    r_size = ++size;
  1022. X
  1023. X    M_ROUNDUP(size);
  1024. X
  1025. X    if( size > ptr->s.size )
  1026. X    {
  1027. X        malloc_join(ptr,ptr->next,1,1);
  1028. X    }
  1029. X
  1030. X    if( size > ptr->s.size )
  1031. X    {
  1032. X        /*
  1033. X         * else we can't combine it, so lets allocate a new chunk,
  1034. X         * copy the data and free the old chunk...
  1035. X         */
  1036. X        new_cptr = malloc(size);
  1037. X
  1038. X        if( new_cptr == (char *) 0)
  1039. X        {
  1040. X            return(new_cptr);
  1041. X        }
  1042. X
  1043. X        if( r_size < ptr->r_size )
  1044. X        {
  1045. X            i = r_size;
  1046. X        }
  1047. X        else
  1048. X        {
  1049. X            i = ptr->r_size;
  1050. X        }
  1051. X        (void)memcpy(new_cptr,ptr->data,i);
  1052. X        free(cptr);
  1053. X        return(new_cptr);
  1054. X
  1055. X    } /* else... */
  1056. X
  1057. X    /*
  1058. X     * save amount of real data in new segment (this will be used in the
  1059. X     * memset later) and then save requested size of this segment.
  1060. X     */
  1061. X
  1062. X    if( ptr->r_size < r_size )
  1063. X    {
  1064. X        i = ptr->r_size;
  1065. X    }
  1066. X    else
  1067. X    {
  1068. X        i = r_size;
  1069. X    }
  1070. X
  1071. X    ptr->r_size = r_size;
  1072. X
  1073. X    /*
  1074. X     * split off extra free space at end of this segment, if possible...
  1075. X     */
  1076. X
  1077. X    malloc_split(ptr);
  1078. X
  1079. X    malloc_memset( ptr->data+i, M_FILL, ptr->s.size - i);
  1080. X        
  1081. X    return(ptr->data);
  1082. X
  1083. X} /* realloc(... */
  1084. X
  1085. X
  1086. X/*
  1087. X * $Log:    realloc.c,v $
  1088. X * Revision 1.7  90/05/11  00:13:10  cpcahil
  1089. X * added copyright statment
  1090. X * 
  1091. X * Revision 1.6  90/02/25  11:01:20  cpcahil
  1092. X * added support for malloc chain checking.
  1093. X * 
  1094. X * Revision 1.5  90/02/24  21:50:31  cpcahil
  1095. X * lots of lint fixes
  1096. X * 
  1097. X * Revision 1.4  90/02/24  17:29:39  cpcahil
  1098. X * changed $Header to $Id so full path wouldnt be included as part of rcs 
  1099. X * id string
  1100. X * 
  1101. X * Revision 1.3  90/02/24  17:20:00  cpcahil
  1102. X * attempt to get rid of full path in rcs header.
  1103. X * 
  1104. X * Revision 1.2  90/02/24  15:14:20  cpcahil
  1105. X * 1. added function header 
  1106. X * 2. changed calls to malloc_warning to conform to new usage
  1107. X * 3. added setting of malloc_errno
  1108. X *  4. broke up bad pointer determination so that errno's would be more
  1109. X *    descriptive
  1110. X * 
  1111. X * Revision 1.1  90/02/22  23:17:43  cpcahil
  1112. X * Initial revision
  1113. X * 
  1114. X */
  1115. SHAR_EOF
  1116. $TOUCH -am 0511001490 realloc.c &&
  1117. chmod 0444 realloc.c ||
  1118. echo "restore of realloc.c failed"
  1119. set `wc -c realloc.c`;Wc_c=$1
  1120. if test "$Wc_c" != "4496"; then
  1121.     echo original size 4496, current size $Wc_c
  1122. fi
  1123. fi
  1124. # ============= string.c ==============
  1125. if test X"$1" != X"-c" -a -f 'string.c'; then
  1126.     echo "File already exists: skipping 'string.c'"
  1127. else
  1128. echo "x - extracting string.c (Text)"
  1129. sed 's/^X//' << 'SHAR_EOF' > string.c &&
  1130. X/*
  1131. X * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).  
  1132. X * You may copy, distribute, and use this software as long as this
  1133. X * copyright statement is not removed.
  1134. X */
  1135. X
  1136. X#include <stdio.h>
  1137. X#include <string.h>
  1138. X#include <sys/types.h>
  1139. X#include "malloc.h"
  1140. X
  1141. X#ifndef lint
  1142. Xstatic
  1143. Xchar rcs_hdr[] = "$Id: string.c,v 1.5 90/06/10 14:59:49 cpcahil Exp $";
  1144. X#endif
  1145. X
  1146. Xint    malloc_checking = 0;
  1147. X
  1148. Xchar *
  1149. Xstrcat(str1,str2)
  1150. X    register char    * str1;
  1151. X    register char    * str2;
  1152. X{
  1153. X    char        * rtn;
  1154. X    int      len;
  1155. X
  1156. X    /* 
  1157. X     * check pointers agains malloc region.  The malloc* functions
  1158. X     * will properly handle the case where a pointer does not
  1159. X     * point into malloc space.
  1160. X     */
  1161. X    malloc_checking = 1;
  1162. X
  1163. X    len = strlen(str2);
  1164. X    malloc_check_str("strcat", str2);
  1165. X
  1166. X    len += strlen(str1) + 1;
  1167. X    malloc_checking = 0;
  1168. X
  1169. X    malloc_check_data("strcat", str1, len);
  1170. X
  1171. X    rtn = str1;
  1172. X
  1173. X    while( *str1 )
  1174. X    {
  1175. X        str1++;
  1176. X    }
  1177. X    
  1178. X    while( (*str1 = *str2) != '\0' )
  1179. X    {
  1180. X        str1++;
  1181. X        str2++;
  1182. X    }
  1183. X    
  1184. X    return(rtn);
  1185. X}
  1186. X
  1187. Xchar *
  1188. Xstrdup(str1)
  1189. X    register char    * str1;
  1190. X{
  1191. X    char        * malloc();
  1192. X    char        * rtn;
  1193. X    register char    * str2;
  1194. X
  1195. X    malloc_check_str("strdup", str1);
  1196. X
  1197. X    rtn = str2 = malloc((unsigned)strlen(str1)+1);
  1198. X
  1199. X    if( rtn != (char *) 0)
  1200. X    {
  1201. X        while( (*str2 = *str1) != '\0' )
  1202. X        {
  1203. X            str1++;
  1204. X            str2++;
  1205. X        }
  1206. X    }
  1207. X
  1208. X    return(rtn);
  1209. X}
  1210. X
  1211. Xchar *
  1212. Xstrncat(str1,str2,len)
  1213. X    register char    * str1;
  1214. X    register char    * str2;
  1215. X    register int      len;
  1216. X{
  1217. X    int           len1;
  1218. X    int           len2;
  1219. X    char        * rtn;
  1220. X
  1221. X    malloc_checking = 1;
  1222. X
  1223. X    len2 = strlen(str2) + 1;
  1224. X    len1 = strlen(str1);
  1225. X
  1226. X    malloc_checking = 0;
  1227. X
  1228. X    malloc_check_data("strncat", str2,len2);
  1229. X
  1230. X    if( (len+1) < len2 )
  1231. X    {
  1232. X        len1 += len + 1;
  1233. X    }
  1234. X    else
  1235. X    {
  1236. X        len1 += len2;
  1237. X    }
  1238. X    malloc_check_data("strncat", str1, len1);
  1239. X
  1240. X    rtn = str1;
  1241. X
  1242. X    while( *str1 )
  1243. X    {
  1244. X        str1++;
  1245. X    }
  1246. X
  1247. X    while( len-- && ((*str1++ = *str2++) != '\0') )
  1248. X    {
  1249. X    }
  1250. X    
  1251. X    if( ! len )
  1252. X    {
  1253. X        *str1 = '\0';
  1254. X    }
  1255. X
  1256. X    return(rtn);
  1257. X}
  1258. X
  1259. Xint
  1260. Xstrcmp(str1,str2)
  1261. X    register char    * str1;
  1262. X    register char    * str2;
  1263. X{
  1264. X    malloc_check_str("strcmp", str1);
  1265. X    malloc_check_str("strcmp", str2);
  1266. X
  1267. X    while( *str1 && (*str1 == *str2) )
  1268. X    {
  1269. X        str1++;
  1270. X        str2++;
  1271. X    }
  1272. X    return( *str1 - *str2 );
  1273. X}
  1274. X
  1275. Xint
  1276. Xstrncmp(str1,str2,len)
  1277. X    register char    * str1;
  1278. X    register char    * str2;
  1279. X    register int      len;
  1280. X{
  1281. X    malloc_check_str("strncmp", str1);
  1282. X    malloc_check_str("strncmp", str2);
  1283. X
  1284. X    while( --len && *str1 && (*str1 == *str2) )
  1285. X    {
  1286. X        str1++;
  1287. X        str2++;
  1288. X    }
  1289. X    return( *str1 - *str2 );
  1290. X}
  1291. X
  1292. Xchar *
  1293. Xstrcpy(str1,str2)
  1294. X    register char    * str1;
  1295. X    register char    * str2;
  1296. X{
  1297. X    char        * rtn;
  1298. X    int          len;
  1299. X
  1300. X    malloc_checking = 1;
  1301. X    len = strlen(str2) + 1;
  1302. X    malloc_checking = 0;
  1303. X
  1304. X    malloc_check_data("strcpy", str1, len);
  1305. X    malloc_check_data("strcpy", str2, len);
  1306. X
  1307. X    rtn = str1;
  1308. X
  1309. X    while( (*str1++ = *str2++) != '\0')
  1310. X    {
  1311. X    }
  1312. X
  1313. X    return(rtn);
  1314. X}
  1315. X
  1316. Xchar *
  1317. Xstrncpy(str1,str2,len)
  1318. X    register char    * str1;
  1319. X    register char    * str2;
  1320. X    register int      len;
  1321. X{
  1322. X    int          i;
  1323. X    extern int      malloc_checking;
  1324. X    char        * rtn;
  1325. X
  1326. X    malloc_check_data("strncpy", str1, len);
  1327. X
  1328. X    malloc_checking = 1;
  1329. X    i = strlen(str2);
  1330. X    malloc_checking = 0;
  1331. X
  1332. X    if( i > len )
  1333. X    {
  1334. X        i = len;
  1335. X    }
  1336. X
  1337. X    malloc_check_data("strncpy", str2, i);
  1338. X
  1339. X    rtn = str1;
  1340. X
  1341. X    while((len-- > 0) && (*str1++ = *str2++) != '\0')
  1342. X    {
  1343. X    }
  1344. X    while( (len-- > 0) )
  1345. X    {
  1346. X        *str1++ = '\0';
  1347. X    }
  1348. X
  1349. X    return(rtn);
  1350. X}
  1351. X
  1352. Xint
  1353. Xstrlen(str1)
  1354. X    register char    * str1;
  1355. X{
  1356. X    register char    * s;
  1357. X
  1358. X    if(! malloc_checking )
  1359. X    {
  1360. X        malloc_check_str("strlen", str1);
  1361. X    }
  1362. X
  1363. X    for( s = str1; *s; s++)
  1364. X    {
  1365. X    }
  1366. X
  1367. X    return( s - str1 );
  1368. X}
  1369. X
  1370. Xchar *
  1371. Xstrchr(str1,c)
  1372. X    register char    * str1;
  1373. X    register int      c;
  1374. X{
  1375. X    malloc_check_str("strchr", str1);
  1376. X
  1377. X    while( *str1 && (*str1 != (char) c) )
  1378. X    {
  1379. X        str1++;
  1380. X    }
  1381. X
  1382. X    if(! *str1 )
  1383. X    {
  1384. X        str1 = (char *) 0;
  1385. X    }
  1386. X
  1387. X    return(str1);
  1388. X}
  1389. X
  1390. Xchar *
  1391. Xstrrchr(str1,c)
  1392. X    register char    * str1;
  1393. X    register int      c;
  1394. X{
  1395. X    register char    * rtn = (char *) 0;
  1396. X
  1397. X    malloc_check_str("strrchr", str1);
  1398. X
  1399. X    while( *str1 )
  1400. X    {
  1401. X        if(*str1 == (char) c )
  1402. X        {
  1403. X            rtn = str1;
  1404. X        }
  1405. X        str1++;
  1406. X    }
  1407. X
  1408. X    return(rtn);
  1409. X}
  1410. X
  1411. Xchar *
  1412. Xindex(str1,c)
  1413. X    char        * str1;
  1414. X    char          c;
  1415. X{
  1416. X    return( strchr(str1,c) );
  1417. X}
  1418. X
  1419. Xchar *
  1420. Xrindex(str1,c)
  1421. X    char        * str1;
  1422. X    char          c;
  1423. X{
  1424. X    return( strrchr(str1,c) );
  1425. X}
  1426. X
  1427. Xchar *
  1428. Xstrpbrk(str1,str2)
  1429. X    register char    * str1;
  1430. X    register char    * str2;
  1431. X{
  1432. X    register char    * tmp;
  1433. X
  1434. X    malloc_check_str("strpbrk", str1);
  1435. X    malloc_check_str("strpbrk", str2);
  1436. X
  1437. X    while(*str1)
  1438. X    {
  1439. X        for( tmp=str2; *tmp && *tmp != *str1; tmp++)
  1440. X        {
  1441. X        }
  1442. X        if( *tmp )
  1443. X        {
  1444. X            break;
  1445. X        }
  1446. X        str1++;
  1447. X    }
  1448. X
  1449. X    if( ! *str1 )
  1450. X    {
  1451. X        str1 = (char *) 0;
  1452. X    }
  1453. X
  1454. X    return(str1);
  1455. X}
  1456. X
  1457. Xint
  1458. Xstrspn(str1,str2)
  1459. X    register char    * str1;
  1460. X    register char    * str2;
  1461. X{
  1462. X    register char    * tmp;
  1463. X    char        * orig = str1;
  1464. X
  1465. X    malloc_check_str("strspn", str1);
  1466. X    malloc_check_str("strspn", str2);
  1467. X
  1468. X    while(*str1)
  1469. X    {
  1470. X        for( tmp=str2; *tmp && *tmp != *str1; tmp++)
  1471. X        {
  1472. X        }
  1473. X        if(! *tmp )
  1474. X        {
  1475. X            break;
  1476. X        }
  1477. X        str1++;
  1478. X    }
  1479. X
  1480. X    return( (int) (str1 - orig) );
  1481. X}
  1482. X
  1483. Xint
  1484. Xstrcspn(str1,str2)
  1485. X    register char    * str1;
  1486. X    register char    * str2;
  1487. X{
  1488. X    register char    * tmp;
  1489. X    char        * orig = str1;
  1490. X
  1491. X    malloc_check_str("strcspn", str1);
  1492. X    malloc_check_str("strcspn", str2);
  1493. X
  1494. X    while(*str1)
  1495. X    {
  1496. X        for( tmp=str2; *tmp && *tmp != *str1; tmp++)
  1497. X        {
  1498. X        }
  1499. X        if( *tmp )
  1500. X        {
  1501. X            break;
  1502. X        }
  1503. X        str1++;
  1504. X    }
  1505. X
  1506. X    return( (int) (str1 - orig) );
  1507. X}
  1508. X
  1509. X/*
  1510. X * strtok() source taken from that posted to comp.lang.c by Chris Torek
  1511. X * in Jan 1990.
  1512. X */
  1513. X
  1514. X/*
  1515. X * Copyright (c) 1989 The Regents of the University of California.
  1516. X * All rights reserved.
  1517. X *
  1518. X * Redistribution and use in source and binary forms are permitted
  1519. X * provided that the above copyright notice and this paragraph are
  1520. X * duplicated in all such forms and that any documentation,
  1521. X * advertising materials, and other materials related to such
  1522. X * distribution and use acknowledge that the software was developed
  1523. X * by the University of California, Berkeley.  The name of the
  1524. X * University may not be used to endorse or promote products derived
  1525. X * from this software without specific prior written permission.
  1526. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  1527. X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  1528. X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  1529. X */
  1530. X
  1531. X/*
  1532. X * Get next token from string s (NULL on 2nd, 3rd, etc. calls),
  1533. X * where tokens are nonempty strings separated by runs of
  1534. X * chars from delim.  Writes NULs into s to end tokens.  delim need not
  1535. X * remain constant from call to call.
  1536. X *
  1537. X * Modified by cpc:     changed variable names to conform with naming
  1538. X *            conventions used in rest of code.  Added malloc pointer
  1539. X *            check calls.
  1540. X */
  1541. Xchar *
  1542. Xstrtok(str1, str2)
  1543. X    char     * str1;
  1544. X    char    * str2;
  1545. X{
  1546. X    static char     * last;
  1547. X    char        * strtoken();
  1548. X
  1549. X    if( str1 )
  1550. X    {
  1551. X        malloc_check_str("strtok", str1);
  1552. X        last = str1;
  1553. X    }
  1554. X    malloc_check_str("strtok", str2);
  1555. X
  1556. X    return (strtoken(&last, str2, 1));
  1557. X}
  1558. X
  1559. X
  1560. X/*
  1561. X * Get next token from string *stringp, where tokens are (possibly empty)
  1562. X * strings separated by characters from delim.  Tokens are separated
  1563. X * by exactly one delimiter iff the skip parameter is false; otherwise
  1564. X * they are separated by runs of characters from delim, because we
  1565. X * skip over any initial `delim' characters.
  1566. X *
  1567. X * Writes NULs into the string at *stringp to end tokens.
  1568. X * delim will usually, but need not, remain constant from call to call.
  1569. X * On return, *stringp points past the last NUL written (if there might
  1570. X * be further tokens), or is NULL (if there are definitely no more tokens).
  1571. X *
  1572. X * If *stringp is NULL, strtoken returns NULL.
  1573. X */
  1574. Xchar *
  1575. Xstrtoken(stringp, delim, skip)
  1576. X    register char **stringp;
  1577. X    register char *delim;
  1578. X    int skip;
  1579. X{
  1580. X    register char *s;
  1581. X    register char *spanp;
  1582. X    register int c, sc;
  1583. X    char *tok;
  1584. X
  1585. X    if ((s = *stringp) == NULL)
  1586. X        return (NULL);
  1587. X
  1588. X    if (skip) {
  1589. X        /*
  1590. X         * Skip (span) leading delimiters (s += strspn(s, delim)).
  1591. X         */
  1592. X    cont:
  1593. X        c = *s;
  1594. X        for (spanp = delim; (sc = *spanp++) != 0;) {
  1595. X            if (c == sc) {
  1596. X                s++;
  1597. X                goto cont;
  1598. X            }
  1599. X        }
  1600. X        if (c == 0) {        /* no token found */
  1601. X            *stringp = NULL;
  1602. X            return (NULL);
  1603. X        }
  1604. X    }
  1605. X
  1606. X    /*
  1607. X     * Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
  1608. X     * Note that delim must have one NUL; we stop if we see that, too.
  1609. X     */
  1610. X    for (tok = s;;) {
  1611. X        c = *s++;
  1612. X        spanp = delim;
  1613. X        do {
  1614. X            if ((sc = *spanp++) == c) {
  1615. X                if (c == 0)
  1616. X                    s = NULL;
  1617. X                else
  1618. X                    s[-1] = 0;
  1619. X                *stringp = s;
  1620. X                return (tok);
  1621. X            }
  1622. X        } while (sc != 0);
  1623. X    }
  1624. X    /* NOTREACHED */
  1625. X}
  1626. X
  1627. X/*
  1628. X * $Log:    string.c,v $
  1629. X * Revision 1.5  90/06/10  14:59:49  cpcahil
  1630. X * Fixed a couple of bugs in strncpy & strdup
  1631. X * 
  1632. X * Revision 1.4  90/05/11  00:13:10  cpcahil
  1633. X * added copyright statment
  1634. X * 
  1635. X * Revision 1.3  90/02/24  21:50:32  cpcahil
  1636. X * lots of lint fixes
  1637. X * 
  1638. X * Revision 1.2  90/02/24  17:29:40  cpcahil
  1639. X * changed $Header to $Id so full path wouldnt be included as part of rcs 
  1640. X * id string
  1641. X * 
  1642. X * Revision 1.1  90/02/22  23:17:44  cpcahil
  1643. X * Initial revision
  1644. X * 
  1645. X */
  1646. SHAR_EOF
  1647. $TOUCH -am 0610150290 string.c &&
  1648. chmod 0444 string.c ||
  1649. echo "restore of string.c failed"
  1650. set `wc -c string.c`;Wc_c=$1
  1651. if test "$Wc_c" != "8521"; then
  1652.     echo original size 8521, current size $Wc_c
  1653. fi
  1654. fi
  1655. # ============= testmalloc.c ==============
  1656. if test X"$1" != X"-c" -a -f 'testmalloc.c'; then
  1657.     echo "File already exists: skipping 'testmalloc.c'"
  1658. else
  1659. echo "x - extracting testmalloc.c (Text)"
  1660. sed 's/^X//' << 'SHAR_EOF' > testmalloc.c &&
  1661. X/* NOT copyright by SoftQuad Inc. -- msb, 1988 */
  1662. X#ifndef lint
  1663. Xstatic char *SQ_SccsId = "@(#)mtest3.c    1.2 88/08/25";
  1664. X#endif
  1665. X#include <stdio.h>
  1666. X/*
  1667. X** looptest.c -- intensive allocator tester 
  1668. X**
  1669. X** Usage:  looptest
  1670. X**
  1671. X** History:
  1672. X**    4-Feb-1987 rtech!daveb 
  1673. X*/
  1674. X
  1675. X# ifdef SYS5
  1676. X# define random    rand
  1677. X# else
  1678. X# include <sys/vadvise.h>
  1679. X# endif
  1680. X
  1681. X# include <stdio.h>
  1682. X# include <signal.h>
  1683. X# include <setjmp.h>
  1684. X
  1685. X# define MAXITER    1000000        /* main loop iterations */
  1686. X# define MAXOBJS    1000        /* objects in pool */
  1687. X# define BIGOBJ        90000        /* max size of a big object */
  1688. X# define TINYOBJ    80        /* max size of a small object */
  1689. X# define BIGMOD        100        /* 1 in BIGMOD is a BIGOBJ */
  1690. X# define STATMOD    10000        /* interation interval for status */
  1691. X
  1692. Xmain( argc, argv )
  1693. Xint argc;
  1694. Xchar **argv;
  1695. X{
  1696. X    register int **objs;        /* array of objects */
  1697. X    register int *sizes;        /* array of object sizes */
  1698. X    register int n;            /* iteration counter */
  1699. X    register int i;            /* object index */
  1700. X    register int size;        /* object size */
  1701. X    register int r;            /* random number */
  1702. X
  1703. X    int objmax;            /* max size this iteration */
  1704. X    int cnt;            /* number of allocated objects */
  1705. X    int nm = 0;            /* number of mallocs */
  1706. X    int nre = 0;            /* number of reallocs */
  1707. X    int nal;            /* number of allocated objects */
  1708. X    int nfre;            /* number of free list objects */
  1709. X    long alm;            /* memory in allocated objects */
  1710. X    long frem;            /* memory in free list */
  1711. X    long startsize;            /* size at loop start */
  1712. X    long endsize;            /* size at loop exit */
  1713. X    long maxiter = 0;        /* real max # iterations */
  1714. X
  1715. X    extern char end;        /* memory before heap */
  1716. X    char *calloc();
  1717. X    char *malloc();
  1718. X    char *sbrk();
  1719. X    long atol();
  1720. X
  1721. X# ifndef SYS5
  1722. X    /* your milage may vary... */
  1723. X    vadvise( VA_ANOM );
  1724. X# endif
  1725. X
  1726. X    if (argc > 1)
  1727. X        maxiter = atol (argv[1]);
  1728. X    if (maxiter <= 0)
  1729. X        maxiter = MAXITER;
  1730. X
  1731. X    printf("MAXITER %d MAXOBJS %d ", maxiter, MAXOBJS );
  1732. X    printf("BIGOBJ %d, TINYOBJ %d, nbig/ntiny 1/%d\n",
  1733. X    BIGOBJ, TINYOBJ, BIGMOD );
  1734. X    fflush( stdout );
  1735. X
  1736. X    if( NULL == (objs = (int **)calloc( MAXOBJS, sizeof( *objs ) ) ) )
  1737. X    {
  1738. X        fprintf(stderr, "Can't allocate memory for objs array\n");
  1739. X        exit(1);
  1740. X    }
  1741. X
  1742. X    if( NULL == ( sizes = (int *)calloc( MAXOBJS, sizeof( *sizes ) ) ) )
  1743. X    {
  1744. X        fprintf(stderr, "Can't allocate memory for sizes array\n");
  1745. X        exit(1);
  1746. X    }
  1747. X
  1748. X    /* as per recent discussion on net.lang.c, calloc does not 
  1749. X    ** necessarily fill in NULL pointers...
  1750. X    */
  1751. X    for( i = 0; i < MAXOBJS; i++ )
  1752. X        objs[ i ] = NULL;
  1753. X
  1754. X    startsize = sbrk(0) - &end;
  1755. X    printf( "Memory use at start: %d bytes\n", startsize );
  1756. X    fflush(stdout);
  1757. X
  1758. X    printf("Starting the test...\n");
  1759. X    fflush(stdout);
  1760. X    for( n = 0; n < maxiter ; n++ )
  1761. X    {
  1762. X        if( !(n % STATMOD) )
  1763. X        {
  1764. X            printf("%d iterations\n", n);
  1765. X            fflush(stdout);
  1766. X        }
  1767. X
  1768. X        /* determine object of interst and it's size */
  1769. X
  1770. X        r = random();
  1771. X        objmax = ( r % BIGMOD ) ? TINYOBJ : BIGOBJ;
  1772. X        size = r % objmax;
  1773. X        i = r % (MAXOBJS - 1);
  1774. X
  1775. X        /* either replace the object of get a new one */
  1776. X
  1777. X        if( objs[ i ] == NULL )
  1778. X        {
  1779. X            objs[ i ] = (int *)malloc( size );
  1780. X            nm++;
  1781. X        }
  1782. X        else
  1783. X        {
  1784. X            /* don't keep bigger objects around */
  1785. X            if( size > sizes[ i ] )
  1786. X            {
  1787. X                objs[ i ] = (int *)realloc( objs[ i ], size );
  1788. X                nre++;
  1789. X            }
  1790. X            else
  1791. X            {
  1792. X                free( objs[ i ] );
  1793. X                objs[ i ] = (int *)malloc( size );
  1794. X                nm++;
  1795. X            }
  1796. X        }
  1797. X
  1798. X        sizes[ i ] = size;
  1799. X        if( objs[ i ] == NULL )
  1800. X        {
  1801. X            printf("\nCouldn't allocate %d byte object!\n", 
  1802. X                size );
  1803. X            break;
  1804. X        }
  1805. X    } /* for() */
  1806. X
  1807. X    printf( "\n" );
  1808. X    cnt = 0;
  1809. X    for( i = 0; i < MAXOBJS; i++ )
  1810. X        if( objs[ i ] )
  1811. X            cnt++;
  1812. X
  1813. X    printf( "Did %d iterations, %d objects, %d mallocs, %d reallocs\n",
  1814. X        n, cnt, nm, nre );
  1815. X    printf( "Memory use at end: %d bytes\n", sbrk(0) - &end );
  1816. X    fflush( stdout );
  1817. X
  1818. X    /* free all the objects */
  1819. X    for( i = 0; i < MAXOBJS; i++ )
  1820. X        if( objs[ i ] != NULL )
  1821. X            free( objs[ i ] );
  1822. X
  1823. X    endsize = sbrk(0) - &end;
  1824. X    printf( "Memory use after free: %d bytes\n", endsize );
  1825. X    fflush( stdout );
  1826. X
  1827. X    if( startsize != endsize )
  1828. X        printf("startsize %d != endsize %d\n", startsize, endsize );
  1829. X
  1830. X    free( objs );
  1831. X    free( sizes );
  1832. X
  1833. X    malloc_dump(2);
  1834. X    exit( 0 );
  1835. X}
  1836. X
  1837. SHAR_EOF
  1838. $TOUCH -am 0511175990 testmalloc.c &&
  1839. chmod 0444 testmalloc.c ||
  1840. echo "restore of testmalloc.c failed"
  1841. set `wc -c testmalloc.c`;Wc_c=$1
  1842. if test "$Wc_c" != "3971"; then
  1843.     echo original size 3971, current size $Wc_c
  1844. fi
  1845. fi
  1846. # ============= testmem.c ==============
  1847. if test X"$1" != X"-c" -a -f 'testmem.c'; then
  1848.     echo "File already exists: skipping 'testmem.c'"
  1849. else
  1850. echo "x - extracting testmem.c (Text)"
  1851. sed 's/^X//' << 'SHAR_EOF' > testmem.c &&
  1852. X/*
  1853. X * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).  
  1854. X * You may copy, distribute, and use this software as long as this
  1855. X * copyright statement is not removed.
  1856. X */
  1857. X
  1858. X/* 
  1859. X * I have only partially implemented these tests.  If you have the time and
  1860. X * energy and wish to add some tests, feel free to do so.  I would appreciate
  1861. X * it if you sent me a copy of the modified files. 
  1862. X */
  1863. X
  1864. X#include <stdio.h>
  1865. X
  1866. X/* 
  1867. X * These tests test the memory functions...
  1868. X */
  1869. X
  1870. Xmain()
  1871. X{
  1872. X    char      buffer[500];
  1873. X    int      exitval = 0;
  1874. X    char    * memccpy();
  1875. X    char    * memchr();
  1876. X    char    * ptr1;
  1877. X    char    * ptr2;
  1878. X
  1879. X    fprintf(stdout,"Begining memory(3) tests...\n");
  1880. X
  1881. X    /*
  1882. X      * test memccpy()...
  1883. X      */
  1884. X
  1885. X    ptr1 = "abcdefghijklmn";    
  1886. X
  1887. X    buffer[0] = 'n';
  1888. X    buffer[1] = 'o';
  1889. X    buffer[2] = 'p';
  1890. X    buffer[3] = 'q'; 
  1891. X    buffer[4] = 'r';
  1892. X    buffer[5] = 's';
  1893. X    ptr2 = memccpy(buffer,ptr1,'d',3);
  1894. X
  1895. X    if( ptr2 != (char *) 0)
  1896. X    {
  1897. X        fprintf(stdout,"memccpy() failed to use passed length\n");
  1898. X        exitval++;
  1899. X    }
  1900. X
  1901. X    /*
  1902. X      * verify that the correct bytes got copied and the others do not
  1903. X     * get clobbered
  1904. X     */
  1905. X    if( (buffer[0] != 'a') ||
  1906. X        (buffer[1] != 'b') ||
  1907. X        (buffer[2] != 'c') ||
  1908. X        (buffer[3] != 'q') ||
  1909. X        (buffer[4] != 'r') ||
  1910. X        (buffer[5] != 's')  )
  1911. X    {
  1912. X        fprintf(stdout,"memccpy() failed to copy bytes correctly\n");
  1913. X        fprintf(stdout,"Should have been 'abcqrs' was '%6.6s'\n",buffer);
  1914. X        exitval++;
  1915. X    }
  1916. X
  1917. X
  1918. X
  1919. X    buffer[0] = 'n';
  1920. X    buffer[1] = 'o';
  1921. X    buffer[2] = 'p';
  1922. X    buffer[3] = 'q'; 
  1923. X    buffer[4] = 'r';
  1924. X    buffer[5] = 's';
  1925. X    ptr2 = memccpy(buffer,ptr1,'d',4);
  1926. X
  1927. X    if( ptr2 != (buffer+4) )
  1928. X    {
  1929. X        fprintf(stdout,"memccpy() failed to find byte in data\n");
  1930. X        exitval++;
  1931. X    }
  1932. X
  1933. X    /*
  1934. X      * verify that the correct bytes got copied and the others do not
  1935. X     * get clobbered
  1936. X     */
  1937. X    if( (buffer[0] != 'a') ||
  1938. X        (buffer[1] != 'b') ||
  1939. X        (buffer[2] != 'c') ||
  1940. X        (buffer[3] != 'd') ||
  1941. X        (buffer[4] != 'r') ||
  1942. X        (buffer[5] != 's')  )
  1943. X    {
  1944. X        fprintf(stdout,"memccpy() failed to copy bytes correctly\n");
  1945. X        fprintf(stdout,"Should have been 'abcdrs' was '%6.6s'\n",buffer);
  1946. X        exitval++;
  1947. X    }
  1948. X
  1949. X    /*
  1950. X     * Test memchr()...
  1951. X     */
  1952. X
  1953. X    ptr1 = "abcdefghijklmn";
  1954. X
  1955. X    ptr2 = memchr(ptr1,'c',10);
  1956. X    
  1957. X    if( ptr2 != (ptr1+2) )
  1958. X    {
  1959. X        fprintf(stdout,"memchr() failed to find byte in data\n");
  1960. X        exitval++;
  1961. X    }
  1962. X
  1963. X    ptr2 = memchr(ptr1,'j',10);
  1964. X    
  1965. X    if( ptr2 != (ptr1+9) )
  1966. X    {
  1967. X        fprintf(stdout,"memchr() failed to find byte in data\n");
  1968. X        exitval++;
  1969. X    }
  1970. X
  1971. X    ptr2 = memchr(ptr1,'k',10);
  1972. X    
  1973. X    if( ptr2 != (char *) 0)
  1974. X    {
  1975. X        fprintf(stdout,"memchr() failed to obey length argument\n");
  1976. X        exitval++;
  1977. X    }
  1978. X
  1979. X    fprintf(stdout,"Memory tests complete!\n");
  1980. X    exit(exitval);
  1981. X
  1982. X}
  1983. SHAR_EOF
  1984. $TOUCH -am 0511153990 testmem.c &&
  1985. chmod 0444 testmem.c ||
  1986. echo "restore of testmem.c failed"
  1987. set `wc -c testmem.c`;Wc_c=$1
  1988. if test "$Wc_c" != "2552"; then
  1989.     echo original size 2552, current size $Wc_c
  1990. fi
  1991. fi
  1992. # ============= tostring.c ==============
  1993. if test X"$1" != X"-c" -a -f 'tostring.c'; then
  1994.     echo "File already exists: skipping 'tostring.c'"
  1995. else
  1996. echo "x - extracting tostring.c (Text)"
  1997. sed 's/^X//' << 'SHAR_EOF' > tostring.c &&
  1998. X/*
  1999. X * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).  
  2000. X * You may copy, distribute, and use this software as long as this
  2001. X * copyright statement is not removed.
  2002. X */
  2003. X#include "tostring.h"
  2004. X
  2005. X/*
  2006. X * Function:    tostring()
  2007. X *
  2008. X * Purpose:    to convert an integer to an ascii display string
  2009. X *
  2010. X * Arguments:    buf    - place to put the 
  2011. X *        val    - integer to convert
  2012. X *        len    - length of output field (0 if just enough to hold data)
  2013. X *        base    - base for number conversion (only works for base <= 16)
  2014. X *        fill    - fill char when len > # digits
  2015. X *
  2016. X * Returns:    length of string
  2017. X *
  2018. X * Narrative:    IF fill character is non-blank
  2019. X *            Determine base
  2020. X *                If base is HEX
  2021. X *                    add "0x" to begining of string
  2022. X *                IF base is OCTAL
  2023. X *                    add "0" to begining of string
  2024. X *
  2025. X *        While value is greater than zero
  2026. X *            use val % base as index into xlation str to get cur char
  2027. X *            divide val by base
  2028. X *
  2029. X *        Determine fill-in length
  2030. X *
  2031. X *        Fill in fill chars
  2032. X *
  2033. X *        Copy in number
  2034. X *        
  2035. X *
  2036. X * Mod History:    
  2037. X *   90/01/24    cpcahil        Initial revision.
  2038. X */
  2039. X
  2040. X#ifndef lint
  2041. Xstatic
  2042. Xchar rcs_hdr[] = "$Id: tostring.c,v 1.4 90/05/11 00:13:11 cpcahil Exp $";
  2043. X#endif
  2044. X
  2045. X#define T_LEN 10
  2046. X
  2047. Xint
  2048. Xtostring(buf,val,len,base,fill)
  2049. X    int      base;
  2050. X    char    * buf;
  2051. X    char      fill;
  2052. X    int      len;
  2053. X    int      val;
  2054. X    
  2055. X{
  2056. X    char    * bufstart = buf;
  2057. X    int      i = T_LEN;
  2058. X    char    * xbuf = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  2059. X    char      tbuf[T_LEN];
  2060. X
  2061. X    /*
  2062. X     * if we are filling with non-blanks, make sure the
  2063. X     * proper start string is added
  2064. X     */
  2065. X    if( fill != ' ' )
  2066. X    {
  2067. X        switch(base)
  2068. X        {
  2069. X            case B_HEX:
  2070. X                *(buf++) = '0';
  2071. X                *(buf++) = 'x';
  2072. X                if( len )
  2073. X                {
  2074. X                    len -= 2;
  2075. X                }
  2076. X                break;
  2077. X            case B_OCTAL:
  2078. X                *(buf++) = fill;
  2079. X                if( len )
  2080. X                {
  2081. X                    len--;
  2082. X                }
  2083. X                break;
  2084. X            default:
  2085. X                break;
  2086. X        }
  2087. X    }
  2088. X
  2089. X    while( val > 0 )
  2090. X    {
  2091. X        tbuf[--i] = xbuf[val % base];
  2092. X        val = val / base;
  2093. X    }
  2094. X
  2095. X    if( len )
  2096. X    {
  2097. X        len -= (T_LEN - i);
  2098. X
  2099. X        if( len > 0 )
  2100. X        {
  2101. X            while(len-- > 0)
  2102. X            {
  2103. X                *(buf++) = fill;
  2104. X            }
  2105. X        }
  2106. X        else
  2107. X        {
  2108. X            /* 
  2109. X             * string is too long so we must truncate
  2110. X             * off some characters.  We do this the easiest
  2111. X             * way by just incrementing i.  This means the
  2112. X             * most significant digits are lost.
  2113. X             */
  2114. X            while( len++ < 0 )
  2115. X            {
  2116. X                i++;
  2117. X            }
  2118. X        }
  2119. X    }
  2120. X
  2121. X    while( i < T_LEN )
  2122. X    {
  2123. X        *(buf++) = tbuf[i++];
  2124. X    }
  2125. X
  2126. X    return( (int) (buf - bufstart) );
  2127. X
  2128. X} /* tostring(... */
  2129. X
  2130. X/*
  2131. X * $Log:    tostring.c,v $
  2132. X * Revision 1.4  90/05/11  00:13:11  cpcahil
  2133. X * added copyright statment
  2134. X * 
  2135. X * Revision 1.3  90/02/24  21:50:33  cpcahil
  2136. X * lots of lint fixes
  2137. X * 
  2138. X * Revision 1.2  90/02/24  17:29:42  cpcahil
  2139. X * changed $Header to $Id so full path wouldnt be included as part of rcs 
  2140. X * id string
  2141. X * 
  2142. X * Revision 1.1  90/02/22  23:17:44  cpcahil
  2143. X * Initial revision
  2144. X * 
  2145. X */
  2146. SHAR_EOF
  2147. $TOUCH -am 0511001490 tostring.c &&
  2148. chmod 0444 tostring.c ||
  2149. echo "restore of tostring.c failed"
  2150. set `wc -c tostring.c`;Wc_c=$1
  2151. if test "$Wc_c" != "2716"; then
  2152.     echo original size 2716, current size $Wc_c
  2153. fi
  2154. fi
  2155. # ============= tostring.h ==============
  2156. if test X"$1" != X"-c" -a -f 'tostring.h'; then
  2157.     echo "File already exists: skipping 'tostring.h'"
  2158. else
  2159. echo "x - extracting tostring.h (Text)"
  2160. sed 's/^X//' << 'SHAR_EOF' > tostring.h &&
  2161. X/*
  2162. X * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).  
  2163. X * You may copy, distribute, and use this software as long as this
  2164. X * copyright statement is not removed.
  2165. X */
  2166. X/*
  2167. X * $Id: tostring.h,v 1.2 90/05/11 00:13:11 cpcahil Exp $
  2168. X */
  2169. X#define B_BIN     2
  2170. X#define B_DEC    10
  2171. X#define B_HEX    16
  2172. X#define B_OCTAL     8
  2173. X
  2174. X/* 
  2175. X * $Log:    tostring.h,v $
  2176. X * Revision 1.2  90/05/11  00:13:11  cpcahil
  2177. X * added copyright statment
  2178. X * 
  2179. X * Revision 1.1  90/02/23  07:09:05  cpcahil
  2180. X * Initial revision
  2181. X * 
  2182. X */
  2183. SHAR_EOF
  2184. $TOUCH -am 0511001490 tostring.h &&
  2185. chmod 0444 tostring.h ||
  2186. echo "restore of tostring.h failed"
  2187. set `wc -c tostring.h`;Wc_c=$1
  2188. if test "$Wc_c" != "491"; then
  2189.     echo original size 491, current size $Wc_c
  2190. fi
  2191. fi
  2192. exit 0
  2193.  
  2194.