diff --git a/lib/Makefile b/lib/Makefile index 8352329b7a5..2607d5d6ab5 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -160,6 +160,7 @@ _libcplusplus= libc++ .endif SUBDIR.${MK_EFI}+= libefivar +SUBDIR.${MK_LIBREGEX}+= libregex SUBDIR.${MK_LIBTHR}+= libthr SUBDIR.${MK_LLVM_LIBUNWIND}+= libgcc_eh SUBDIR.${MK_LLVM_LIBUNWIND}+= libgcc_s diff --git a/lib/libc/regex/Makefile.inc b/lib/libc/regex/Makefile.inc index 4595361b281..5a73c90f5ad 100644 --- a/lib/libc/regex/Makefile.inc +++ b/lib/libc/regex/Makefile.inc @@ -2,7 +2,7 @@ # $FreeBSD$ # regex sources -.PATH: ${LIBC_SRCTOP}/regex +.PATH: ${SRCTOP}/lib/libc/regex CFLAGS+=-DPOSIX_MISTAKE @@ -10,8 +10,11 @@ SRCS+= regcomp.c regerror.c regexec.c regfree.c SYM_MAPS+=${LIBC_SRCTOP}/regex/Symbol.map +# manpages only included in libc version +.if ${LIB} == "c" MAN+= regex.3 MAN+= re_format.7 MLINKS+=regex.3 regcomp.3 regex.3 regexec.3 regex.3 regerror.3 MLINKS+=regexec.3 regfree.3 +.endif diff --git a/lib/libc/regex/cname.h b/lib/libc/regex/cname.h index ba7dd8cb964..28452c93fe7 100644 --- a/lib/libc/regex/cname.h +++ b/lib/libc/regex/cname.h @@ -36,7 +36,7 @@ /* character-name table */ static struct cname { - char *name; + const char *name; char code; } cnames[] = { {"NUL", '\0'}, diff --git a/lib/libc/regex/engine.c b/lib/libc/regex/engine.c index 073e0010882..95c04b712ab 100644 --- a/lib/libc/regex/engine.c +++ b/lib/libc/regex/engine.c @@ -680,7 +680,7 @@ backref(struct match *m, ssp = m->offp + m->pmatch[i].rm_so; if (memcmp(sp, ssp, len) != 0) return(NULL); - while (m->g->strip[ss] != SOP(O_BACK, i)) + while (m->g->strip[ss] != (sop)SOP(O_BACK, i)) ss++; return(backref(m, sp+len, stop, ss+1, stopst, lev, rec)); case OQUEST_: /* to null or not */ @@ -841,7 +841,7 @@ fast( struct match *m, } /* are we done? */ - if (ISSET(st, stopst) || p == stop || clen > stop - p) + if (ISSET(st, stopst) || p == stop || clen > (size_t)(stop - p)) break; /* NOTE BREAK OUT */ /* no, we must deal with this character */ @@ -946,7 +946,7 @@ slow( struct match *m, /* are we done? */ if (ISSET(st, stopst)) matchp = p; - if (EQ(st, empty) || p == stop || clen > stop - p) + if (EQ(st, empty) || p == stop || clen > (size_t)(stop - p)) break; /* NOTE BREAK OUT */ /* no, we must deal with this character */ diff --git a/lib/libc/regex/regcomp.c b/lib/libc/regex/regcomp.c index 95764717bda..63966b0d9ce 100644 --- a/lib/libc/regex/regcomp.c +++ b/lib/libc/regex/regcomp.c @@ -54,7 +54,9 @@ __FBSDID("$FreeBSD$"); #include #include +#ifndef LIBREGEX_BUILD #include "collate.h" +#endif #include "utils.h" #include "regex2.h" @@ -92,6 +94,7 @@ static void p_bre(struct parse *p, int end1, int end2); static int p_simp_re(struct parse *p, int starordinary); static int p_count(struct parse *p); static void p_bracket(struct parse *p); +static int p_range_cmp(wchar_t c1, wchar_t c2); static void p_b_term(struct parse *p, cset *cs); static void p_b_cclass(struct parse *p, cset *cs); static void p_b_eclass(struct parse *p, cset *cs); @@ -207,7 +210,7 @@ regcomp(regex_t * __restrict preg, return(REG_INVARG); len = preg->re_endp - pattern; } else - len = strlen((char *)pattern); + len = strlen(pattern); /* do the mallocs early so failure handling is easy */ g = (struct re_guts *)malloc(sizeof(struct re_guts)); @@ -239,7 +242,7 @@ regcomp(regex_t * __restrict preg, /* set things up */ p->g = g; - p->next = (char *)pattern; /* convenience; we do not modify it */ + p->next = __DECONST(char *, pattern); /* convenience; we do not modify it */ p->end = p->next + len; p->error = 0; p->ncsalloc = 0; @@ -757,6 +760,23 @@ p_bracket(struct parse *p) EMIT(OANYOF, (int)(cs - p->g->sets)); } +static int +p_range_cmp(wchar_t c1, wchar_t c2) +{ +#ifndef LIBREGEX_BUILD + return __wcollate_range_cmp(c1, c2); +#else + /* Copied from libc/collate __wcollate_range_cmp */ + wchar_t s1[2], s2[2]; + + s1[0] = c1; + s1[1] = L'\0'; + s2[0] = c2; + s2[1] = L'\0'; + return (wcscoll(s1, s2)); +#endif +} + /* - p_b_term - parse one term of a bracketed character list == static void p_b_term(struct parse *p, cset *cs); @@ -767,9 +787,10 @@ p_b_term(struct parse *p, cset *cs) char c; wint_t start, finish; wint_t i; +#ifndef LIBREGEX_BUILD struct xlocale_collate *table = (struct xlocale_collate*)__get_locale()->components[XLC_COLLATE]; - +#endif /* classify what we've got */ switch ((MORE()) ? PEEK() : '\0') { case '[': @@ -816,15 +837,18 @@ p_b_term(struct parse *p, cset *cs) if (start == finish) CHadd(p, cs, start); else { +#ifndef LIBREGEX_BUILD if (table->__collate_load_error || MB_CUR_MAX > 1) { +#else + if (MB_CUR_MAX > 1) { +#endif (void)REQUIRE(start <= finish, REG_ERANGE); CHaddrange(p, cs, start, finish); } else { - (void)REQUIRE(__wcollate_range_cmp(start, finish) <= 0, REG_ERANGE); + (void)REQUIRE(p_range_cmp(start, finish) <= 0, REG_ERANGE); for (i = 0; i <= UCHAR_MAX; i++) { - if ( __wcollate_range_cmp(start, i) <= 0 - && __wcollate_range_cmp(i, finish) <= 0 - ) + if (p_range_cmp(start, i) <= 0 && + p_range_cmp(i, finish) <= 0 ) CHadd(p, cs, i); } } @@ -905,7 +929,7 @@ p_b_coll_elem(struct parse *p, { char *sp = p->next; struct cname *cp; - int len; + size_t len; mbstate_t mbs; wchar_t wc; size_t clen; diff --git a/lib/libc/regex/regerror.c b/lib/libc/regex/regerror.c index 253f0b1fb71..8496ba78002 100644 --- a/lib/libc/regex/regerror.c +++ b/lib/libc/regex/regerror.c @@ -54,7 +54,7 @@ extern "C" { #endif /* === regerror.c === */ -static char *regatoi(const regex_t *preg, char *localbuf); +static const char *regatoi(const regex_t *preg, char *localbuf); #ifdef __cplusplus } @@ -83,8 +83,8 @@ static char *regatoi(const regex_t *preg, char *localbuf); */ static struct rerr { int code; - char *name; - char *explain; + const char *name; + const char *explain; } rerrs[] = { {REG_NOMATCH, "REG_NOMATCH", "regexec() failed to match"}, {REG_BADPAT, "REG_BADPAT", "invalid regular expression"}, @@ -120,7 +120,7 @@ regerror(int errcode, struct rerr *r; size_t len; int target = errcode &~ REG_ITOA; - char *s; + const char *s; char convbuf[50]; if (errcode == REG_ATOI) @@ -158,7 +158,7 @@ regerror(int errcode, - regatoi - internal routine to implement REG_ATOI == static char *regatoi(const regex_t *preg, char *localbuf); */ -static char * +static const char * regatoi(const regex_t *preg, char *localbuf) { struct rerr *r; diff --git a/lib/libc/regex/regexec.c b/lib/libc/regex/regexec.c index 0edfe43dbab..cf141069aa8 100644 --- a/lib/libc/regex/regexec.c +++ b/lib/libc/regex/regexec.c @@ -225,9 +225,9 @@ regexec(const regex_t * __restrict preg, eflags = GOODFLAGS(eflags); if (MB_CUR_MAX > 1) - return(mmatcher(g, (char *)string, nmatch, pmatch, eflags)); - else if (g->nstates <= CHAR_BIT*sizeof(states1) && !(eflags®_LARGE)) - return(smatcher(g, (char *)string, nmatch, pmatch, eflags)); + return(mmatcher(g, string, nmatch, pmatch, eflags)); + else if (g->nstates <= (sopno)(CHAR_BIT*sizeof(states1)) && !(eflags®_LARGE)) + return(smatcher(g, string, nmatch, pmatch, eflags)); else - return(lmatcher(g, (char *)string, nmatch, pmatch, eflags)); + return(lmatcher(g, string, nmatch, pmatch, eflags)); } diff --git a/lib/libregex/Makefile b/lib/libregex/Makefile new file mode 100644 index 00000000000..12b559a6534 --- /dev/null +++ b/lib/libregex/Makefile @@ -0,0 +1,10 @@ +# $FreeBSD$ + +PACKAGE=lib${LIB} +LIB= regex + +CFLAGS+= -DLIBREGEX_BUILD +SYMBOL_MAPS= ${SYM_MAPS} + +.include "${SRCTOP}/lib/libc/regex/Makefile.inc" +.include diff --git a/share/mk/src.opts.mk b/share/mk/src.opts.mk index 86485557b70..5d07a47b30f 100644 --- a/share/mk/src.opts.mk +++ b/share/mk/src.opts.mk @@ -122,6 +122,7 @@ __DEFAULT_YES_OPTIONS = \ LEGACY_CONSOLE \ LIB32 \ LIBPTHREAD \ + LIBREGEX \ LIBTHR \ LOCALES \ LOCATE \ diff --git a/tools/build/options/WITHOUT_LIBREGEX b/tools/build/options/WITHOUT_LIBREGEX new file mode 100644 index 00000000000..7206749a0d4 --- /dev/null +++ b/tools/build/options/WITHOUT_LIBREGEX @@ -0,0 +1,4 @@ +.\" $FreeBSD$ +Set to not build the +.Nm libregex +library for GNU regex(3) extensions.