source: mainline/uspace/lib/posix/src/string.c@ c124c985

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since c124c985 was 99d3123, checked in by Jiri Svoboda <jiri@…>, 7 years ago

libc needs a string.h (for the outside users, at least).

  • Property mode set to 100644
File size: 7.9 KB
RevLine 
[7bb9b53]1/*
2 * Copyright (c) 2011 Petr Koupy
3 * Copyright (c) 2011 Jiri Zarevucky
[99d3123]4 * Copyright (c) 2018 Jiri Svoboda
[7bb9b53]5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * - Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * - Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * - The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31/** @addtogroup libposix
32 * @{
33 */
[5273eb6]34/** @file String manipulation.
[7bb9b53]35 */
36
[a6d908c1]37#include "internal/common.h"
[a3da2b2]38#include "posix/string.h"
[7bb9b53]39
[e8d3c6f5]40#include <assert.h>
[0d0b319]41
42#include <errno.h>
43
[a3da2b2]44#include "posix/limits.h"
45#include "posix/stdlib.h"
46#include "posix/signal.h"
[ef6dd3f]47
[1d6dd2a]48#include "libc/str.h"
[a6d908c1]49#include "libc/str_error.h"
50
[7bb9b53]51/**
[5273eb6]52 * Copy a string.
[7bb9b53]53 *
[5273eb6]54 * @param dest Destination pre-allocated buffer.
55 * @param src Source string to be copied.
56 * @return Pointer to the nul character in the destination string.
[7bb9b53]57 */
[7f9df7b9]58char *stpcpy(char *restrict dest, const char *restrict src)
[7bb9b53]59{
[ef6dd3f]60 assert(dest != NULL);
61 assert(src != NULL);
62
[4f4b4e7]63 for (size_t i = 0; ; ++i) {
[ef6dd3f]64 dest[i] = src[i];
[a35b458]65
[ef6dd3f]66 if (src[i] == '\0') {
67 /* pointer to the terminating nul character */
68 return &dest[i];
69 }
70 }
[a35b458]71
[ef6dd3f]72 /* unreachable */
73 return NULL;
[7bb9b53]74}
75
76/**
[5273eb6]77 * Copy fixed length string.
[7bb9b53]78 *
[5273eb6]79 * @param dest Destination pre-allocated buffer.
80 * @param src Source string to be copied.
81 * @param n Number of bytes to be stored into destination buffer.
82 * @return Pointer to the first written nul character or &dest[n].
[7bb9b53]83 */
[7f9df7b9]84char *stpncpy(char *restrict dest, const char *restrict src, size_t n)
[7bb9b53]85{
[ef6dd3f]86 assert(dest != NULL);
87 assert(src != NULL);
88
[4f4b4e7]89 for (size_t i = 0; i < n; ++i) {
[ef6dd3f]90 dest[i] = src[i];
[a35b458]91
[7c3fb9b]92 /*
93 * the standard requires that nul characters
[ef6dd3f]94 * are appended to the length of n, in case src is shorter
95 */
96 if (src[i] == '\0') {
97 char *result = &dest[i];
[4f4b4e7]98 for (++i; i < n; ++i) {
[ef6dd3f]99 dest[i] = '\0';
100 }
101 return result;
102 }
103 }
[a35b458]104
[ef6dd3f]105 return &dest[n];
[7bb9b53]106}
107
108/**
[5273eb6]109 * Copy limited number of bytes in memory.
[7bb9b53]110 *
[5273eb6]111 * @param dest Destination buffer.
112 * @param src Source buffer.
113 * @param c Character after which the copying shall stop.
114 * @param n Number of bytes that shall be copied if not stopped earlier by c.
[ef6dd3f]115 * @return Pointer to the first byte after c in dest if found, NULL otherwise.
[7bb9b53]116 */
[7f9df7b9]117void *memccpy(void *restrict dest, const void *restrict src, int c, size_t n)
[7bb9b53]118{
[ef6dd3f]119 assert(dest != NULL);
120 assert(src != NULL);
[a35b458]121
[1433ecda]122 unsigned char *bdest = dest;
123 const unsigned char *bsrc = src;
[a35b458]124
[4f4b4e7]125 for (size_t i = 0; i < n; ++i) {
[ef6dd3f]126 bdest[i] = bsrc[i];
[a35b458]127
[ef6dd3f]128 if (bsrc[i] == (unsigned char) c) {
129 /* pointer to the next byte */
130 return &bdest[i + 1];
131 }
132 }
[a35b458]133
[ef6dd3f]134 return NULL;
[7bb9b53]135}
136
137/**
[5273eb6]138 * Duplicate a string.
[7bb9b53]139 *
[5273eb6]140 * @param s String to be duplicated.
141 * @return Newly allocated copy of the string.
[7bb9b53]142 */
[7f9df7b9]143char *strdup(const char *s)
[7bb9b53]144{
[7f9df7b9]145 return strndup(s, SIZE_MAX);
[7bb9b53]146}
147
148/**
[5273eb6]149 * Duplicate a specific number of bytes from a string.
[7bb9b53]150 *
[5273eb6]151 * @param s String to be duplicated.
152 * @param n Maximum length of the resulting string..
153 * @return Newly allocated string copy of length at most n.
[7bb9b53]154 */
[7f9df7b9]155char *strndup(const char *s, size_t n)
[7bb9b53]156{
[ef6dd3f]157 assert(s != NULL);
158
[7f9df7b9]159 size_t len = strnlen(s, n);
[ef6dd3f]160 char *dup = malloc(len + 1);
161 if (dup == NULL) {
162 return NULL;
163 }
164
165 memcpy(dup, s, len);
166 dup[len] = '\0';
167
168 return dup;
[7bb9b53]169}
170
[5273eb6]171/**
172 * Scan string for a first occurence of a character.
173 *
174 * @param s String in which to look for the character.
175 * @param c Character to look for.
176 * @return Pointer to the specified character on success, pointer to the
177 * string terminator otherwise.
178 */
[517cedc0]179char *gnu_strchrnul(const char *s, int c)
180{
181 assert(s != NULL);
[a35b458]182
[517cedc0]183 while (*s != c && *s != '\0') {
184 s++;
185 }
[a35b458]186
[517cedc0]187 return (char *) s;
188}
189
[12b29f3]190/** Split string by delimiters.
191 *
192 * @param s String to be tokenized. May not be NULL.
193 * @param delim String with the delimiters.
194 * @param next Variable which will receive the pointer to the
195 * continuation of the string following the first
196 * occurrence of any of the delimiter characters.
197 * May be NULL.
198 * @return Pointer to the prefix of @a s before the first
199 * delimiter character. NULL if no such prefix
200 * exists.
201 */
[7f9df7b9]202char *strtok_r(char *s, const char *delim, char **next)
[12b29f3]203{
[99d3123]204 return __strtok_r(s, delim, next);
[ef6dd3f]205}
206
207/**
[5273eb6]208 * Get error message string.
[ef6dd3f]209 *
[5273eb6]210 * @param errnum Error code for which to obtain human readable string.
211 * @param buf Buffer to store a human readable string to.
212 * @param bufsz Size of buffer pointed to by buf.
213 * @return Zero on success, errno otherwise.
[ef6dd3f]214 */
[7f9df7b9]215int strerror_r(int errnum, char *buf, size_t bufsz)
[ef6dd3f]216{
217 assert(buf != NULL);
[a35b458]218
[7f9df7b9]219 char *errstr = strerror(errnum);
[a35b458]220
[7f9df7b9]221 if (strlen(errstr) + 1 > bufsz) {
[1b55da67]222 return ERANGE;
[ef6dd3f]223 } else {
[7f9df7b9]224 strcpy(buf, errstr);
[ef6dd3f]225 }
226
[0d0b319]227 return EOK;
[7bb9b53]228}
229
[ef6dd3f]230/**
[5273eb6]231 * Get limited length of the string.
[ef6dd3f]232 *
[5273eb6]233 * @param s String which length shall be determined.
234 * @param n Maximum number of bytes that can be examined to determine length.
235 * @return The lower of either string length or n limit.
[ef6dd3f]236 */
[7f9df7b9]237size_t strnlen(const char *s, size_t n)
[ef6dd3f]238{
239 assert(s != NULL);
[a35b458]240
[4f4b4e7]241 for (size_t sz = 0; sz < n; ++sz) {
[a35b458]242
[ef6dd3f]243 if (s[sz] == '\0') {
244 return sz;
245 }
246 }
[a35b458]247
[ef6dd3f]248 return n;
[7bb9b53]249}
250
[d3ce33fa]251/**
[5273eb6]252 * Get description of a signal.
[d3ce33fa]253 *
[5273eb6]254 * @param signum Signal number.
255 * @return Human readable signal description.
[d3ce33fa]256 */
[7f9df7b9]257char *strsignal(int signum)
[d3ce33fa]258{
259 static const char *const sigstrings[] = {
260 [SIGABRT] = "SIGABRT (Process abort signal)",
261 [SIGALRM] = "SIGALRM (Alarm clock)",
262 [SIGBUS] = "SIGBUS (Access to an undefined portion of a memory object)",
263 [SIGCHLD] = "SIGCHLD (Child process terminated, stopped, or continued)",
264 [SIGCONT] = "SIGCONT (Continue executing, if stopped)",
265 [SIGFPE] = "SIGFPE (Erroneous arithmetic operation)",
266 [SIGHUP] = "SIGHUP (Hangup)",
267 [SIGILL] = "SIGILL (Illegal instruction)",
268 [SIGINT] = "SIGINT (Terminal interrupt signal)",
269 [SIGKILL] = "SIGKILL (Kill process)",
270 [SIGPIPE] = "SIGPIPE (Write on a pipe with no one to read it)",
271 [SIGQUIT] = "SIGQUIT (Terminal quit signal)",
272 [SIGSEGV] = "SIGSEGV (Invalid memory reference)",
273 [SIGSTOP] = "SIGSTOP (Stop executing)",
274 [SIGTERM] = "SIGTERM (Termination signal)",
275 [SIGTSTP] = "SIGTSTP (Terminal stop signal)",
276 [SIGTTIN] = "SIGTTIN (Background process attempting read)",
277 [SIGTTOU] = "SIGTTOU (Background process attempting write)",
278 [SIGUSR1] = "SIGUSR1 (User-defined signal 1)",
279 [SIGUSR2] = "SIGUSR2 (User-defined signal 2)",
280 [SIGPOLL] = "SIGPOLL (Pollable event)",
281 [SIGPROF] = "SIGPROF (Profiling timer expired)",
282 [SIGSYS] = "SIGSYS (Bad system call)",
283 [SIGTRAP] = "SIGTRAP (Trace/breakpoint trap)",
284 [SIGURG] = "SIGURG (High bandwidth data is available at a socket)",
285 [SIGVTALRM] = "SIGVTALRM (Virtual timer expired)",
286 [SIGXCPU] = "SIGXCPU (CPU time limit exceeded)",
287 [SIGXFSZ] = "SIGXFSZ (File size limit exceeded)"
288 };
289
290 if (signum <= _TOP_SIGNAL) {
291 return (char *) sigstrings[signum];
292 }
293
294 return (char *) "ERROR, Invalid signal number";
295}
296
[7bb9b53]297/** @}
298 */
Note: See TracBrowser for help on using the repository browser.