15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The authors of this software are Rob Pike and Ken Thompson. 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright (c) 2002 by Lucent Technologies. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Permission to use, copy, modify, and distribute this software for any 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * purpose without fee is hereby granted, provided that this entire notice 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * is included in all copies of any software which is or includes a copy 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * or modification of this software and in all copies of the supporting 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * documentation for such software. 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdarg.h> 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h> 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "util/utf.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace re2 { 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bit1 = 7, 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bitx = 6, 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bit2 = 5, 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bit3 = 4, 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bit4 = 3, 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bit5 = 2, 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) T1 = ((1<<(Bit1+1))-1) ^ 0xFF, /* 0000 0000 */ 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tx = ((1<<(Bitx+1))-1) ^ 0xFF, /* 1000 0000 */ 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) T2 = ((1<<(Bit2+1))-1) ^ 0xFF, /* 1100 0000 */ 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) T3 = ((1<<(Bit3+1))-1) ^ 0xFF, /* 1110 0000 */ 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) T4 = ((1<<(Bit4+1))-1) ^ 0xFF, /* 1111 0000 */ 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) T5 = ((1<<(Bit5+1))-1) ^ 0xFF, /* 1111 1000 */ 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Rune1 = (1<<(Bit1+0*Bitx))-1, /* 0000 0000 0111 1111 */ 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Rune2 = (1<<(Bit2+1*Bitx))-1, /* 0000 0111 1111 1111 */ 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Rune3 = (1<<(Bit3+2*Bitx))-1, /* 1111 1111 1111 1111 */ 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Rune4 = (1<<(Bit4+3*Bitx))-1, 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 0001 1111 1111 1111 1111 1111 */ 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Maskx = (1<<Bitx)-1, /* 0011 1111 */ 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Testx = Maskx ^ 0xFF, /* 1100 0000 */ 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bad = Runeerror, 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)chartorune(Rune *rune, const char *str) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int c, c1, c2, c3; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long l; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * one character sequence 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 00000-0007F => T1 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c = *(unsigned char*)str; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(c < Tx) { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *rune = c; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 1; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * two character sequence 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 0080-07FF => T2 Tx 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c1 = *(unsigned char*)(str+1) ^ Tx; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(c1 & Testx) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto bad; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(c < T3) { 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(c < T2) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto bad; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l = ((c << Bitx) | c1) & Rune2; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(l <= Rune1) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto bad; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *rune = l; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 2; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * three character sequence 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 0800-FFFF => T3 Tx Tx 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c2 = *(unsigned char*)(str+2) ^ Tx; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(c2 & Testx) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto bad; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(c < T4) { 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l = ((((c << Bitx) | c1) << Bitx) | c2) & Rune3; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(l <= Rune2) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto bad; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *rune = l; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 3; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * four character sequence (21-bit value) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 10000-1FFFFF => T4 Tx Tx Tx 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c3 = *(unsigned char*)(str+3) ^ Tx; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (c3 & Testx) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto bad; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (c < T5) { 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l = ((((((c << Bitx) | c1) << Bitx) | c2) << Bitx) | c3) & Rune4; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (l <= Rune3) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto bad; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *rune = l; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 4; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Support for 5-byte or longer UTF-8 would go here, but 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * since we don't have that, we'll just fall through to bad. 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * bad decoding 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bad: 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *rune = Bad; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 1; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)runetochar(char *str, const Rune *rune) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Runes are signed, so convert to unsigned for range check. */ 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long c; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * one character sequence 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 00000-0007F => 00-7F 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c = *rune; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(c <= Rune1) { 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) str[0] = c; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 1; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * two character sequence 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 0080-07FF => T2 Tx 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(c <= Rune2) { 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) str[0] = T2 | (c >> 1*Bitx); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) str[1] = Tx | (c & Maskx); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 2; 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If the Rune is out of range, convert it to the error rune. 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Do this test here because the error rune encodes to three bytes. 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Doing it earlier would duplicate work, since an out of range 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Rune wouldn't have fit in one or two bytes. 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (c > Runemax) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c = Runeerror; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * three character sequence 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 0800-FFFF => T3 Tx Tx 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (c <= Rune3) { 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) str[0] = T3 | (c >> 2*Bitx); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) str[1] = Tx | ((c >> 1*Bitx) & Maskx); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) str[2] = Tx | (c & Maskx); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 3; 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * four character sequence (21-bit value) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 10000-1FFFFF => T4 Tx Tx Tx 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) str[0] = T4 | (c >> 3*Bitx); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) str[1] = Tx | ((c >> 2*Bitx) & Maskx); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) str[2] = Tx | ((c >> 1*Bitx) & Maskx); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) str[3] = Tx | (c & Maskx); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 4; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)runelen(Rune rune) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char str[10]; 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return runetochar(str, &rune); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)fullrune(const char *str, int n) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (n > 0) { 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int c = *(unsigned char*)str; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (c < Tx) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 1; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (n > 1) { 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (c < T3) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 1; 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (n > 2) { 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (c < T4 || n > 3) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 1; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)utflen(const char *s) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int c; 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long n; 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Rune rune; 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) n = 0; 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(;;) { 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c = *(unsigned char*)s; 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(c < Runeself) { 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(c == 0) 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return n; 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s++; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s += chartorune(&rune, s); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) n++; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)char* 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)utfrune(const char *s, Rune c) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long c1; 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Rune r; 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int n; 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(c < Runesync) /* not part of utf sequence */ 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return strchr((char*)s, c); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(;;) { 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c1 = *(unsigned char*)s; 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(c1 < Runeself) { /* one byte rune */ 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(c1 == 0) 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(c1 == c) 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (char*)s; 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s++; 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) n = chartorune(&r, s); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(r == c) 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (char*)s; 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s += n; 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace re2 259