home *** CD-ROM | disk | FTP | other *** search
/ ftp.ncftp.com / ftp.ncftp.com.zip / ftp.ncftp.com / libncftp / libncftp-3.2.5-src.zip / libncftp-3.2.5 / Strn / strtokc.c < prev    next >
C/C++ Source or Header  |  2001-11-19  |  5KB  |  241 lines

  1. #include "syshdrs.h"
  2. #ifdef PRAGMA_HDRSTOP
  3. #    pragma hdrstop
  4. #endif
  5.  
  6. char *
  7. strtokc(char *parsestr, const char *delims, char **context)
  8. {
  9.     char *cp;
  10.     const char *cp2;
  11.     char c, c2;
  12.     char *start;
  13.  
  14.     if (parsestr == NULL)
  15.         start = *context;
  16.     else
  17.         start = parsestr;
  18.  
  19.     if ((start == NULL) || (delims == NULL)) {
  20.         *context = NULL;
  21.         return NULL;
  22.     }
  23.  
  24.     /* Eat leading delimiters. */
  25.     for (cp = start; ; ) {
  26. next1:
  27.         c = *cp++;
  28.         if (c == '\0') {
  29.             /* No more tokens. */
  30.             *context = NULL;
  31.             return (NULL);
  32.         }
  33.         for (cp2 = delims; ; ) {
  34.             c2 = (char) *cp2++;
  35.             if (c2 == '\0') {
  36.                 /* This character was not a delimiter.
  37.                  * The token starts here.
  38.                  */
  39.                 start = cp - 1;
  40.                 goto starttok;
  41.             }
  42.             if (c2 == c) {
  43.                 /* This char was a delimiter. */
  44.                 /* Skip it, look at next character. */
  45.                 goto next1;
  46.             }
  47.         }
  48.         /*NOTREACHED*/
  49.     }
  50.  
  51. starttok:
  52.     for ( ; ; cp++) {
  53.         c = *cp;
  54.         if (c == '\0') {
  55.             /* Token is finished. */
  56.             *context = cp;
  57.             break;
  58.         }
  59.         for (cp2 = delims; ; ) {
  60.             c2 = (char) *cp2++;
  61.             if (c2 == '\0') {
  62.                 /* This character was not a delimiter.
  63.                  * Keep it as part of current token.
  64.                  */
  65.                 break;
  66.             }
  67.             if (c2 == c) {
  68.                 /* This char was a delimiter. */
  69.                 /* End of token. */
  70.                 *cp++ = '\0';
  71.                 *context = cp;
  72.                 return (start);
  73.             }
  74.         }
  75.     }
  76.     return (start);
  77. }    /* strtokc */
  78.  
  79.  
  80.  
  81.  
  82. /* Same as strtokc, only you specify the destination buffer to write
  83.  * the token in along with its size.  strntokc will write to the dst
  84.  * buffer, always nul-terminating it.
  85.  *
  86.  * It also returns the length of the token, or zero if there was no
  87.  * token.  This differs from strtokc, which returns a pointer to the
  88.  * token or NULL for no token.
  89.  */
  90.  
  91. size_t
  92. strntokc(char *dstTokenStart, size_t tokenSize, char *parsestr, const char *delims, char **context)
  93. {
  94.     char *cp;
  95.     const char *cp2;
  96.     char c, c2;
  97.     char *start;
  98.     size_t len;
  99.     char *dst, *lim;
  100.  
  101.     dst = dstTokenStart;
  102.     lim = dst + tokenSize - 1;        /* Leave room for nul byte. */
  103.  
  104.     if (parsestr == NULL)
  105.         start = *context;
  106.     else
  107.         start = parsestr;
  108.  
  109.     if ((start == NULL) || (delims == NULL)) {
  110.         *context = NULL;
  111.         goto done;
  112.     }
  113.  
  114.     /* Eat leading delimiters. */
  115.     for (cp = start; ; ) {
  116. next1:
  117.         c = *cp++;
  118.         if (c == '\0') {
  119.             /* No more tokens. */
  120.             *context = NULL;
  121.             goto done;
  122.         }
  123.         for (cp2 = delims; ; ) {
  124.             c2 = (char) *cp2++;
  125.             if (c2 == '\0') {
  126.                 /* This character was not a delimiter.
  127.                  * The token starts here.
  128.                  */
  129.                 start = cp - 1;
  130.                 if (dst < lim)
  131.                     *dst++ = c;
  132.                 goto starttok;
  133.             }
  134.             if (c2 == c) {
  135.                 /* This char was a delimiter. */
  136.                 /* Skip it, look at next character. */
  137.                 goto next1;
  138.             }
  139.         }
  140.         /*NOTREACHED*/
  141.     }
  142.  
  143. starttok:
  144.     for ( ; ; cp++) {
  145.         c = *cp;
  146.         if (c == '\0') {
  147.             /* Token is finished. */
  148.             *context = cp;
  149.             break;
  150.         }
  151.         for (cp2 = delims; ; ) {
  152.             c2 = (char) *cp2++;
  153.             if (c2 == '\0') {
  154.                 /* This character was not a delimiter.
  155.                  * Keep it as part of current token.
  156.                  */
  157.                 break;
  158.             }
  159.             if (c2 == c) {
  160.                 /* This char was a delimiter. */
  161.                 /* End of token. */
  162.                 *cp++ = '\0';
  163.                 *context = cp;
  164.                 goto done;
  165.             }
  166.         }
  167.         if (dst < lim)            /* Don't overrun token size. */
  168.             *dst++ = c;
  169.     }
  170.  
  171. done:
  172.     *dst = '\0';
  173.     len = (size_t) (dst - dstTokenStart);        /* Return length of token. */
  174.  
  175. #if (STRN_ZERO_PAD == 1)
  176.     /* Pad with zeros. */
  177.     for (++dst; dst <= lim; )
  178.         *dst++ = 0;
  179. #endif    /* STRN_ZERO_PAD */
  180.  
  181.     return (len);
  182. }    /* strntokc */
  183.  
  184.  
  185.  
  186.  
  187. #ifdef TESTING_STRTOK
  188. #include <stdio.h>
  189.  
  190. void
  191. main(int argc, char **argv)
  192. {
  193.     char buf[256];
  194.     int i;
  195.     char *t;
  196.     char token[8];
  197.     int tokenLen;
  198.     char *context;
  199.  
  200.     if (argc < 3) {
  201.         fprintf(stderr, "Usage: test \"buffer,with,delims\" <delimiters>\n");
  202.         exit(1);
  203.     }
  204.     strcpy(buf, argv[1]);
  205.     i = 1;
  206.     t = strtok(buf, argv[2]);
  207.     if (t == NULL)
  208.         exit(0);
  209.     do {
  210.         printf("strtok %d=[%s] length=%d\n", i, t, (int) strlen(t));
  211.         t = strtok(NULL, argv[2]);
  212.         ++i;
  213.     } while (t != NULL);
  214.  
  215.     printf("------------------------------------------------\n");
  216.     strcpy(buf, argv[1]);
  217.     i = 1;
  218.     t = strtokc(buf, argv[2], &context);
  219.     if (t == NULL)
  220.         exit(0);
  221.     do {
  222.         printf("strtokc %d=[%s] length=%d\n", i, t, (int) strlen(t));
  223.         t = strtokc(NULL, argv[2], &context);
  224.         ++i;
  225.     } while (t != NULL);
  226.  
  227.     printf("------------------------------------------------\n");
  228.     strcpy(buf, argv[1]);
  229.     i = 1;
  230.     tokenLen = strntokc(token, sizeof(token), buf, argv[2], &context);
  231.     if (tokenLen <= 0)
  232.         exit(0);
  233.     do {
  234.         printf("strntokc %d=[%s] length=%d\n", i, token, tokenLen);
  235.         tokenLen = strntokc(token, sizeof(token), NULL, argv[2], &context);
  236.         ++i;
  237.     } while (tokenLen > 0);
  238.     exit(0);
  239. }
  240. #endif
  241.