1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22
23 /*
24 * Copyright 2015 Gary Mills
25 */
26
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
29
30
31 /* EMACS_MODES: !fill, lnumb, !overwrite, !nodelete, !picture */
32
33 #include "string.h"
34 #include "errno.h"
35 #include "stdlib.h"
36
37 #include "lp.h"
38
39 #if defined(__STDC__)
40 static char *unq_strdup ( char * , char * );
41 #else
42 static char *unq_strdup();
43 #endif
44
45 /**
46 ** getlist() - CONSTRUCT LIST FROM STRING
47 **/
48
49 /*
50 * Any number of characters from "ws", or a single
51 * character from "hardsep", can separate items in the list.
52 */
53
54 char **
55 #if defined(__STDC__)
getlist(char * str,char * ws,char * hardsep)56 getlist (
57 char * str,
58 char * ws,
59 char * hardsep
60 )
61 #else
62 getlist (str, ws, hardsep)
63 register char *str,
64 *ws;
65 char *hardsep;
66 #endif
67 {
68 register char **list,
69 *p,
70 *sep,
71 c;
72
73 int n,
74 len;
75
76 char buf[10];
77
78
79 char *copy,
80 *begin;
81
82 if (!str || !*str)
83 return (0);
84
85 /*
86 * Construct in "sep" the full list of characters that
87 * can separate items in the list. Avoid a "malloc()"
88 * if possible.
89 */
90 len = strlen(ws) + strlen(hardsep) + 1;
91 if (len > sizeof(buf)) {
92 if (!(sep = Malloc(len))) {
93 errno = ENOMEM;
94 return (0);
95 }
96 } else
97 sep = buf;
98 strcpy (sep, hardsep);
99 strcat (sep, ws);
100
101 /*
102 * Copy the input string because getlist() sometimes writes to it.
103 */
104 if (!(begin = Strdup(str))) {
105 errno = ENOMEM;
106 return (0);
107 }
108 copy = begin;
109
110 /*
111 * Skip leading white-space.
112 */
113 copy += strspn(copy, ws);
114 if (!*copy) {
115 Free (begin);
116 return (0);
117 }
118
119 /*
120 * Strip trailing white-space.
121 */
122 p = strchr(copy, '\0');
123 while (--p != copy && strchr(ws, *p))
124 ;
125 *++p = 0;
126
127 /*
128 * Pass 1: Count the number of items in the list.
129 */
130 for (n = 0, p = copy; *p; ) {
131 if ((c = *p++) == '\\')
132 p++;
133 else
134 if (strchr(sep, c)) {
135 n++;
136 p += strspn(p, ws);
137 if (
138 !strchr(hardsep, c)
139 && strchr(hardsep, *p)
140 ) {
141 p++;
142 p += strspn(p, ws);
143 }
144 }
145 }
146
147 /*
148 * Pass 2: Create the list.
149 */
150
151 /*
152 * Pass 1 counted the number of list separaters, so
153 * add 2 to the count (includes 1 for terminating null).
154 */
155 if (!(list = (char **)Malloc((n+2) * sizeof(char *)))) {
156 errno = ENOMEM;
157 goto Done;
158 }
159
160 /*
161 * This loop will copy all but the last item.
162 */
163 for (n = 0, p = copy; *p; )
164 if ((c = *p++) == '\\')
165 p++;
166 else
167 if (strchr(sep, c)) {
168
169 p[-1] = 0;
170 list[n++] = unq_strdup(copy, sep);
171 p[-1] = c;
172
173 p += strspn(p, ws);
174 if (
175 !strchr(hardsep, c)
176 && strchr(hardsep, *p)
177 ) {
178 p++;
179 p += strspn(p, ws);
180 }
181 copy = p;
182
183 }
184
185 list[n++] = unq_strdup(copy, sep);
186
187 list[n] = 0;
188
189 Done: if (sep != buf)
190 Free (sep);
191 Free (begin);
192 return (list);
193 }
194
195 /**
196 ** unq_strdup()
197 **/
198
199 static char *
200 #if defined(__STDC__)
unq_strdup(char * str,char * sep)201 unq_strdup (
202 char * str,
203 char * sep
204 )
205 #else
206 unq_strdup (str, sep)
207 char *str,
208 *sep;
209 #endif
210 {
211 register int len = 0;
212
213 register char *p,
214 *q,
215 *ret;
216
217
218 for (p = str; *p; p++)
219 if (*p != '\\' || !p[1] || !strchr(sep, p[1]))
220 len++;
221 if (!(q = ret = Malloc(len + 1)))
222 return (0);
223 for (p = str; *p; p++)
224 if (*p != '\\' || !p[1] || !strchr(sep, p[1]))
225 *q++ = *p;
226 *q = 0;
227 return (ret);
228 }
229