Rev 54706 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
/*tre_regcomp.c - TRE POSIX compatible regex compilation functions.This software is released under a BSD-style license.See the file LICENSE for details and copyright.*/#ifdef HAVE_CONFIG_H#include <config.h>#endif /* HAVE_CONFIG_H */#include <string.h>#include <errno.h>#include <stdlib.h>#include "tre.h"#include "tre-internal.h"#include "xmalloc.h"inttre_regncomp(regex_t *preg, const char *regex, size_t n, int cflags){int ret;#if TRE_WCHARtre_char_t *wregex;size_t wlen;wregex = xmalloc(sizeof(tre_char_t) * (n + 1));if (wregex == NULL)return REG_ESPACE;/* If the current locale uses the standard single byte encoding ofcharacters, we don't do a multibyte string conversion. If we did,many applications which use the default locale would break sincethe default "C" locale uses the 7-bit ASCII character set, andall characters with the eighth bit set would be considered invalid. */#if TRE_MULTIBYTEif (TRE_MB_CUR_MAX == 1)#endif /* TRE_MULTIBYTE */{unsigned int i;const unsigned char *str = (const unsigned char *)regex;tre_char_t *wstr = wregex;for (i = 0; i < n; i++)*(wstr++) = *(str++);wlen = n;}#if TRE_MULTIBYTEelse{int consumed;tre_char_t *wcptr = wregex;#ifdef HAVE_MBSTATE_Tmbstate_t state;memset(&state, '\0', sizeof(state));#endif /* HAVE_MBSTATE_T */while (n > 0){consumed = tre_mbrtowc(wcptr, regex, n, &state);switch (consumed){case 0:if (*regex == '\0')consumed = 1;else{xfree(wregex);return REG_BADPAT;}break;case -1:DPRINT(("mbrtowc: error %d: %s.\n", errno, strerror(errno)));xfree(wregex);return REG_BADPAT;case -2:/* The last character wasn't complete. Let's not call it afatal error. */consumed = n;break;}regex += consumed;n -= consumed;wcptr++;}wlen = wcptr - wregex;}#endif /* TRE_MULTIBYTE */wregex[wlen] = L'\0';ret = tre_compile(preg, wregex, wlen, cflags);xfree(wregex);#else /* !TRE_WCHAR */ret = tre_compile(preg, (const tre_char_t *)regex, n, cflags);#endif /* !TRE_WCHAR */return ret;}/* this version takes bytes literally, to be used with raw vectors */inttre_regncompb(regex_t *preg, const char *regex, size_t n, int cflags){int ret;#if TRE_WCHAR /* wide chars = we need to convert it all to the wide format */tre_char_t *wregex;size_t i;wregex = xmalloc(sizeof(tre_char_t) * n);if (wregex == NULL)return REG_ESPACE;for (i = 0; i < n; i++)wregex[i] = (tre_char_t) ((unsigned char) regex[i]);ret = tre_compile(preg, wregex, n, cflags);xfree(wregex);#else /* !TRE_WCHAR */ret = tre_compile(preg, (const tre_char_t *)regex, n, cflags);#endif /* !TRE_WCHAR */return ret;}inttre_regcomp(regex_t *preg, const char *regex, int cflags){return tre_regncomp(preg, regex, regex ? strlen(regex) : 0, cflags);}/* R addition */inttre_regcompb(regex_t *preg, const char *regex, int cflags){int ret;tre_char_t *wregex;size_t wlen, n = strlen(regex);unsigned int i;const unsigned char *str = (const unsigned char *)regex;tre_char_t *wstr;wregex = xmalloc(sizeof(tre_char_t) * (n + 1));if (wregex == NULL) return REG_ESPACE;wstr = wregex;for (i = 0; i < n; i++) *(wstr++) = *(str++);wlen = n;wregex[wlen] = L'\0';ret = tre_compile(preg, wregex, wlen, cflags);xfree(wregex);return ret;}#ifdef TRE_WCHARinttre_regwncomp(regex_t *preg, const wchar_t *regex, size_t n, int cflags){return tre_compile(preg, regex, n, cflags);}inttre_regwcomp(regex_t *preg, const wchar_t *regex, int cflags){return tre_compile(preg, regex, regex ? wcslen(regex) : 0, cflags);}#endif /* TRE_WCHAR */voidtre_regfree(regex_t *preg){tre_free(preg);}/* EOF */