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