diff options
Diffstat (limited to 'usr.bin/lex/regex.c')
-rw-r--r-- | usr.bin/lex/regex.c | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/usr.bin/lex/regex.c b/usr.bin/lex/regex.c new file mode 100644 index 00000000000..4144231b416 --- /dev/null +++ b/usr.bin/lex/regex.c @@ -0,0 +1,174 @@ +/* $OpenBSD: regex.c,v 1.1 2015/11/19 19:43:40 tedu Exp $ */ + +/** regex - regular expression functions related to POSIX regex lib. */ + +/* This file is part of flex. */ + +/* Redistribution and use in source and binary forms, with or without */ +/* modification, are permitted provided that the following conditions */ +/* are met: */ + +/* 1. Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* 2. Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in the */ +/* documentation and/or other materials provided with the distribution. */ + +/* Neither the name of the University nor the names of its contributors */ +/* may be used to endorse or promote products derived from this software */ +/* without specific prior written permission. */ + +/* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR */ +/* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */ +/* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */ +/* PURPOSE. */ + +#include "flexdef.h" + + +static const char* REGEXP_LINEDIR = "^#line ([[:digit:]]+) \"(.*)\""; +static const char* REGEXP_BLANK_LINE = "^[[:space:]]*$"; + +regex_t regex_linedir; /**< matches line directives */ +regex_t regex_blank_line; /**< matches blank lines */ + + +/** Initialize the regular expressions. + * @return true upon success. + */ +bool flex_init_regex(void) +{ + flex_regcomp(®ex_linedir, REGEXP_LINEDIR, REG_EXTENDED); + flex_regcomp(®ex_blank_line, REGEXP_BLANK_LINE, REG_EXTENDED); + + return true; +} + +/** Compiles a regular expression or dies trying. + * @param preg Same as for regcomp(). + * @param regex Same as for regcomp(). + * @param cflags Same as for regcomp(). + */ +void flex_regcomp(regex_t *preg, const char *regex, int cflags) +{ + int err; + + memset (preg, 0, sizeof (regex_t)); + + if ((err = regcomp (preg, regex, cflags)) != 0) { + const int errbuf_sz = 200; + char *errbuf, *rxerr; + + errbuf = (char*)flex_alloc(errbuf_sz *sizeof(char)); + if (!errbuf) + flexfatal(_("Unable to allocate buffer to report regcomp")); + rxerr = (char*)flex_alloc(errbuf_sz *sizeof(char)); + if (!rxerr) + flexfatal(_("Unable to allocate buffer for regerror")); + regerror (err, preg, rxerr, errbuf_sz); + snprintf (errbuf, errbuf_sz, "regcomp for \"%s\" failed: %s", regex, rxerr); + + flexfatal (errbuf); + free(errbuf); + free(rxerr); + } +} + +/** Extract a copy of the match, or NULL if no match. + * @param m A match as returned by regexec(). + * @param src The source string that was passed to regexec(). + * @return The allocated string. + */ +char *regmatch_dup (regmatch_t * m, const char *src) +{ + char *str; + int len; + + if (m == NULL || m->rm_so < 0) + return NULL; + len = m->rm_eo - m->rm_so; + str = (char *) flex_alloc ((len + 1) * sizeof (char)); + if (!str) + flexfatal(_("Unable to allocate a copy of the match")); + strncpy (str, src + m->rm_so, len); + str[len] = 0; + return str; +} + +/** Copy the match. + * @param m A match as returned by regexec(). + * @param dest The destination buffer. + * @param src The source string that was passed to regexec(). + * @return dest + */ +char *regmatch_cpy (regmatch_t * m, char *dest, const char *src) +{ + if (m == NULL || m->rm_so < 0) { + if (dest) + dest[0] = '\0'; + return dest; + } + + snprintf (dest, regmatch_len(m), "%s", src + m->rm_so); + return dest; +} + +/** Get the length in characters of the match. + * @param m A match as returned by regexec(). + * @param src The source string that was passed to regexec(). + * @return The length of the match. + */ +int regmatch_len (regmatch_t * m) +{ + if (m == NULL || m->rm_so < 0) { + return 0; + } + + return m->rm_eo - m->rm_so; +} + + + +/** Convert a regmatch_t object to an integer using the strtol() function. + * @param m A match as returned by regexec(). + * @param src The source string that was passed to regexec(). + * @param endptr Same as the second argument to strtol(). + * @param base Same as the third argument to strtol(). + * @return The converted integer or error (Return value is the same as for strtol()). + */ +int regmatch_strtol (regmatch_t * m, const char *src, char **endptr, + int base) +{ + int n = 0; + +#define bufsz 20 + char buf[bufsz]; + char *s; + + if (m == NULL || m->rm_so < 0) + return 0; + + if (regmatch_len (m) < bufsz) + s = regmatch_cpy (m, buf, src); + else + s = regmatch_dup (m, src); + + n = strtol (s, endptr, base); + + if (s != buf) + free (s); + + return n; +} + +/** Check for empty or non-existent match. + * @param m A match as returned by regexec(). + * @return false if match length is non-zero. + * Note that reg_empty returns true even if match did not occur at all. + */ +bool regmatch_empty (regmatch_t * m) +{ + return (m == NULL || m->rm_so < 0 || m->rm_so == m->rm_eo); +} + +/* vim:set expandtab cindent tabstop=4 softtabstop=4 shiftwidth=4 textwidth=0: */ |