home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 11 Util / 11-Util.zip / TIMEXSRC.ZIP / STRING.C < prev    next >
Text File  |  1990-03-29  |  7KB  |  334 lines

  1. /* string.c -- String operations
  2.  
  3.     December 1989    Mark E. Mallett
  4.  
  5.     Copied from the FFS program.
  6.  
  7. This file contains routines dealing with character strings.
  8. These include:
  9.  
  10.     gettoken    Extract a token from a string
  11.     newstr        Make a new copy of a string
  12.     stricmp        strcmp without case sensitivity
  13.     strnicmp    strncmp without case sensitivity
  14.     strscmp        strcmp that returns sign only.
  15.     tkline        Tokenize a line
  16.  
  17. */
  18.  
  19. #include <stdio.h>
  20. #include <string.h>
  21. #include <os2.h>
  22.  
  23. #include "timex.h"
  24.  
  25.  
  26. /* Local Definitions */
  27.  
  28. #ifndef NUL
  29. #define NUL     '\0'
  30. #endif  /* NUL */
  31.  
  32. /* External data referenced */
  33.  
  34.  
  35. /* External routines used */
  36.  
  37. extern    char    *malloc();
  38.  
  39. /* Local data publicly available */
  40.  
  41.  
  42. /* Local routines and forward references */
  43.  
  44.  
  45.  
  46. /* Private data */
  47.  
  48.  
  49. /*
  50.  
  51. *//* tkline( bufP, tbufP, tokcP, tokv, tokmax, vsepP, isepP )
  52.  
  53.     Tokenize a line of text
  54.  
  55. Accepts :
  56.  
  57.     bufP        The buffer containing data to be tokenized
  58.     tbufP        A buffer in which tokens will be placed
  59.     tokv        Ptr to tokv array -- ptrs to tokens
  60.     tokmax        Maximum number of tokens to return
  61.     vsepP, isepP    Separators, as in call to gettoken() (refer there)
  62.     
  63. Returns :
  64.  
  65.     <value>        Number of tokens extracted
  66.     *tokv        Ptrs to tokens
  67.  
  68. Notes :
  69.  
  70.     Caller must insure that the token buffer is large enough to receive
  71.     all of the tokens.
  72.  
  73.     The source and destination buffers may overlap, as long as the
  74.     source buffer's address is greater than the token buffer's.  Thus,
  75.     &bufP[0] can be &tbufP[1] (this is a convenient arrangement).
  76.  
  77. */
  78.  
  79. int
  80. tkline( bufP, tbufP, tokv, tokmax, vsepP, isepP )
  81.     char        *bufP;        /* Buffer ptr */
  82.     char        *tbufP;        /* Token buffer pointer */
  83.     char        **tokv;        /* Arg vectors */
  84.     int        tokmax;        /* Max # tokens */
  85.     char        *vsepP;        /* Visible separators */
  86.     char        *isepP;        /* Invisible separators */
  87. {
  88.     int        tokC;        /* # of tokens */
  89.  
  90.     /* Extract the tokens */
  91.     for( tokC = 0;
  92.       ( tokC < tokmax ) && 
  93.           ( bufP = gettoken( bufP, tbufP, 9999, vsepP, isepP ) ) != NULL;
  94.         ++tokC ) {
  95.     *tokv++ = tbufP;
  96.     tbufP += strlen( tbufP ) +1;
  97.     }
  98.  
  99.     return( tokC );
  100. }    
  101. /*
  102.  
  103. *//* gettoken( strP, tokP, tokmax, vsepP, isepP )
  104.  
  105.     Extract a token from a string
  106.  
  107. Accepts :
  108.  
  109.     strP        Source string
  110.     tokP        Buffer to contain the token
  111.     tokmax        Maximum lenght of token (including NUL)
  112.     vsepP        "visible" separators -- chars that will terminate
  113.              and will also be returned as single-character tokens;
  114.     isepP        "invisible" separators -- chars that will terminate
  115.               a token and will be deleted from the source string.
  116.  
  117. Returns :
  118.  
  119.     <value>        Ptr to the rest of the string, or NULL if no
  120.              more tokens;
  121.     *tokP        Token extracted
  122.  
  123. */
  124.  
  125. char *
  126. gettoken( strP, tokP, tokmax, vsepP, isepP )
  127.     char        *strP;        /* Source string */
  128.     char        *tokP;        /* Where to put token */
  129.     int        tokmax;        /* Max length of token */
  130.     char        *vsepP;        /* Visible separators */
  131.     char        *isepP;        /* Invisible separators */
  132. {
  133.     char        ch;        /* Character */
  134.     char        quote;        /* Quoting character */
  135.     int        tokX;        /* Index into token string */
  136.  
  137.     /* Trap NULL source string pointer */
  138.     if ( strP == NULL )
  139.     return( NULL );
  140.  
  141.     /* Strip leading "invisible" separators */
  142.     for( ; ( ( ch = *strP ) != NUL ) && ( strchr( isepP, ch ) != NULL ); )
  143.      ++strP;
  144.  
  145.     /* Check end of character string */
  146.     if ( ch == NUL )
  147.     return( NULL );
  148.  
  149.     /* Loop to get token characters */
  150.     for( quote = NUL, tokX = 0; ( ch = *strP ) != NUL; ++strP ) {
  151.         /* Check for escaped character -- only a quote or an escape
  152.            character may be quoted.
  153.         */
  154.         if ( ( ch == '\\' ) &&
  155.              ( ( strP[1] == '\\' ) ||
  156.                ( strP[1] == '\"' ) ||
  157.                ( strP[1] == '\'' )
  158.              )
  159.            )
  160.         ch = *++strP;        /* Use the escaped char */
  161.     else {
  162.         /* Check for terminating quote */
  163.         if ( quote != NUL ) {
  164.         if ( ch == quote ) {
  165.             quote = NUL;    /* No more quoted string */
  166.             continue;        /* Try next character */
  167.         }
  168.         }
  169.         else {
  170.         /* Check for quoted character string */
  171.         if ( ( ch == '"' ) || ( ch == '\'' ) ) {
  172.             quote = ch;        /* Remember quote char */
  173.             continue;        /* Go for next char */
  174.         }
  175.  
  176.         /* Check "visible" delimiters */
  177.         if ( strchr( vsepP, ch ) != NULL ) {
  178.             if ( tokX == 0 ) {
  179.             /* Only character of token */
  180.             tokP[tokX++] = ch;
  181.             ++strP;
  182.             }
  183.             break;            /* End of token */
  184.         }
  185.  
  186.         /* Check "invisible" delimiters */
  187.         if ( strchr( isepP, ch ) != NULL ) {
  188.             ++strP;            /* Skip the invisible char */
  189.             break;
  190.         }
  191.         }
  192.     }
  193.  
  194.     /* Add the character to the token */
  195.     if ( tokX < tokmax -1 )
  196.         tokP[tokX++] = ch;
  197.     }
  198.  
  199.     tokP[tokX] = NUL;
  200.  
  201.     return( strP );
  202. }
  203. /*
  204.  
  205. *//* newstr( facP, nameP, oldP )
  206.  
  207.     Allocate a new copy of a string
  208.  
  209. Accepts :
  210.  
  211.     facP        Name of facility (e.g., subroutine name)
  212.     nameP        Name of item being allocated
  213.     oldP        Ptr to old string to duplicate
  214.  
  215. Returns :
  216.  
  217.     < value >    Ptr to new string
  218.  
  219. Notes :
  220.  
  221.     error return is taken if allocation fails.
  222. */
  223.  
  224. char *
  225. newstr( facP, nameP, oldP )
  226.     char        *facP;        /* Ptr to facility name */
  227.     char        *nameP;        /* Ptr to name of thing */
  228.     char        *oldP;        /* Ptr to existing string */
  229. {
  230.     char        *newP;        /* Ptr to memory */
  231.  
  232.     newP = (char *)emalloc( facP, nameP, strlen( oldP ) +1 );
  233.     strcpy( newP, oldP );
  234.     return( newP );
  235. }
  236. /*
  237.  
  238. *//* strscmp( str1P, str2P )
  239.  
  240.     Like strcmp() but return just the sign.
  241.  
  242. Accepts :
  243.  
  244.     str1P        First string
  245.     str2P        Second string
  246.  
  247. Returns :
  248.  
  249.     <value>        -1 if str1P < str2P     (stringwise, of course)
  250.              0 if str1P == str2P
  251.              1 if str1P > str2P
  252.  
  253. Notes :
  254.  
  255.     This mimics the "old" behaviour of strcmp().
  256.  
  257. */
  258.  
  259. int
  260. strscmp( str1P, str2P )
  261.     char        *str1P;        /* First string */
  262.     char        *str2P;        /* Second string */
  263. {
  264.     int        cmpval;        /* Comparison value */
  265.  
  266.     if ( ( cmpval = strcmp( str1P, str2P ) ) < 0 )
  267.     return( -1 );
  268.     else if ( cmpval == 0 )
  269.     return( 0 );
  270.     else
  271.     return( 1 );
  272. }
  273. /*
  274.  
  275. *//* stricmp() and strnicmp()
  276.  
  277.     Like strcmp() and strncmp() but ignoring case.  These may
  278.     not be present in the C library in use, in which case these
  279.     routines may be conditionally compiled.
  280.  
  281. */
  282.  
  283. #ifndef HAVE_STRICMP
  284.  
  285. #include <ctype.h>
  286.  
  287. int
  288. stricmp( s1, s2 )
  289. register char        *s1, *s2;
  290. {
  291. register unsigned char    c1, c2;
  292.  
  293.     for( ; ; ) {
  294.     c1 = *s1++;
  295.     c2 = *s2++;
  296.     if ( isupper( c1 ) )
  297.         c1 = tolower( c1 );
  298.     if ( isupper( c2 ) )
  299.         c2 = tolower( c2 );
  300.     if ( c1 < c2 )
  301.         return( -1 );
  302.     if ( c1 > c2 )
  303.         return( 1 );
  304.     if ( c1 == NUL )
  305.         return( 0 );
  306.     }
  307. }
  308.  
  309. int
  310. strnicmp( s1, s2, max )
  311. register char        *s1, *s2;
  312.     int        max;
  313. {
  314. register unsigned char    c1, c2;
  315.  
  316.     for( ; max > 0; --max ) {
  317.     c1 = *s1++;
  318.     c2 = *s2++;
  319.     if ( isupper( c1 ) )
  320.         c1 = tolower( c1 );
  321.     if ( isupper( c2 ) )
  322.         c2 = tolower( c2 );
  323.     if ( c1 < c2 )
  324.         return( -1 );
  325.     if ( c1 > c2 )
  326.         return( 1 );
  327.     if ( c1 == NUL )
  328.         return( 0 );
  329.     }
  330.     return( 0 );
  331. }
  332.  
  333. #endif  /* HAVE_STRICMP */
  334.