home *** CD-ROM | disk | FTP | other *** search
/ PC World 2001 April / PCWorld_2001-04_cd.bin / Software / TemaCD / junkbust / ssplit.c < prev    next >
C/C++ Source or Header  |  1998-10-30  |  3KB  |  125 lines

  1. char *ssplit_rcs = "$Id: ssplit.c,v 1.6 1998/10/27 16:25:07 ACJC Exp $";
  2. /* Written and copyright 1997 Anonymous Coders and Junkbusters Corporation.
  3.  * Distributed under the GNU General Public License; see the README file.
  4.  * This code comes with NO WARRANTY. http://www.junkbusters.com/ht/en/gpl.html
  5.  */
  6.  
  7. /* ssplit() - split a string (in-place) into fields
  8.  *      s = string to split
  9.  *      c = list of characters to be used as field separators
  10.  *          (if NULL, use default separators of space, tab, and newline)
  11.  *
  12.  *      v = vector into which field pointers are placed
  13.  *      n = number of fields in vector
  14.  *
  15.  *      m = flag indicating whether to treat strings of field
  16.  *          separators as indicating multiple fields
  17.  *
  18.  *      l = flag indicating whether to ignore leading field separators
  19.  */
  20.  
  21. #include <string.h>
  22.  
  23. int ssplit(char *s, char *c, char *v[], int n, int m, int l)
  24. {
  25.     char t[256];
  26.     char **x = NULL;
  27.     int xsize = 0;
  28.     unsigned char *p, b;
  29.     int xi = 0;
  30.     int vi = 0;
  31.     int i;
  32.     int last_was_null;
  33.  
  34.     if (!s)
  35.     return (-1);
  36.  
  37.     memset(t, '\0', sizeof(t));
  38.  
  39.     p = (unsigned char *) c;
  40.  
  41.     if (!p)
  42.     p = (unsigned char *) " \t";    /* default field separators */
  43.  
  44.     while (*p)
  45.     t[*p++] = 1;    /* separator  */
  46.  
  47.     t['\0'] = 2;    /* terminator */
  48.     t['\n'] = 2;    /* terminator */
  49.  
  50.     p = (unsigned char *) s;
  51.  
  52.     if(l) {    /* are we to skip leading separators ? */
  53.         while((b = t[*p]) != 2) {
  54.         if(b != 1) break;
  55.         p++;
  56.     }
  57.     }
  58.  
  59.     xsize = 256;
  60.  
  61.     x = (char **) zalloc((xsize) * sizeof(char *));
  62.  
  63.     x[xi++] = (char *) p;    /* first pointer is the beginning of string */
  64.  
  65.     /* first pass:  save pointers to the field separators */
  66.     while((b = t[*p]) != 2) {
  67.         if(b == 1) {        /* if the char is a separator ... */
  68.         *p++    = '\0';    /* null terminate the substring */
  69.  
  70.         if(xi == xsize) {
  71.             /* get another chunk */
  72.             int new_xsize = xsize + 256;
  73.             char **new_x = (char **)
  74.                 zalloc((new_xsize) * sizeof(char *));
  75.  
  76.             for(i=0; i < xsize; i++) new_x[i] = x[i];
  77.  
  78.             free(x);
  79.             xsize = new_xsize;
  80.             x     = new_x;
  81.         }
  82.         x[xi++] = (char *) p;    /* save pointer to beginning of next string */
  83.     } else {
  84.         p++;
  85.     }
  86.     }
  87.     *p = '\0';        /* null terminate the substring */
  88.  
  89. #ifdef DEBUG
  90. print(x, xi); /* debugging */
  91. #endif
  92.  
  93.     /* second pass: copy the relevant pointers to the output vector */
  94.     last_was_null = 0;
  95.     for(i=0 ; i < xi; i++) {
  96.     if(m) {
  97.         /* there are NO null fields */
  98.         if(*x[i] == 0) continue;
  99.     }
  100.     if(vi < n) {
  101.         v[vi++] = x[i];
  102.     } else {
  103.         free(x);
  104.         return(-1);    /* overflow */
  105.     }
  106.     }
  107.     free(x);
  108.  
  109. #ifdef DEBUG
  110. print(v, vi); /* debugging  */
  111. #endif
  112.     return (vi);
  113. }
  114.  
  115. #ifdef DEBUG
  116. print(char **v, int n)
  117. {
  118.     int i;
  119.     printf("dump %d strings\n", n);
  120.     for(i=0; i < n; i++) {
  121.         printf("%d '%s'\n", i, v[i]);
  122.     }
  123. }
  124. #endif
  125.