regex(3) documents non-standard extensions REG_ITOA and REG_ATOI to
regerror(). In the OpenBSD tree, the only use of them is by the regress
test, so why not move that specific code to the regress test and shrink
libc a bit - remember that this code is present in the installation
media through grep(1).
Assuming there are no objections against this, it would be worth trying
a ports build with this diff to confirm there are no 3rd-party users of
these extensions.
Index: include/regex.h
===================================================================
RCS file: /OpenBSD/src/include/regex.h,v
retrieving revision 1.7
diff -u -p -r1.7 regex.h
--- include/regex.h 5 Dec 2012 23:19:57 -0000 1.7
+++ include/regex.h 3 Jan 2021 17:48:03 -0000
@@ -83,8 +83,6 @@ typedef struct {
#define REG_EMPTY 14
#define REG_ASSERT 15
#define REG_INVARG 16
-#define REG_ATOI 255 /* convert name to number (!) */
-#define REG_ITOA 0400 /* convert number to name (!) */
/* regexec() flags */
#define REG_NOTBOL 00001
Index: lib/libc/regex/regerror.c
===================================================================
RCS file: /OpenBSD/src/lib/libc/regex/regerror.c,v
retrieving revision 1.15
diff -u -p -r1.15 regerror.c
--- lib/libc/regex/regerror.c 30 Dec 2020 08:56:38 -0000 1.15
+++ lib/libc/regex/regerror.c 3 Jan 2021 17:48:03 -0000
@@ -48,26 +48,25 @@ static const char *regatoi(const regex_t
static const struct rerr {
int code;
- const char *name;
const char *explain;
} rerrs[] = {
- { REG_NOMATCH, "REG_NOMATCH", "regexec() failed to match" },
- { REG_BADPAT, "REG_BADPAT", "invalid regular expression" },
- { REG_ECOLLATE, "REG_ECOLLATE", "invalid collating element" },
- { REG_ECTYPE, "REG_ECTYPE", "invalid character class" },
- { REG_EESCAPE, "REG_EESCAPE", "trailing backslash (\\)" },
- { REG_ESUBREG, "REG_ESUBREG", "invalid backreference number" },
- { REG_EBRACK, "REG_EBRACK", "brackets ([ ]) not balanced" },
- { REG_EPAREN, "REG_EPAREN", "parentheses not balanced" },
- { REG_EBRACE, "REG_EBRACE", "braces not balanced" },
- { REG_BADBR, "REG_BADBR", "invalid repetition count(s)" },
- { REG_ERANGE, "REG_ERANGE", "invalid character range" },
- { REG_ESPACE, "REG_ESPACE", "out of memory" },
- { REG_BADRPT, "REG_BADRPT", "repetition-operator operand invalid" },
- { REG_EMPTY, "REG_EMPTY", "empty (sub)expression" },
- { REG_ASSERT, "REG_ASSERT", "\"can't happen\" -- you found a bug" },
- { REG_INVARG, "REG_INVARG", "invalid argument to regex routine" },
- { 0, "", "*** unknown regexp error code ***" }
+ { REG_NOMATCH, "regexec() failed to match" },
+ { REG_BADPAT, "invalid regular expression" },
+ { REG_ECOLLATE, "invalid collating element" },
+ { REG_ECTYPE, "invalid character class" },
+ { REG_EESCAPE, "trailing backslash (\\)" },
+ { REG_ESUBREG, "invalid backreference number" },
+ { REG_EBRACK, "brackets ([ ]) not balanced" },
+ { REG_EPAREN, "parentheses not balanced" },
+ { REG_EBRACE, "braces not balanced" },
+ { REG_BADBR, "invalid repetition count(s)" },
+ { REG_ERANGE, "invalid character range" },
+ { REG_ESPACE, "out of memory" },
+ { REG_BADRPT, "repetition-operator operand invalid" },
+ { REG_EMPTY, "empty (sub)expression" },
+ { REG_ASSERT, "\"can't happen\" -- you found a bug" },
+ { REG_INVARG, "invalid argument to regex routine" },
+ { 0, "unknown regexp error code ***" }
};
/*
@@ -79,51 +78,15 @@ regerror(int errcode, const regex_t *pre
{
const struct rerr *r;
size_t len;
- int target = errcode &~ REG_ITOA;
- const char *s;
- char convbuf[50];
- if (errcode == REG_ATOI)
- s = regatoi(preg, convbuf, sizeof convbuf);
- else {
- for (r = rerrs; r->code != 0; r++)
- if (r->code == target)
- break;
-
- if (errcode®_ITOA) {
- if (r->code != 0) {
- assert(strlen(r->name) < sizeof(convbuf));
- (void) strlcpy(convbuf, r->name, sizeof
convbuf);
- } else
- (void)snprintf(convbuf, sizeof convbuf,
- "REG_0x%x", target);
- s = convbuf;
- } else
- s = r->explain;
- }
+ for (r = rerrs; r->code != 0; r++)
+ if (r->code == errcode)
+ break;
if (errbuf_size != 0)
- len = strlcpy(errbuf, s, errbuf_size);
+ len = strlcpy(errbuf, r->explain, errbuf_size);
else
- len = strlen(s);
+ len = strlen(r->explain);
return len + 1;
-}
-
-/*
- - regatoi - internal routine to implement REG_ATOI
- */
-static const char *
-regatoi(const regex_t *preg, char *localbuf, int localbufsize)
-{
- const struct rerr *r;
-
- for (r = rerrs; r->code != 0; r++)
- if (strcmp(r->name, preg->re_endp) == 0)
- break;
- if (r->code == 0)
- return("0");
-
- (void)snprintf(localbuf, localbufsize, "%d", r->code);
- return(localbuf);
}
Index: lib/libc/regex/regex.3
===================================================================
RCS file: /OpenBSD/src/lib/libc/regex/regex.3,v
retrieving revision 1.27
diff -u -p -r1.27 regex.3
--- lib/libc/regex/regex.3 26 May 2016 05:46:44 -0000 1.27
+++ lib/libc/regex/regex.3 3 Jan 2021 17:48:03 -0000
@@ -448,46 +448,6 @@ is 0,
.Fa errbuf
is ignored but the return value is still correct.
.Pp
-If the
-.Fa errcode
-given to
-.Fn regerror
-is first
-.Tn OR Ns 'ed
-with
-.Dv REG_ITOA ,
-the
-.Dq message
-that results is the printable name of the error code,
-e.g.,
-.Dq REG_NOMATCH ,
-rather than an explanation thereof.
-If
-.Fa errcode
-is
-.Dv REG_ATOI ,
-then
-.Fa preg
-shall be non-null and the
-.Fa re_endp
-member of the structure it points to
-must point to the printable name of an error code;
-in this case, the result in
-.Fa errbuf
-is the decimal digits of
-the numeric value of the error code
-(0 if the name is not recognized).
-.Dv REG_ITOA
-and
-.Dv REG_ATOI
-are intended primarily as debugging facilities;
-they are extensions,
-compatible with but not specified by
-.St -p1003.2
-and should be used with
-caution in software intended to be portable to other systems.
-Be warned also that they are considered experimental and changes are possible.
-.Pp
.Fn regfree
frees any dynamically allocated storage associated with the compiled RE
pointed to by
Index: regress/lib/libc/regex/main.c
===================================================================
RCS file: /OpenBSD/src/regress/lib/libc/regex/main.c,v
retrieving revision 1.11
diff -u -p -r1.11 main.c
--- regress/lib/libc/regex/main.c 14 Feb 2020 19:17:34 -0000 1.11
+++ regress/lib/libc/regex/main.c 3 Jan 2021 17:48:03 -0000
@@ -179,20 +179,20 @@ FILE *in;
erbuf, SHORT-1, badpat);
status = 1;
}
- ne = regerror(REG_ITOA|REG_BADPAT, (regex_t *)NULL, erbuf,
sizeof(erbuf));
+ ne = regitoa(REG_BADPAT, erbuf, sizeof(erbuf));
if (strcmp(erbuf, bpname) != 0 || ne != strlen(bpname)+1) {
- fprintf(stderr, "end: regerror() ITOA test gave `%s' not
`%s'\n",
+ fprintf(stderr, "end: regitoa() test gave `%s' not `%s'\n",
erbuf, bpname);
status = 1;
}
re.re_endp = bpname;
- ne = regerror(REG_ATOI, &re, erbuf, sizeof(erbuf));
+ ne = regatoi(&re, erbuf, sizeof(erbuf));
if (atoi(erbuf) != (int)REG_BADPAT) {
- fprintf(stderr, "end: regerror() ATOI test gave `%s' not
`%ld'\n",
+ fprintf(stderr, "end: regatoi() test gave `%s' not `%ld'\n",
erbuf, (long)REG_BADPAT);
status = 1;
} else if (ne != strlen(erbuf)+1) {
- fprintf(stderr, "end: regerror() ATOI test len(`%s') = %ld\n",
+ fprintf(stderr, "end: regatoi() test len(`%s') = %ld\n",
erbuf, (long)REG_BADPAT);
status = 1;
}
@@ -482,6 +482,29 @@ char *should;
return(NULL);
}
+static const struct rerr {
+ int code;
+ const char *name;
+} rerrs[] = {
+ { REG_NOMATCH, "REG_NOMATCH" },
+ { REG_BADPAT, "REG_BADPAT" },
+ { REG_ECOLLATE, "REG_ECOLLATE" },
+ { REG_ECTYPE, "REG_ECTYPE" },
+ { REG_EESCAPE, "REG_EESCAPE" },
+ { REG_ESUBREG, "REG_ESUBREG" },
+ { REG_EBRACK, "REG_EBRACK" },
+ { REG_EPAREN, "REG_EPAREN" },
+ { REG_EBRACE, "REG_EBRACE" },
+ { REG_BADBR, "REG_BADBR" },
+ { REG_ERANGE, "REG_ERANGE" },
+ { REG_ESPACE, "REG_ESPACE" },
+ { REG_BADRPT, "REG_BADRPT" },
+ { REG_EMPTY, "REG_EMPTY" },
+ { REG_ASSERT, "REG_ASSERT" },
+ { REG_INVARG, "REG_INVARG" },
+ { 0, "" }
+};
+
/*
- eprint - convert error number to name
== static char *eprint(int err);
@@ -493,7 +516,7 @@ int err;
static char epbuf[100];
size_t len;
- len = regerror(REG_ITOA|err, (regex_t *)NULL, epbuf, sizeof(epbuf));
+ len = regitoa(err, epbuf, sizeof(epbuf));
assert(len <= sizeof(epbuf));
return(epbuf);
}
@@ -512,6 +535,46 @@ char *name;
snprintf(efbuf, sizeof efbuf, "REG_%s", name);
assert(strlen(efbuf) < sizeof(efbuf));
re.re_endp = efbuf;
- (void) regerror(REG_ATOI, &re, efbuf, sizeof(efbuf));
+ (void) regatoi(&re, efbuf, sizeof(efbuf));
return(atoi(efbuf));
+}
+
+static size_t
+regitoa(int errcode, char *errbuf, size_t errbuf_size)
+{
+ const struct rerr *r;
+ size_t len;
+ const char *s;
+ char convbuf[50];
+
+ for (r = rerrs; r->code != 0; r++)
+ if (r->code == errcode)
+ break;
+
+ if (r->code != 0) {
+ (void) strlcpy(convbuf, r->name, sizeof convbuf);
+ } else
+ (void)snprintf(convbuf, sizeof convbuf, "REG_0x%x", errcode);
+ s = convbuf;
+
+ if (errbuf_size != 0)
+ len = strlcpy(errbuf, s, errbuf_size);
+ else
+ len = strlen(s);
+
+ return len + 1;
+}
+
+static size_t
+regatoi(const regex_t *preg, char *buf, size_t bufsize)
+{
+ const struct rerr *r;
+
+ for (r = rerrs; r->code != 0; r++)
+ if (strcmp(r->name, preg->re_endp) == 0)
+ break;
+ if (r->code == 0)
+ return strlcpy(buf, "0", bufsize) + 1;
+
+ return snprintf(buf, bufsize, "%d", r->code) + 1;
}
Index: regress/lib/libc/regex/main.ih
===================================================================
RCS file: /OpenBSD/src/regress/lib/libc/regex/main.ih,v
retrieving revision 1.3
diff -u -p -r1.3 main.ih
--- regress/lib/libc/regex/main.ih 16 Feb 2002 21:27:32 -0000 1.3
+++ regress/lib/libc/regex/main.ih 3 Jan 2021 17:48:03 -0000
@@ -15,6 +15,8 @@ void fixstr(register char *p);
char *check(char *str, regmatch_t sub, char *should);
static char *eprint(int err);
static int efind(char *name);
+static size_t regitoa(int, char *, size_t);
+static size_t regatoi(const regex_t *, char *, size_t);
#ifdef __cplusplus
}