- Added auto-generation of CRLFs for Win32 config files
[privoxy.git] / ssplit.c
1 const char ssplit_rcs[] = "$Id: ssplit.c,v 1.1 2001/05/13 21:57:07 administrator Exp $";
2 /*********************************************************************
3  *
4  * File        :  $Source: /home/administrator/cvs/ijb/ssplit.c,v $
5  *
6  * Purpose     :  A function to split a string at specified deliminters.
7  *
8  * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
9  *                IJBSWA team.  http://ijbswa.sourceforge.net
10  *
11  *                Based on the Internet Junkbuster originally written
12  *                by and Copyright (C) 1997 Anonymous Coders and 
13  *                Junkbusters Corporation.  http://www.junkbusters.com
14  *
15  *                This program is free software; you can redistribute it 
16  *                and/or modify it under the terms of the GNU General
17  *                Public License as published by the Free Software
18  *                Foundation; either version 2 of the License, or (at
19  *                your option) any later version.
20  *
21  *                This program is distributed in the hope that it will
22  *                be useful, but WITHOUT ANY WARRANTY; without even the
23  *                implied warranty of MERCHANTABILITY or FITNESS FOR A
24  *                PARTICULAR PURPOSE.  See the GNU General Public
25  *                License for more details.
26  *
27  *                The GNU General Public License should be included with
28  *                this file.  If not, you can view it at
29  *                http://www.gnu.org/copyleft/gpl.html
30  *                or write to the Free Software Foundation, Inc., 59
31  *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
32  *
33  * Revisions   :
34  *    $Log: ssplit.c,v $
35  *
36  *********************************************************************/
37 \f
38
39 #include "config.h"
40
41 #include <string.h>
42 #include <stdlib.h>\r
43
44 #ifdef _WIN32
45 #include <malloc.h>
46 #endif
47
48 #include "ssplit.h"
49 #include "miscutil.h"
50
51 const char ssplit_h_rcs[] = SSPLIT_H_VERSION;
52
53 /* Define this for lots of debugging information to stdout */
54 /* #define SSPLIT_VERBOSE */
55
56 #ifdef SSPLIT_VERBOSE
57 /*********************************************************************
58  *
59  * Function    :  print
60  *
61  * Description :  Debugging routine to spit info on stdout.  Not very
62  *                useful to the non-console based IJB compiles.
63  *
64  * Parameters  :
65  *          1  :  v = an array of strings
66  *          2  :  n = number of strings in `v' to dump to stdout
67  *
68  * Returns     :  N/A
69  *
70  *********************************************************************/
71 static void print(char **v, int n)
72 {
73    int i;
74    printf("dump %d strings\n", n);
75    for (i=0; i < n; i++)
76    {
77       printf("%d '%s'\n", i, v[i]);
78    }
79
80 }
81 #endif /* def SSPLIT_VERBOSE */
82
83
84 /*********************************************************************
85  *
86  * Function    :  ssplit
87  *
88  * Description :  Split a string using deliminters in `c'.  Results go
89  *                into `v'.
90  *
91  * Parameters  :
92  *          1  :  s = string to split
93  *          2  :  c = array of delimiters
94  *          3  :  v[] = results vector (aka. array)
95  *          4  :  n = number of usable slots in the vector (aka. array size)
96  *          5  :  m = consecutive delimiters means multiple fields?
97  *          6  :  l = ignore leading field separators?
98  *
99  * Returns     :  -1 => failure, else the number of fields put in `v'.
100  *
101  *********************************************************************/
102 int ssplit(char *s, char *c, char *v[], int n, int m, int l)
103 {
104    char t[256];
105    char **x = NULL;
106    int xsize = 0;
107    unsigned char *p, b;
108    int xi = 0;
109    int vi = 0;
110    int i;
111    int last_was_null;
112
113    if (!s)
114    {
115       return(-1);
116    }
117
118    memset(t, '\0', sizeof(t));
119
120    p = (unsigned char *) c;
121
122    if (!p)
123    {
124       p = (unsigned char *) " \t";  /* default field separators */
125    }
126
127    while (*p)
128    {
129       t[*p++] = 1;   /* separator  */
130    }
131
132    t['\0'] = 2;   /* terminator */
133    t['\n'] = 2;   /* terminator */
134
135    p = (unsigned char *) s;
136
137    if (l)/* are we to skip leading separators ? */
138    {
139       while ((b = t[*p]) != 2)
140       {
141          if (b != 1)
142          {
143             break;
144          }
145          p++;
146       }
147    }
148
149    xsize = 256;
150
151    x = (char **) zalloc((xsize) * sizeof(char *));
152
153    x[xi++] = (char *) p;   /* first pointer is the beginning of string */
154
155    /* first pass:  save pointers to the field separators */
156    while ((b = t[*p]) != 2)
157    {
158       if (b == 1)    /* if the char is a separator ... */
159       {
160          *p++ = '\0';      /* null terminate the substring */
161
162          if (xi == xsize)
163          {
164             /* get another chunk */
165             int new_xsize = xsize + 256;
166             char **new_x = (char **)zalloc((new_xsize) * sizeof(char *));
167
168             for (i=0; i < xsize; i++)
169             {
170                new_x[i] = x[i];
171             }
172
173             free(x);
174             xsize = new_xsize;
175             x     = new_x;
176          }
177          x[xi++] = (char *) p;   /* save pointer to beginning of next string */
178       }
179       else
180       {
181          p++;
182       }
183    }
184    *p = '\0';     /* null terminate the substring */
185
186
187 #ifdef SSPLIT_VERBOSE
188    if (DEBUG(HDR))
189    {
190       print(x, xi); /* debugging */
191    }
192 #endif /* def SSPLIT_VERBOSE */
193
194
195    /* second pass: copy the relevant pointers to the output vector */
196    last_was_null = 0;
197    for (i=0 ; i < xi; i++)
198    {
199       if (m)
200       {
201          /* there are NO null fields */
202          if (*x[i] == 0)
203          {
204             continue;
205          }
206       }
207       if (vi < n)
208       {
209          v[vi++] = x[i];
210       }
211       else
212       {
213          free(x);
214          return(-1); /* overflow */
215       }
216    }
217    free(x);
218
219 #ifdef SSPLIT_VERBOSE
220    if (DEBUG(HDR))
221    {
222       print(v, vi); /* debugging  */
223    }
224 #endif /* def SSPLIT_VERBOSE */
225
226    return(vi);
227
228 }
229
230
231 /*
232   Local Variables:
233   tab-width: 3
234   end:
235 */