119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/*-
219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman * This code is derived from OpenBSD's libc/regex, original license follows:
319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman *
419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman * Copyright (c) 1992, 1993, 1994 Henry Spencer.
519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman * Copyright (c) 1992, 1993, 1994
619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman *	The Regents of the University of California.  All rights reserved.
719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman *
819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman * This code is derived from software contributed to Berkeley by
919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman * Henry Spencer.
1019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman *
1119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman * Redistribution and use in source and binary forms, with or without
1219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman * modification, are permitted provided that the following conditions
1319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman * are met:
1419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman * 1. Redistributions of source code must retain the above copyright
1519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman *    notice, this list of conditions and the following disclaimer.
1619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman * 2. Redistributions in binary form must reproduce the above copyright
1719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman *    notice, this list of conditions and the following disclaimer in the
1819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman *    documentation and/or other materials provided with the distribution.
1919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman * 3. Neither the name of the University nor the names of its contributors
2019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman *    may be used to endorse or promote products derived from this software
2119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman *    without specific prior written permission.
2219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman *
2319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman * SUCH DAMAGE.
3419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman *
3519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman *	@(#)regerror.c	8.4 (Berkeley) 3/20/94
3619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman */
3719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
3819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include <sys/types.h>
3919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include <stdio.h>
4019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include <string.h>
4119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include <ctype.h>
4219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include <limits.h>
4319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include <stdlib.h>
4419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "regex_impl.h"
4519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
4619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "regutils.h"
4719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
4819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#ifdef _MSC_VER
4919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#define snprintf _snprintf
5019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#endif
5119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
5219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic const char *regatoi(const llvm_regex_t *, char *, int);
5319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
5419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic struct rerr {
5519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	int code;
5619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	const char *name;
5719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	const char *explain;
5819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} rerrs[] = {
5919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	{ REG_NOMATCH,	"REG_NOMATCH",	"llvm_regexec() failed to match" },
6019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	{ REG_BADPAT,	"REG_BADPAT",	"invalid regular expression" },
6119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	{ REG_ECOLLATE,	"REG_ECOLLATE",	"invalid collating element" },
6219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	{ REG_ECTYPE,	"REG_ECTYPE",	"invalid character class" },
6319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	{ REG_EESCAPE,	"REG_EESCAPE",	"trailing backslash (\\)" },
6419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	{ REG_ESUBREG,	"REG_ESUBREG",	"invalid backreference number" },
6519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	{ REG_EBRACK,	"REG_EBRACK",	"brackets ([ ]) not balanced" },
6619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	{ REG_EPAREN,	"REG_EPAREN",	"parentheses not balanced" },
6719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	{ REG_EBRACE,	"REG_EBRACE",	"braces not balanced" },
6819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	{ REG_BADBR,	"REG_BADBR",	"invalid repetition count(s)" },
6919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	{ REG_ERANGE,	"REG_ERANGE",	"invalid character range" },
7019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	{ REG_ESPACE,	"REG_ESPACE",	"out of memory" },
7119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	{ REG_BADRPT,	"REG_BADRPT",	"repetition-operator operand invalid" },
7219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	{ REG_EMPTY,	"REG_EMPTY",	"empty (sub)expression" },
7319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	{ REG_ASSERT,	"REG_ASSERT",	"\"can't happen\" -- you found a bug" },
7419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	{ REG_INVARG,	"REG_INVARG",	"invalid argument to regex routine" },
7519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	{ 0,		"",		"*** unknown regexp error code ***" }
7619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman};
7719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
7819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/*
7919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman - llvm_regerror - the interface to error numbers
8019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman = extern size_t llvm_regerror(int, const llvm_regex_t *, char *, size_t);
8119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman */
8219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/* ARGSUSED */
8319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumansize_t
8419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanllvm_regerror(int errcode, const llvm_regex_t *preg, char *errbuf, size_t errbuf_size)
8519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman{
8619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	struct rerr *r;
8719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	size_t len;
8819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	int target = errcode &~ REG_ITOA;
8919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	const char *s;
9019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	char convbuf[50];
9119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
9219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	if (errcode == REG_ATOI)
9319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		s = regatoi(preg, convbuf, sizeof convbuf);
9419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	else {
9519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		for (r = rerrs; r->code != 0; r++)
9619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			if (r->code == target)
9719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				break;
9819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
9919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		if (errcode&REG_ITOA) {
10019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			if (r->code != 0) {
10119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				assert(strlen(r->name) < sizeof(convbuf));
10219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				(void) llvm_strlcpy(convbuf, r->name, sizeof convbuf);
10319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			} else
10419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				(void)snprintf(convbuf, sizeof convbuf,
10519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman				    "REG_0x%x", target);
10619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			s = convbuf;
10719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		} else
10819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			s = r->explain;
10919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	}
11019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
11119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	len = strlen(s) + 1;
11219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	if (errbuf_size > 0) {
11319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		llvm_strlcpy(errbuf, s, errbuf_size);
11419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	}
11519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
11619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	return(len);
11719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
11819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
11919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/*
12019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman - regatoi - internal routine to implement REG_ATOI
12119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman */
12219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic const char *
12319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanregatoi(const llvm_regex_t *preg, char *localbuf, int localbufsize)
12419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman{
12519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	struct rerr *r;
12619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
12719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	for (r = rerrs; r->code != 0; r++)
12819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		if (strcmp(r->name, preg->re_endp) == 0)
12919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman			break;
13019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	if (r->code == 0)
13119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman		return("0");
13219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
13319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	(void)snprintf(localbuf, localbufsize, "%d", r->code);
13419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman	return(localbuf);
13519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
136