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