utf.c (3014B)
1 /* MIT/X Consortium Copyright (c) 2012 Connor Lane Smith <cls@lubutu.com> 2 * 3 * Permission is hereby granted, free of charge, to any person obtaining a 4 * copy of this software and associated documentation files (the "Software"), 5 * to deal in the Software without restriction, including without limitation 6 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 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 included in 11 * all copies or substantial portions of the Software. 12 * 13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 16 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 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[i])); i += n) 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 }