[BACK]Return to regex.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / lex

Annotation of src/usr.bin/lex/regex.c, Revision 1.2

1.2     ! tedu        1: /* $OpenBSD: regex.c,v 1.1 2015/11/19 19:43:40 tedu Exp $ */
1.1       tedu        2:
                      3: /** regex - regular expression functions related to POSIX regex lib. */
                      4:
                      5: /*  This file is part of flex. */
                      6:
                      7: /*  Redistribution and use in source and binary forms, with or without */
                      8: /*  modification, are permitted provided that the following conditions */
                      9: /*  are met: */
                     10:
                     11: /*  1. Redistributions of source code must retain the above copyright */
                     12: /*     notice, this list of conditions and the following disclaimer. */
                     13: /*  2. Redistributions in binary form must reproduce the above copyright */
                     14: /*     notice, this list of conditions and the following disclaimer in the */
                     15: /*     documentation and/or other materials provided with the distribution. */
                     16:
                     17: /*  Neither the name of the University nor the names of its contributors */
                     18: /*  may be used to endorse or promote products derived from this software */
                     19: /*  without specific prior written permission. */
                     20:
                     21: /*  THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR */
                     22: /*  IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */
                     23: /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */
                     24: /*  PURPOSE. */
                     25:
                     26: #include "flexdef.h"
                     27:
                     28:
                     29: static const char* REGEXP_LINEDIR = "^#line ([[:digit:]]+) \"(.*)\"";
                     30: static const char* REGEXP_BLANK_LINE = "^[[:space:]]*$";
                     31:
                     32: regex_t regex_linedir; /**< matches line directives */
                     33: regex_t regex_blank_line; /**< matches blank lines */
                     34:
                     35:
                     36: /** Initialize the regular expressions.
                     37:  * @return true upon success.
                     38:  */
                     39: bool flex_init_regex(void)
                     40: {
                     41:     flex_regcomp(&regex_linedir, REGEXP_LINEDIR, REG_EXTENDED);
                     42:     flex_regcomp(&regex_blank_line, REGEXP_BLANK_LINE, REG_EXTENDED);
                     43:
                     44:     return true;
                     45: }
                     46:
                     47: /** Compiles a regular expression or dies trying.
                     48:  * @param preg  Same as for regcomp().
                     49:  * @param regex Same as for regcomp().
                     50:  * @param cflags Same as for regcomp().
                     51:  */
                     52: void flex_regcomp(regex_t *preg, const char *regex, int cflags)
                     53: {
                     54:     int err;
                     55:
                     56:        memset (preg, 0, sizeof (regex_t));
                     57:
                     58:        if ((err = regcomp (preg, regex, cflags)) != 0) {
                     59:         const int errbuf_sz = 200;
                     60:         char *errbuf, *rxerr;
                     61:
                     62:                errbuf = (char*)flex_alloc(errbuf_sz *sizeof(char));
                     63:                if (!errbuf)
                     64:                        flexfatal(_("Unable to allocate buffer to report regcomp"));
                     65:                rxerr = (char*)flex_alloc(errbuf_sz *sizeof(char));
                     66:                if (!rxerr)
                     67:                        flexfatal(_("Unable to allocate buffer for regerror"));
                     68:                regerror (err, preg, rxerr, errbuf_sz);
                     69:                snprintf (errbuf, errbuf_sz, "regcomp for \"%s\" failed: %s", regex, rxerr);
                     70:
                     71:                flexfatal (errbuf);
                     72:         free(errbuf);
                     73:         free(rxerr);
                     74:        }
                     75: }
                     76:
                     77: /** Extract a copy of the match, or NULL if no match.
                     78:  * @param m A match as returned by regexec().
                     79:  * @param src The source string that was passed to regexec().
                     80:  * @return The allocated string.
                     81:  */
                     82: char   *regmatch_dup (regmatch_t * m, const char *src)
                     83: {
                     84:        char   *str;
                     85:        int     len;
                     86:
                     87:        if (m == NULL || m->rm_so < 0)
                     88:                return NULL;
                     89:        len = m->rm_eo - m->rm_so;
                     90:        str = (char *) flex_alloc ((len + 1) * sizeof (char));
                     91:        if (!str)
                     92:                flexfatal(_("Unable to allocate a copy of the match"));
                     93:        strncpy (str, src + m->rm_so, len);
                     94:        str[len] = 0;
                     95:        return str;
                     96: }
                     97:
                     98: /** Copy the match.
                     99:  * @param m A match as returned by regexec().
                    100:  * @param dest The destination buffer.
                    101:  * @param src The source string that was passed to regexec().
                    102:  * @return dest
                    103:  */
                    104: char   *regmatch_cpy (regmatch_t * m, char *dest, const char *src)
                    105: {
                    106:        if (m == NULL || m->rm_so < 0) {
                    107:                if (dest)
                    108:                        dest[0] = '\0';
                    109:                return dest;
                    110:        }
                    111:
                    112:        snprintf (dest, regmatch_len(m), "%s", src + m->rm_so);
                    113:     return dest;
                    114: }
                    115:
                    116: /** Get the length in characters of the match.
                    117:  * @param m A match as returned by regexec().
                    118:  * @param src The source string that was passed to regexec().
                    119:  * @return The length of the match.
                    120:  */
                    121: int regmatch_len (regmatch_t * m)
                    122: {
                    123:        if (m == NULL || m->rm_so < 0) {
                    124:                return 0;
                    125:        }
                    126:
                    127:        return m->rm_eo - m->rm_so;
                    128: }
                    129:
                    130:
                    131:
                    132: /** Convert a regmatch_t object to an integer using the strtol() function.
                    133:  * @param m A match as returned by regexec().
                    134:  * @param src The source string that was passed to regexec().
                    135:  * @param endptr Same as the second argument to strtol().
                    136:  * @param base   Same as the third argument to strtol().
                    137:  * @return The converted integer or error (Return value is the same as for strtol()).
                    138:  */
                    139: int regmatch_strtol (regmatch_t * m, const char *src, char **endptr,
                    140:                     int base)
                    141: {
                    142:        int     n = 0;
                    143:
                    144: #define bufsz 20
                    145:        char    buf[bufsz];
                    146:        char   *s;
                    147:
                    148:        if (m == NULL || m->rm_so < 0)
                    149:                return 0;
                    150:
                    151:        if (regmatch_len (m) < bufsz)
                    152:                s = regmatch_cpy (m, buf, src);
                    153:        else
                    154:                s = regmatch_dup (m, src);
                    155:
                    156:        n = strtol (s, endptr, base);
                    157:
                    158:        if (s != buf)
                    159:                free (s);
                    160:
                    161:        return n;
                    162: }
                    163:
                    164: /** Check for empty or non-existent match.
                    165:  * @param m A match as returned by regexec().
                    166:  * @return false if match length is non-zero.
                    167:  * Note that reg_empty returns true even if match did not occur at all.
                    168:  */
                    169: bool regmatch_empty (regmatch_t * m)
                    170: {
                    171:        return (m == NULL || m->rm_so < 0 || m->rm_so == m->rm_eo);
                    172: }