1/* Copyright (C) 2003 Free Software Foundation, Inc. 2 3 This file is part of GNU Bash, the Bourne Again SHell. 4 5 Bash is free software; you can redistribute it and/or modify it under 6 the terms of the GNU General Public License as published by the Free 7 Software Foundation; either version 2, or (at your option) any later 8 version. 9 10 Bash is distributed in the hope that it will be useful, but WITHOUT ANY 11 WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 for more details. 14 15 You should have received a copy of the GNU General Public License along 16 with Bash; see the file COPYING. If not, write to the Free Software 17 Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ 18 19/* 20 * shmatch.c -- shell interface to posix regular expression matching. 21 */ 22 23#ifdef HAVE_CONFIG_H 24# include <config.h> 25#endif 26 27#if defined (HAVE_POSIX_REGEXP) 28 29#ifdef HAVE_UNISTD_H 30# include <unistd.h> 31#endif 32 33#include "bashansi.h" 34 35#include <stdio.h> 36#include <regex.h> 37 38#include "shell.h" 39#include "variables.h" 40#include "externs.h" 41 42extern int glob_ignore_case, match_ignore_case; 43 44int 45sh_regmatch (string, pattern, flags) 46 const char *string; 47 const char *pattern; 48 int flags; 49{ 50 regex_t regex = { 0 }; 51 regmatch_t *matches; 52 int rflags; 53#if defined (ARRAY_VARS) 54 SHELL_VAR *rematch; 55 ARRAY *amatch; 56 int subexp_ind; 57 char *subexp_str; 58 int subexp_len; 59#endif 60 int result; 61 62#if defined (ARRAY_VARS) 63 rematch = (SHELL_VAR *)NULL; 64#endif 65 66 rflags = REG_EXTENDED; 67 if (glob_ignore_case || match_ignore_case) 68 rflags |= REG_ICASE; 69#if !defined (ARRAY_VARS) 70 rflags |= REG_NOSUB; 71#endif 72 73 if (regcomp (®ex, pattern, rflags)) 74 return 2; /* flag for printing a warning here. */ 75 76#if defined (ARRAY_VARS) 77 matches = (regmatch_t *)malloc (sizeof (regmatch_t) * (regex.re_nsub + 1)); 78#else 79 matches = NULL; 80#endif 81 82 if (regexec (®ex, string, regex.re_nsub + 1, matches, 0)) 83 result = EXECUTION_FAILURE; 84 else 85 result = EXECUTION_SUCCESS; /* match */ 86 87#if defined (ARRAY_VARS) 88 subexp_len = strlen (string) + 10; 89 subexp_str = malloc (subexp_len + 1); 90 91 /* Store the parenthesized subexpressions in the array BASH_REMATCH. 92 Element 0 is the portion that matched the entire regexp. Element 1 93 is the part that matched the first subexpression, and so on. */ 94 unbind_variable ("BASH_REMATCH"); 95 rematch = make_new_array_variable ("BASH_REMATCH"); 96 amatch = array_cell (rematch); 97 98 if ((flags & SHMAT_SUBEXP) && result == EXECUTION_SUCCESS && subexp_str) 99 { 100 for (subexp_ind = 0; subexp_ind <= regex.re_nsub; subexp_ind++) 101 { 102 memset (subexp_str, 0, subexp_len); 103 strncpy (subexp_str, string + matches[subexp_ind].rm_so, 104 matches[subexp_ind].rm_eo - matches[subexp_ind].rm_so); 105 array_insert (amatch, subexp_ind, subexp_str); 106 } 107 } 108 109 VSETATTR (rematch, att_readonly); 110 111 free (subexp_str); 112 free (matches); 113#endif /* ARRAY_VARS */ 114 115 regfree (®ex); 116 117 return result; 118} 119 120#endif /* HAVE_POSIX_REGEXP */ 121