155848Sbostic /*-
266362Sbostic * Copyright (c) 1992, 1993, 1994 Henry Spencer.
366362Sbostic * Copyright (c) 1992, 1993, 1994
461162Sbostic * The Regents of the University of California. All rights reserved.
555848Sbostic *
655848Sbostic * This code is derived from software contributed to Berkeley by
7*66406Sbostic * Henry Spencer.
855848Sbostic *
955848Sbostic * %sccs.include.redist.c%
1055848Sbostic *
11*66406Sbostic * @(#)regerror.c 8.4 (Berkeley) 03/20/94
1255848Sbostic */
1355848Sbostic
1455848Sbostic #if defined(LIBC_SCCS) && !defined(lint)
15*66406Sbostic static char sccsid[] = "@(#)regerror.c 8.4 (Berkeley) 03/20/94";
1655848Sbostic #endif /* LIBC_SCCS and not lint */
1755848Sbostic
1855848Sbostic #include <sys/types.h>
1955848Sbostic #include <stdio.h>
2055848Sbostic #include <string.h>
2155848Sbostic #include <ctype.h>
2255848Sbostic #include <limits.h>
2355848Sbostic #include <stdlib.h>
2455848Sbostic #include <regex.h>
2555848Sbostic
2655848Sbostic #include "utils.h"
2755848Sbostic
2866362Sbostic /* ========= begin header generated by ./mkh ========= */
2966362Sbostic #ifdef __cplusplus
3066362Sbostic extern "C" {
3166362Sbostic #endif
3260201Sbostic
3366362Sbostic /* === regerror.c === */
3466385Sbostic static char *regatoi __P((const regex_t *preg, char *localbuf));
3566362Sbostic
3666362Sbostic #ifdef __cplusplus
3766362Sbostic }
3866362Sbostic #endif
3966362Sbostic /* ========= end header generated by ./mkh ========= */
4060201Sbostic /*
4160201Sbostic = #define REG_NOMATCH 1
4260201Sbostic = #define REG_BADPAT 2
4360201Sbostic = #define REG_ECOLLATE 3
4460201Sbostic = #define REG_ECTYPE 4
4560201Sbostic = #define REG_EESCAPE 5
4660201Sbostic = #define REG_ESUBREG 6
4760201Sbostic = #define REG_EBRACK 7
4860201Sbostic = #define REG_EPAREN 8
4960201Sbostic = #define REG_EBRACE 9
5060201Sbostic = #define REG_BADBR 10
5160201Sbostic = #define REG_ERANGE 11
5260201Sbostic = #define REG_ESPACE 12
5360201Sbostic = #define REG_BADRPT 13
5460201Sbostic = #define REG_EMPTY 14
5560201Sbostic = #define REG_ASSERT 15
5660201Sbostic = #define REG_INVARG 16
5760201Sbostic = #define REG_ATOI 255 // convert name to number (!)
5860201Sbostic = #define REG_ITOA 0400 // convert number to name (!)
5960201Sbostic */
6055848Sbostic static struct rerr {
6155848Sbostic int code;
6255848Sbostic char *name;
6355848Sbostic char *explain;
6455848Sbostic } rerrs[] = {
6560201Sbostic REG_NOMATCH, "REG_NOMATCH", "regexec() failed to match",
6660201Sbostic REG_BADPAT, "REG_BADPAT", "invalid regular expression",
6760201Sbostic REG_ECOLLATE, "REG_ECOLLATE", "invalid collating element",
6860201Sbostic REG_ECTYPE, "REG_ECTYPE", "invalid character class",
6960201Sbostic REG_EESCAPE, "REG_EESCAPE", "trailing backslash (\\)",
7060201Sbostic REG_ESUBREG, "REG_ESUBREG", "invalid backreference number",
7160201Sbostic REG_EBRACK, "REG_EBRACK", "brackets ([ ]) not balanced",
7260201Sbostic REG_EPAREN, "REG_EPAREN", "parentheses not balanced",
7360201Sbostic REG_EBRACE, "REG_EBRACE", "braces not balanced",
7460201Sbostic REG_BADBR, "REG_BADBR", "invalid repetition count(s)",
7560201Sbostic REG_ERANGE, "REG_ERANGE", "invalid character range",
7660201Sbostic REG_ESPACE, "REG_ESPACE", "out of memory",
7760201Sbostic REG_BADRPT, "REG_BADRPT", "repetition-operator operand invalid",
7860201Sbostic REG_EMPTY, "REG_EMPTY", "empty (sub)expression",
7960201Sbostic REG_ASSERT, "REG_ASSERT", "\"can't happen\" -- you found a bug",
8060201Sbostic REG_INVARG, "REG_INVARG", "invalid argument to regex routine",
8155848Sbostic 0, "", "*** unknown regexp error code ***",
8255848Sbostic };
8355848Sbostic
8455848Sbostic /*
8555848Sbostic - regerror - the interface to error numbers
8666362Sbostic = extern size_t regerror(int, const regex_t *, char *, size_t);
8755848Sbostic */
8855848Sbostic /* ARGSUSED */
8955848Sbostic size_t
regerror(errcode,preg,errbuf,errbuf_size)9055848Sbostic regerror(errcode, preg, errbuf, errbuf_size)
9155848Sbostic int errcode;
9255848Sbostic const regex_t *preg;
9355848Sbostic char *errbuf;
9455848Sbostic size_t errbuf_size;
9555848Sbostic {
9655848Sbostic register struct rerr *r;
9755848Sbostic register size_t len;
9860201Sbostic register int target = errcode &~ REG_ITOA;
9960201Sbostic register char *s;
10060201Sbostic char convbuf[50];
10155848Sbostic
10260201Sbostic if (errcode == REG_ATOI)
10360201Sbostic s = regatoi(preg, convbuf);
10460201Sbostic else {
10560201Sbostic for (r = rerrs; r->code != 0; r++)
10660201Sbostic if (r->code == target)
10760201Sbostic break;
10860201Sbostic
10960201Sbostic if (errcode®_ITOA) {
11060201Sbostic if (r->code != 0)
11160201Sbostic (void) strcpy(convbuf, r->name);
11260201Sbostic else
11360201Sbostic sprintf(convbuf, "REG_0x%x", target);
11460201Sbostic assert(strlen(convbuf) < sizeof(convbuf));
11560201Sbostic s = convbuf;
11660201Sbostic } else
11760201Sbostic s = r->explain;
11860201Sbostic }
11955848Sbostic
12060201Sbostic len = strlen(s) + 1;
12155848Sbostic if (errbuf_size > 0) {
12255848Sbostic if (errbuf_size > len)
12360201Sbostic (void) strcpy(errbuf, s);
12455848Sbostic else {
12560201Sbostic (void) strncpy(errbuf, s, errbuf_size-1);
12655848Sbostic errbuf[errbuf_size-1] = '\0';
12755848Sbostic }
12855848Sbostic }
12955848Sbostic
13055848Sbostic return(len);
13155848Sbostic }
13255848Sbostic
13355848Sbostic /*
13460201Sbostic - regatoi - internal routine to implement REG_ATOI
13566362Sbostic == static char *regatoi(const regex_t *preg, char *localbuf);
13655848Sbostic */
13760201Sbostic static char *
regatoi(preg,localbuf)13860201Sbostic regatoi(preg, localbuf)
13960201Sbostic const regex_t *preg;
14060201Sbostic char *localbuf;
14155848Sbostic {
14255848Sbostic register struct rerr *r;
14360201Sbostic register size_t siz;
14460201Sbostic register char *p;
14555848Sbostic
14655848Sbostic for (r = rerrs; r->code != 0; r++)
14760201Sbostic if (strcmp(r->name, preg->re_endp) == 0)
14860201Sbostic break;
14960201Sbostic if (r->code == 0)
15060201Sbostic return("0");
15155848Sbostic
15260201Sbostic sprintf(localbuf, "%d", r->code);
15360201Sbostic return(localbuf);
15455848Sbostic }
155