about summary refs log tree commit diff
path: root/posix/glob.c
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>1996-03-17 01:58:17 +0000
committerRoland McGrath <roland@gnu.org>1996-03-17 01:58:17 +0000
commit6025c399e9fd73efeb5b93db78ec021d3fce2b1c (patch)
treee213f46f05f3cb8638d22a81d437a32754062173 /posix/glob.c
parentd3b7d2ac93ed6fce3f7cb8e567d2b96719dde01a (diff)
downloadglibc-6025c399e9fd73efeb5b93db78ec021d3fce2b1c.tar.gz
glibc-6025c399e9fd73efeb5b93db78ec021d3fce2b1c.tar.xz
glibc-6025c399e9fd73efeb5b93db78ec021d3fce2b1c.zip
Sat Mar 16 20:08:22 1996 David Mosberger-Tang <davidm@azstarnet.com>
	* sysdeps/alpha/memchr.S: new file.
	* sysdeps/alpha/memchr.c: obsolete file removed.

Sat Mar 16 16:26:09 1996  Roland McGrath  <roland@charlie-brown.gnu.ai.mit.edu>

	* misc/Makefile (headers): Add sysexits.h.
	* misc/sysexits.h: New file.

Thu Mar 14 15:20:45 1996  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* sysdeps/libm-ieee754/e_atan2.c (__ieee754_atan2): Change atan
	call to __atan.
	* sysdeps/libm-ieee754/e_atan2f.c (__ieee754_atan2f): Change atanf
 	call to __atanf.

	* sysdeps/m68k/fpu/e_acos.c, sysdeps/m68k/fpu/e_acosf.c,
	sysdeps/m68k/fpu/e_asin.c, sysdeps/m68k/fpu/e_asinf.c,
	sysdeps/m68k/fpu/e_atanh.c, sysdeps/m68k/fpu/e_atanhf.c,
	sysdeps/m68k/fpu/e_cosh.c, sysdeps/m68k/fpu/e_coshf.c,
	sysdeps/m68k/fpu/e_exp.c, sysdeps/m68k/fpu/e_expf.c,
	sysdeps/m68k/fpu/e_fmod.c, sysdeps/m68k/fpu/e_fmodf.c,
	sysdeps/m68k/fpu/e_log.c, sysdeps/m68k/fpu/e_log10.c,
	sysdeps/m68k/fpu/e_log10f.c, sysdeps/m68k/fpu/e_logf.c,
	sysdeps/m68k/fpu/e_pow.c, sysdeps/m68k/fpu/e_powf.c,
	sysdeps/m68k/fpu/e_remainder.c, sysdeps/m68k/fpu/e_remainderf.c,
	sysdeps/m68k/fpu/e_scalb.c, sysdeps/m68k/fpu/e_scalbf.c,
	sysdeps/m68k/fpu/e_sinh.c, sysdeps/m68k/fpu/e_sinhf.c,
	sysdeps/m68k/fpu/e_sqrt.c, sysdeps/m68k/fpu/e_sqrtf.c,
	sysdeps/m68k/fpu/k_cos.c, sysdeps/m68k/fpu/k_cosf.c,
	sysdeps/m68k/fpu/k_sin.c, sysdeps/m68k/fpu/k_sinf.c,
	sysdeps/m68k/fpu/k_tan.c, sysdeps/m68k/fpu/k_tanf.c,
	sysdeps/m68k/fpu/s_atan.c, sysdeps/m68k/fpu/s_atanf.c,
	sysdeps/m68k/fpu/s_ceil.c, sysdeps/m68k/fpu/s_ceilf.c,
	sysdeps/m68k/fpu/s_cos.c, sysdeps/m68k/fpu/s_cosf.c,
	sysdeps/m68k/fpu/s_expm1.c, sysdeps/m68k/fpu/s_expm1f.c,
	sysdeps/m68k/fpu/s_fabs.c, sysdeps/m68k/fpu/s_fabsf.c,
	sysdeps/m68k/fpu/s_finite.c, sysdeps/m68k/fpu/s_finitef.c,
	sysdeps/m68k/fpu/s_floor.c, sysdeps/m68k/fpu/s_floorf.c,
	sysdeps/m68k/fpu/s_frexp.c, sysdeps/m68k/fpu/s_frexpf.c,
	sysdeps/m68k/fpu/s_ilogb.c, sysdeps/m68k/fpu/s_ilogbf.c,
	sysdeps/m68k/fpu/s_isinf.c, sysdeps/m68k/fpu/s_isinff.c,
	sysdeps/m68k/fpu/s_isnan.c, sysdeps/m68k/fpu/s_isnanf.c,
	sysdeps/m68k/fpu/s_ldexp.c, sysdeps/m68k/fpu/s_ldexpf.c,
	sysdeps/m68k/fpu/s_log1p.c, sysdeps/m68k/fpu/s_log1pf.c,
	sysdeps/m68k/fpu/s_logb.c, sysdeps/m68k/fpu/s_logbf.c,
	sysdeps/m68k/fpu/s_modf.c, sysdeps/m68k/fpu/s_modff.c,
	sysdeps/m68k/fpu/s_rint.c, sysdeps/m68k/fpu/s_rintf.c,
	sysdeps/m68k/fpu/s_scalbn.c, sysdeps/m68k/fpu/s_scalbnf.c,
	sysdeps/m68k/fpu/s_significand.c,
	sysdeps/m68k/fpu/s_significandf.c, sysdeps/m68k/fpu/s_sin.c,
	sysdeps/m68k/fpu/s_sinf.c, sysdeps/m68k/fpu/s_tan.c,
	sysdeps/m68k/fpu/s_tanf.c, sysdeps/m68k/fpu/s_tanh.c,
	sysdeps/m68k/fpu/s_tanhf.c: New files, for m68881 port of fdlibm.

	* sysdeps/m68k/fpu/__math.h: Rewritten for fdlibm.

	* sysdeps/m68k/fpu/isinfl.c: Rewritten to get argument type right.
	* sysdeps/m68k/fpu/isnanl.c: Likewise.

Thu Mar 14 06:01:07 1996  Roland McGrath  <roland@charlie-brown.gnu.ai.mit.edu>

	* posix/glob.c (glob): In GLOB_BRACE brace expansion, fix buffer size
	calculation to include trailing invariant portion.  Don't use alloca;
	instead use a dynamic auto array for GCC, malloc for non-GCC.
	Handle nested braces properly.

	* elf/elf.h (Elf32_auxv_t): Specify prototype (void) for `a_un.a_fcn'.

	* libc-symbols.h (lint): New macro.

Fri Mar 15 01:18:00 1996  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* libio/iosetvbuf.c: Add weak alias setvbuf.
Diffstat (limited to 'posix/glob.c')
-rw-r--r--posix/glob.c139
1 files changed, 106 insertions, 33 deletions
diff --git a/posix/glob.c b/posix/glob.c
index 8646bba570..eea126d800 100644
--- a/posix/glob.c
+++ b/posix/glob.c
@@ -268,48 +268,121 @@ glob (pattern, flags, errfunc, pglob)
       const char *begin = strchr (pattern, '{');
       if (begin != NULL)
 	{
-	  const char *end = strchr (begin + 1, '}');
-	  if (end != NULL && end != begin + 1)
+	  int firstc;
+	  size_t restlen;
+	  const char *p, *end, *next;
+	  unsigned int depth = 0;
+
+	  /* Find the end of the brace expression, by counting braces.
+	     While we're at it, notice the first comma at top brace level.  */
+	  end = begin + 1;
+	  next = NULL;
+	  while (1)
 	    {
-	      size_t restlen = strlen (end + 1) + 1;
-	      const char *p, *comma;
-	      char *buf;
-	      size_t bufsz = 0;
-	      int firstc;
-	      if (!(flags & GLOB_APPEND))
+	      switch (*end++)
 		{
-		  pglob->gl_pathc = 0;
-		  pglob->gl_pathv = NULL;
+		case ',':
+		  if (depth == 0 && next == NULL)
+		    next = end;
+		  continue;
+		case '{':
+		  ++depth;
+		  continue;
+		case '}':
+		  if (depth-- == 0)
+		    break;
+		  continue;
+		case '\0':
+		  return glob (pattern, flags &~ GLOB_BRACE, errfunc, pglob);
 		}
-	      firstc = pglob->gl_pathc;
-	      for (p = begin + 1;; p = comma + 1)
+	      break;
+	    }
+	  restlen = strlen (end) + 1;
+	  if (next == NULL)
+	    next = end;
+
+	  /* We have a brace expression.  BEGIN points to the opening {,
+	     NEXT points past the terminator of the first element, and END
+	     points past the final }.  We will accumulate result names from
+	     recursive runs for each brace alternative in the buffer using
+	     GLOB_APPEND.  */
+
+	  if (!(flags & GLOB_APPEND))
+	    {
+	      /* This call is to set a new vector, so clear out the
+		 vector so we can append to it.  */
+	      pglob->gl_pathc = 0;
+	      pglob->gl_pathv = NULL;
+	    }
+	  firstc = pglob->gl_pathc;
+
+	  /* In this loop P points to the beginning of the current element
+	     and NEXT points past its terminator.  */
+	  p = begin + 1;
+	  while (1)
+	    {
+	      /* Construct a whole name that is one of the brace
+		 alternatives in a temporary buffer.  */
+	      int result;
+	      size_t bufsz = (begin - pattern) + (next - 1 - p) + restlen;
+#ifdef __GNUC__
+	      char onealt[bufsz];
+#else
+	      char *onealt = malloc (bufsz);
+	      if (onealt == NULL)
 		{
-		  int result;
-		  comma = strchr (p, ',');
-		  if (comma == NULL)
-		    comma = strchr (p, '\0');
-		  if ((begin - pattern) + (comma - p) + 1 > bufsz)
+		  if (!(flags & GLOB_APPEND))
+		    globfree (&pglob);
+		  return GLOB_NOSPACE;
+		}
+#endif
+	      memcpy (onealt, pattern, begin - pattern);
+	      memcpy (&onealt[begin - pattern], p, next - 1 - p);
+	      memcpy (&onealt[(begin - pattern) + (next - 1 - p)],
+		      end, restlen);
+	      result = glob (onealt,
+			     ((flags & ~(GLOB_NOCHECK|GLOB_NOMAGIC)) |
+			      GLOB_APPEND), errfunc, pglob);
+#ifndef __GNUC__
+	      free (onealt);
+#endif
+
+	      /* If we got an error, return it.  */
+	      if (result && result != GLOB_NOMATCH)
+		{
+		  if (!(flags & GLOB_APPEND))
+		    globfree (pglob);
+		  return result;
+		}
+
+	      /* Advance past this alternative and process the next.  */
+	      p = next;
+	      depth = 0;
+	    scan:
+	      switch (*p++)
+		{
+		case ',':
+		  if (depth == 0)
 		    {
-		      if (bufsz * 2 < comma - p + 1)
-			bufsz *= 2;
-		      else
-			bufsz = comma - p + 1;
-		      buf = __alloca (bufsz);
+		      /* Found the next alternative.  Loop to glob it.  */
+		      next = p;
+		      continue;
 		    }
-		  memcpy (buf, pattern, begin - pattern);
-		  memcpy (buf + (begin - pattern), p, comma - p);
-		  memcpy (buf + (begin - pattern) + (comma - p), end, restlen);
-		  result = glob (buf, ((flags & ~(GLOB_NOCHECK|GLOB_NOMAGIC)) |
-				       GLOB_APPEND), errfunc, pglob);
-		  if (result && result != GLOB_NOMATCH)
-		    return result;
-		  if (*comma == '\0')
+		  goto scan;
+		case '{':
+		  ++depth;
+		  goto scan;
+		case '}':
+		  if (depth-- == 0)
+		    /* End of the brace expression.  Break out of the loop.  */
 		    break;
+		  goto scan;
 		}
-	      if (pglob->gl_pathc == firstc &&
-		  !(flags & (GLOB_NOCHECK|GLOB_NOMAGIC)))
-		return GLOB_NOMATCH;
 	    }
+
+	  if (pglob->gl_pathc == firstc &&
+	      !(flags & (GLOB_NOCHECK|GLOB_NOMAGIC)))
+	    return GLOB_NOMATCH;
 	}
     }