1/* $NetBSD$ */ 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 29static const char* REGEXP_LINEDIR = "^#line ([[:digit:]]+) \"(.*)\""; 30static const char* REGEXP_BLANK_LINE = "^[[:space:]]*$"; 31 32regex_t regex_linedir; /**< matches line directives */ 33regex_t regex_blank_line; /**< matches blank lines */ 34 35 36/** Initialize the regular expressions. 37 * @return true upon success. 38 */ 39bool 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 */ 52void 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=0; 61 62 errbuf = (char*)flex_alloc(errbuf_sz *sizeof(char)); 63 regerror (err, preg, errbuf, errbuf_sz); 64 snprintf (errbuf, errbuf_sz, "regcomp failed: %s\n", errbuf); 65 66 flexfatal (errbuf); 67 free(errbuf); 68 } 69} 70 71/** Extract a copy of the match, or NULL if no match. 72 * @param m A match as returned by regexec(). 73 * @param src The source string that was passed to regexec(). 74 * @return The allocated string. 75 */ 76char *regmatch_dup (regmatch_t * m, const char *src) 77{ 78 char *str; 79 int len; 80 81 if (m == NULL || m->rm_so < 0) 82 return NULL; 83 len = m->rm_eo - m->rm_so; 84 str = (char *) flex_alloc ((len + 1) * sizeof (char)); 85 strncpy (str, src + m->rm_so, len); 86 str[len] = 0; 87 return str; 88} 89 90/** Copy the match. 91 * @param m A match as returned by regexec(). 92 * @param dest The destination buffer. 93 * @param src The source string that was passed to regexec(). 94 * @return dest 95 */ 96char *regmatch_cpy (regmatch_t * m, char *dest, const char *src) 97{ 98 if (m == NULL || m->rm_so < 0) { 99 if (dest) 100 dest[0] = '\0'; 101 return dest; 102 } 103 104 snprintf (dest, regmatch_len(m), "%s", src + m->rm_so); 105 return dest; 106} 107 108/** Get the length in characters of the match. 109 * @param m A match as returned by regexec(). 110 * @param src The source string that was passed to regexec(). 111 * @return The length of the match. 112 */ 113int regmatch_len (regmatch_t * m) 114{ 115 if (m == NULL || m->rm_so < 0) { 116 return 0; 117 } 118 119 return m->rm_eo - m->rm_so; 120} 121 122 123 124/** Convert a regmatch_t object to an integer using the strtol() function. 125 * @param m A match as returned by regexec(). 126 * @param src The source string that was passed to regexec(). 127 * @param endptr Same as the second argument to strtol(). 128 * @param base Same as the third argument to strtol(). 129 * @return The converted integer or error (Return value is the same as for strtol()). 130 */ 131int regmatch_strtol (regmatch_t * m, const char *src, char **endptr, 132 int base) 133{ 134 int n = 0; 135 136#define bufsz 20 137 char buf[bufsz]; 138 char *s; 139 140 if (m == NULL || m->rm_so < 0) 141 return 0; 142 143 if (regmatch_len (m) < bufsz) 144 s = regmatch_cpy (m, buf, src); 145 else 146 s = regmatch_dup (m, src); 147 148 n = strtol (s, endptr, base); 149 150 if (s != buf) 151 free (s); 152 153 return n; 154} 155 156/** Check for empty or non-existent match. 157 * @param m A match as returned by regexec(). 158 * @return false if match length is non-zero. 159 * Note that reg_empty returns true even if match did not occur at all. 160 */ 161bool regmatch_empty (regmatch_t * m) 162{ 163 return (m == NULL || m->rm_so < 0 || m->rm_so == m->rm_eo); 164} 165 166/* vim:set expandtab cindent tabstop=4 softtabstop=4 shiftwidth=4 textwidth=0: */ 167