utf.c - sbase - suckless unix tools | |
git clone git://git.suckless.org/sbase | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
utf.c (3014B) | |
--- | |
1 /* MIT/X Consortium Copyright (c) 2012 Connor Lane Smith <[email protected]> | |
2 * | |
3 * Permission is hereby granted, free of charge, to any person obtaining… | |
4 * copy of this software and associated documentation files (the "Softwa… | |
5 * to deal in the Software without restriction, including without limita… | |
6 * the rights to use, copy, modify, merge, publish, distribute, sublicen… | |
7 * and/or sell copies of the Software, and to permit persons to whom the | |
8 * Software is furnished to do so, subject to the following conditions: | |
9 * | |
10 * The above copyright notice and this permission notice shall be includ… | |
11 * all copies or substantial portions of the Software. | |
12 * | |
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRE… | |
14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILI… | |
15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SH… | |
16 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR … | |
17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISI… | |
18 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
19 * DEALINGS IN THE SOFTWARE. | |
20 */ | |
21 #include <string.h> | |
22 #include "../utf.h" | |
23 | |
24 char * | |
25 utfecpy(char *to, char *end, const char *from) | |
26 { | |
27 Rune r = Runeerror; | |
28 size_t i, n; | |
29 | |
30 /* seek through to find final full rune */ | |
31 for(i = 0; r != '\0' && (n = charntorune(&r, &from[i], end - &to… | |
32 ; | |
33 memcpy(to, from, i); /* copy over bytes up to this rune */ | |
34 | |
35 if(i > 0 && r != '\0') | |
36 to[i] = '\0'; /* terminate if unterminated */ | |
37 return &to[i]; | |
38 } | |
39 | |
40 size_t | |
41 utflen(const char *s) | |
42 { | |
43 const char *p = s; | |
44 size_t i; | |
45 Rune r; | |
46 | |
47 for(i = 0; *p != '\0'; i++) | |
48 p += chartorune(&r, p); | |
49 return i; | |
50 } | |
51 | |
52 size_t | |
53 utfnlen(const char *s, size_t len) | |
54 { | |
55 const char *p = s; | |
56 size_t i; | |
57 Rune r; | |
58 int n; | |
59 | |
60 for(i = 0; (n = charntorune(&r, p, len-(p-s))) && r != '\0'; i++) | |
61 p += n; | |
62 return i; | |
63 } | |
64 | |
65 size_t | |
66 utfmemlen(const char *s, size_t len) | |
67 { | |
68 const char *p = s; | |
69 size_t i; | |
70 Rune r; | |
71 int n; | |
72 | |
73 for(i = 0; (n = charntorune(&r, p, len-(p-s))); i++) | |
74 p += n; | |
75 return i; | |
76 } | |
77 | |
78 char * | |
79 utfrune(const char *s, Rune r) | |
80 { | |
81 if(r < Runeself) { | |
82 return strchr(s, r); | |
83 } | |
84 else if(r == Runeerror) { | |
85 Rune r0; | |
86 int n; | |
87 | |
88 for(; *s != '\0'; s += n) { | |
89 n = chartorune(&r0, s); | |
90 if(r == r0) | |
91 return (char *)s; | |
92 } | |
93 } | |
94 else { | |
95 char buf[UTFmax+1]; | |
96 int n; | |
97 | |
98 if(!(n = runetochar(buf, &r))) | |
99 return NULL; | |
100 buf[n] = '\0'; | |
101 return strstr(s, buf); | |
102 } | |
103 return NULL; | |
104 } | |
105 | |
106 char * | |
107 utfrrune(const char *s, Rune r) | |
108 { | |
109 const char *p = NULL; | |
110 Rune r0; | |
111 int n; | |
112 | |
113 if(r < Runeself) | |
114 return strrchr(s, r); | |
115 | |
116 for(; *s != '\0'; s += n) { | |
117 n = chartorune(&r0, s); | |
118 if(r == r0) | |
119 p = s; | |
120 } | |
121 return (char *)p; | |
122 } | |
123 | |
124 char * | |
125 utfutf(const char *s, const char *t) | |
126 { | |
127 const char *p, *q; | |
128 Rune r0, r1, r2; | |
129 int n, m; | |
130 | |
131 for(chartorune(&r0, t); (s = utfrune(s, r0)); s++) { | |
132 for(p = s, q = t; *q && *p; p += n, q += m) { | |
133 n = chartorune(&r1, p); | |
134 m = chartorune(&r2, q); | |
135 if(r1 != r2) | |
136 break; | |
137 } | |
138 if(!*q) | |
139 return (char *)s; | |
140 } | |
141 return NULL; | |
142 } |