[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.1

1.1     ! tedu        1: /* $OpenBSD$ */
        !             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: }
        !           173:
        !           174: /* vim:set expandtab cindent tabstop=4 softtabstop=4 shiftwidth=4 textwidth=0: */