xref: /illumos-gate/usr/src/cmd/sgs/libconv/common/strproc.c (revision 5422785d352a2bb398daceab3d1898a8aa64d006)
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 (the "License").
6  * You may not use this file except in compliance with the License.
7  *
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.
12  *
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]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 
28 /*
29  * General purpse string manipulation routines
30  */
31 
32 #include	<stdio.h>
33 #include	<_conv.h>
34 
35 
36 /*
37  * Implementation of isspace() that does not require <ctype.h>
38  * or <sys/ctype.h>, appropriate for simple non-localized use.
39  */
40 int
41 conv_strproc_isspace(int c)
42 {
43 	return ((c == ' ') || (c == '\t') || (c == '\r') || (c == '\n'));
44 }
45 
46 /*
47  * Remove leading and trailing whitespace from the given string.
48  *
49  * entry:
50  *	str - String to be trimmed
51  *
52  * exit:
53  *	The pointer to the trimmed string is returned.
54  *
55  * note:
56  *	Leading whitespace is trimmed by advancing the given str pointer,
57  *	and not by making a copy or allocing more memory. Hence, the caller
58  *	should retain a copy of the original str pointer if they need to
59  *	free the original memory or otherwise access it.
60  *
61  *	Trailing whitespace is trimmed by inserting a NULL termination
62  *	in the position at which the first trailing whitespce character
63  *	lies. This routine can therefore modify the memory used by
64  *	the input string.
65  */
66 char *
67 conv_strproc_trim(char *str)
68 {
69 	char	*tail;
70 
71 	/* Skip leading whitespace */
72 	while (conv_strproc_isspace(*str))
73 		str++;
74 
75 	/* Back up over trailing whitespace */
76 	tail = str + strlen(str);
77 	while ((tail > str) && conv_strproc_isspace(*(tail - 1)))
78 		tail--;
79 	*tail = '\0';
80 
81 	return (str);
82 }
83 
84 /*
85  * Given a debug token of the form:
86  *
87  *	token=value
88  *
89  * extract and return a pointer to the value.
90  *
91  * entry:
92  *	str - String to process
93  *	token_len = Length of the token, not counting the '=' character,
94  *		or any whitespace between the token and the '='.
95  *	to_upper - True to convert the returned value to upper case.
96  *	value - Address of pointer to receive the value string.
97  *
98  * exit:
99  *	On success, *value is updated to point at the value string,
100  *	and True (1) is returned. On failure, False (0) is returned.
101  *
102  * note:
103  *	If CONV_SPEXV_F_UCASE is specified, this routine modifies
104  *	the memory pointed at by str.
105  */
106 Boolean
107 conv_strproc_extract_value(char *str, size_t token_len, int flags,
108     const char **value)
109 {
110 	int	trim = (flags & CONV_SPEXV_F_NOTRIM) == 0;
111 
112 	/* Skip the token */
113 	str += token_len;
114 
115 	/*
116 	 * If TRIM, skip whitespace between token and '='
117 	 */
118 	if (trim)
119 		while (conv_strproc_isspace(*str))
120 			str++;
121 
122 	/* If there's not a '=' here, this isn't the token we thought it was */
123 	if (*str != '=')
124 		return (FALSE);
125 
126 	str++;			/* skip the '=' */
127 
128 	/* if TRIM, skip whitespace following the '=' */
129 	if (trim)
130 		while (conv_strproc_isspace(*str))
131 			str++;
132 
133 	/* Null value and it's not OK? Make it an error. */
134 	if (((flags & CONV_SPEXV_F_NULLOK) == 0) && (*str == '\0'))
135 		return (FALSE);
136 
137 	*value = str;
138 
139 	/* Convert to uppercase on request */
140 	if (flags & CONV_SPEXV_F_UCASE)
141 		for (; *str; str++)
142 			if ((*str >= 'a') && (*str <= 'z'))
143 				*str = *str - ('a' - 'A');
144 
145 	return (TRUE);
146 }
147