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(®ex_linedir, REGEXP_LINEDIR, REG_EXTENDED);
! 42: flex_regcomp(®ex_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: */