summaryrefslogtreecommitdiff
path: root/lib/sh/shmatch.c
diff options
context:
space:
mode:
authorAn-Cheng Huang <ancheng@vyatta.com>2007-11-12 13:06:02 -0800
committerAn-Cheng Huang <ancheng@vyatta.com>2007-11-12 13:06:02 -0800
commitb7fc9e0f6d6105ba2203f219743d4b269415e84b (patch)
treeef6586dfc62798c2b17487b443864699aca55f31 /lib/sh/shmatch.c
downloadvyatta-bash-b7fc9e0f6d6105ba2203f219743d4b269415e84b.tar.gz
vyatta-bash-b7fc9e0f6d6105ba2203f219743d4b269415e84b.zip
initial import from bash_3.1dfsg.orig.tar.gz
Diffstat (limited to 'lib/sh/shmatch.c')
-rw-r--r--lib/sh/shmatch.c121
1 files changed, 121 insertions, 0 deletions
diff --git a/lib/sh/shmatch.c b/lib/sh/shmatch.c
new file mode 100644
index 0000000..4508ed0
--- /dev/null
+++ b/lib/sh/shmatch.c
@@ -0,0 +1,121 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+
+ This file is part of GNU Bash, the Bourne Again SHell.
+
+ Bash is free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as published by the Free
+ Software Foundation; either version 2, or (at your option) any later
+ version.
+
+ Bash is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with Bash; see the file COPYING. If not, write to the Free Software
+ Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+
+/*
+ * shmatch.c -- shell interface to posix regular expression matching.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if defined (HAVE_POSIX_REGEXP)
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#include "bashansi.h"
+
+#include <stdio.h>
+#include <regex.h>
+
+#include "shell.h"
+#include "variables.h"
+#include "externs.h"
+
+extern int glob_ignore_case, match_ignore_case;
+
+int
+sh_regmatch (string, pattern, flags)
+ const char *string;
+ const char *pattern;
+ int flags;
+{
+ regex_t regex = { 0 };
+ regmatch_t *matches;
+ int rflags;
+#if defined (ARRAY_VARS)
+ SHELL_VAR *rematch;
+ ARRAY *amatch;
+ int subexp_ind;
+ char *subexp_str;
+ int subexp_len;
+#endif
+ int result;
+
+
+#if defined (ARRAY_VARS)
+ rematch = (SHELL_VAR *)NULL;
+#endif
+
+ rflags = REG_EXTENDED;
+ if (glob_ignore_case || match_ignore_case)
+ rflags |= REG_ICASE;
+#if !defined (ARRAY_VARS)
+ rflags |= REG_NOSUB;
+#endif
+
+ if (regcomp (&regex, pattern, rflags))
+ return 2; /* flag for printing a warning here. */
+
+#if defined (ARRAY_VARS)
+ matches = (regmatch_t *)malloc (sizeof (regmatch_t) * (regex.re_nsub + 1));
+#else
+ matches = NULL;
+#endif
+
+ if (regexec (&regex, string, regex.re_nsub + 1, matches, 0))
+ result = EXECUTION_FAILURE;
+ else
+ result = EXECUTION_SUCCESS; /* match */
+
+#if defined (ARRAY_VARS)
+ subexp_len = strlen (string) + 10;
+ subexp_str = malloc (subexp_len + 1);
+
+ /* Store the parenthesized subexpressions in the array BASH_REMATCH.
+ Element 0 is the portion that matched the entire regexp. Element 1
+ is the part that matched the first subexpression, and so on. */
+ unbind_variable ("BASH_REMATCH");
+ rematch = make_new_array_variable ("BASH_REMATCH");
+ amatch = array_cell (rematch);
+
+ if ((flags & SHMAT_SUBEXP) && result == EXECUTION_SUCCESS && subexp_str)
+ {
+ for (subexp_ind = 0; subexp_ind <= regex.re_nsub; subexp_ind++)
+ {
+ memset (subexp_str, 0, subexp_len);
+ strncpy (subexp_str, string + matches[subexp_ind].rm_so,
+ matches[subexp_ind].rm_eo - matches[subexp_ind].rm_so);
+ array_insert (amatch, subexp_ind, subexp_str);
+ }
+ }
+
+ VSETATTR (rematch, att_readonly);
+
+ free (subexp_str);
+ free (matches);
+#endif /* ARRAY_VARS */
+
+ regfree (&regex);
+
+ return result;
+}
+
+#endif /* HAVE_POSIX_REGEXP */