Annotation of /trunk/mkinitrd-magellan/klibc/usr/dash/mystring.c
Parent Directory | Revision Log
Revision 1122 -
(hide annotations)
(download)
Wed Aug 18 21:11:40 2010 UTC (13 years, 8 months ago) by niro
File MIME type: text/plain
File size: 5315 byte(s)
Wed Aug 18 21:11:40 2010 UTC (13 years, 8 months ago) by niro
File MIME type: text/plain
File size: 5315 byte(s)
-updated to klibc-1.5.19
1 | niro | 532 | /*- |
2 | * Copyright (c) 1991, 1993 | ||
3 | * The Regents of the University of California. All rights reserved. | ||
4 | * Copyright (c) 1997-2005 | ||
5 | * Herbert Xu <herbert@gondor.apana.org.au>. All rights reserved. | ||
6 | * | ||
7 | * This code is derived from software contributed to Berkeley by | ||
8 | * Kenneth Almquist. | ||
9 | * | ||
10 | * Redistribution and use in source and binary forms, with or without | ||
11 | * modification, are permitted provided that the following conditions | ||
12 | * are met: | ||
13 | * 1. Redistributions of source code must retain the above copyright | ||
14 | * notice, this list of conditions and the following disclaimer. | ||
15 | * 2. Redistributions in binary form must reproduce the above copyright | ||
16 | * notice, this list of conditions and the following disclaimer in the | ||
17 | * documentation and/or other materials provided with the distribution. | ||
18 | * 3. Neither the name of the University nor the names of its contributors | ||
19 | * may be used to endorse or promote products derived from this software | ||
20 | * without specific prior written permission. | ||
21 | * | ||
22 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
23 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
24 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
25 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
28 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
29 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
32 | * SUCH DAMAGE. | ||
33 | */ | ||
34 | |||
35 | /* | ||
36 | * String functions. | ||
37 | * | ||
38 | * equal(s1, s2) Return true if strings are equal. | ||
39 | * scopy(from, to) Copy a string. | ||
40 | * scopyn(from, to, n) Like scopy, but checks for overflow. | ||
41 | * number(s) Convert a string of digits to an integer. | ||
42 | * is_number(s) Return true if s is a string of digits. | ||
43 | */ | ||
44 | |||
45 | niro | 1122 | #include <ctype.h> |
46 | #include <errno.h> | ||
47 | #include <inttypes.h> | ||
48 | #include <limits.h> | ||
49 | #include <stdint.h> | ||
50 | niro | 532 | #include <stdlib.h> |
51 | #include "shell.h" | ||
52 | #include "syntax.h" | ||
53 | #include "error.h" | ||
54 | #include "mystring.h" | ||
55 | #include "memalloc.h" | ||
56 | #include "parser.h" | ||
57 | #include "system.h" | ||
58 | |||
59 | |||
60 | char nullstr[1]; /* zero length string */ | ||
61 | const char spcstr[] = " "; | ||
62 | const char snlfmt[] = "%s\n"; | ||
63 | niro | 1122 | const char dolatstr[] = { CTLQUOTEMARK, CTLVAR, VSNORMAL, '@', '=', |
64 | CTLQUOTEMARK, '\0' }; | ||
65 | niro | 532 | const char illnum[] = "Illegal number: %s"; |
66 | const char homestr[] = "HOME"; | ||
67 | |||
68 | /* | ||
69 | * equal - #defined in mystring.h | ||
70 | */ | ||
71 | |||
72 | /* | ||
73 | * scopy - #defined in mystring.h | ||
74 | */ | ||
75 | |||
76 | |||
77 | #if 0 | ||
78 | /* | ||
79 | * scopyn - copy a string from "from" to "to", truncating the string | ||
80 | * if necessary. "To" is always nul terminated, even if | ||
81 | * truncation is performed. "Size" is the size of "to". | ||
82 | */ | ||
83 | |||
84 | void | ||
85 | scopyn(const char *from, char *to, int size) | ||
86 | { | ||
87 | |||
88 | while (--size > 0) { | ||
89 | if ((*to++ = *from++) == '\0') | ||
90 | return; | ||
91 | } | ||
92 | *to = '\0'; | ||
93 | } | ||
94 | #endif | ||
95 | |||
96 | |||
97 | /* | ||
98 | * prefix -- see if pfx is a prefix of string. | ||
99 | */ | ||
100 | |||
101 | char * | ||
102 | prefix(const char *string, const char *pfx) | ||
103 | { | ||
104 | while (*pfx) { | ||
105 | if (*pfx++ != *string++) | ||
106 | return 0; | ||
107 | } | ||
108 | return (char *) string; | ||
109 | } | ||
110 | |||
111 | niro | 1122 | void badnum(const char *s) |
112 | { | ||
113 | sh_error(illnum, s); | ||
114 | } | ||
115 | niro | 532 | |
116 | /* | ||
117 | niro | 1122 | * Convert a string into an integer of type intmax_t. Alow trailing spaces. |
118 | */ | ||
119 | intmax_t atomax(const char *s, int base) | ||
120 | { | ||
121 | char *p; | ||
122 | intmax_t r; | ||
123 | |||
124 | errno = 0; | ||
125 | r = strtoimax(s, &p, base); | ||
126 | |||
127 | if (errno != 0) | ||
128 | badnum(s); | ||
129 | |||
130 | /* | ||
131 | * Disallow completely blank strings in non-arithmetic (base != 0) | ||
132 | * contexts. | ||
133 | */ | ||
134 | if (p == s && base) | ||
135 | badnum(s); | ||
136 | |||
137 | while (isspace((unsigned char)*p)) | ||
138 | p++; | ||
139 | |||
140 | if (*p) | ||
141 | badnum(s); | ||
142 | |||
143 | return r; | ||
144 | } | ||
145 | |||
146 | intmax_t atomax10(const char *s) | ||
147 | { | ||
148 | return atomax(s, 10); | ||
149 | } | ||
150 | |||
151 | /* | ||
152 | niro | 532 | * Convert a string of digits to an integer, printing an error message on |
153 | * failure. | ||
154 | */ | ||
155 | |||
156 | int | ||
157 | number(const char *s) | ||
158 | { | ||
159 | niro | 1122 | intmax_t n = atomax10(s); |
160 | niro | 532 | |
161 | niro | 1122 | if (n < 0 || n > INT_MAX) |
162 | badnum(s); | ||
163 | |||
164 | return n; | ||
165 | niro | 532 | } |
166 | |||
167 | |||
168 | |||
169 | /* | ||
170 | * Check for a valid number. This should be elsewhere. | ||
171 | */ | ||
172 | |||
173 | int | ||
174 | is_number(const char *p) | ||
175 | { | ||
176 | do { | ||
177 | if (! is_digit(*p)) | ||
178 | return 0; | ||
179 | } while (*++p != '\0'); | ||
180 | return 1; | ||
181 | } | ||
182 | |||
183 | |||
184 | /* | ||
185 | * Produce a possibly single quoted string suitable as input to the shell. | ||
186 | * The return string is allocated on the stack. | ||
187 | */ | ||
188 | |||
189 | char * | ||
190 | single_quote(const char *s) { | ||
191 | char *p; | ||
192 | |||
193 | STARTSTACKSTR(p); | ||
194 | |||
195 | do { | ||
196 | char *q; | ||
197 | size_t len; | ||
198 | |||
199 | len = strchrnul(s, '\'') - s; | ||
200 | |||
201 | q = p = makestrspace(len + 3, p); | ||
202 | |||
203 | *q++ = '\''; | ||
204 | q = mempcpy(q, s, len); | ||
205 | *q++ = '\''; | ||
206 | s += len; | ||
207 | |||
208 | STADJUST(q - p, p); | ||
209 | |||
210 | len = strspn(s, "'"); | ||
211 | if (!len) | ||
212 | break; | ||
213 | |||
214 | q = p = makestrspace(len + 3, p); | ||
215 | |||
216 | *q++ = '"'; | ||
217 | q = mempcpy(q, s, len); | ||
218 | *q++ = '"'; | ||
219 | s += len; | ||
220 | |||
221 | STADJUST(q - p, p); | ||
222 | } while (*s); | ||
223 | |||
224 | USTPUTC(0, p); | ||
225 | |||
226 | return stackblock(); | ||
227 | } | ||
228 | |||
229 | /* | ||
230 | * Like strdup but works with the ash stack. | ||
231 | */ | ||
232 | |||
233 | char * | ||
234 | sstrdup(const char *p) | ||
235 | { | ||
236 | size_t len = strlen(p) + 1; | ||
237 | return memcpy(stalloc(len), p, len); | ||
238 | } | ||
239 | |||
240 | /* | ||
241 | * Wrapper around strcmp for qsort/bsearch/... | ||
242 | */ | ||
243 | int | ||
244 | pstrcmp(const void *a, const void *b) | ||
245 | { | ||
246 | return strcmp(*(const char *const *) a, *(const char *const *) b); | ||
247 | } | ||
248 | |||
249 | /* | ||
250 | * Find a string is in a sorted array. | ||
251 | */ | ||
252 | const char *const * | ||
253 | findstring(const char *s, const char *const *array, size_t nmemb) | ||
254 | { | ||
255 | return bsearch(&s, array, nmemb, sizeof(const char *), pstrcmp); | ||
256 | } |