Serenity Operating System
1/*
2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this
9 * list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include <AK/Assertions.h>
28#include <wchar.h>
29
30extern "C" {
31
32size_t wcslen(const wchar_t* str)
33{
34 size_t len = 0;
35 while (*(str++))
36 ++len;
37 return len;
38}
39
40wchar_t* wcscpy(wchar_t* dest, const wchar_t* src)
41{
42 wchar_t* originalDest = dest;
43 while ((*dest++ = *src++) != '\0')
44 ;
45 return originalDest;
46}
47
48wchar_t* wcsncpy(wchar_t* dest, const wchar_t* src, size_t num)
49{
50 wchar_t* originalDest = dest;
51 while (((*dest++ = *src++) != '\0') && ((size_t)(dest - originalDest) < num))
52 ;
53 return originalDest;
54}
55
56int wcscmp(const wchar_t* s1, const wchar_t* s2)
57{
58 while (*s1 == *s2++)
59 if (*s1++ == 0)
60 return 0;
61 return *(const wchar_t*)s1 - *(const wchar_t*)--s2;
62}
63
64wchar_t* wcschr(const wchar_t* str, int c)
65{
66 wchar_t ch = c;
67 for (;; ++str) {
68 if (*str == ch)
69 return const_cast<wchar_t*>(str);
70 if (!*str)
71 return nullptr;
72 }
73}
74
75const wchar_t* wcsrchr(const wchar_t* str, wchar_t wc)
76{
77 wchar_t* last = nullptr;
78 wchar_t c;
79 for (; (c = *str); ++str) {
80 if (c == wc)
81 last = const_cast<wchar_t*>(str);
82 }
83 return last;
84}
85
86wchar_t* wcscat(wchar_t* dest, const wchar_t* src)
87{
88 size_t dest_length = wcslen(dest);
89 size_t i;
90 for (i = 0; src[i] != '\0'; i++)
91 dest[dest_length + i] = src[i];
92 dest[dest_length + i] = '\0';
93 return dest;
94}
95
96wchar_t* wcstok(wchar_t* str, const wchar_t* delim, wchar_t** ptr)
97{
98 wchar_t* used_str = str;
99 if (!used_str) {
100 used_str = *ptr;
101 }
102
103 size_t token_start = 0;
104 size_t token_end = 0;
105 size_t str_len = wcslen(used_str);
106 size_t delim_len = wcslen(delim);
107
108 for (size_t i = 0; i < str_len; ++i) {
109 bool is_proper_delim = false;
110
111 for (size_t j = 0; j < delim_len; ++j) {
112 if (used_str[i] == delim[j]) {
113 // Skip beginning delimiters
114 if (token_end - token_start == 0) {
115 ++token_start;
116 break;
117 }
118
119 is_proper_delim = true;
120 }
121 }
122
123 ++token_end;
124 if (is_proper_delim && token_end > 0) {
125 --token_end;
126 break;
127 }
128 }
129
130 if (used_str[token_start] == '\0')
131 return nullptr;
132
133 if (token_end == 0) {
134 return &used_str[token_start];
135 }
136
137 used_str[token_end] = '\0';
138 return &used_str[token_start];
139}
140
141wchar_t* wcsncat(wchar_t* dest, const wchar_t* src, size_t n)
142{
143 size_t dest_length = wcslen(dest);
144 size_t i;
145 for (i = 0; i < n && src[i] != '\0'; i++)
146 dest[dest_length + i] = src[i];
147 dest[dest_length + i] = '\0';
148 return dest;
149}
150}