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__) 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__) 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