utf.c (2841B)
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 char * 66 utfrune(const char *s, Rune r) 67 { 68 if(r < Runeself) { 69 return strchr(s, r); 70 } 71 else if(r == Runeerror) { 72 Rune r0; 73 int n; 74 75 for(; *s != '\0'; s += n) { 76 n = chartorune(&r0, s); 77 if(r == r0) 78 return (char *)s; 79 } 80 } 81 else { 82 char buf[UTFmax+1]; 83 int n; 84 85 if(!(n = runetochar(buf, &r))) 86 return NULL; 87 buf[n] = '\0'; 88 return strstr(s, buf); 89 } 90 return NULL; 91 } 92 93 char * 94 utfrrune(const char *s, Rune r) 95 { 96 const char *p = NULL; 97 Rune r0; 98 int n; 99 100 if(r < Runeself) 101 return strrchr(s, r); 102 103 for(; *s != '\0'; s += n) { 104 n = chartorune(&r0, s); 105 if(r == r0) 106 p = s; 107 } 108 return (char *)p; 109 } 110 111 char * 112 utfutf(const char *s, const char *t) 113 { 114 const char *p, *q; 115 Rune r0, r1, r2; 116 int n, m; 117 118 for(chartorune(&r0, t); (s = utfrune(s, r0)); s++) { 119 for(p = s, q = t; *q && *p; p += n, q += m) { 120 n = chartorune(&r1, p); 121 m = chartorune(&r2, q); 122 if(r1 != r2) 123 break; 124 } 125 if(!*q) 126 return (char *)s; 127 } 128 return NULL; 129 }