home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / dbmalloc.zip / string.c < prev    next >
C/C++ Source or Header  |  1995-04-26  |  22KB  |  1,116 lines

  1.  
  2. /*
  3.  * (c) Copyright 1990, 1991, 1992 Conor P. Cahill (cpcahil@virtech.vti.com)
  4.  *
  5.  * This software may be distributed freely as long as the following conditions
  6.  * are met:
  7.  *         * the distribution, or any derivative thereof, may not be
  8.  *          included as part of a commercial product
  9.  *        * full source code is provided including this copyright
  10.  *        * there is no charge for the software itself (there may be
  11.  *          a minimal charge for the copying or distribution effort)
  12.  *        * this copyright notice is not modified or removed from any
  13.  *          source file
  14.  */
  15.  
  16. /*
  17.  * NOTE: if you have problems compiling this file, the first thing to try is
  18.  * to take out the include of string.h.  This is due to the fact that some
  19.  * systems (like ultrix) have conflicting definitions and some (like aix)
  20.  * even set up some of these functions to be in-lined.
  21.  */
  22.  
  23. #include <stdio.h>
  24. #if ! defined(_IBMR2) && ! defined(ultrix)
  25. #include <string.h>
  26. #endif
  27.  
  28. #include "mallocin.h"
  29.  
  30.  
  31. #include <ctype.h>
  32.  
  33. #ifndef CTYPE_SUPPORT
  34. #define CTYPE_SUPPORT 1
  35. #endif
  36.  
  37. #if CTYPE_SUPPORT == 3
  38.  
  39. #undef islower
  40. #undef isascii
  41. #undef toupper
  42.  
  43. #endif
  44.  
  45. #if CTYPE_SUPPORT > 1
  46.  
  47. #define isascii(a) 1
  48.  
  49. #endif
  50.  
  51. #if CTYPE_SUPPORT == 2
  52.  
  53. #include <locale.h>
  54.  
  55. static int locale_initialized;
  56.  
  57. #define INIT_CTYPE() (local_initialized ? 0 : \
  58.              local_initialized++, setlocale(LC_CTYPE,"") )
  59.  
  60. #else /* CTYPE_SUPPORT == 2 */
  61.  
  62. #define INIT_CTYPE()
  63.  
  64. #endif /* CTYPE_SUPPORT == 2 */
  65.  
  66. #ifndef lint
  67. static
  68. char rcs_hdr[] = "$Id: string.c,v 1.30 1992/08/22 16:27:13 cpcahil Exp $";
  69. #endif
  70.  
  71. static int    in_string_code;
  72.  
  73. #define CompareUpper(c) ((STRCMPTYPE) \
  74.             (isascii((int)(unsigned char)(c)) \
  75.                 && islower( (int) (unsigned char)(c)) ? \
  76.                 toupper((int)(unsigned char)(c)) \
  77.              /* else */ : \
  78.                 (c)))
  79.  
  80. /*
  81.  * strcat - concatenate a string onto the end of another string
  82.  */
  83. char *
  84. strcat(str1,str2)
  85.     char        * str1;
  86.     CONST char    * str2;
  87. {
  88.     return( DBstrcat((char *)NULL,0,str1,str2) );
  89. }
  90.  
  91. char *
  92. DBstrcat(file,line,str1,str2)
  93.     CONST char        * file;
  94.     int              line;
  95.     register char        * str1;
  96.     register CONST char    * str2;
  97. {
  98.     char            * rtn;
  99.     SIZETYPE          len;
  100.  
  101.     /* 
  102.      * check pointers agains malloc region.  The malloc* functions
  103.      * will properly handle the case where a pointer does not
  104.      * point into malloc space.
  105.      */
  106.     in_string_code++;
  107.  
  108.     len = strlen(str2);
  109.     malloc_check_str("strcat", file, line, str2);
  110.  
  111.     len += strlen(str1) + 1;
  112.     in_string_code--;
  113.  
  114.     malloc_check_data("strcat", file, line, str1, (SIZETYPE)len);
  115.  
  116.     rtn = str1;
  117.  
  118.     while( *str1 )
  119.     {
  120.         str1++;
  121.     }
  122.     
  123.     while( (*str1 = *str2) != '\0' )
  124.     {
  125.         str1++;
  126.         str2++;
  127.     }
  128.     
  129.     return(rtn);
  130. }
  131.  
  132. /*
  133.  * strdup - duplicate a string
  134.  */
  135. char *
  136. strdup(str1)
  137.     CONST char    * str1;
  138. {
  139.     return( DBstrdup((char *)NULL, 0, str1) );
  140. }
  141.  
  142. char *
  143. DBstrdup(file, line, str1)
  144.     CONST char        * file;
  145.     int              line;
  146.     register CONST char    * str1;
  147. {
  148.     char            * rtn;
  149.     register char        * str2;
  150.  
  151.     malloc_check_str("strdup", file, line, str1);
  152.  
  153.     in_string_code++;
  154.     rtn = str2 = malloc((SIZETYPE)strlen(str1)+1);
  155.     in_string_code--;
  156.  
  157.     if( rtn != (char *) 0)
  158.     {
  159.         while( (*str2 = *str1) != '\0' )
  160.         {
  161.             str1++;
  162.             str2++;
  163.         }
  164.     }
  165.  
  166.     return(rtn);
  167. }
  168.  
  169. /*
  170.  * strncat - concatenate a string onto the end of another up to a specified len
  171.  */
  172. char *
  173. strncat(str1,str2,len)
  174.     char        * str1;
  175.     CONST char    * str2;
  176.     STRSIZE       len;
  177. {
  178.     return( DBstrncat((char *)NULL, 0, str1, str2, len) );
  179. }
  180.  
  181. char *
  182. DBstrncat(file, line, str1, str2, len)
  183.     CONST char        * file;
  184.     int              line;
  185.     register char        * str1;
  186.     register CONST char    * str2;
  187.     register STRSIZE       len;
  188. {
  189.     STRSIZE       len1;
  190.     STRSIZE       len2;
  191.     char        * rtn;
  192.  
  193.     malloc_check_strn("strncat", file, line, str2, len);
  194.  
  195.     in_string_code++;
  196.  
  197.     len2 = strlen(str2) + 1;
  198.     len1 = strlen(str1);
  199.  
  200.     in_string_code--;
  201.  
  202.  
  203.     if( (len+1) < len2 )
  204.     {
  205.         len1 += len + 1;
  206.     }
  207.     else
  208.     {
  209.         len1 += len2;
  210.     }
  211.     malloc_check_data("strncat", file, line, str1, (SIZETYPE)len1);
  212.  
  213.     rtn = str1;
  214.  
  215.     while( *str1 )
  216.     {
  217.         str1++;
  218.     }
  219.  
  220.     while( len && ((*str1++ = *str2++) != '\0') )
  221.     {
  222.         len--;
  223.     }
  224.     
  225.     if( ! len )
  226.     {
  227.         *str1 = '\0';
  228.     }
  229.  
  230.     return(rtn);
  231. }
  232.  
  233. /*
  234.  * strcmp - compare two strings
  235.  */
  236. int
  237. strcmp(str1,str2)
  238.     register CONST char    * str1;
  239.     register CONST char    * str2;
  240. {
  241.     return( DBstrcmp((char *) NULL, 0, str1, str2) );
  242. }
  243.  
  244. int
  245. DBstrcmp(file, line, str1, str2)
  246.     CONST char        * file;
  247.     int              line;
  248.     register CONST char    * str1;
  249.     register CONST char    * str2;
  250. {
  251.     malloc_check_str("strcmp", file, line, str1);
  252.     malloc_check_str("strcmp", file, line, str2);
  253.  
  254.     while( *str1 && (*str1 == *str2) )
  255.     {
  256.         str1++;
  257.         str2++;
  258.     }
  259.  
  260.  
  261.     /*
  262.      * in order to deal with the case of a negative last char of either
  263.      * string when the other string has a null
  264.      */
  265.     if( (*str2 == '\0') && (*str1 == '\0') )
  266.     {
  267.         return(0);
  268.     }
  269.     else if( *str2 == '\0' )
  270.     {
  271.         return(1);
  272.     }
  273.     else if( *str1 == '\0' )
  274.     {
  275.         return(-1);
  276.     }
  277.     
  278.     return( *(CONST STRCMPTYPE *)str1 - *(CONST STRCMPTYPE *)str2 );
  279. }
  280.  
  281. /*
  282.  * strncmp - compare two strings up to a specified length
  283.  */
  284. int
  285. strncmp(str1,str2,len)
  286.     register CONST char    * str1;
  287.     register CONST char    * str2;
  288.     register STRSIZE       len;
  289. {
  290.     return( DBstrncmp((char *)NULL, 0, str1, str2, len) );
  291. }
  292.  
  293. int
  294. DBstrncmp(file, line, str1,str2,len)
  295.     CONST char        * file;
  296.     int              line;
  297.     register CONST char    * str1;
  298.     register CONST char    * str2;
  299.     register STRSIZE       len;
  300. {
  301.     malloc_check_strn("strncmp", file, line, str1, len);
  302.     malloc_check_strn("strncmp", file, line, str2, len);
  303.  
  304.     while( len > 0 && *str1 && (*str1 == *str2) )
  305.     {
  306.         len--;
  307.         str1++;
  308.         str2++;
  309.     }
  310.  
  311.     if( len == 0 )
  312.     {
  313.         return(0);
  314.     }
  315.     /*
  316.      * in order to deal with the case of a negative last char of either
  317.      * string when the other string has a null
  318.      */
  319.     if( (*str2 == '\0') && (*str1 == '\0') )
  320.     {
  321.         return(0);
  322.     }
  323.     else if( *str2 == '\0' )
  324.     {
  325.         return(1);
  326.     }
  327.     else if( *str1 == '\0' )
  328.     {
  329.         return(-1);
  330.     }
  331.     
  332.     return( *(CONST STRCMPTYPE *)str1 - *(CONST STRCMPTYPE *)str2 );
  333. }
  334.  
  335. /*
  336.  * stricmp - compare two strings
  337.  */
  338. int
  339. stricmp(str1,str2)
  340.     register CONST char    * str1;
  341.     register CONST char    * str2;
  342. {
  343.     return( DBstricmp((char *) NULL, 0, str1, str2) );
  344. }
  345.  
  346. int
  347. DBstricmp(file, line, str1, str2)
  348.     CONST char        * file;
  349.     int              line;
  350.     register CONST char    * str1;
  351.     register CONST char    * str2;
  352. {
  353.  
  354.     /*
  355.      * Make sure ctype is initialized
  356.      */
  357.     INIT_CTYPE();
  358.  
  359.     malloc_check_str("stricmp", file, line, str1);
  360.     malloc_check_str("stricmp", file, line, str2);
  361.  
  362.     while( *str1 && (CompareUpper(*str1) == CompareUpper(*str2)) )
  363.     {
  364.         str1++;
  365.         str2++;
  366.     }
  367.  
  368.  
  369.     /*
  370.      * in order to deal with the case of a negative last char of either
  371.      * string when the other string has a null
  372.      */
  373.     if( (*str2 == '\0') && (*str1 == '\0') )
  374.     {
  375.         return(0);
  376.     }
  377.     else if( *str2 == '\0' )
  378.     {
  379.         return(1);
  380.     }
  381.     else if( *str1 == '\0' )
  382.     {
  383.         return(-1);
  384.     }
  385.     
  386.     return( CompareUpper(*str1) - CompareUpper(*str2) );
  387.  
  388. } /* DBstricmp(... */
  389.  
  390. /*
  391.  * strincmp - compare two strings up to a specified length, ignoring case
  392.  */
  393. int
  394. strincmp(str1,str2,len)
  395.     register CONST char    * str1;
  396.     register CONST char    * str2;
  397.     register STRSIZE       len;
  398. {
  399.     return( DBstrincmp((char *)NULL, 0, str1, str2, len) );
  400. }
  401.  
  402. int
  403. DBstrincmp(file, line, str1,str2,len)
  404.     CONST char        * file;
  405.     int              line;
  406.     register CONST char    * str1;
  407.     register CONST char    * str2;
  408.     register STRSIZE       len;
  409. {
  410.  
  411.     /*
  412.      * Make sure ctype is initialized
  413.      */
  414.     INIT_CTYPE();
  415.  
  416.     malloc_check_strn("strincmp", file, line, str1, len);
  417.     malloc_check_strn("strincmp", file, line, str2, len);
  418.  
  419.     while( len > 0 && *str1 && (CompareUpper(*str1)==CompareUpper(*str2)) )
  420.     {
  421.         len--;
  422.         str1++;
  423.         str2++;
  424.     }
  425.  
  426.     if( len == 0 )
  427.     {
  428.         return(0);
  429.     }
  430.     /*
  431.      * in order to deal with the case of a negative last char of either
  432.      * string when the other string has a null
  433.      */
  434.     if( (*str2 == '\0') && (*str1 == '\0') )
  435.     {
  436.         return(0);
  437.     }
  438.     else if( *str2 == '\0' )
  439.     {
  440.         return(1);
  441.     }
  442.     else if( *str1 == '\0' )
  443.     {
  444.         return(-1);
  445.     }
  446.     
  447.     return( CompareUpper(*str1) - CompareUpper(*str2) );
  448.  
  449. } /* DBstrincmp(... */
  450.  
  451. /*
  452.  * strcpy - copy a string somewhere else
  453.  */
  454. char *
  455. strcpy(str1,str2)
  456.     register char        * str1;
  457.     register CONST char    * str2;
  458. {
  459.     return( DBstrcpy((char *)NULL, 0, str1, str2) );
  460. }
  461.  
  462. char *
  463. DBstrcpy(file, line, str1, str2)
  464.     CONST char        * file;
  465.     int              line;
  466.     register char        * str1;
  467.     register CONST char    * str2;
  468. {
  469.     char        * rtn;
  470.     SIZETYPE      len;
  471.  
  472.     in_string_code++;
  473.     len = strlen(str2) + 1;
  474.     in_string_code--;
  475.  
  476.     malloc_check_data("strcpy", file, line, str1, len);
  477.     malloc_check_data("strcpy", file, line, str2, len);
  478.  
  479.     rtn = str1;
  480.  
  481.     memmove(str1, str2, len);
  482.  
  483.     return(rtn);
  484. }
  485.  
  486. /*
  487.  * strncpy - copy a string upto a specified number of chars somewhere else
  488.  */
  489. char *
  490. strncpy(str1,str2,len)
  491.     register char        * str1;
  492.     register CONST char    * str2;
  493.     register STRSIZE       len;
  494. {
  495.     return( DBstrncpy((char *)NULL, 0, str1, str2, len) );
  496. }
  497.  
  498. char *
  499. DBstrncpy(file,line,str1,str2,len)
  500.     CONST char        * file;
  501.     int              line;
  502.     register char        * str1;
  503.     register CONST char    * str2;
  504.     STRSIZE               len;
  505. {
  506.     register SIZETYPE          i;
  507.     char            * rtn = str1;
  508.  
  509.     malloc_check_data("strncpy", file, line, str1, len);
  510.  
  511.     for(i=0; (i < len) && (str2[i] != '\0'); i++)
  512.     {
  513.         /* do nothing */;
  514.     }
  515.  
  516.     malloc_check_data("strncpy", file, line, str2, i);
  517.  
  518.     /*
  519.      * copy the real data
  520.      */
  521.     memmove(str1,str2,i);
  522.  
  523.     /*
  524.      * if there is data left over
  525.      */
  526.     if( i < len )
  527.     {
  528.         /*
  529.          * figure out where and how much is left over
  530.          */
  531.         str1 += i;
  532.         len  -= i;
  533.  
  534.         /*
  535.          * fill in the rest of the bytes with nulls
  536.          */
  537.         DataMS(str1, '\0', len);
  538.     }
  539.  
  540.     return(rtn);
  541. }
  542.  
  543. /*
  544.  * strlen - determine length of a string
  545.  */
  546. STRSIZE 
  547. strlen(str1)
  548.     CONST char    * str1;
  549. {
  550.     return( DBstrlen((char *) NULL, 0, str1) );
  551. }
  552.  
  553. STRSIZE 
  554. DBstrlen(file, line, str1)
  555.     CONST char        * file;
  556.     int              line;
  557.     register CONST char    * str1;
  558. {
  559.     register CONST char    * s;
  560.  
  561.     if(! in_string_code )
  562.     {
  563.         malloc_check_str("strlen", file, line, str1);
  564.     }
  565.  
  566.     for( s = str1; *s; s++)
  567.     {
  568.     }
  569.  
  570.     return( s - str1 );
  571. }
  572.  
  573. /*
  574.  * strchr - find location of a character in a string
  575.  */
  576. char *
  577. strchr(str1,c)
  578.     CONST char    * str1;
  579.     int          c;
  580. {
  581.     return( DBstrchr((char *)NULL,0,str1,c) );
  582. }
  583.  
  584. char *
  585. DBstrchr(file, line, str1,c)
  586.     CONST char        * file;
  587.     int              line;
  588.     CONST char        * str1;
  589.     int              c;
  590. {
  591.     return( DBFstrchr("strchr",file,line,str1,c) );
  592. }
  593.  
  594. char *
  595. DBFstrchr(func,file, line, str1,c)
  596.     CONST char        * func;
  597.     CONST char        * file;
  598.     int              line;
  599.     register CONST char    * str1;
  600.     register int          c;
  601. {
  602.     malloc_check_str(func, file, line, str1);
  603.  
  604.     while( *str1 && (*str1 != (char) c) )
  605.     {
  606.         str1++;
  607.     }
  608.  
  609.     if(*str1 != (char) c)
  610.     {
  611.         str1 = (char *) 0;
  612.     }
  613.  
  614.     return((char *)str1);
  615. }
  616.  
  617. /*
  618.  * strrchr - find rightmost location of a character in a string
  619.  */
  620.  
  621. char *
  622. strrchr(str1,c)
  623.     CONST char    * str1;
  624.     int          c;
  625. {
  626.     return( DBstrrchr( (char *)NULL, 0, str1, c) );
  627. }
  628.  
  629. char *
  630. DBstrrchr(file,line,str1,c)
  631.     CONST char        * file;
  632.     int              line;
  633.     CONST char        * str1;
  634.     int              c;
  635. {
  636.     return( DBFstrrchr("strchr",file,line,str1,c) );
  637. }
  638.  
  639. char *
  640. DBFstrrchr(func,file,line,str1,c)
  641.     CONST char        * func;
  642.     CONST char        * file;
  643.     int              line;
  644.     register CONST char    * str1;
  645.     register int          c;
  646. {
  647.     char    * rtn = (char *) 0;
  648.  
  649.     malloc_check_str(func, file, line, str1);
  650.  
  651.     while( *str1 )
  652.     {
  653.         if(*str1 == (char) c )
  654.         {
  655.             rtn = (char *)str1;
  656.         }
  657.         str1++;
  658.     }
  659.  
  660.     if( *str1 == (char) c)
  661.     {
  662.         rtn = (char *)str1;
  663.     }
  664.  
  665.     return(rtn);
  666. }
  667.  
  668. /*
  669.  * index - find location of character within string
  670.  */
  671. char *
  672. index(str1,c)
  673.     CONST char        * str1;
  674.     char          c;
  675. {
  676.     return( DBindex((char *) NULL, 0, str1, c) );
  677. }
  678. char *
  679. DBindex(file, line, str1, c)
  680.     CONST char    * file;
  681.     int          line;
  682.     CONST char    * str1;
  683.     char          c;
  684. {
  685.     return( DBFstrchr("index",file,line,str1,c) );
  686. }
  687.  
  688. /*
  689.  * rindex - find rightmost location of character within string
  690.  */
  691. char *
  692. rindex(str1,c)
  693.     CONST char    * str1;
  694.     char          c;
  695. {
  696.     return( DBrindex((char *)NULL, 0, str1, c) );
  697. }
  698.  
  699. char *
  700. DBrindex(file, line, str1, c)
  701.     CONST char    * file;
  702.     int          line;
  703.     CONST char    * str1;
  704.     char          c;
  705. {
  706.     return( DBFstrrchr("rindex",file,line,str1,c) );
  707. }
  708.  
  709. /*
  710.  * strpbrk - find the first occurance of any character from str2 in str1
  711.  */
  712. char *
  713. strpbrk(str1,str2)
  714.     CONST char    * str1;
  715.     CONST char    * str2;
  716. {
  717.     return( DBstrpbrk((char *)NULL, 0, str1, str2) );
  718. }
  719.  
  720. char *
  721. DBstrpbrk(file, line, str1,str2)
  722.     CONST char        * file;
  723.     int              line;
  724.     register CONST char    * str1;
  725.     register CONST char    * str2;
  726. {
  727.     register CONST char    * tmp;
  728.  
  729.     malloc_check_str("strpbrk", file, line, str1);
  730.     malloc_check_str("strpbrk", file, line, str2);
  731.  
  732.     while(*str1)
  733.     {
  734.         for( tmp=str2; *tmp && *tmp != *str1; tmp++)
  735.         {
  736.         }
  737.         if( *tmp )
  738.         {
  739.             break;
  740.         }
  741.         str1++;
  742.     }
  743.  
  744.     if( ! *str1 )
  745.     {
  746.         str1 = (char *) 0;
  747.     }
  748.  
  749.     return( (char *) str1);
  750. }
  751.  
  752. /*
  753.  * strspn - get length of str1 that consists totally of chars from str2
  754.  */
  755. STRSIZE 
  756. strspn(str1,str2)
  757.     CONST char    * str1;
  758.     CONST char    * str2;
  759. {
  760.     return( DBstrspn((char *)NULL, 0, str1, str2) );
  761. }
  762.  
  763. STRSIZE 
  764. DBstrspn(file, line, str1,str2)
  765.     CONST char        * file;
  766.     int              line;
  767.     register CONST char    * str1;
  768.     register CONST char    * str2;
  769. {
  770.     register CONST char    * tmp;
  771.     CONST char        * orig = str1;
  772.  
  773.     malloc_check_str("strspn", file, line, str1);
  774.     malloc_check_str("strspn", file, line, str2);
  775.  
  776.     while(*str1)
  777.     {
  778.         for( tmp=str2; *tmp && *tmp != *str1; tmp++)
  779.         {
  780.         }
  781.         if(! *tmp )
  782.         {
  783.             break;
  784.         }
  785.         str1++;
  786.     }
  787.  
  788.     return( (STRSIZE ) (str1 - orig) );
  789. }
  790.  
  791. /*
  792.  * strcspn - get lenght of str1 that consists of no chars from str2
  793.  */
  794. STRSIZE 
  795. strcspn(str1,str2)
  796.     CONST char    * str1;
  797.     CONST char    * str2;
  798. {
  799.     return( DBstrcspn((char *)NULL,0,str1,str2) );
  800. }
  801.  
  802. STRSIZE 
  803. DBstrcspn(file, line, str1,str2)
  804.     CONST char        * file;
  805.     int              line;
  806.     register CONST char    * str1;
  807.     register CONST char    * str2;
  808. {
  809.     register CONST char    * tmp;
  810.     CONST char    * orig = str1;
  811.  
  812.     malloc_check_str("strcspn", file, line, str1);
  813.     malloc_check_str("strcspn", file, line, str2);
  814.  
  815.     while(*str1)
  816.     {
  817.         for( tmp=str2; *tmp && *tmp != *str1; tmp++)
  818.         {
  819.         }
  820.         if( *tmp )
  821.         {
  822.             break;
  823.         }
  824.         str1++;
  825.     }
  826.  
  827.     return( (int) (str1 - orig) );
  828. }
  829.  
  830. /*
  831.  * strstr - locate string within another string
  832.  */
  833. char *
  834. strstr(str1, str2)
  835.     CONST char    * str1;
  836.     CONST char    * str2;
  837. {
  838.     return( DBstrstr((char *)NULL, 0, str1, str2) );
  839. }
  840.  
  841. char *
  842. DBstrstr(file, line, str1, str2)
  843.     CONST char    * file;
  844.     int          line;
  845.     CONST char    * str1;
  846.     CONST char    * str2;
  847. {
  848.     register CONST char    * s;
  849.     register CONST char    * t;
  850.     
  851.     malloc_check_str("strstr", file, line, str1);
  852.     malloc_check_str("strstr", file, line, str2);
  853.  
  854.     /*
  855.      * until we run out of room in str1
  856.      */
  857.     while( *str1 != '\0' )
  858.     {
  859.         /*
  860.          * get tmp pointers to both strings
  861.          */
  862.         s = str2;
  863.         t = str1;
  864.  
  865.         /*
  866.          * see if they match
  867.          */
  868.         while( *s &&  (*s == *t) )
  869.         {
  870.             s++;
  871.             t++;
  872.         }
  873.  
  874.         /*
  875.          * if we ran out of str2, we found the match,
  876.          * so return the pointer within str1.
  877.          */
  878.         if( ! *s )
  879.         {
  880.             return( (char *) str1);
  881.         }
  882.         str1++;
  883.     }
  884.  
  885.     if( *str2 == '\0' )
  886.     {
  887.         return( (char *) str1);
  888.     }
  889.     return(NULL);
  890. }
  891.  
  892. /*
  893.  * strtok() source taken from that posted to comp.lang.c by Chris Torek
  894.  * in Jan 1990.
  895.  */
  896.  
  897. /*
  898.  * Copyright (c) 1989 The Regents of the University of California.
  899.  * All rights reserved.
  900.  *
  901.  * Redistribution and use in source and binary forms are permitted
  902.  * provided that the above copyright notice and this paragraph are
  903.  * duplicated in all such forms and that any documentation,
  904.  * advertising materials, and other materials related to such
  905.  * distribution and use acknowledge that the software was developed
  906.  * by the University of California, Berkeley.  The name of the
  907.  * University may not be used to endorse or promote products derived
  908.  * from this software without specific prior written permission.
  909.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  910.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  911.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  912.  */
  913.  
  914. /*
  915.  * Get next token from string s (NULL on 2nd, 3rd, etc. calls),
  916.  * where tokens are nonempty strings separated by runs of
  917.  * chars from delim.  Writes NULs into s to end tokens.  delim need not
  918.  * remain CONSTant from call to call.
  919.  *
  920.  * Modified by cpc:     changed variable names to conform with naming
  921.  *            conventions used in rest of code.  Added malloc pointer
  922.  *            check calls.
  923.  */
  924.  
  925. char *
  926. strtok(str1, str2)
  927.     char         * str1;
  928.     CONST char    * str2;
  929. {
  930.     return( DBstrtok( (char *)NULL, 0, str1, str2) );
  931. }
  932.  
  933. char *
  934. DBstrtok(file, line, str1, str2)
  935.     CONST char    * file;
  936.     int          line;
  937.     char         * str1;
  938.     CONST char    * str2;
  939. {
  940.     static char     * last;
  941.  
  942.     if( str1 )
  943.     {
  944.         malloc_check_str("strtok", file, line, str1);
  945.         last = str1;
  946.     }
  947.     malloc_check_str("strtok", file, line, str2);
  948.  
  949.     return (strtoken(&last, str2, 1));
  950. }
  951.  
  952.  
  953. /*
  954.  * Get next token from string *stringp, where tokens are (possibly empty)
  955.  * strings separated by characters from delim.  Tokens are separated
  956.  * by exactly one delimiter iff the skip parameter is false; otherwise
  957.  * they are separated by runs of characters from delim, because we
  958.  * skip over any initial `delim' characters.
  959.  *
  960.  * Writes NULs into the string at *stringp to end tokens.
  961.  * delim will usually, but need not, remain CONSTant from call to call.
  962.  * On return, *stringp points past the last NUL written (if there might
  963.  * be further tokens), or is NULL (if there are definitely no more tokens).
  964.  *
  965.  * If *stringp is NULL, strtoken returns NULL.
  966.  */
  967. char *
  968. strtoken(stringp, delim, skip)
  969.     register char **stringp;
  970.     register CONST char *delim;
  971.     int skip;
  972. {
  973.     register char *s;
  974.     register CONST char *spanp;
  975.     register int c, sc;
  976.     char *tok;
  977.  
  978.     if ((s = *stringp) == NULL)
  979.         return (NULL);
  980.  
  981.     if (skip) {
  982.         /*
  983.          * Skip (span) leading delimiters (s += strspn(s, delim)).
  984.          */
  985.     cont:
  986.         c = *s;
  987.         for (spanp = delim; (sc = *spanp++) != 0;) {
  988.             if (c == sc) {
  989.                 s++;
  990.                 goto cont;
  991.             }
  992.         }
  993.         if (c == 0) {        /* no token found */
  994.             *stringp = NULL;
  995.             return (NULL);
  996.         }
  997.     }
  998.  
  999.     /*
  1000.      * Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
  1001.      * Note that delim must have one NUL; we stop if we see that, too.
  1002.      */
  1003.     for (tok = s;;) {
  1004.         c = *s++;
  1005.         spanp = delim;
  1006.         do {
  1007.             if ((sc = *spanp++) == c) {
  1008.                 if (c == 0)
  1009.                     s = NULL;
  1010.                 else
  1011.                     s[-1] = 0;
  1012.                 *stringp = s;
  1013.                 return( (char *) tok );
  1014.             }
  1015.         } while (sc != 0);
  1016.     }
  1017.     /* NOTREACHED */
  1018. }
  1019.  
  1020. /*
  1021.  * $Log: string.c,v $
  1022.  * Revision 1.30  1992/08/22  16:27:13  cpcahil
  1023.  * final changes for pl14
  1024.  *
  1025.  * Revision 1.29  1992/07/03  00:03:25  cpcahil
  1026.  * more fixes for pl13, several suggestons from Rich Salz.
  1027.  *
  1028.  * Revision 1.28  1992/06/30  13:06:39  cpcahil
  1029.  * added support for aligned allocations
  1030.  *
  1031.  * Revision 1.27  1992/06/27  22:48:48  cpcahil
  1032.  * misc fixes per bug reports from first week of reviews
  1033.  *
  1034.  * Revision 1.26  1992/06/23  11:12:54  cpcahil
  1035.  * fixed bug in case insensitive comparisons.
  1036.  *
  1037.  * Revision 1.25  1992/06/22  23:40:10  cpcahil
  1038.  * many fixes for working on small int systems
  1039.  *
  1040.  * Revision 1.24  1992/05/09  21:27:09  cpcahil
  1041.  * final (hopefully) changes for patch 11
  1042.  *
  1043.  * Revision 1.23  1992/05/09  00:16:16  cpcahil
  1044.  * port to hpux and lots of fixes
  1045.  *
  1046.  * Revision 1.22  1992/05/08  02:30:35  cpcahil
  1047.  * minor cleanups from minix/atari port
  1048.  *
  1049.  * Revision 1.21  1992/05/08  01:44:11  cpcahil
  1050.  * more performance enhancements
  1051.  *
  1052.  * Revision 1.20  1992/04/20  22:29:14  cpcahil
  1053.  * changes to fix problems introduced by insertion of size_t
  1054.  *
  1055.  * Revision 1.19  1992/04/14  01:15:25  cpcahil
  1056.  * port to RS/6000
  1057.  *
  1058.  * Revision 1.18  1992/04/13  19:08:18  cpcahil
  1059.  * fixed case insensitive stuff
  1060.  *
  1061.  * Revision 1.17  1992/04/13  18:41:18  cpcahil
  1062.  * added case insensitive string comparison routines
  1063.  *
  1064.  * Revision 1.16  1992/04/13  03:06:33  cpcahil
  1065.  * Added Stack support, marking of non-leaks, auto-config, auto-testing
  1066.  *
  1067.  * Revision 1.15  1992/01/30  12:23:06  cpcahil
  1068.  * renamed mallocint.h -> mallocin.h
  1069.  *
  1070.  * Revision 1.14  1991/12/04  09:23:44  cpcahil
  1071.  * several performance enhancements including addition of free list
  1072.  *
  1073.  * Revision 1.13  91/12/02  19:10:14  cpcahil
  1074.  * changes for patch release 5
  1075.  * 
  1076.  * Revision 1.12  91/11/25  14:42:05  cpcahil
  1077.  * Final changes in preparation for patch 4 release
  1078.  * 
  1079.  * Revision 1.11  91/11/24  16:56:43  cpcahil
  1080.  * porting changes for patch level 4
  1081.  * 
  1082.  * Revision 1.10  91/11/24  00:49:32  cpcahil
  1083.  * first cut at patch 4
  1084.  * 
  1085.  * Revision 1.9  91/11/20  11:54:11  cpcahil
  1086.  * interim checkin
  1087.  * 
  1088.  * Revision 1.8  91/05/30  12:07:04  cpcahil
  1089.  * added fix to get the stuff to compile correctly on ultirx and aix systems.
  1090.  * 
  1091.  * Revision 1.7  90/08/29  22:24:19  cpcahil
  1092.  * added new function to check on strings up to a specified length 
  1093.  * and used it within several strn* functions.
  1094.  * 
  1095.  * Revision 1.6  90/07/16  20:06:56  cpcahil
  1096.  * fixed several minor bugs found with Henry Spencer's string/mem function
  1097.  * tester program.
  1098.  * 
  1099.  * Revision 1.5  90/06/10  14:59:49  cpcahil
  1100.  * Fixed a couple of bugs in strncpy & strdup
  1101.  * 
  1102.  * Revision 1.4  90/05/11  00:13:10  cpcahil
  1103.  * added copyright statment
  1104.  * 
  1105.  * Revision 1.3  90/02/24  21:50:32  cpcahil
  1106.  * lots of lint fixes
  1107.  * 
  1108.  * Revision 1.2  90/02/24  17:29:40  cpcahil
  1109.  * changed $Header to $Id so full path wouldnt be included as part of rcs 
  1110.  * id string
  1111.  * 
  1112.  * Revision 1.1  90/02/22  23:17:44  cpcahil
  1113.  * Initial revision
  1114.  * 
  1115.  */
  1116.