aboutsummaryrefslogtreecommitdiffstats
path: root/lib/glob/glob.c
diff options
context:
space:
mode:
authorJari Aalto <jari.aalto@cante.net>2004-07-27 13:29:18 +0000
committerJari Aalto <jari.aalto@cante.net>2009-09-12 16:46:56 +0000
commitb80f6443b6b7b620c7272664c66ecb0b120a0998 (patch)
tree9f71c98d8fe8fa0f41d95e1eb4227f32a09d43ca /lib/glob/glob.c
parent7117c2d221b2aed4ede8600f6a36b7c1454b4f55 (diff)
downloadandroid_external_bash-b80f6443b6b7b620c7272664c66ecb0b120a0998.tar.gz
android_external_bash-b80f6443b6b7b620c7272664c66ecb0b120a0998.tar.bz2
android_external_bash-b80f6443b6b7b620c7272664c66ecb0b120a0998.zip
Imported from ../bash-3.0.tar.gz.
Diffstat (limited to 'lib/glob/glob.c')
-rw-r--r--lib/glob/glob.c124
1 files changed, 74 insertions, 50 deletions
diff --git a/lib/glob/glob.c b/lib/glob/glob.c
index 27099f7..a62054e 100644
--- a/lib/glob/glob.c
+++ b/lib/glob/glob.c
@@ -62,6 +62,10 @@
# endif /* __STDC__ */
#endif /* !NULL */
+#if !defined (FREE)
+# define FREE(x) if (x) free (x)
+#endif
+
extern void throw_to_top_level __P((void));
extern int test_eaccess __P((char *, int));
@@ -118,7 +122,6 @@ glob_pattern_p (pattern)
const char *pattern;
{
#if HANDLE_MULTIBYTE
- mbstate_t ps;
size_t n;
wchar_t *wpattern;
int r;
@@ -127,15 +130,14 @@ glob_pattern_p (pattern)
return (internal_glob_pattern_p (pattern));
/* Convert strings to wide chars, and call the multibyte version. */
- memset (&ps, '\0', sizeof (ps));
- n = xmbsrtowcs (NULL, (const char **)&pattern, 0, &ps);
+ n = xdupmbstowcs (&wpattern, NULL, pattern);
if (n == (size_t)-1)
/* Oops. Invalid multibyte sequence. Try it as single-byte sequence. */
return (internal_glob_pattern_p (pattern));
- wpattern = (wchar_t *)xmalloc ((n + 1) * sizeof (wchar_t));
- (void) xmbsrtowcs (wpattern, (const char **)&pattern, n + 1, &ps);
+
r = internal_glob_wpattern_p (wpattern);
free (wpattern);
+
return r;
#else
return (internal_glob_pattern_p (pattern));
@@ -174,50 +176,36 @@ static int
mbskipname (pat, dname)
char *pat, *dname;
{
- char *pat_bak, *dn_bak;
+ int ret;
wchar_t *pat_wc, *dn_wc;
- mbstate_t pat_ps, dn_ps;
size_t pat_n, dn_n, n;
- n = strlen(pat);
- pat_bak = (char *) alloca (n + 1);
- memcpy (pat_bak, pat, n + 1);
-
- n = strlen(dname);
- dn_bak = (char *) alloca (n + 1);
- memcpy (dn_bak, dname, n + 1);
-
- memset(&pat_ps, '\0', sizeof(mbstate_t));
- memset(&dn_ps, '\0', sizeof(mbstate_t));
-
- pat_n = xmbsrtowcs (NULL, (const char **)&pat_bak, 0, &pat_ps);
- dn_n = xmbsrtowcs (NULL, (const char **)&dn_bak, 0, &dn_ps);
+ pat_n = xdupmbstowcs (&pat_wc, NULL, pat);
+ dn_n = xdupmbstowcs (&dn_wc, NULL, dname);
+ ret = 0;
if (pat_n != (size_t)-1 && dn_n !=(size_t)-1)
{
- pat_wc = (wchar_t *) alloca ((pat_n + 1) * sizeof(wchar_t));
- dn_wc = (wchar_t *) alloca ((dn_n + 1) * sizeof(wchar_t));
-
- (void) xmbsrtowcs (pat_wc, (const char **)&pat_bak, pat_n + 1, &pat_ps);
- (void) xmbsrtowcs (dn_wc, (const char **)&dn_bak, dn_n + 1, &dn_ps);
-
/* If a leading dot need not be explicitly matched, and the
pattern doesn't start with a `.', don't match `.' or `..' */
if (noglob_dot_filenames == 0 && pat_wc[0] != L'.' &&
(pat_wc[0] != L'\\' || pat_wc[1] != L'.') &&
(dn_wc[0] == L'.' &&
(dn_wc[1] == L'\0' || (dn_wc[1] == L'.' && dn_wc[2] == L'\0'))))
- return 1;
+ ret = 1;
/* If a leading dot must be explicity matched, check to see if the
pattern and dirname both have one. */
else if (noglob_dot_filenames && dn_wc[0] == L'.' &&
pat_wc[0] != L'.' &&
(pat_wc[0] != L'\\' || pat_wc[1] != L'.'))
- return 1;
+ ret = 1;
}
- return 0;
+ FREE (pat_wc);
+ FREE (dn_wc);
+
+ return ret;
}
#endif /* HANDLE_MULTIBYTE */
@@ -235,7 +223,7 @@ udequote_pathname (pathname)
pathname[j++] = pathname[i++];
- if (!pathname[i - 1])
+ if (pathname[i - 1] == 0)
break;
}
pathname[j] = '\0';
@@ -250,22 +238,16 @@ wdequote_pathname (pathname)
mbstate_t ps;
size_t len, n;
wchar_t *wpathname;
- char *pathname_bak;
int i, j;
+ wchar_t *orig_wpathname;
len = strlen (pathname);
- pathname_bak = (char *) alloca (len + 1);
- memcpy (pathname_bak, pathname , len + 1);
-
/* Convert the strings into wide characters. */
- memset (&ps, '\0', sizeof (ps));
- n = xmbsrtowcs (NULL, (const char **)&pathname_bak, 0, &ps);
+ n = xdupmbstowcs (&wpathname, NULL, pathname);
if (n == (size_t) -1)
/* Something wrong. */
return;
-
- wpathname = (wchar_t *) alloca ((n + 1) * sizeof (wchar_t));
- (void) xmbsrtowcs (wpathname, (const char **)&pathname_bak, n + 1, &ps);
+ orig_wpathname = wpathname;
for (i = j = 0; wpathname && wpathname[i]; )
{
@@ -274,7 +256,7 @@ wdequote_pathname (pathname)
wpathname[j++] = wpathname[i++];
- if (!wpathname[i - 1])
+ if (wpathname[i - 1] == L'\0')
break;
}
wpathname[j] = L'\0';
@@ -283,6 +265,9 @@ wdequote_pathname (pathname)
memset (&ps, '\0', sizeof(mbstate_t));
n = wcsrtombs(pathname, (const wchar_t **)&wpathname, len, &ps);
pathname[len] = '\0';
+
+ /* Can't just free wpathname here; wcsrtombs changes it in many cases. */
+ free (orig_wpathname);
}
static void
@@ -373,6 +358,9 @@ glob_vector (pat, dir, flags)
return ((char **) &glob_error_return);
nextlink = (struct globval *)alloca (sizeof (struct globval));
+ if (nextlink == NULL)
+ return ((char **) NULL);
+
nextlink->next = (struct globval *)0;
nextname = (char *) malloc (1);
if (nextname == 0)
@@ -418,10 +406,15 @@ glob_vector (pat, dir, flags)
{
free (nextname);
nextlink = (struct globval *)alloca (sizeof (struct globval));
- nextlink->next = (struct globval *)0;
- lastlink = nextlink;
- nextlink->name = npat;
- count = 1;
+ if (nextlink)
+ {
+ nextlink->next = (struct globval *)0;
+ lastlink = nextlink;
+ nextlink->name = npat;
+ count = 1;
+ }
+ else
+ lose = 1;
}
else
{
@@ -480,6 +473,11 @@ glob_vector (pat, dir, flags)
if (REAL_DIR_ENTRY (dp) == 0)
continue;
+#if 0
+ if (dp->d_name == 0 || *dp->d_name == 0)
+ continue;
+#endif
+
#if HANDLE_MULTIBYTE
if (MB_CUR_MAX > 1 && mbskipname (pat, dp->d_name))
continue;
@@ -490,14 +488,14 @@ glob_vector (pat, dir, flags)
if (strmatch (pat, dp->d_name, mflags) != FNM_NOMATCH)
{
- nextlink = (struct globval *) alloca (sizeof (struct globval));
- nextlink->next = lastlink;
nextname = (char *) malloc (D_NAMLEN (dp) + 1);
- if (nextname == NULL)
+ nextlink = (struct globval *) alloca (sizeof (struct globval));
+ if (nextlink == 0 || nextname == 0)
{
lose = 1;
break;
}
+ nextlink->next = lastlink;
lastlink = nextlink;
nextlink->name = nextname;
bcopy (dp->d_name, nextname, D_NAMLEN (dp) + 1);
@@ -631,6 +629,7 @@ glob_filename (pathname, flags)
unsigned int result_size;
char *directory_name, *filename;
unsigned int directory_len;
+ int free_dirname; /* flag */
result = (char **) malloc (sizeof (char *));
result_size = 1;
@@ -639,6 +638,8 @@ glob_filename (pathname, flags)
result[0] = NULL;
+ directory_name = NULL;
+
/* Find the filename. */
filename = strrchr (pathname, '/');
if (filename == NULL)
@@ -646,15 +647,20 @@ glob_filename (pathname, flags)
filename = pathname;
directory_name = "";
directory_len = 0;
+ free_dirname = 0;
}
else
{
directory_len = (filename - pathname) + 1;
- directory_name = (char *) alloca (directory_len + 1);
+ directory_name = (char *) malloc (directory_len + 1);
+
+ if (directory_name == 0) /* allocation failed? */
+ return (NULL);
bcopy (pathname, directory_name, directory_len);
directory_name[directory_len] = '\0';
++filename;
+ free_dirname = 1;
}
/* If directory_name contains globbing characters, then we
@@ -669,6 +675,12 @@ glob_filename (pathname, flags)
directories = glob_filename (directory_name, flags & ~GX_MARKDIRS);
+ if (free_dirname)
+ {
+ free (directory_name);
+ directory_name = NULL;
+ }
+
if (directories == NULL)
goto memory_error;
else if (directories == (char **)&glob_error_return)
@@ -746,6 +758,8 @@ glob_filename (pathname, flags)
if (result[0] == NULL)
goto memory_error;
bcopy (directory_name, result[0], directory_len + 1);
+ if (free_dirname)
+ free (directory_name);
result[1] = NULL;
return (result);
}
@@ -770,9 +784,16 @@ glob_filename (pathname, flags)
flags & ~GX_MARKDIRS);
if (temp_results == NULL || temp_results == (char **)&glob_error_return)
- return (temp_results);
+ {
+ if (free_dirname)
+ free (directory_name);
+ return (temp_results);
+ }
- return (glob_dir_to_array (directory_name, temp_results, flags));
+ result = glob_dir_to_array (directory_name, temp_results, flags);
+ if (free_dirname)
+ free (directory_name);
+ return (result);
}
/* We get to memory_error if the program has run out of memory, or
@@ -786,6 +807,9 @@ glob_filename (pathname, flags)
free ((char *) result);
}
+ if (free_dirname && directory_name)
+ free (directory_name);
+
QUIT;
return (NULL);