1 /**************************************************************************************************
2 	$Id: strsep_quotes.c,v 1.1 2005/04/28 18:43:14 bboy Exp $
3 
4 	strsep_quotes.c: strsep()-style function that obeys quoted strings.
5 
6 	Copyright (C) 2002-2005  Don Moore <bboy@bboy.net>
7 
8 	This program is free software; you can redistribute it and/or modify
9 	it under the terms of the GNU General Public License as published by
10 	the Free Software Foundation; either version 2 of the License, or
11 	(at Your option) any later version.
12 
13 	This program is distributed in the hope that it will be useful,
14 	but WITHOUT ANY WARRANTY; without even the implied warranty of
15 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 	GNU General Public License for more details.
17 
18 	You should have received a copy of the GNU General Public License
19 	along with this program; if not, write to the Free Software
20 	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21 **************************************************************************************************/
22 
23 #include "mydnsutil.h"
24 
25 
26 /**************************************************************************************************
27 	STRSEP_QUOTES
28 	Like strsep(), but considers strings inside quotes to be single tokens, even if there are
29 	spaces inside.  The delimiters are assumed to be isspace() characters.
30 **************************************************************************************************/
31 char *
strsep_quotes(char ** stringp,char * dest,size_t destlen)32 strsep_quotes(char **stringp, char *dest, size_t destlen) {
33   register char *end;
34   char	*begin = *stringp;
35   char	*d = dest;
36   char	quote;								/* Quote character found */
37 
38   /* Advance 'begin' past leading spaces */
39   for (; *begin && isspace(*begin); begin++)
40     /* DONOTHING */;
41   if (!*begin)
42     return (NULL);
43 
44   /* If 'begin' is a quote, advance searching for matching quote, otherwise advance looking for
45      whitespace */
46   if (*begin == '\'' || *begin == '"') {
47     quote = *begin++;
48 
49     /* We need to be sure to ignore back-quoted quotation marks in here */
50     for (end = begin; *end && ((d - dest) < (int)destlen - 1); end++) {
51       if (*end == quote)
52 	break;
53       if ((*end == '\\') && (end > begin) && (end[1] == quote))
54 	end++;
55       *d++ = *end;
56     }
57   } else {
58     for (end = begin; *end && !isspace(*end) && ((d - dest) < (int)destlen - 1); end++)
59       *d++ = *end;
60   }
61 
62   /* Terminate 'dest' */
63   *d = '\0';
64 
65   /* Terminate token and set *stringp past NUL */
66   *end++ = '\0';
67   for (; *end && isspace(*end); end++) /* DONOTHING */;
68   *stringp = end;
69 
70   return (begin);
71 }
72 
73 /*
74  * Split off first word from the string passed in string!
75  * Return string length found with quotes stripped as result.
76  * Advance stringp to point beyond string removed.
77  * Write string without quotes into dest dynamically allocated!
78  * DO NOT ALTER the input string!
79  */
80 int
strsep_quotes2(char ** stringp,char ** dest)81 strsep_quotes2(char **stringp, char **dest) {
82   register char *end;
83   char		*begin = *stringp;
84   char		quote = '\0';					/* Quote character found */
85   size_t	destlen = 0;
86 
87   *dest = NULL;
88 
89   /* Advance 'begin' past leading spaces */
90   for (; *begin && isspace(*begin); begin++) /* DONOTHING */;
91 
92   if (!*begin) return (0); /* String is just white space or empty */
93 
94   /*
95   ** If 'begin' is a quote, advance searching for matching quote,
96   ** otherwise advance looking for whitespace
97   ** This does not allow embedded strings within other characters!
98   */
99   if (*begin == '\'' || *begin == '"') {
100     quote = *begin++; /* Advance over opening quote */
101   }
102 
103   for (end = begin; *end; end++) {
104     if (quote == '\0') {
105       if (isspace(*end)) break; /* Space terminated */
106       continue;
107     }
108 
109     /* We need to be sure to ignore back-quoted quotation marks in here */
110     if (*end == quote) break; /* Matching quote */
111     if ((*end == '\\') && (end > begin) && (end[1] == quote)) end++; /* Skip quoting '\' */
112   }
113 
114   destlen = end - begin;
115 
116   *dest = STRNDUP(begin, destlen);
117 //  *dest[destlen] = '\0';
118   (*dest)[destlen] = '\0';
119 
120    if((*end)&&(quote!='\0'))
121    end++;
122    for (; *end && isspace(*end); end++) /* DONOTHING */;
123 
124   /* Terminate token and set *stringp past NUL */
125   *stringp = end;
126 
127   return (destlen);
128 }
129 /*--- strsep_quotes() ---------------------------------------------------------------------------*/
130 
131 /* vi:set ts=3: */
132