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 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
23 /* All Rights Reserved */
24
25
26 #ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.13 */
27 /* EMACS_MODES: !fill, lnumb, !overwrite, !nodelete, !picture */
28
29 #include "string.h"
30 #include "errno.h"
31 #include "stdlib.h"
32
33 #include "lp.h"
34
35 #if defined(__STDC__)
36 static char *unq_strdup ( char * , char * );
37 #else
38 static char *unq_strdup();
39 #endif
40
41 /**
42 ** getlist() - CONSTRUCT LIST FROM STRING
43 **/
44
45 /*
46 * Any number of characters from "ws", or a single
47 * character from "hardsep", can separate items in the list.
48 */
49
50 char **
51 #if defined(__STDC__)
52 getlist (
53 char * str,
54 char * ws,
55 char * hardsep
56 )
57 #else
58 getlist (str, ws, hardsep)
59 register char *str,
60 *ws;
61 char *hardsep;
62 #endif
63 {
64 register char **list,
65 *p,
66 *sep,
67 c;
68
69 int n,
70 len;
71
72 char buf[10];
73
74
75 if (!str || !*str)
76 return (0);
77
78 /*
79 * Construct in "sep" the full list of characters that
80 * can separate items in the list. Avoid a "malloc()"
81 * if possible.
82 */
83 len = strlen(ws) + strlen(hardsep) + 1;
84 if (len > sizeof(buf)) {
85 if (!(sep = Malloc(len))) {
86 errno = ENOMEM;
87 return (0);
88 }
89 } else
90 sep = buf;
91 strcpy (sep, hardsep);
92 strcat (sep, ws);
93
94 /*
95 * Skip leading white-space.
96 */
97 str += strspn(str, ws);
98 if (!*str)
99 return (0);
100
101 /*
102 * Strip trailing white-space.
103 */
104 p = strchr(str, '\0');
105 while (--p != str && strchr(ws, *p))
106 ;
107 *++p = 0;
108
109 /*
110 * Pass 1: Count the number of items in the list.
111 */
112 for (n = 0, p = str; *p; ) {
113 if ((c = *p++) == '\\')
114 p++;
115 else
116 if (strchr(sep, c)) {
117 n++;
118 p += strspn(p, ws);
119 if (
120 !strchr(hardsep, c)
121 && strchr(hardsep, *p)
122 ) {
123 p++;
124 p += strspn(p, ws);
125 }
126 }
127 }
128
129 /*
130 * Pass 2: Create the list.
131 */
132
133 /*
134 * Pass 1 counted the number of list separaters, so
135 * add 2 to the count (includes 1 for terminating null).
136 */
137 if (!(list = (char **)Malloc((n+2) * sizeof(char *)))) {
138 errno = ENOMEM;
139 goto Done;
140 }
141
142 /*
143 * This loop will copy all but the last item.
144 */
145 for (n = 0, p = str; *p; )
146 if ((c = *p++) == '\\')
147 p++;
148 else
149 if (strchr(sep, c)) {
150
151 p[-1] = 0;
152 list[n++] = unq_strdup(str, sep);
153 p[-1] = c;
154
155 p += strspn(p, ws);
156 if (
157 !strchr(hardsep, c)
158 && strchr(hardsep, *p)
159 ) {
160 p++;
161 p += strspn(p, ws);
162 }
163 str = p;
164
165 }
166
167 list[n++] = unq_strdup(str, sep);
168
169 list[n] = 0;
170
171 Done: if (sep != buf)
172 Free (sep);
173 return (list);
174 }
175
176 /**
177 ** unq_strdup()
178 **/
179
180 static char *
181 #if defined(__STDC__)
182 unq_strdup (
183 char * str,
184 char * sep
185 )
186 #else
187 unq_strdup (str, sep)
188 char *str,
189 *sep;
190 #endif
191 {
192 register int len = 0;
193
194 register char *p,
195 *q,
196 *ret;
197
198
199 for (p = str; *p; p++)
200 if (*p != '\\' || !p[1] || !strchr(sep, p[1]))
201 len++;
202 if (!(q = ret = Malloc(len + 1)))
203 return (0);
204 for (p = str; *p; p++)
205 if (*p != '\\' || !p[1] || !strchr(sep, p[1]))
206 *q++ = *p;
207 *q = 0;
208 return (ret);
209 }