Imported from ../bash-3.0.tar.gz.
diff --git a/pcomplete.c b/pcomplete.c
index 1811351..7f5ac54 100644
--- a/pcomplete.c
+++ b/pcomplete.c
@@ -1,7 +1,7 @@
 /* pcomplete.c - functions to generate lists of matches for programmable
 		 completion. */
 
-/* Copyright (C) 1999-2002 Free Software Foundation, Inc.
+/* Copyright (C) 1999-2004 Free Software Foundation, Inc.
 
    This file is part of GNU Bash, the Bourne Again SHell.
 
@@ -40,6 +40,7 @@
 
 #include <stdio.h>
 #include "bashansi.h"
+#include "bashintl.h"
 
 #include "shell.h"
 #include "pcomplete.h"
@@ -371,6 +372,11 @@
   register int i, n;
 
   vlist = (*svfunc) ();
+  if (vlist == 0)
+    {
+      itp->slist = (STRINGLIST *)NULL;
+      return;
+    }    
   for (n = 0; vlist[n]; n++)
     ;
   sl = strlist_create (n+1);
@@ -628,7 +634,8 @@
 /* Generate a list of all matches for TEXT using the STRINGLIST in itp->slist
    as the list of possibilities.  If the itemlist has been marked dirty or
    it should be regenerated every time, destroy the old STRINGLIST and make a
-   new one before trying the match. */
+   new one before trying the match.  TEXT is dequoted before attempting a
+   match. */
 static STRINGLIST *
 gen_matches_from_itemlist (itp, text)
      ITEMLIST *itp;
@@ -636,6 +643,7 @@
 {
   STRINGLIST *ret, *sl;
   int tlen, i, n;
+  char *ntxt;
 
   if ((itp->flags & (LIST_DIRTY|LIST_DYNAMIC)) ||
       (itp->flags & LIST_INITIALIZED) == 0)
@@ -649,13 +657,18 @@
     return ((STRINGLIST *)NULL);
   ret = strlist_create (itp->slist->list_len+1);
   sl = itp->slist;
-  tlen = STRLEN (text);
+
+  ntxt = bash_dequote_text (text);
+  tlen = STRLEN (ntxt);
+
   for (i = n = 0; i < sl->list_len; i++)
     {
-      if (tlen == 0 || STREQN (sl->list[i], text, tlen))
+      if (tlen == 0 || STREQN (sl->list[i], ntxt, tlen))
 	ret->list[n++] = STRDUP (sl->list[i]);
     }
   ret->list[ret->list_len = n] = (char *)NULL;
+
+  FREE (ntxt);
   return ret;
 }
 
@@ -675,7 +688,15 @@
       /* remove backslashes quoting special characters in filenames. */
       if (rl_filename_dequoting_function)
 	{
+#if 0
 	  qc = (text[0] == '"' || text[0] == '\'') ? text[0] : 0;
+#else
+	  /* Use rl_completion_quote_character because any single or
+	     double quotes have been removed by the time TEXT makes it
+	     here, and we don't want to remove backslashes inside
+	     quoted strings. */
+	  qc = rl_dispatching ? rl_completion_quote_character : 0;
+#endif
 	  dfn = (*rl_filename_dequoting_function) ((char *)text, qc);
 	}
       else
@@ -792,7 +813,8 @@
 {
   WORD_LIST *l, *l2;
   STRINGLIST *sl;
-  int nw, tlen;
+  int nw, tlen, qc;
+  char *ntxt;		/* dequoted TEXT to use in comparisons */
 
   if (cs->words == 0 || cs->words[0] == '\0')
     return ((STRINGLIST *)NULL);
@@ -810,15 +832,18 @@
 
   nw = list_length (l2);
   sl = strlist_create (nw + 1);
-  tlen = STRLEN (text);
+
+  ntxt = bash_dequote_text (text);
+  tlen = STRLEN (ntxt);
 
   for (nw = 0, l = l2; l; l = l->next)
     {
-      if (tlen == 0 || STREQN (l->word->word, text, tlen))
+      if (tlen == 0 || STREQN (l->word->word, ntxt, tlen))
 	sl->list[nw++] = STRDUP (l->word->word);
     }
   sl->list[sl->list_len = nw] = (char *)NULL;
 
+  FREE (ntxt);
   return sl;
 }
 
@@ -968,7 +993,7 @@
   f = find_function (funcname);
   if (f == 0)
     {
-      internal_error ("completion: function `%s' not found", funcname);
+      internal_error (_("completion: function `%s' not found"), funcname);
       rl_ding ();
       rl_on_new_line ();
       return ((STRINGLIST *)NULL);
@@ -1132,6 +1157,7 @@
   char *line;
   int llen, nw, cw;
   WORD_LIST *lwords;
+  COMPSPEC *tcs;
 
 #ifdef DEBUG
   debug_printf ("gen_compspec_completions (%s, %s, %d, %d)", cmd, word, start, end);
@@ -1286,12 +1312,19 @@
       names. */
   if ((ret == 0 || ret->list_len == 0) && (cs->options & COPT_DIRNAMES))
     {
-      COMPSPEC *dummy;
-
-      dummy = compspec_create ();
-      dummy->actions = CA_DIRECTORY;
-      ret = gen_action_completions (dummy, word);
-      compspec_dispose (dummy);
+      tcs = compspec_create ();
+      tcs->actions = CA_DIRECTORY;
+      ret = gen_action_completions (tcs, word);
+      compspec_dispose (tcs);
+    }
+  else if (cs->options & COPT_PLUSDIRS)
+    {
+      tcs = compspec_create ();
+      tcs->actions = CA_DIRECTORY;
+      tmatches = gen_action_completions (tcs, word);
+      ret = strlist_append (ret, tmatches);
+      strlist_dispose (tmatches);
+      compspec_dispose (tcs);
     }
 
   return (ret);
@@ -1326,6 +1359,8 @@
       return ((char **)NULL);
     }
 
+  cs = compspec_copy (cs);
+
   /* Signal the caller that we found a COMPSPEC for this command, and pass
      back any meta-options associated with the compspec. */
   if (foundp)
@@ -1333,6 +1368,8 @@
 
   ret = gen_compspec_completions (cs, cmd, word, start, end);
 
+  compspec_dispose (cs);
+
   if (ret)
     {
       rmatches = ret->list;