Shorten ssplit()'s prototype by removing the last two arguments
[privoxy.git] / ssplit.c
1 const char ssplit_rcs[] = "$Id: ssplit.c,v 1.13 2012/03/09 16:23:50 fabiankeil Exp $";
2 /*********************************************************************
3  *
4  * File        :  $Source: /cvsroot/ijbswa/current/ssplit.c,v $
5  *
6  * Purpose     :  A function to split a string at specified delimiters.
7  *
8  * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
9  *                Privoxy team. http://www.privoxy.org/
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  *********************************************************************/
34
35
36 #include "config.h"
37
38 #include <string.h>
39 #include <stdlib.h>
40
41 #include "ssplit.h"
42 #include "miscutil.h"
43
44 const char ssplit_h_rcs[] = SSPLIT_H_VERSION;
45
46 /* Define this for lots of debugging information to stdout */
47 #undef SSPLIT_VERBOSE
48 /* #define SSPLIT_VERBOSE 1 */
49
50
51 /*********************************************************************
52  *
53  * Function    :  ssplit
54  *
55  * Description :  Split a string using delimiters in `delim'.  Results
56  *                go into `vec'.
57  *
58  * Parameters  :
59  *          1  :  str = string to split.  Will be split in place
60  *                (i.e. do not free until you've finished with vec,
61  *                previous contents will be trashed by the call).
62  *          2  :  delim = array of delimiters (if NULL, uses " \t").
63  *          3  :  vec[] = results vector (aka. array) [out]
64  *          4  :  vec_len = number of usable slots in the vector (aka. array size)
65  *
66  * Returns     :  -1 => Error: vec_len is too small to hold all the
67  *                      data, or str == NULL.
68  *                >=0 => the number of fields put in `vec'.
69  *                On error, vec and str may still have been overwritten.
70  *
71  *********************************************************************/
72 int ssplit(char *str, const char *delim, char *vec[], size_t vec_len)
73 {
74    unsigned char is_delim[256];
75    unsigned char char_type;
76    int vec_count = 0;
77
78    if (!str)
79    {
80       return(-1);
81    }
82
83
84    /* Build is_delim array */
85
86    memset(is_delim, '\0', sizeof(is_delim));
87
88    if (!delim)
89    {
90       delim = " \t";  /* default field separators */
91    }
92
93    while (*delim)
94    {
95       is_delim[(unsigned)(unsigned char)*delim++] = 1;   /* separator  */
96    }
97
98    is_delim[(unsigned)(unsigned char)'\0'] = 2;   /* terminator */
99    is_delim[(unsigned)(unsigned char)'\n'] = 2;   /* terminator */
100
101
102    /* Parse string */
103
104    /* Skip leading separators. XXX: Why do they matter? */
105    while (is_delim[(unsigned)(unsigned char)*str] == 1)
106    {
107       str++;
108    }
109
110    /* The first pointer is the beginning of string */
111    if (is_delim[(unsigned)(unsigned char)*str] == 0)
112    {
113       /*
114        * The first character in this field is not a
115        * delimiter or the end of string, so save it.
116        */
117       if (vec_count >= vec_len)
118       {
119          return(-1); /* overflow */
120       }
121       vec[vec_count++] = (char *) str;
122    }
123
124    while ((char_type = is_delim[(unsigned)(unsigned char)*str]) != 2)
125    {
126       if (char_type == 1)
127       {
128          /* the char is a separator */
129
130          /* null terminate the substring */
131          *str++ = '\0';
132
133          /* Check if we want to save this field */
134          if (is_delim[(unsigned)(unsigned char)*str] == 0)
135          {
136             /*
137              * The first character in this field is not a
138              * delimiter or the end of string. So save it.
139              */
140             if (vec_count >= vec_len)
141             {
142                return(-1); /* overflow */
143             }
144             vec[vec_count++] = (char *) str;
145          }
146       }
147       else
148       {
149          str++;
150       }
151    }
152    *str = '\0';     /* null terminate the substring */
153
154 #ifdef SSPLIT_VERBOSE
155    {
156       int i;
157       printf("dump %d strings\n", vec_count);
158       for (i = 0; i < vec_count; i++)
159       {
160          printf("%d '%s'\n", i, vec[i]);
161       }
162    }
163 #endif /* def SSPLIT_VERBOSE */
164
165    return(vec_count);
166 }
167
168
169 /*
170   Local Variables:
171   tab-width: 3
172   end:
173 */