xref: /illumos-gate/usr/src/cmd/ttymon/tmparse.c (revision 4e320a8a375380e6f3963134cd6c1001e2bdb7fa)
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 *
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
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