sbase

suckless unix tools
git clone git://git.suckless.org/sbase
Log | Files | Refs | README | 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 }