sbase

suckless unix tools
git clone git://git.2f30.org/sbase
Log | Files | Refs | README | LICENSE

utf.c (2841B)


      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 char *
     66 utfrune(const char *s, Rune r)
     67 {
     68 	if(r < Runeself) {
     69 		return strchr(s, r);
     70 	}
     71 	else if(r == Runeerror) {
     72 		Rune r0;
     73 		int n;
     74 
     75 		for(; *s != '\0'; s += n) {
     76 			n = chartorune(&r0, s);
     77 			if(r == r0)
     78 				return (char *)s;
     79 		}
     80 	}
     81 	else {
     82 		char buf[UTFmax+1];
     83 		int n;
     84 
     85 		if(!(n = runetochar(buf, &r)))
     86 			return NULL;
     87 		buf[n] = '\0';
     88 		return strstr(s, buf);
     89 	}
     90 	return NULL;
     91 }
     92 
     93 char *
     94 utfrrune(const char *s, Rune r)
     95 {
     96 	const char *p = NULL;
     97 	Rune r0;
     98 	int n;
     99 
    100 	if(r < Runeself)
    101 		return strrchr(s, r);
    102 
    103 	for(; *s != '\0'; s += n) {
    104 		n = chartorune(&r0, s);
    105 		if(r == r0)
    106 			p = s;
    107 	}
    108 	return (char *)p;
    109 }
    110 
    111 char *
    112 utfutf(const char *s, const char *t)
    113 {
    114 	const char *p, *q;
    115 	Rune r0, r1, r2;
    116 	int n, m;
    117 
    118 	for(chartorune(&r0, t); (s = utfrune(s, r0)); s++) {
    119 		for(p = s, q = t; *q && *p; p += n, q += m) {
    120 			n = chartorune(&r1, p);
    121 			m = chartorune(&r2, q);
    122 			if(r1 != r2)
    123 				break;
    124 		}
    125 		if(!*q)
    126 			return (char *)s;
    127 	}
    128 	return NULL;
    129 }