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