X-Git-Url: http://www.privoxy.org/gitweb/?p=privoxy.git;a=blobdiff_plain;f=ssplit.c;h=01618989fb14c53e1e6d813169ed182da1f174b2;hp=81246fdf9c8a212a4fea7de21c3bf8ecc60b3ab0;hb=cae3149411d1f24e533eb6028e7fe5c3057c4626;hpb=c75584ebcc79f939fb4ec9c8f842cef6692640c7 diff --git a/ssplit.c b/ssplit.c index 81246fdf..01618989 100644 --- a/ssplit.c +++ b/ssplit.c @@ -1,18 +1,18 @@ -const char ssplit_rcs[] = "$Id: ssplit.c,v 1.1 2001/05/13 21:57:07 administrator Exp $"; +const char ssplit_rcs[] = "$Id: ssplit.c,v 1.19 2012/07/23 12:46:40 fabiankeil Exp $"; /********************************************************************* * - * File : $Source: /home/administrator/cvs/ijb/ssplit.c,v $ + * File : $Source: /cvsroot/ijbswa/current/ssplit.c,v $ * - * Purpose : A function to split a string at specified deliminters. + * Purpose : A function to split a string at specified delimiters. * - * Copyright : Written by and Copyright (C) 2001 the SourceForge - * IJBSWA team. http://ijbswa.sourceforge.net + * Copyright : Written by and Copyright (C) 2001-2012 the + * Privoxy team. http://www.privoxy.org/ * * Based on the Internet Junkbuster originally written - * by and Copyright (C) 1997 Anonymous Coders and + * by and Copyright (C) 1997 Anonymous Coders and * Junkbusters Corporation. http://www.junkbusters.com * - * This program is free software; you can redistribute it + * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software * Foundation; either version 2 of the License, or (at @@ -30,201 +30,134 @@ const char ssplit_rcs[] = "$Id: ssplit.c,v 1.1 2001/05/13 21:57:07 administrator * or write to the Free Software Foundation, Inc., 59 * Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - * Revisions : - * $Log: ssplit.c,v $ - * *********************************************************************/ - + #include "config.h" #include -#include - -#ifdef _WIN32 -#include -#endif +#include +#include #include "ssplit.h" #include "miscutil.h" const char ssplit_h_rcs[] = SSPLIT_H_VERSION; -/* Define this for lots of debugging information to stdout */ -/* #define SSPLIT_VERBOSE */ -#ifdef SSPLIT_VERBOSE /********************************************************************* * - * Function : print + * Function : ssplit * - * Description : Debugging routine to spit info on stdout. Not very - * useful to the non-console based IJB compiles. + * Description : Split a string using delimiters in `delim'. Results + * go into `vec'. * * Parameters : - * 1 : v = an array of strings - * 2 : n = number of strings in `v' to dump to stdout - * - * Returns : N/A + * 1 : str = string to split. Will be split in place + * (i.e. do not free until you've finished with vec, + * previous contents will be trashed by the call). + * 2 : delim = array of delimiters (if NULL, uses " \t"). + * 3 : vec[] = results vector (aka. array) [out] + * 4 : vec_len = number of usable slots in the vector (aka. array size) + * + * Returns : -1 => Error: vec_len is too small to hold all the + * data, or str == NULL. + * >=0 => the number of fields put in `vec'. + * On error, vec and str may still have been overwritten. * *********************************************************************/ -static void print(char **v, int n) +int ssplit(char *str, const char *delim, char *vec[], size_t vec_len) { - int i; - printf("dump %d strings\n", n); - for (i=0; i < n; i++) - { - printf("%d '%s'\n", i, v[i]); - } - -} -#endif /* def SSPLIT_VERBOSE */ + unsigned char is_delim[256]; + unsigned char char_type; + int vec_count = 0; + enum char_type { + WANTED = 0, + SEPARATOR = 1, + TERMINATOR = 2, + }; -/********************************************************************* - * - * Function : ssplit - * - * Description : Split a string using deliminters in `c'. Results go - * into `v'. - * - * Parameters : - * 1 : s = string to split - * 2 : c = array of delimiters - * 3 : v[] = results vector (aka. array) - * 4 : n = number of usable slots in the vector (aka. array size) - * 5 : m = consecutive delimiters means multiple fields? - * 6 : l = ignore leading field separators? - * - * Returns : -1 => failure, else the number of fields put in `v'. - * - *********************************************************************/ -int ssplit(char *s, char *c, char *v[], int n, int m, int l) -{ - char t[256]; - char **x = NULL; - int xsize = 0; - unsigned char *p, b; - int xi = 0; - int vi = 0; - int i; - int last_was_null; - - if (!s) + if (!str) { return(-1); } - memset(t, '\0', sizeof(t)); - p = (unsigned char *) c; + /* Build is_delim array */ - if (!p) - { - p = (unsigned char *) " \t"; /* default field separators */ - } + memset(is_delim, '\0', sizeof(is_delim)); - while (*p) + if (!delim) { - t[*p++] = 1; /* separator */ + delim = " \t"; /* default field separators */ } - t['\0'] = 2; /* terminator */ - t['\n'] = 2; /* terminator */ - - p = (unsigned char *) s; - - if (l)/* are we to skip leading separators ? */ + while (*delim) { - while ((b = t[*p]) != 2) - { - if (b != 1) - { - break; - } - p++; - } + is_delim[(unsigned)(unsigned char)*delim++] = SEPARATOR; } - xsize = 256; + is_delim[(unsigned)(unsigned char)'\0'] = TERMINATOR; + is_delim[(unsigned)(unsigned char)'\n'] = TERMINATOR; - x = (char **) zalloc((xsize) * sizeof(char *)); - x[xi++] = (char *) p; /* first pointer is the beginning of string */ + /* Parse string */ - /* first pass: save pointers to the field separators */ - while ((b = t[*p]) != 2) + /* Skip leading separators. XXX: Why do they matter? */ + while (is_delim[(unsigned)(unsigned char)*str] == SEPARATOR) { - if (b == 1) /* if the char is a separator ... */ - { - *p++ = '\0'; /* null terminate the substring */ - - if (xi == xsize) - { - /* get another chunk */ - int new_xsize = xsize + 256; - char **new_x = (char **)zalloc((new_xsize) * sizeof(char *)); - - for (i=0; i < xsize; i++) - { - new_x[i] = x[i]; - } + str++; + } - free(x); - xsize = new_xsize; - x = new_x; - } - x[xi++] = (char *) p; /* save pointer to beginning of next string */ - } - else + /* The first pointer is the beginning of string */ + if (is_delim[(unsigned)(unsigned char)*str] == WANTED) + { + /* + * The first character in this field is not a + * delimiter or the end of string, so save it. + */ + if (vec_count >= vec_len) { - p++; + return(-1); /* overflow */ } + vec[vec_count++] = str; } - *p = '\0'; /* null terminate the substring */ - -#ifdef SSPLIT_VERBOSE - if (DEBUG(HDR)) + while ((char_type = is_delim[(unsigned)(unsigned char)*str]) != TERMINATOR) { - print(x, xi); /* debugging */ - } -#endif /* def SSPLIT_VERBOSE */ + if (char_type == SEPARATOR) + { + /* the char is a separator */ + /* null terminate the substring */ + *str++ = '\0'; - /* second pass: copy the relevant pointers to the output vector */ - last_was_null = 0; - for (i=0 ; i < xi; i++) - { - if (m) - { - /* there are NO null fields */ - if (*x[i] == 0) + /* Check if we want to save this field */ + if (is_delim[(unsigned)(unsigned char)*str] == WANTED) { - continue; + /* + * The first character in this field is not a + * delimiter or the end of string. So save it. + */ + if (vec_count >= vec_len) + { + return(-1); /* overflow */ + } + vec[vec_count++] = str; } } - if (vi < n) - { - v[vi++] = x[i]; - } else { - free(x); - return(-1); /* overflow */ + str++; } } - free(x); - -#ifdef SSPLIT_VERBOSE - if (DEBUG(HDR)) - { - print(v, vi); /* debugging */ - } -#endif /* def SSPLIT_VERBOSE */ - - return(vi); + /* null terminate the substring */ + /* XXX: this shouldn't be necessary, so assert that it isn't. */ + assert(*str == '\0'); + *str = '\0'; + return(vec_count); }