| /* MIT/X Consortium Copyright (c) 2012 Connor Lane Smith <cls@lubutu.com> |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining a |
| * copy of this software and associated documentation files (the "Software"), |
| * to deal in the Software without restriction, including without limitation |
| * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| * and/or sell copies of the Software, and to permit persons to whom the |
| * Software is furnished to do so, subject to the following conditions: |
| * |
| * The above copyright notice and this permission notice shall be included in |
| * all copies or substantial portions of the Software. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
| * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
| * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
| * DEALINGS IN THE SOFTWARE. |
| */ |
| #include <string.h> |
| #include "../utf.h" |
| |
| char * |
| utfecpy(char *to, char *end, const char *from) |
| { |
| Rune r = Runeerror; |
| size_t i, n; |
| |
| /* seek through to find final full rune */ |
| for(i = 0; r != '\0' && (n = charntorune(&r, &from[i], end - &to[i])); i += n) |
| ; |
| memcpy(to, from, i); /* copy over bytes up to this rune */ |
| |
| if(i > 0 && r != '\0') |
| to[i] = '\0'; /* terminate if unterminated */ |
| return &to[i]; |
| } |
| |
| size_t |
| utflen(const char *s) |
| { |
| const char *p = s; |
| size_t i; |
| Rune r; |
| |
| for(i = 0; *p != '\0'; i++) |
| p += chartorune(&r, p); |
| return i; |
| } |
| |
| size_t |
| utfnlen(const char *s, size_t len) |
| { |
| const char *p = s; |
| size_t i; |
| Rune r; |
| int n; |
| |
| for(i = 0; (n = charntorune(&r, p, len-(p-s))) && r != '\0'; i++) |
| p += n; |
| return i; |
| } |
| |
| char * |
| utfrune(const char *s, Rune r) |
| { |
| if(r < Runeself) { |
| return strchr(s, r); |
| } |
| else if(r == Runeerror) { |
| Rune r0; |
| int n; |
| |
| for(; *s != '\0'; s += n) { |
| n = chartorune(&r0, s); |
| if(r == r0) |
| return (char *)s; |
| } |
| } |
| else { |
| char buf[UTFmax+1]; |
| int n; |
| |
| if(!(n = runetochar(buf, &r))) |
| return NULL; |
| buf[n] = '\0'; |
| return strstr(s, buf); |
| } |
| return NULL; |
| } |
| |
| char * |
| utfrrune(const char *s, Rune r) |
| { |
| const char *p = NULL; |
| Rune r0; |
| int n; |
| |
| if(r < Runeself) |
| return strrchr(s, r); |
| |
| for(; *s != '\0'; s += n) { |
| n = chartorune(&r0, s); |
| if(r == r0) |
| p = s; |
| } |
| return (char *)p; |
| } |
| |
| char * |
| utfutf(const char *s, const char *t) |
| { |
| const char *p, *q; |
| Rune r0, r1, r2; |
| int n, m; |
| |
| for(chartorune(&r0, t); (s = utfrune(s, r0)); s++) { |
| for(p = s, q = t; *q && *p; p += n, q += m) { |
| n = chartorune(&r1, p); |
| m = chartorune(&r2, q); |
| if(r1 != r2) |
| break; |
| } |
| if(!*q) |
| return (char *)s; |
| } |
| return NULL; |
| } |