]> git.ipfire.org Git - thirdparty/bash.git/blame - lib/sh/shmatch.c
fix for SIGINT in sourced script
[thirdparty/bash.git] / lib / sh / shmatch.c
CommitLineData
3185942a
JA
1/*
2 * shmatch.c -- shell interface to posix regular expression matching.
3 */
4
a0c0a00f 5/* Copyright (C) 2003-2015 Free Software Foundation, Inc.
b80f6443
JA
6
7 This file is part of GNU Bash, the Bourne Again SHell.
8
3185942a
JA
9 Bash is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
b80f6443 13
3185942a
JA
14 Bash is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
b80f6443 18
3185942a
JA
19 You should have received a copy of the GNU General Public License
20 along with Bash. If not, see <http://www.gnu.org/licenses/>.
21*/
b80f6443
JA
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
95732b49 42extern int glob_ignore_case, match_ignore_case;
b80f6443
JA
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
0628567a 60 int result;
b80f6443
JA
61
62#if defined (ARRAY_VARS)
63 rematch = (SHELL_VAR *)NULL;
64#endif
495aee44 65
b80f6443 66 rflags = REG_EXTENDED;
95732b49 67 if (glob_ignore_case || match_ignore_case)
b80f6443
JA
68 rflags |= REG_ICASE;
69#if !defined (ARRAY_VARS)
70 rflags |= REG_NOSUB;
71#endif
72
73 if (regcomp (&regex, 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
a0c0a00f
CR
82 /* man regexec: NULL PMATCH ignored if NMATCH == 0 */
83 if (regexec (&regex, string, matches ? regex.re_nsub + 1 : 0, matches, 0))
b80f6443
JA
84 result = EXECUTION_FAILURE;
85 else
86 result = EXECUTION_SUCCESS; /* match */
87
88#if defined (ARRAY_VARS)
89 subexp_len = strlen (string) + 10;
90 subexp_str = malloc (subexp_len + 1);
91
92 /* Store the parenthesized subexpressions in the array BASH_REMATCH.
93 Element 0 is the portion that matched the entire regexp. Element 1
94 is the part that matched the first subexpression, and so on. */
a0c0a00f 95 unbind_variable_noref ("BASH_REMATCH");
b80f6443
JA
96 rematch = make_new_array_variable ("BASH_REMATCH");
97 amatch = array_cell (rematch);
98
a0c0a00f 99 if (matches && (flags & SHMAT_SUBEXP) && result == EXECUTION_SUCCESS && subexp_str)
b80f6443
JA
100 {
101 for (subexp_ind = 0; subexp_ind <= regex.re_nsub; subexp_ind++)
102 {
103 memset (subexp_str, 0, subexp_len);
104 strncpy (subexp_str, string + matches[subexp_ind].rm_so,
105 matches[subexp_ind].rm_eo - matches[subexp_ind].rm_so);
106 array_insert (amatch, subexp_ind, subexp_str);
107 }
108 }
109
110 VSETATTR (rematch, att_readonly);
111
112 free (subexp_str);
113 free (matches);
114#endif /* ARRAY_VARS */
115
116 regfree (&regex);
117
118 return result;
119}
120
121#endif /* HAVE_POSIX_REGEXP */