4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
30 #pragma ident "%Z%%M% %I% %E% SMI"
32 #include <sys/types.h>
38 /* global to this file */
40 #define STRALLOC 128UL
41 #define MAXINCR 250000UL
43 /* buffer pool for allocating string structures */
48 static stralloc
*freep
= NULL
;
50 /* pool of freed strings */
51 static string
*freed
= NULL
;
52 static string
*s_alloc(void);
53 static void s_simplegrow(string
*, size_t);
59 sp
->ptr
= (char *)freed
;
64 /* allocate a string head */
68 if (freep
== NULL
|| freep
->o
>= STRALLOC
) {
69 freep
= (stralloc
*)malloc(sizeof (stralloc
));
71 perror("allocating string");
76 return (&(freep
->s
[freep
->o
++]));
79 /* create a new `short' string */
88 freed
= (string
*)(freed
->ptr
);
93 sp
->base
= sp
->ptr
= malloc(STRLEN
);
94 if (sp
->base
== NULL
) {
95 perror("allocating string");
98 sp
->end
= sp
->base
+ STRLEN
;
103 /* grow a string's allocation by at least `incr' bytes */
105 s_simplegrow(string
*sp
, size_t incr
)
111 * take a larger increment to avoid mallocing too often
113 if (((sp
->end
- sp
->base
) < incr
) && (MAXINCR
< incr
))
114 size
= (sp
->end
- sp
->base
) + incr
;
115 else if ((sp
->end
- sp
->base
) > MAXINCR
)
116 size
= (sp
->end
- sp
->base
) + MAXINCR
;
118 size
= (size_t)2 * (sp
->end
- sp
->base
);
120 cp
= realloc(sp
->base
, size
);
125 sp
->ptr
= (sp
->ptr
- sp
->base
) + cp
;
130 /* grow a string's allocation */
132 s_grow(string
*sp
, int c
)
134 s_simplegrow(sp
, (size_t)2);
139 /* return a string containing a character array (this had better not grow) */
141 s_array(char *cp
, size_t len
)
143 string
*sp
= s_alloc();
145 sp
->base
= sp
->ptr
= cp
;
146 sp
->end
= sp
->base
+ len
;
150 /* return a string containing a copy of the passed char array */
159 sp
->base
= malloc(len
);
160 if (sp
->base
== NULL
) {
164 sp
->end
= sp
->base
+ len
; /* point past end of allocation */
165 (void) strcpy(sp
->base
, cp
);
166 sp
->ptr
= sp
->end
- (size_t)1; /* point to NULL terminator */
170 /* convert string to lower case */
172 s_tolower(string
*sp
)
176 for (cp
= sp
->ptr
; *cp
; cp
++)
181 s_skipwhite(string
*sp
)
183 while (isspace(*sp
->ptr
))
187 /* append a char array to a string */
189 s_append(string
*to
, char *from
)
195 for (; *from
; from
++)
196 s_putc(to
, (int)(unsigned int)*from
);
202 * Append a logical input sequence into a string. Ignore blank and
203 * comment lines. Backslash preceding newline indicates continuation.
204 * The `lineortoken' variable indicates whether the sequence to beinput
205 * is a whitespace delimited token or a whole line.
207 * FILE *fp; stream to read from
208 * string *to; where to put token
209 * int lineortoken; how the sequence terminates
211 * Returns a pointer to the string or NULL. Trailing newline is stripped off.
214 s_seq_read(FILE *fp
, string
*to
, int lineortoken
)
222 /* get rid of leading goo */
232 while ((c
= getc(fp
)) != '\n' && c
!= EOF
)
250 /* gather up a sequence */
256 s_putc(to
, (int)(unsigned int)'\\');
268 if (lineortoken
== TOKEN
) {
282 s_tok(string
*from
, char *split
)
284 char *splitend
= strpbrk(from
->ptr
, split
);
287 string
*to
= s_new();
288 for (; from
->ptr
< splitend
; ) {
289 s_putc(to
, (int)(unsigned int)*from
->ptr
);
294 /* LINT: warning due to lint bug */
295 from
->ptr
+= strspn(from
->ptr
, split
);
299 else if (from
->ptr
[0]) {
300 string
*to
= s_clone(from
);
311 * Append an input line to a string.
313 * Returns a pointer to the string (or NULL).
314 * Trailing newline is left on.
317 s_read_line(FILE *fp
, string
*to
)
325 if (feof(fp
) || (c
= getc(fp
)) == EOF
)
328 /* gather up a line */
334 return (to
->ptr
- len
);
336 s_putc(to
, (int)(unsigned int)'\n');
338 return (to
->ptr
- len
);
351 s_read_to_eof(FILE *fp
, string
*to
)
361 /* allocate room for a full buffer */
362 have
= to
->end
- to
->ptr
;
364 s_simplegrow(to
, (size_t)4096);
366 /* get a buffers worth */
367 have
= to
->end
- to
->ptr
;
368 got
= fread(to
->ptr
, (size_t)1, have
, fp
);
369 if (got
== (size_t)0)
371 /* LINT: warning due to lint bug */
375 /* null terminate the line */
377 return (to
->ptr
- to
->base
);
381 * Get the next field from a string. The field is delimited by white space,
382 * single or double quotes.
384 * string *from; string to parse
385 * string *to; where to put parsed token
388 s_parse(string
*from
, string
*to
)
390 while (isspace(*from
->ptr
))
392 if (*from
->ptr
== '\0')
396 if (*from
->ptr
== '\'') {
398 for (; *from
->ptr
!= '\'' && *from
->ptr
!= '\0'; from
->ptr
++)
399 s_putc(to
, (int)(unsigned int)*from
->ptr
);
400 if (*from
->ptr
== '\'')
402 } else if (*from
->ptr
== '"') {
404 for (; *from
->ptr
!= '"' && *from
->ptr
!= '\0'; from
->ptr
++)
405 s_putc(to
, (int)(unsigned int)*from
->ptr
);
406 if (*from
->ptr
== '"')
409 for (; !isspace(*from
->ptr
) && *from
->ptr
!= '\0'; from
->ptr
++)
410 s_putc(to
, (int)(unsigned int)*from
->ptr
);