utf.c - sbase - suckless unix tools
 (HTM) git clone git://git.suckless.org/sbase
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
       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 }