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 #include <stdio.h>
26 #include <ctype.h>
27
28 char quoted(char *, int *);
29
30 /*
31 * getword - extract one token from the string
32 * char *ptr; pointer to the string to be scanned
33 * int *size; *size = number of characters scanned
34 * int getall; if TRUE, get all char until ':' or '\0'
35 * - token delimiter is white space if getall is FALSE
36 * - token delimiter is ':' or '\0' if getall is TRUE
37 */
38 char *
getword(char * ptr,int * size,int getall)39 getword(char *ptr, int *size, int getall)
40 {
41 char *optr, c;
42 static char word[BUFSIZ];
43 int qsize;
44
45 *size = 0;
46 if (!getall) {
47 /* Skip all white spaces */
48 while (isspace(*ptr)) {
49 (*size)++;
50 ptr++;
51 }
52 }
53
54 /* Put all characters from here to next white space or ':' or '\0' */
55 /* into the word, up to the size of the word. */
56 for (optr = word, *optr = '\0';
57 *ptr != '\0' && *ptr != ':'; ptr++, (*size)++) {
58 if (!getall) {
59 if (isspace(*ptr))
60 break;
61 }
62
63 /* If the character is quoted, analyze it. */
64 if (*ptr == '\\') {
65 c = quoted(ptr, &qsize);
66 (*size) += qsize;
67 ptr += qsize;
68 } else c = *ptr;
69
70 /* If there is room, add this character to the word. */
71 if (optr < &word[BUFSIZ])
72 *optr++ = c;
73 }
74
75 /* skip trailing blanks if any */
76 while (isspace(*ptr)) {
77 (*size)++;
78 ptr++;
79 }
80
81 /* Make sure the line is null terminated. */
82 *optr++ = '\0';
83 return (word);
84 }
85
86 /* "quoted" takes a quoted character, starting at the quote */
87 /* character, and returns a single character plus the size of */
88 /* the quote string. "quoted" recognizes the following as */
89 /* special, \n,\r,\v,\t,\b,\f as well as the \nnn notation. */
90 char
quoted(char * ptr,int * qsize)91 quoted(char *ptr, int *qsize)
92 {
93 char c, *rptr;
94 int i;
95
96 rptr = ptr;
97 switch (*++rptr) {
98 case 'n':
99 c = '\n';
100 break;
101 case 'r':
102 c = '\r';
103 break;
104 case 'v':
105 c = '\013';
106 break;
107 case 'b':
108 c = '\b';
109 break;
110 case 't':
111 c = '\t';
112 break;
113 case 'f':
114 c = '\f';
115 break;
116 case ':':
117 c = ':';
118 break;
119 default:
120
121 /* If this is a numeric string, take up to three characters of */
122 /* it as the value of the quoted character. */
123 if (*rptr >= '0' && *rptr <= '7') {
124 for (i = 0, c = 0; i < 3; i++) {
125 c = c * 8 + (*rptr - '0');
126 if (*++rptr < '0' || *rptr > '7')
127 break;
128 }
129 rptr--;
130
131 /* If the character following the '\\' is a NULL, back up the */
132 /* ptr so that the NULL won't be missed. The sequence */
133 /* backslash null is essentually illegal. */
134 } else if (*rptr == '\0') {
135 c = '\0';
136 rptr--;
137
138 /* In all other cases the quoting does nothing. */
139 } else {
140 c = *rptr;
141 }
142 break;
143 }
144
145 /* Compute the size of the quoted character. */
146 (*qsize) = rptr - ptr;
147 return (c);
148 }
149