17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7257d1b4Sraf * Common Development and Distribution License (the "License"). 6*7257d1b4Sraf * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 21e8031f0aSraf 227c478bd9Sstevel@tonic-gate /* 23*7257d1b4Sraf * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24e8031f0aSraf * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 27*7257d1b4Sraf /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28*7257d1b4Sraf /* All Rights Reserved */ 297c478bd9Sstevel@tonic-gate 30*7257d1b4Sraf #pragma ident "%Z%%M% %I% %E% SMI" 31*7257d1b4Sraf 327c478bd9Sstevel@tonic-gate #include <sys/types.h> 337c478bd9Sstevel@tonic-gate #include <stdio.h> 347c478bd9Sstevel@tonic-gate #include <ctype.h> 357c478bd9Sstevel@tonic-gate #include "s_string.h" 367c478bd9Sstevel@tonic-gate #include <stdlib.h> 377c478bd9Sstevel@tonic-gate 387c478bd9Sstevel@tonic-gate /* global to this file */ 397c478bd9Sstevel@tonic-gate #define STRLEN 128UL 407c478bd9Sstevel@tonic-gate #define STRALLOC 128UL 417c478bd9Sstevel@tonic-gate #define MAXINCR 250000UL 427c478bd9Sstevel@tonic-gate 437c478bd9Sstevel@tonic-gate /* buffer pool for allocating string structures */ 447c478bd9Sstevel@tonic-gate typedef struct { 457c478bd9Sstevel@tonic-gate string s[STRALLOC]; 467c478bd9Sstevel@tonic-gate size_t o; 477c478bd9Sstevel@tonic-gate } stralloc; 487c478bd9Sstevel@tonic-gate static stralloc *freep = NULL; 497c478bd9Sstevel@tonic-gate 507c478bd9Sstevel@tonic-gate /* pool of freed strings */ 517c478bd9Sstevel@tonic-gate static string *freed = NULL; 527c478bd9Sstevel@tonic-gate static string *s_alloc(void); 537c478bd9Sstevel@tonic-gate static void s_simplegrow(string *, size_t); 547c478bd9Sstevel@tonic-gate 557c478bd9Sstevel@tonic-gate void 567c478bd9Sstevel@tonic-gate s_free(string *sp) 577c478bd9Sstevel@tonic-gate { 587c478bd9Sstevel@tonic-gate if (sp != NULL) { 597c478bd9Sstevel@tonic-gate sp->ptr = (char *)freed; 607c478bd9Sstevel@tonic-gate freed = sp; 617c478bd9Sstevel@tonic-gate } 627c478bd9Sstevel@tonic-gate } 637c478bd9Sstevel@tonic-gate 647c478bd9Sstevel@tonic-gate /* allocate a string head */ 657c478bd9Sstevel@tonic-gate static string * 667c478bd9Sstevel@tonic-gate s_alloc(void) 677c478bd9Sstevel@tonic-gate { 687c478bd9Sstevel@tonic-gate if (freep == NULL || freep->o >= STRALLOC) { 697c478bd9Sstevel@tonic-gate freep = (stralloc *)malloc(sizeof (stralloc)); 707c478bd9Sstevel@tonic-gate if (freep == NULL) { 717c478bd9Sstevel@tonic-gate perror("allocating string"); 727c478bd9Sstevel@tonic-gate exit(1); 737c478bd9Sstevel@tonic-gate } 747c478bd9Sstevel@tonic-gate freep->o = (size_t)0; 757c478bd9Sstevel@tonic-gate } 767c478bd9Sstevel@tonic-gate return (&(freep->s[freep->o++])); 777c478bd9Sstevel@tonic-gate } 787c478bd9Sstevel@tonic-gate 797c478bd9Sstevel@tonic-gate /* create a new `short' string */ 807c478bd9Sstevel@tonic-gate string * 817c478bd9Sstevel@tonic-gate s_new(void) 827c478bd9Sstevel@tonic-gate { 837c478bd9Sstevel@tonic-gate string *sp; 847c478bd9Sstevel@tonic-gate 857c478bd9Sstevel@tonic-gate if (freed != NULL) { 867c478bd9Sstevel@tonic-gate sp = freed; 877c478bd9Sstevel@tonic-gate /*LINTED*/ 887c478bd9Sstevel@tonic-gate freed = (string *)(freed->ptr); 897c478bd9Sstevel@tonic-gate sp->ptr = sp->base; 907c478bd9Sstevel@tonic-gate return (sp); 917c478bd9Sstevel@tonic-gate } 927c478bd9Sstevel@tonic-gate sp = s_alloc(); 937c478bd9Sstevel@tonic-gate sp->base = sp->ptr = malloc(STRLEN); 947c478bd9Sstevel@tonic-gate if (sp->base == NULL) { 957c478bd9Sstevel@tonic-gate perror("allocating string"); 967c478bd9Sstevel@tonic-gate exit(1); 977c478bd9Sstevel@tonic-gate } 987c478bd9Sstevel@tonic-gate sp->end = sp->base + STRLEN; 997c478bd9Sstevel@tonic-gate s_terminate(sp); 1007c478bd9Sstevel@tonic-gate return (sp); 1017c478bd9Sstevel@tonic-gate } 1027c478bd9Sstevel@tonic-gate 1037c478bd9Sstevel@tonic-gate /* grow a string's allocation by at least `incr' bytes */ 1047c478bd9Sstevel@tonic-gate static void 1057c478bd9Sstevel@tonic-gate s_simplegrow(string *sp, size_t incr) 1067c478bd9Sstevel@tonic-gate { 1077c478bd9Sstevel@tonic-gate char *cp; 1087c478bd9Sstevel@tonic-gate size_t size; 1097c478bd9Sstevel@tonic-gate 1107c478bd9Sstevel@tonic-gate /* 1117c478bd9Sstevel@tonic-gate * take a larger increment to avoid mallocing too often 1127c478bd9Sstevel@tonic-gate */ 1137c478bd9Sstevel@tonic-gate if (((sp->end - sp->base) < incr) && (MAXINCR < incr)) 1147c478bd9Sstevel@tonic-gate size = (sp->end - sp->base) + incr; 1157c478bd9Sstevel@tonic-gate else if ((sp->end - sp->base) > MAXINCR) 1167c478bd9Sstevel@tonic-gate size = (sp->end - sp->base) + MAXINCR; 1177c478bd9Sstevel@tonic-gate else 1187c478bd9Sstevel@tonic-gate size = (size_t)2 * (sp->end - sp->base); 1197c478bd9Sstevel@tonic-gate 1207c478bd9Sstevel@tonic-gate cp = realloc(sp->base, size); 1217c478bd9Sstevel@tonic-gate if (cp == NULL) { 1227c478bd9Sstevel@tonic-gate perror("string:"); 1237c478bd9Sstevel@tonic-gate exit(1); 1247c478bd9Sstevel@tonic-gate } 1257c478bd9Sstevel@tonic-gate sp->ptr = (sp->ptr - sp->base) + cp; 1267c478bd9Sstevel@tonic-gate sp->end = cp + size; 1277c478bd9Sstevel@tonic-gate sp->base = cp; 1287c478bd9Sstevel@tonic-gate } 1297c478bd9Sstevel@tonic-gate 1307c478bd9Sstevel@tonic-gate /* grow a string's allocation */ 1317c478bd9Sstevel@tonic-gate int 1327c478bd9Sstevel@tonic-gate s_grow(string *sp, int c) 1337c478bd9Sstevel@tonic-gate { 1347c478bd9Sstevel@tonic-gate s_simplegrow(sp, (size_t)2); 1357c478bd9Sstevel@tonic-gate s_putc(sp, c); 1367c478bd9Sstevel@tonic-gate return (c); 1377c478bd9Sstevel@tonic-gate } 1387c478bd9Sstevel@tonic-gate 1397c478bd9Sstevel@tonic-gate /* return a string containing a character array (this had better not grow) */ 1407c478bd9Sstevel@tonic-gate string * 1417c478bd9Sstevel@tonic-gate s_array(char *cp, size_t len) 1427c478bd9Sstevel@tonic-gate { 1437c478bd9Sstevel@tonic-gate string *sp = s_alloc(); 1447c478bd9Sstevel@tonic-gate 1457c478bd9Sstevel@tonic-gate sp->base = sp->ptr = cp; 1467c478bd9Sstevel@tonic-gate sp->end = sp->base + len; 1477c478bd9Sstevel@tonic-gate return (sp); 1487c478bd9Sstevel@tonic-gate } 1497c478bd9Sstevel@tonic-gate 1507c478bd9Sstevel@tonic-gate /* return a string containing a copy of the passed char array */ 1517c478bd9Sstevel@tonic-gate string* 1527c478bd9Sstevel@tonic-gate s_copy(char *cp) 1537c478bd9Sstevel@tonic-gate { 1547c478bd9Sstevel@tonic-gate string *sp; 1557c478bd9Sstevel@tonic-gate size_t len; 1567c478bd9Sstevel@tonic-gate 1577c478bd9Sstevel@tonic-gate sp = s_alloc(); 1587c478bd9Sstevel@tonic-gate len = strlen(cp)+1; 1597c478bd9Sstevel@tonic-gate sp->base = malloc(len); 1607c478bd9Sstevel@tonic-gate if (sp->base == NULL) { 1617c478bd9Sstevel@tonic-gate perror("string:"); 1627c478bd9Sstevel@tonic-gate exit(1); 1637c478bd9Sstevel@tonic-gate } 1647c478bd9Sstevel@tonic-gate sp->end = sp->base + len; /* point past end of allocation */ 1657c478bd9Sstevel@tonic-gate (void) strcpy(sp->base, cp); 1667c478bd9Sstevel@tonic-gate sp->ptr = sp->end - (size_t)1; /* point to NULL terminator */ 1677c478bd9Sstevel@tonic-gate return (sp); 1687c478bd9Sstevel@tonic-gate } 1697c478bd9Sstevel@tonic-gate 1707c478bd9Sstevel@tonic-gate /* convert string to lower case */ 1717c478bd9Sstevel@tonic-gate void 1727c478bd9Sstevel@tonic-gate s_tolower(string *sp) 1737c478bd9Sstevel@tonic-gate { 1747c478bd9Sstevel@tonic-gate char *cp; 1757c478bd9Sstevel@tonic-gate 1767c478bd9Sstevel@tonic-gate for (cp = sp->ptr; *cp; cp++) 1777c478bd9Sstevel@tonic-gate *cp = tolower(*cp); 1787c478bd9Sstevel@tonic-gate } 1797c478bd9Sstevel@tonic-gate 1807c478bd9Sstevel@tonic-gate void 1817c478bd9Sstevel@tonic-gate s_skipwhite(string *sp) 1827c478bd9Sstevel@tonic-gate { 1837c478bd9Sstevel@tonic-gate while (isspace(*sp->ptr)) 1847c478bd9Sstevel@tonic-gate s_skipc(sp); 1857c478bd9Sstevel@tonic-gate } 1867c478bd9Sstevel@tonic-gate 1877c478bd9Sstevel@tonic-gate /* append a char array to a string */ 1887c478bd9Sstevel@tonic-gate string * 1897c478bd9Sstevel@tonic-gate s_append(string *to, char *from) 1907c478bd9Sstevel@tonic-gate { 1917c478bd9Sstevel@tonic-gate if (to == NULL) 1927c478bd9Sstevel@tonic-gate to = s_new(); 1937c478bd9Sstevel@tonic-gate if (from == NULL) 1947c478bd9Sstevel@tonic-gate return (to); 1957c478bd9Sstevel@tonic-gate for (; *from; from++) 1967c478bd9Sstevel@tonic-gate s_putc(to, (int)(unsigned int)*from); 1977c478bd9Sstevel@tonic-gate s_terminate(to); 1987c478bd9Sstevel@tonic-gate return (to); 1997c478bd9Sstevel@tonic-gate } 2007c478bd9Sstevel@tonic-gate 2017c478bd9Sstevel@tonic-gate /* 2027c478bd9Sstevel@tonic-gate * Append a logical input sequence into a string. Ignore blank and 2037c478bd9Sstevel@tonic-gate * comment lines. Backslash preceding newline indicates continuation. 2047c478bd9Sstevel@tonic-gate * The `lineortoken' variable indicates whether the sequence to beinput 2057c478bd9Sstevel@tonic-gate * is a whitespace delimited token or a whole line. 2067c478bd9Sstevel@tonic-gate * 2077c478bd9Sstevel@tonic-gate * FILE *fp; stream to read from 2087c478bd9Sstevel@tonic-gate * string *to; where to put token 2097c478bd9Sstevel@tonic-gate * int lineortoken; how the sequence terminates 2107c478bd9Sstevel@tonic-gate * 2117c478bd9Sstevel@tonic-gate * Returns a pointer to the string or NULL. Trailing newline is stripped off. 2127c478bd9Sstevel@tonic-gate */ 2137c478bd9Sstevel@tonic-gate string * 2147c478bd9Sstevel@tonic-gate s_seq_read(FILE *fp, string *to, int lineortoken) 2157c478bd9Sstevel@tonic-gate { 2167c478bd9Sstevel@tonic-gate int c; 2177c478bd9Sstevel@tonic-gate int done = 0; 2187c478bd9Sstevel@tonic-gate 2197c478bd9Sstevel@tonic-gate if (feof(fp)) 2207c478bd9Sstevel@tonic-gate return (NULL); 2217c478bd9Sstevel@tonic-gate 2227c478bd9Sstevel@tonic-gate /* get rid of leading goo */ 2237c478bd9Sstevel@tonic-gate do { 2247c478bd9Sstevel@tonic-gate c = getc(fp); 2257c478bd9Sstevel@tonic-gate switch (c) { 2267c478bd9Sstevel@tonic-gate case EOF: 2277c478bd9Sstevel@tonic-gate if (to != NULL) 2287c478bd9Sstevel@tonic-gate s_terminate(to); 2297c478bd9Sstevel@tonic-gate return (NULL); 2307c478bd9Sstevel@tonic-gate case '#': 2317c478bd9Sstevel@tonic-gate /*LINTED*/ 232*7257d1b4Sraf while ((c = getc(fp)) != '\n' && c != EOF) 233*7257d1b4Sraf continue; 2347c478bd9Sstevel@tonic-gate break; 2357c478bd9Sstevel@tonic-gate case ' ': 2367c478bd9Sstevel@tonic-gate case '\t': 2377c478bd9Sstevel@tonic-gate case '\n': 2387c478bd9Sstevel@tonic-gate case '\r': 2397c478bd9Sstevel@tonic-gate case '\f': 2407c478bd9Sstevel@tonic-gate break; 2417c478bd9Sstevel@tonic-gate default: 2427c478bd9Sstevel@tonic-gate done = 1; 2437c478bd9Sstevel@tonic-gate break; 2447c478bd9Sstevel@tonic-gate } 2457c478bd9Sstevel@tonic-gate } while (!done); 2467c478bd9Sstevel@tonic-gate 2477c478bd9Sstevel@tonic-gate if (to == NULL) 2487c478bd9Sstevel@tonic-gate to = s_new(); 2497c478bd9Sstevel@tonic-gate 2507c478bd9Sstevel@tonic-gate /* gather up a sequence */ 2517c478bd9Sstevel@tonic-gate for (;;) { 2527c478bd9Sstevel@tonic-gate switch (c) { 2537c478bd9Sstevel@tonic-gate case '\\': 2547c478bd9Sstevel@tonic-gate c = getc(fp); 2557c478bd9Sstevel@tonic-gate if (c != '\n') { 2567c478bd9Sstevel@tonic-gate s_putc(to, (int)(unsigned int)'\\'); 2577c478bd9Sstevel@tonic-gate s_putc(to, c); 2587c478bd9Sstevel@tonic-gate } 2597c478bd9Sstevel@tonic-gate break; 2607c478bd9Sstevel@tonic-gate case EOF: 2617c478bd9Sstevel@tonic-gate case '\r': 2627c478bd9Sstevel@tonic-gate case '\f': 2637c478bd9Sstevel@tonic-gate case '\n': 2647c478bd9Sstevel@tonic-gate s_terminate(to); 2657c478bd9Sstevel@tonic-gate return (to); 2667c478bd9Sstevel@tonic-gate case ' ': 2677c478bd9Sstevel@tonic-gate case '\t': 2687c478bd9Sstevel@tonic-gate if (lineortoken == TOKEN) { 2697c478bd9Sstevel@tonic-gate s_terminate(to); 2707c478bd9Sstevel@tonic-gate return (to); 2717c478bd9Sstevel@tonic-gate } 2727c478bd9Sstevel@tonic-gate /* fall through */ 2737c478bd9Sstevel@tonic-gate default: 2747c478bd9Sstevel@tonic-gate s_putc(to, c); 2757c478bd9Sstevel@tonic-gate break; 2767c478bd9Sstevel@tonic-gate } 2777c478bd9Sstevel@tonic-gate c = getc(fp); 2787c478bd9Sstevel@tonic-gate } 2797c478bd9Sstevel@tonic-gate } 2807c478bd9Sstevel@tonic-gate 2817c478bd9Sstevel@tonic-gate string * 2827c478bd9Sstevel@tonic-gate s_tok(string *from, char *split) 2837c478bd9Sstevel@tonic-gate { 2847c478bd9Sstevel@tonic-gate char *splitend = strpbrk(from->ptr, split); 2857c478bd9Sstevel@tonic-gate 2867c478bd9Sstevel@tonic-gate if (splitend) { 2877c478bd9Sstevel@tonic-gate string *to = s_new(); 2887c478bd9Sstevel@tonic-gate for (; from->ptr < splitend; ) { 2897c478bd9Sstevel@tonic-gate s_putc(to, (int)(unsigned int)*from->ptr); 2907c478bd9Sstevel@tonic-gate from->ptr++; 2917c478bd9Sstevel@tonic-gate } 2927c478bd9Sstevel@tonic-gate s_terminate(to); 2937c478bd9Sstevel@tonic-gate s_restart(to); 2947c478bd9Sstevel@tonic-gate /* LINT: warning due to lint bug */ 2957c478bd9Sstevel@tonic-gate from->ptr += strspn(from->ptr, split); 2967c478bd9Sstevel@tonic-gate return (to); 2977c478bd9Sstevel@tonic-gate } 2987c478bd9Sstevel@tonic-gate 2997c478bd9Sstevel@tonic-gate else if (from->ptr[0]) { 3007c478bd9Sstevel@tonic-gate string *to = s_clone(from); 3017c478bd9Sstevel@tonic-gate while (*from->ptr) 3027c478bd9Sstevel@tonic-gate from->ptr++; 3037c478bd9Sstevel@tonic-gate return (to); 3047c478bd9Sstevel@tonic-gate } 3057c478bd9Sstevel@tonic-gate 3067c478bd9Sstevel@tonic-gate else 3077c478bd9Sstevel@tonic-gate return (NULL); 3087c478bd9Sstevel@tonic-gate } 3097c478bd9Sstevel@tonic-gate 3107c478bd9Sstevel@tonic-gate /* 3117c478bd9Sstevel@tonic-gate * Append an input line to a string. 3127c478bd9Sstevel@tonic-gate * 3137c478bd9Sstevel@tonic-gate * Returns a pointer to the string (or NULL). 3147c478bd9Sstevel@tonic-gate * Trailing newline is left on. 3157c478bd9Sstevel@tonic-gate */ 3167c478bd9Sstevel@tonic-gate char * 3177c478bd9Sstevel@tonic-gate s_read_line(FILE *fp, string *to) 3187c478bd9Sstevel@tonic-gate { 3197c478bd9Sstevel@tonic-gate int c; 3207c478bd9Sstevel@tonic-gate size_t len = 0; 3217c478bd9Sstevel@tonic-gate 3227c478bd9Sstevel@tonic-gate s_terminate(to); 3237c478bd9Sstevel@tonic-gate 3247c478bd9Sstevel@tonic-gate /* end of input */ 3257c478bd9Sstevel@tonic-gate if (feof(fp) || (c = getc(fp)) == EOF) 3267c478bd9Sstevel@tonic-gate return (NULL); 3277c478bd9Sstevel@tonic-gate 3287c478bd9Sstevel@tonic-gate /* gather up a line */ 3297c478bd9Sstevel@tonic-gate for (; ; ) { 3307c478bd9Sstevel@tonic-gate len++; 3317c478bd9Sstevel@tonic-gate switch (c) { 3327c478bd9Sstevel@tonic-gate case EOF: 3337c478bd9Sstevel@tonic-gate s_terminate(to); 3347c478bd9Sstevel@tonic-gate return (to->ptr - len); 3357c478bd9Sstevel@tonic-gate case '\n': 3367c478bd9Sstevel@tonic-gate s_putc(to, (int)(unsigned int)'\n'); 3377c478bd9Sstevel@tonic-gate s_terminate(to); 3387c478bd9Sstevel@tonic-gate return (to->ptr - len); 3397c478bd9Sstevel@tonic-gate default: 3407c478bd9Sstevel@tonic-gate s_putc(to, c); 3417c478bd9Sstevel@tonic-gate break; 3427c478bd9Sstevel@tonic-gate } 3437c478bd9Sstevel@tonic-gate c = getc(fp); 3447c478bd9Sstevel@tonic-gate } 3457c478bd9Sstevel@tonic-gate } 3467c478bd9Sstevel@tonic-gate 3477c478bd9Sstevel@tonic-gate /* 3487c478bd9Sstevel@tonic-gate * Read till eof 3497c478bd9Sstevel@tonic-gate */ 3507c478bd9Sstevel@tonic-gate size_t 3517c478bd9Sstevel@tonic-gate s_read_to_eof(FILE *fp, string *to) 3527c478bd9Sstevel@tonic-gate { 3537c478bd9Sstevel@tonic-gate size_t got; 3547c478bd9Sstevel@tonic-gate size_t have; 3557c478bd9Sstevel@tonic-gate 3567c478bd9Sstevel@tonic-gate s_terminate(to); 3577c478bd9Sstevel@tonic-gate 3587c478bd9Sstevel@tonic-gate for (; ; ) { 3597c478bd9Sstevel@tonic-gate if (feof(fp)) 3607c478bd9Sstevel@tonic-gate break; 3617c478bd9Sstevel@tonic-gate /* allocate room for a full buffer */ 3627c478bd9Sstevel@tonic-gate have = to->end - to->ptr; 3637c478bd9Sstevel@tonic-gate if (have < 4096UL) 3647c478bd9Sstevel@tonic-gate s_simplegrow(to, (size_t)4096); 3657c478bd9Sstevel@tonic-gate 3667c478bd9Sstevel@tonic-gate /* get a buffers worth */ 3677c478bd9Sstevel@tonic-gate have = to->end - to->ptr; 3687c478bd9Sstevel@tonic-gate got = fread(to->ptr, (size_t)1, have, fp); 3697c478bd9Sstevel@tonic-gate if (got == (size_t)0) 3707c478bd9Sstevel@tonic-gate break; 3717c478bd9Sstevel@tonic-gate /* LINT: warning due to lint bug */ 3727c478bd9Sstevel@tonic-gate to->ptr += got; 3737c478bd9Sstevel@tonic-gate } 3747c478bd9Sstevel@tonic-gate 3757c478bd9Sstevel@tonic-gate /* null terminate the line */ 3767c478bd9Sstevel@tonic-gate s_terminate(to); 3777c478bd9Sstevel@tonic-gate return (to->ptr - to->base); 3787c478bd9Sstevel@tonic-gate } 3797c478bd9Sstevel@tonic-gate 3807c478bd9Sstevel@tonic-gate /* 3817c478bd9Sstevel@tonic-gate * Get the next field from a string. The field is delimited by white space, 3827c478bd9Sstevel@tonic-gate * single or double quotes. 3837c478bd9Sstevel@tonic-gate * 3847c478bd9Sstevel@tonic-gate * string *from; string to parse 3857c478bd9Sstevel@tonic-gate * string *to; where to put parsed token 3867c478bd9Sstevel@tonic-gate */ 3877c478bd9Sstevel@tonic-gate string * 3887c478bd9Sstevel@tonic-gate s_parse(string *from, string *to) 3897c478bd9Sstevel@tonic-gate { 3907c478bd9Sstevel@tonic-gate while (isspace(*from->ptr)) 3917c478bd9Sstevel@tonic-gate from->ptr++; 3927c478bd9Sstevel@tonic-gate if (*from->ptr == '\0') 3937c478bd9Sstevel@tonic-gate return (NULL); 3947c478bd9Sstevel@tonic-gate if (to == NULL) 3957c478bd9Sstevel@tonic-gate to = s_new(); 3967c478bd9Sstevel@tonic-gate if (*from->ptr == '\'') { 3977c478bd9Sstevel@tonic-gate from->ptr++; 3987c478bd9Sstevel@tonic-gate for (; *from->ptr != '\'' && *from->ptr != '\0'; from->ptr++) 3997c478bd9Sstevel@tonic-gate s_putc(to, (int)(unsigned int)*from->ptr); 4007c478bd9Sstevel@tonic-gate if (*from->ptr == '\'') 4017c478bd9Sstevel@tonic-gate from->ptr++; 4027c478bd9Sstevel@tonic-gate } else if (*from->ptr == '"') { 4037c478bd9Sstevel@tonic-gate from->ptr++; 4047c478bd9Sstevel@tonic-gate for (; *from->ptr != '"' && *from->ptr != '\0'; from->ptr++) 4057c478bd9Sstevel@tonic-gate s_putc(to, (int)(unsigned int)*from->ptr); 4067c478bd9Sstevel@tonic-gate if (*from->ptr == '"') 4077c478bd9Sstevel@tonic-gate from->ptr++; 4087c478bd9Sstevel@tonic-gate } else { 4097c478bd9Sstevel@tonic-gate for (; !isspace(*from->ptr) && *from->ptr != '\0'; from->ptr++) 4107c478bd9Sstevel@tonic-gate s_putc(to, (int)(unsigned int)*from->ptr); 4117c478bd9Sstevel@tonic-gate } 4127c478bd9Sstevel@tonic-gate s_terminate(to); 4137c478bd9Sstevel@tonic-gate 4147c478bd9Sstevel@tonic-gate return (to); 4157c478bd9Sstevel@tonic-gate } 416