utf.c (1742B)
1 /* See LICENSE file for copyright and license details. */ 2 #include <string.h> 3 #include "utf.h" 4 5 char * 6 utfecpy(char *to, char *end, const char *from) 7 { 8 Rune r = Runeerror; 9 size_t i, n; 10 11 /* seek through to find final full rune */ 12 for(i = 0; r != '\0' && (n = charntorune(&r, &from[i], end - &to[i])); i += n) 13 ; 14 memcpy(to, from, i); /* copy over bytes up to this rune */ 15 16 if(i > 0 && r != '\0') 17 to[i] = '\0'; /* terminate if unterminated */ 18 return &to[i]; 19 } 20 21 size_t 22 utflen(const char *s) 23 { 24 const char *p = s; 25 size_t i; 26 Rune r; 27 28 for(i = 0; *p != '\0'; i++) 29 p += chartorune(&r, p); 30 return i; 31 } 32 33 size_t 34 utfnlen(const char *s, size_t len) 35 { 36 const char *p = s; 37 size_t i; 38 Rune r; 39 int n; 40 41 for(i = 0; (n = charntorune(&r, p, len-(p-s))) && r != '\0'; i++) 42 p += n; 43 return i; 44 } 45 46 char * 47 utfrune(const char *s, Rune r) 48 { 49 if(r < Runeself) { 50 return strchr(s, r); 51 } 52 else if(r == Runeerror) { 53 Rune r0; 54 int n; 55 56 for(; *s != '\0'; s += n) { 57 n = chartorune(&r0, s); 58 if(r == r0) 59 return (char *)s; 60 } 61 } 62 else { 63 char buf[UTFmax+1]; 64 int n; 65 66 if(!(n = runetochar(buf, &r))) 67 return NULL; 68 buf[n] = '\0'; 69 return strstr(s, buf); 70 } 71 return NULL; 72 } 73 74 char * 75 utfrrune(const char *s, Rune r) 76 { 77 const char *p = NULL; 78 Rune r0; 79 int n; 80 81 if(r < Runeself) 82 return strrchr(s, r); 83 84 for(; *s != '\0'; s += n) { 85 n = chartorune(&r0, s); 86 if(r == r0) 87 p = s; 88 } 89 return (char *)p; 90 } 91 92 char * 93 utfutf(const char *s, const char *t) 94 { 95 const char *p, *q; 96 Rune r0, r1, r2; 97 int n, m; 98 99 for(chartorune(&r0, t); (s = utfrune(s, r0)); s++) { 100 for(p = s, q = t; *q && *p; p += n, q += m) { 101 n = chartorune(&r1, p); 102 m = chartorune(&r2, q); 103 if(r1 != r2) 104 break; 105 } 106 if(!*q) 107 return (char *)s; 108 } 109 return NULL; 110 }