/***********************************************************************1* *2* This software is part of the ast package *3* Copyright (c) 1985-2012 AT&T Intellectual Property *4* and is licensed under the *5* Eclipse Public License, Version 1.0 *6* by AT&T Intellectual Property *7* *8* A copy of the License is available at *9* http://www.eclipse.org/org/documents/epl-v10.html *10* (with md5 checksum b35adb5213ca9657e911e9befb180842) *11* *12* Information and Software Systems Research *13* AT&T Research *14* Florham Park NJ *15* *16* Glenn Fowler <[email protected]> *17* David Korn <[email protected]> *18* Phong Vo <[email protected]> *19* *20***********************************************************************/21#pragma prototyped22/*23* regex collation symbol support24*/2526#include "reglib.h"2728/*29* return the collating symbol delimited by [c c], where c is either '=' or '.'30* s points to the first char after the initial [31* if e!=0 it is set to point to the next char in s on return32*33* the collating symbol is converted to multibyte in <buf,size>34* the return value is:35* -1 syntax error / invalid collating element36* >=0 size with 0-terminated mb character (*wc != 0)37* or collating element (*wc == 0) in buf38*/3940int41regcollate(register const char* s, char** e, char* buf, size_t size, wchar_t* wc)42{43register int c;44register char* b;45register char* x;46const char* t;47int i;48int r;49int term;50wchar_t w;51char xfm[256];52char tmp[sizeof(xfm)];5354if (size < 2 || (term = *s) != '.' && term != '=' || !*++s || *s == term && *(s + 1) == ']')55goto nope;56t = s;57w = mbchar(s);58if ((r = (s - t)) > 1)59{60if (*s++ != term || *s++ != ']')61goto oops;62goto done;63}64if (*s == term && *(s + 1) == ']')65{66s += 2;67goto done;68}69b = buf;70x = buf + size - 2;71s = t;72for (;;)73{74if (!(c = *s++))75goto oops;76if (c == term)77{78if (!(c = *s++))79goto oops;80if (c != term)81{82if (c != ']')83goto oops;84break;85}86}87if (b < x)88*b++ = c;89}90r = s - t - 2;91w = 0;92if (b >= x)93goto done;94*b = 0;95for (i = 0; i < r && i < sizeof(tmp) - 1; i++)96tmp[i] = '0';97tmp[i] = 0;98if (mbxfrm(xfm, buf, sizeof(xfm)) >= mbxfrm(xfm, tmp, sizeof(xfm)))99goto nope;100t = (const char*)buf;101done:102if (r <= size && (char*)t != buf)103{104memcpy(buf, t, r);105if (r < size)106buf[r] = 0;107}108if (wc)109*wc = w;110if (e)111*e = (char*)s;112return r;113oops:114s--;115nope:116if (e)117*e = (char*)s;118return -1;119}120121122