summaryrefslogtreecommitdiff
path: root/util/sbase/libutf/utf.c
diff options
context:
space:
mode:
Diffstat (limited to 'util/sbase/libutf/utf.c')
-rw-r--r--util/sbase/libutf/utf.c142
1 files changed, 142 insertions, 0 deletions
diff --git a/util/sbase/libutf/utf.c b/util/sbase/libutf/utf.c
new file mode 100644
index 00000000..492e020f
--- /dev/null
+++ b/util/sbase/libutf/utf.c
@@ -0,0 +1,142 @@
+/* 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;
+}
+
+size_t
+utfmemlen(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))); 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;
+}