Imported from ../bash-2.04.tar.gz.
[platform/upstream/bash.git] / y.tab.c
diff --git a/y.tab.c b/y.tab.c
index 406b32e..dd66aa9 100644 (file)
--- a/y.tab.c
+++ b/y.tab.c
@@ -1,5 +1,5 @@
 
-/*  A Bison parser, made from ./parse.y
+/*  A Bison parser, made from /usr/homes/chet/src/bash/src/parse.y
  by  GNU Bison version 1.25
   */
 
 #define        DO      269
 #define        DONE    270
 #define        FUNCTION        271
-#define        IN      272
-#define        BANG    273
-#define        TIME    274
-#define        TIMEOPT 275
-#define        WORD    276
-#define        ASSIGNMENT_WORD 277
-#define        NUMBER  278
-#define        AND_AND 279
-#define        OR_OR   280
-#define        GREATER_GREATER 281
-#define        LESS_LESS       282
-#define        LESS_AND        283
-#define        GREATER_AND     284
-#define        SEMI_SEMI       285
-#define        LESS_LESS_MINUS 286
-#define        AND_GREATER     287
-#define        LESS_GREATER    288
-#define        GREATER_BAR     289
-#define        yacc_EOF        290
-
-#line 21 "./parse.y"
+#define        COND_START      272
+#define        COND_END        273
+#define        COND_ERROR      274
+#define        IN      275
+#define        BANG    276
+#define        TIME    277
+#define        TIMEOPT 278
+#define        WORD    279
+#define        ASSIGNMENT_WORD 280
+#define        NUMBER  281
+#define        ARITH_CMD       282
+#define        ARITH_FOR_EXPRS 283
+#define        COND_CMD        284
+#define        AND_AND 285
+#define        OR_OR   286
+#define        GREATER_GREATER 287
+#define        LESS_LESS       288
+#define        LESS_AND        289
+#define        GREATER_AND     290
+#define        SEMI_SEMI       291
+#define        LESS_LESS_MINUS 292
+#define        AND_GREATER     293
+#define        LESS_GREATER    294
+#define        GREATER_BAR     295
+#define        yacc_EOF        296
+
+#line 21 "/usr/homes/chet/src/bash/src/parse.y"
 
 #include "config.h"
 
 #endif /* ALIAS */
 
 #if defined (PROMPT_STRING_DECODE)
-#include <sys/param.h>
-#include <time.h>
-#include "maxpath.h"
+#  ifndef _MINIX
+#    include <sys/param.h>
+#  endif
+#  include <time.h>
+#  include "maxpath.h"
 #endif /* PROMPT_STRING_DECODE */
 
 #define RE_READ_TOKEN  -99
 
 #define YYDEBUG 0
 
+#if defined (EXTENDED_GLOB)
+#define PATTERN_CHAR(c) \
+       ((c) == '@' || (c) == '*' || (c) == '+' || (c) == '?' || (c) == '!')
+
+extern int extended_glob;
+#endif
+
 extern int eof_encountered;
 extern int no_line_editing, running_under_emacs;
 extern int current_command_number;
@@ -107,12 +122,13 @@ extern int interrupt_immediately;
 extern char *shell_name, *current_host_name;
 extern char *dist_version;
 extern int patch_level;
-extern int dump_translatable_strings;
+extern int dump_translatable_strings, dump_po_strings;
 extern Function *last_shell_builtin, *this_shell_builtin;
 #if defined (BUFFERED_INPUT)
 extern int bash_input_fd_changed;
 #endif
 
+extern int errno;
 /* **************************************************************** */
 /*                                                                 */
 /*                 "Forward" declarations                          */
@@ -124,15 +140,23 @@ static char *localeexpand ();
 static int reserved_word_acceptable ();
 static int read_token ();
 static int yylex ();
+static int parse_arith_cmd ();
+#if defined (COND_COMMAND)
+static COMMAND *parse_cond_command ();
+#endif
 static int read_token_word ();
 static void discard_parser_constructs ();
 
 static void report_syntax_error ();
 static void handle_eof_input_unit ();
 static void prompt_again ();
+#if 0
 static void reset_readline_prompt ();
+#endif
 static void print_prompt ();
 
+extern int yyerror ();
+
 /* Default prompt strings */
 char *primary_prompt = PPROMPT;
 char *secondary_prompt = SPROMPT;
@@ -182,9 +206,12 @@ static int function_dstart;
 /* The line number in a script on which a function body starts. */
 static int function_bstart;
 
+/* The line number in a script at which an arithmetic for command starts. */
+static int arith_for_lineno;
+
 static REDIRECTEE redir;
 
-#line 166 "./parse.y"
+#line 187 "/usr/homes/chet/src/bash/src/parse.y"
 typedef union {
   WORD_DESC *word;             /* the word that we read. */
   int number;                  /* the number that we read. */
@@ -204,26 +231,26 @@ typedef union {
 
 
 
-#define        YYFINAL         263
+#define        YYFINAL         279
 #define        YYFLAG          -32768
-#define        YYNTBASE        47
+#define        YYNTBASE        53
 
-#define YYTRANSLATE(x) ((unsigned)(x) <= 290 ? yytranslate[x] : 78)
+#define YYTRANSLATE(x) ((unsigned)(x) <= 296 ? yytranslate[x] : 87)
 
 static const char yytranslate[] = {     0,
-     2,     2,     2,     2,     2,     2,     2,     2,     2,    37,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,    43,
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     2,     2,     2,     2,     2,     2,     2,    35,     2,    45,
-    46,     2,     2,     2,    42,     2,     2,     2,     2,     2,
-     2,     2,     2,     2,     2,     2,     2,     2,    36,    41,
-     2,    40,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,    41,     2,    51,
+    52,     2,     2,     2,    48,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,    42,    47,
+     2,    46,     2,     2,     2,     2,     2,     2,     2,     2,
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     2,     2,    43,    39,    44,     2,     2,     2,     2,     2,
+     2,     2,    49,    45,    50,     2,     2,     2,     2,     2,
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
@@ -239,7 +266,8 @@ static const char yytranslate[] = {     0,
      2,     2,     2,     2,     2,     1,     2,     3,     4,     5,
      6,     7,     8,     9,    10,    11,    12,    13,    14,    15,
     16,    17,    18,    19,    20,    21,    22,    23,    24,    25,
-    26,    27,    28,    29,    30,    31,    32,    33,    34,    38
+    26,    27,    28,    29,    30,    31,    32,    33,    34,    35,
+    36,    37,    38,    39,    40,    44
 };
 
 #if YYDEBUG != 0
@@ -249,87 +277,89 @@ static const short yyprhs[] = {     0,
     64,    67,    71,    74,    78,    81,    85,    88,    92,    95,
     99,   102,   105,   109,   111,   113,   115,   117,   120,   122,
    125,   127,   129,   132,   134,   136,   142,   148,   150,   152,
-   154,   156,   158,   165,   172,   180,   188,   199,   210,   217,
-   224,   232,   240,   251,   262,   269,   277,   284,   290,   297,
-   302,   306,   312,   320,   327,   331,   336,   343,   349,   351,
-   354,   359,   364,   370,   376,   379,   383,   385,   389,   392,
-   394,   397,   401,   405,   409,   414,   419,   424,   429,   434,
-   436,   438,   440,   442,   443,   446,   448,   451,   454,   459,
-   464,   468,   472,   474,   476,   479,   482,   486,   490,   495,
-   497,   499
+   154,   156,   158,   160,   162,   164,   171,   178,   186,   194,
+   205,   216,   224,   232,   239,   246,   254,   262,   273,   284,
+   291,   299,   306,   312,   319,   324,   328,   334,   342,   349,
+   353,   355,   359,   364,   371,   377,   379,   382,   387,   392,
+   398,   404,   407,   411,   413,   417,   420,   422,   425,   429,
+   433,   437,   442,   447,   452,   457,   462,   464,   466,   468,
+   470,   471,   474,   476,   479,   482,   487,   492,   496,   500,
+   502,   504,   507,   510,   514,   518,   523,   525,   527
 };
 
-static const short yyrhs[] = {    73,
-    37,     0,    37,     0,     1,    37,     0,    38,     0,    21,
-     0,    48,    21,     0,    40,    21,     0,    41,    21,     0,
-    23,    40,    21,     0,    23,    41,    21,     0,    26,    21,
-     0,    23,    26,    21,     0,    27,    21,     0,    23,    27,
-    21,     0,    28,    23,     0,    23,    28,    23,     0,    29,
-    23,     0,    23,    29,    23,     0,    28,    21,     0,    23,
-    28,    21,     0,    29,    21,     0,    23,    29,    21,     0,
-    31,    21,     0,    23,    31,    21,     0,    29,    42,     0,
-    23,    29,    42,     0,    28,    42,     0,    23,    28,    42,
-     0,    32,    21,     0,    23,    33,    21,     0,    33,    21,
-     0,    34,    21,     0,    23,    34,    21,     0,    21,     0,
-    22,     0,    49,     0,    49,     0,    51,    49,     0,    50,
-     0,    52,    50,     0,    52,     0,    54,     0,    54,    51,
-     0,    55,     0,    57,     0,    12,    68,    14,    68,    15,
-     0,    13,    68,    14,    68,    15,     0,    56,     0,    60,
-     0,    59,     0,    61,     0,    58,     0,    10,    21,    72,
-    14,    67,    15,     0,    10,    21,    72,    43,    67,    44,
-     0,    10,    21,    36,    72,    14,    67,    15,     0,    10,
-    21,    36,    72,    43,    67,    44,     0,    10,    21,    72,
-    17,    48,    71,    72,    14,    67,    15,     0,    10,    21,
-    72,    17,    48,    71,    72,    43,    67,    44,     0,    11,
-    21,    72,    14,    67,    15,     0,    11,    21,    72,    43,
-    67,    44,     0,    11,    21,    36,    72,    14,    67,    15,
-     0,    11,    21,    36,    72,    43,    67,    44,     0,    11,
-    21,    72,    17,    48,    71,    72,    14,    67,    15,     0,
-    11,    21,    72,    17,    48,    71,    72,    43,    67,    44,
-     0,     8,    21,    72,    17,    72,     9,     0,     8,    21,
-    72,    17,    65,    72,     9,     0,     8,    21,    72,    17,
-    63,     9,     0,    21,    45,    46,    72,    61,     0,    16,
-    21,    45,    46,    72,    61,     0,    16,    21,    72,    61,
-     0,    45,    68,    46,     0,     3,    68,     4,    68,     7,
-     0,     3,    68,     4,    68,     5,    68,     7,     0,     3,
-    68,     4,    68,    62,     7,     0,    43,    67,    44,     0,
-     6,    68,     4,    68,     0,     6,    68,     4,    68,     5,
-    68,     0,     6,    68,     4,    68,    62,     0,    64,     0,
-    65,    64,     0,    72,    66,    46,    68,     0,    72,    66,
-    46,    72,     0,    72,    45,    66,    46,    68,     0,    72,
-    45,    66,    46,    72,     0,    64,    30,     0,    65,    64,
-    30,     0,    21,     0,    66,    39,    21,     0,    72,    69,
-     0,    67,     0,    72,    70,     0,    70,    37,    72,     0,
-    70,    35,    72,     0,    70,    36,    72,     0,    70,    24,
-    72,    70,     0,    70,    25,    72,    70,     0,    70,    35,
-    72,    70,     0,    70,    36,    72,    70,     0,    70,    37,
-    72,    70,     0,    75,     0,    37,     0,    36,     0,    38,
-     0,     0,    72,    37,     0,    74,     0,    74,    35,     0,
-    74,    36,     0,    74,    24,    72,    74,     0,    74,    25,
-    72,    74,     0,    74,    35,    74,     0,    74,    36,    74,
-     0,    75,     0,    76,     0,    18,    76,     0,    77,    76,
-     0,    77,    18,    76,     0,    18,    77,    76,     0,    76,
-    39,    72,    76,     0,    53,     0,    19,     0,    19,    20,
-     0
+static const short yyrhs[] = {    82,
+    43,     0,    43,     0,     1,    43,     0,    44,     0,    24,
+     0,    54,    24,     0,    46,    24,     0,    47,    24,     0,
+    26,    46,    24,     0,    26,    47,    24,     0,    32,    24,
+     0,    26,    32,    24,     0,    33,    24,     0,    26,    33,
+    24,     0,    34,    26,     0,    26,    34,    26,     0,    35,
+    26,     0,    26,    35,    26,     0,    34,    24,     0,    26,
+    34,    24,     0,    35,    24,     0,    26,    35,    24,     0,
+    37,    24,     0,    26,    37,    24,     0,    35,    48,     0,
+    26,    35,    48,     0,    34,    48,     0,    26,    34,    48,
+     0,    38,    24,     0,    26,    39,    24,     0,    39,    24,
+     0,    40,    24,     0,    26,    40,    24,     0,    24,     0,
+    25,     0,    55,     0,    55,     0,    57,    55,     0,    56,
+     0,    58,    56,     0,    58,     0,    60,     0,    60,    57,
+     0,    61,     0,    64,     0,    12,    77,    14,    77,    15,
+     0,    13,    77,    14,    77,    15,     0,    63,     0,    67,
+     0,    66,     0,    68,     0,    69,     0,    70,     0,    62,
+     0,    65,     0,    10,    24,    81,    14,    77,    15,     0,
+    10,    24,    81,    49,    77,    50,     0,    10,    24,    42,
+    81,    14,    77,    15,     0,    10,    24,    42,    81,    49,
+    77,    50,     0,    10,    24,    81,    20,    54,    80,    81,
+    14,    77,    15,     0,    10,    24,    81,    20,    54,    80,
+    81,    49,    77,    50,     0,    10,    28,    80,    81,    14,
+    77,    15,     0,    10,    28,    80,    81,    49,    77,    50,
+     0,    11,    24,    81,    14,    76,    15,     0,    11,    24,
+    81,    49,    76,    50,     0,    11,    24,    42,    81,    14,
+    76,    15,     0,    11,    24,    42,    81,    49,    76,    50,
+     0,    11,    24,    81,    20,    54,    80,    81,    14,    76,
+    15,     0,    11,    24,    81,    20,    54,    80,    81,    49,
+    76,    50,     0,     8,    24,    81,    20,    81,     9,     0,
+     8,    24,    81,    20,    74,    81,     9,     0,     8,    24,
+    81,    20,    72,     9,     0,    24,    51,    52,    81,    68,
+     0,    16,    24,    51,    52,    81,    68,     0,    16,    24,
+    81,    68,     0,    51,    77,    52,     0,     3,    77,     4,
+    77,     7,     0,     3,    77,     4,    77,     5,    77,     7,
+     0,     3,    77,     4,    77,    71,     7,     0,    49,    76,
+    50,     0,    27,     0,    17,    29,    18,     0,     6,    77,
+     4,    77,     0,     6,    77,     4,    77,     5,    77,     0,
+     6,    77,     4,    77,    71,     0,    73,     0,    74,    73,
+     0,    81,    75,    52,    77,     0,    81,    75,    52,    81,
+     0,    81,    51,    75,    52,    77,     0,    81,    51,    75,
+    52,    81,     0,    73,    36,     0,    74,    73,    36,     0,
+    24,     0,    75,    45,    24,     0,    81,    78,     0,    76,
+     0,    81,    79,     0,    79,    43,    81,     0,    79,    41,
+    81,     0,    79,    42,    81,     0,    79,    30,    81,    79,
+     0,    79,    31,    81,    79,     0,    79,    41,    81,    79,
+     0,    79,    42,    81,    79,     0,    79,    43,    81,    79,
+     0,    84,     0,    43,     0,    42,     0,    44,     0,     0,
+    81,    43,     0,    83,     0,    83,    41,     0,    83,    42,
+     0,    83,    30,    81,    83,     0,    83,    31,    81,    83,
+     0,    83,    41,    83,     0,    83,    42,    83,     0,    84,
+     0,    85,     0,    21,    85,     0,    86,    85,     0,    86,
+    21,    85,     0,    21,    86,    85,     0,    85,    45,    81,
+    85,     0,    59,     0,    22,     0,    22,    23,     0
 };
 
 #endif
 
 #if YYDEBUG != 0
 static const short yyrline[] = { 0,
-   209,   218,   225,   240,   250,   252,   256,   261,   266,   271,
-   276,   281,   286,   292,   298,   303,   308,   313,   318,   323,
-   328,   333,   338,   345,   352,   357,   362,   367,   372,   377,
-   382,   387,   392,   399,   401,   403,   407,   411,   422,   424,
-   428,   430,   432,   461,   463,   465,   467,   469,   471,   473,
-   475,   477,   481,   483,   485,   487,   489,   491,   495,   499,
-   503,   507,   511,   515,   521,   523,   525,   529,   533,   536,
-   540,   544,   546,   548,   553,   557,   559,   561,   565,   566,
-   570,   572,   574,   576,   580,   581,   585,   587,   596,   604,
-   605,   611,   612,   619,   623,   625,   627,   634,   636,   638,
-   642,   643,   644,   647,   648,   657,   663,   672,   680,   682,
-   684,   691,   694,   698,   700,   705,   710,   715,   722,   725,
-   729,   731
+   237,   246,   253,   268,   278,   280,   284,   289,   294,   299,
+   304,   309,   314,   320,   326,   331,   336,   341,   346,   351,
+   356,   361,   366,   373,   380,   385,   390,   395,   400,   405,
+   410,   415,   420,   427,   429,   431,   435,   439,   450,   452,
+   456,   458,   460,   497,   499,   501,   503,   505,   507,   509,
+   511,   513,   515,   517,   519,   523,   525,   527,   529,   531,
+   533,   537,   539,   542,   546,   550,   554,   558,   562,   568,
+   570,   572,   576,   580,   583,   587,   594,   596,   598,   603,
+   607,   611,   615,   617,   619,   623,   624,   628,   630,   632,
+   634,   638,   639,   643,   645,   654,   662,   663,   669,   670,
+   677,   681,   683,   685,   692,   694,   696,   700,   701,   702,
+   705,   706,   715,   721,   730,   738,   740,   742,   749,   752,
+   756,   758,   763,   768,   773,   780,   783,   787,   789
 };
 #endif
 
@@ -338,32 +368,34 @@ static const short yyrline[] = { 0,
 
 static const char * const yytname[] = {   "$","error","$undefined.","IF","THEN",
 "ELSE","ELIF","FI","CASE","ESAC","FOR","SELECT","WHILE","UNTIL","DO","DONE",
-"FUNCTION","IN","BANG","TIME","TIMEOPT","WORD","ASSIGNMENT_WORD","NUMBER","AND_AND",
+"FUNCTION","COND_START","COND_END","COND_ERROR","IN","BANG","TIME","TIMEOPT",
+"WORD","ASSIGNMENT_WORD","NUMBER","ARITH_CMD","ARITH_FOR_EXPRS","COND_CMD","AND_AND",
 "OR_OR","GREATER_GREATER","LESS_LESS","LESS_AND","GREATER_AND","SEMI_SEMI","LESS_LESS_MINUS",
 "AND_GREATER","LESS_GREATER","GREATER_BAR","'&'","';'","'\\n'","yacc_EOF","'|'",
 "'>'","'<'","'-'","'{'","'}'","'('","')'","inputunit","word_list","redirection",
 "simple_command_element","redirection_list","simple_command","command","shell_command",
-"for_command","select_command","case_command","function_def","subshell","if_command",
-"group_command","elif_clause","case_clause","pattern_list","case_clause_sequence",
-"pattern","list","compound_list","list0","list1","list_terminator","newline_list",
-"simple_list","simple_list1","pipeline_command","pipeline","timespec", NULL
+"for_command","arith_for_command","select_command","case_command","function_def",
+"subshell","if_command","group_command","arith_command","cond_command","elif_clause",
+"case_clause","pattern_list","case_clause_sequence","pattern","list","compound_list",
+"list0","list1","list_terminator","newline_list","simple_list","simple_list1",
+"pipeline_command","pipeline","timespec", NULL
 };
 #endif
 
 static const short yyr1[] = {     0,
-    47,    47,    47,    47,    48,    48,    49,    49,    49,    49,
-    49,    49,    49,    49,    49,    49,    49,    49,    49,    49,
-    49,    49,    49,    49,    49,    49,    49,    49,    49,    49,
-    49,    49,    49,    50,    50,    50,    51,    51,    52,    52,
-    53,    53,    53,    54,    54,    54,    54,    54,    54,    54,
-    54,    54,    55,    55,    55,    55,    55,    55,    56,    56,
-    56,    56,    56,    56,    57,    57,    57,    58,    58,    58,
-    59,    60,    60,    60,    61,    62,    62,    62,    63,    63,
-    64,    64,    64,    64,    65,    65,    66,    66,    67,    68,
-    68,    69,    69,    69,    70,    70,    70,    70,    70,    70,
-    71,    71,    71,    72,    72,    73,    73,    73,    74,    74,
-    74,    74,    74,    75,    75,    75,    75,    75,    76,    76,
-    77,    77
+    53,    53,    53,    53,    54,    54,    55,    55,    55,    55,
+    55,    55,    55,    55,    55,    55,    55,    55,    55,    55,
+    55,    55,    55,    55,    55,    55,    55,    55,    55,    55,
+    55,    55,    55,    56,    56,    56,    57,    57,    58,    58,
+    59,    59,    59,    60,    60,    60,    60,    60,    60,    60,
+    60,    60,    60,    60,    60,    61,    61,    61,    61,    61,
+    61,    62,    62,    63,    63,    63,    63,    63,    63,    64,
+    64,    64,    65,    65,    65,    66,    67,    67,    67,    68,
+    69,    70,    71,    71,    71,    72,    72,    73,    73,    73,
+    73,    74,    74,    75,    75,    76,    77,    77,    78,    78,
+    78,    79,    79,    79,    79,    79,    79,    80,    80,    80,
+    81,    81,    82,    82,    82,    83,    83,    83,    83,    83,
+    84,    84,    84,    84,    84,    85,    85,    86,    86
 };
 
 static const short yyr2[] = {     0,
@@ -372,207 +404,219 @@ static const short yyr2[] = {     0,
      2,     3,     2,     3,     2,     3,     2,     3,     2,     3,
      2,     2,     3,     1,     1,     1,     1,     2,     1,     2,
      1,     1,     2,     1,     1,     5,     5,     1,     1,     1,
-     1,     1,     6,     6,     7,     7,    10,    10,     6,     6,
-     7,     7,    10,    10,     6,     7,     6,     5,     6,     4,
-     3,     5,     7,     6,     3,     4,     6,     5,     1,     2,
-     4,     4,     5,     5,     2,     3,     1,     3,     2,     1,
-     2,     3,     3,     3,     4,     4,     4,     4,     4,     1,
-     1,     1,     1,     0,     2,     1,     2,     2,     4,     4,
-     3,     3,     1,     1,     2,     2,     3,     3,     4,     1,
-     1,     2
+     1,     1,     1,     1,     1,     6,     6,     7,     7,    10,
+    10,     7,     7,     6,     6,     7,     7,    10,    10,     6,
+     7,     6,     5,     6,     4,     3,     5,     7,     6,     3,
+     1,     3,     4,     6,     5,     1,     2,     4,     4,     5,
+     5,     2,     3,     1,     3,     2,     1,     2,     3,     3,
+     3,     4,     4,     4,     4,     4,     1,     1,     1,     1,
+     0,     2,     1,     2,     2,     4,     4,     3,     3,     1,
+     1,     2,     2,     3,     3,     4,     1,     1,     2
 };
 
 static const short yydefact[] = {     0,
-     0,   104,     0,     0,     0,   104,   104,     0,     0,   121,
-    34,    35,     0,     0,     0,     0,     0,     0,     0,     0,
-     0,     2,     4,     0,     0,   104,   104,    36,    39,    41,
-   120,    42,    44,    48,    45,    52,    50,    49,    51,     0,
-   106,   113,   114,     0,     3,    90,     0,     0,   104,   104,
-   104,     0,     0,   104,   115,     0,   122,     0,     0,     0,
-     0,     0,     0,     0,     0,     0,     0,    11,    13,    19,
-    15,    27,    21,    17,    25,    23,    29,    31,    32,     7,
-     8,     0,     0,     0,    34,    40,    37,    43,     1,   104,
-   104,   107,   108,   104,     0,   116,   104,   105,    89,    91,
-   100,     0,   104,     0,   104,     0,   104,   104,     0,     0,
-   118,   104,    12,    14,    20,    16,    28,    22,    18,    26,
-    24,    30,    33,     9,    10,    75,     0,    71,    38,     0,
-     0,   111,   112,     0,   117,     0,   104,   104,   104,   104,
-   104,   104,     0,   104,     0,   104,     0,   104,     0,   104,
-     0,     0,   104,    70,     0,   109,   110,     0,     0,   119,
-   104,   104,    72,     0,     0,     0,    93,    94,    92,     0,
-    79,   104,     0,   104,   104,     0,     5,     0,     0,   104,
-   104,     0,     0,     0,    46,    47,     0,    68,     0,     0,
-    74,    95,    96,    97,    98,    99,    67,    85,    80,     0,
-    65,    87,     0,     0,     0,     0,    53,     6,   102,   101,
-   103,   104,    54,     0,     0,    59,   104,    60,    69,    73,
-   104,   104,   104,   104,    86,    66,     0,     0,   104,    55,
-    56,     0,    61,    62,     0,    76,     0,     0,     0,   104,
-    88,    81,    82,   104,   104,   104,   104,   104,    78,    83,
-    84,     0,     0,     0,     0,    77,    57,    58,    63,    64,
-     0,     0,     0
+     0,   111,     0,     0,     0,   111,   111,     0,     0,     0,
+   128,    34,    35,     0,    81,     0,     0,     0,     0,     0,
+     0,     0,     0,     2,     4,     0,     0,   111,   111,    36,
+    39,    41,   127,    42,    44,    54,    48,    45,    55,    50,
+    49,    51,    52,    53,     0,   113,   120,   121,     0,     3,
+    97,     0,     0,   111,   111,     0,   111,     0,     0,   111,
+     0,   122,     0,   129,     0,     0,     0,     0,     0,     0,
+     0,     0,     0,     0,    11,    13,    19,    15,    27,    21,
+    17,    25,    23,    29,    31,    32,     7,     8,     0,     0,
+     0,    34,    40,    37,    43,     1,   111,   111,   114,   115,
+   111,     0,   123,   111,   112,    96,    98,   107,     0,   111,
+     0,   109,   108,   110,   111,   111,     0,   111,   111,     0,
+     0,    82,   125,   111,    12,    14,    20,    16,    28,    22,
+    18,    26,    24,    30,    33,     9,    10,    80,     0,    76,
+    38,     0,     0,   118,   119,     0,   124,     0,   111,   111,
+   111,   111,   111,   111,     0,   111,     0,   111,     0,     0,
+   111,     0,   111,     0,     0,   111,    75,     0,   116,   117,
+     0,     0,   126,   111,   111,    77,     0,     0,     0,   100,
+   101,    99,     0,    86,   111,     0,   111,   111,     0,     5,
+     0,     0,   111,   111,   111,   111,     0,     0,     0,    46,
+    47,     0,    73,     0,     0,    79,   102,   103,   104,   105,
+   106,    72,    92,    87,     0,    70,    94,     0,     0,     0,
+     0,    56,     6,   111,    57,     0,     0,     0,     0,    64,
+   111,    65,    74,    78,   111,   111,   111,   111,    93,    71,
+     0,     0,   111,    58,    59,     0,    62,    63,    66,    67,
+     0,    83,     0,     0,     0,   111,    95,    88,    89,   111,
+   111,   111,   111,   111,    85,    90,    91,     0,     0,     0,
+     0,    84,    60,    61,    68,    69,     0,     0,     0
 };
 
-static const short yydefgoto[] = {   261,
-   178,    28,    29,    88,    30,    31,    32,    33,    34,    35,
-    36,    37,    38,    39,   164,   170,   171,   172,   204,    46,
-    47,    99,   100,   212,    83,    40,   132,   101,    43,    44
+static const short yydefgoto[] = {   277,
+   191,    30,    31,    95,    32,    33,    34,    35,    36,    37,
+    38,    39,    40,    41,    42,    43,    44,   177,   183,   184,
+   185,   219,    51,    52,   106,   107,   115,    53,    45,   144,
+   108,    48,    49
 };
 
-static const short yypact[] = {   246,
-   -19,-32768,     8,    25,    29,-32768,-32768,    33,   354,     4,
-    34,-32768,   499,    46,    51,    32,    38,    56,    70,    72,
-    90,-32768,-32768,    97,   101,-32768,-32768,-32768,-32768,   161,
--32768,   483,-32768,-32768,-32768,-32768,-32768,-32768,-32768,     6,
-   139,-32768,    84,   390,-32768,-32768,   120,   282,-32768,    89,
-    94,   112,   117,    87,    84,   462,-32768,    96,   123,   127,
-    52,    55,   128,   129,   133,   137,   140,-32768,-32768,-32768,
+static const short yypact[] = {   256,
+    -9,-32768,    28,    54,    31,-32768,-32768,    38,   -14,   382,
+    49,    24,-32768,   188,-32768,    41,    56,    35,    42,    61,
+    73,    75,   100,-32768,-32768,   111,   112,-32768,-32768,-32768,
+-32768,   171,-32768,   530,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,    95,   124,-32768,    59,   424,-32768,
+-32768,   136,   298,-32768,   104,    64,   107,   137,   142,   106,
+   140,    59,   508,-32768,   108,   135,   138,    45,    55,   139,
+   143,   146,   154,   155,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,   114,   298,
+   131,-32768,-32768,-32768,   530,-32768,-32768,-32768,   340,   340,
+-32768,   508,    59,-32768,-32768,-32768,    80,-32768,    -8,-32768,
+    -4,-32768,-32768,-32768,-32768,-32768,    -1,-32768,-32768,   132,
+   -11,-32768,    59,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,    80,-32768,
+-32768,   298,   298,    89,    89,   466,    59,    82,-32768,-32768,
+-32768,-32768,-32768,-32768,    -3,-32768,   156,-32768,     4,    11,
+-32768,   156,-32768,   170,   177,-32768,-32768,   -11,-32768,-32768,
+   340,   340,    59,-32768,-32768,-32768,   179,   298,   298,   298,
+   298,   298,   184,   158,-32768,    -2,-32768,-32768,   183,-32768,
+    52,   149,-32768,-32768,-32768,-32768,   186,    52,   152,-32768,
+-32768,   -11,-32768,   208,   212,-32768,-32768,-32768,   101,   101,
+   101,-32768,-32768,   190,     0,-32768,-32768,   200,   -31,   215,
+   181,-32768,-32768,-32768,-32768,   218,   191,   221,   194,-32768,
 -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
--32768,   121,   282,   122,-32768,-32768,-32768,   483,-32768,-32768,
--32768,   318,   318,-32768,   462,    84,-32768,-32768,-32768,    92,
--32768,   -10,-32768,     2,-32768,    14,-32768,-32768,   130,   -28,
-    84,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
--32768,-32768,-32768,-32768,-32768,-32768,    92,-32768,-32768,   282,
-   282,    10,    10,   426,    84,    93,-32768,-32768,-32768,-32768,
--32768,-32768,    23,-32768,   148,-32768,    26,-32768,   148,-32768,
-   158,   164,-32768,-32768,   -28,-32768,-32768,   318,   318,    84,
--32768,-32768,-32768,   178,   282,   282,   282,   282,   282,   177,
-   166,-32768,    -7,-32768,-32768,   176,-32768,    83,   153,-32768,
--32768,   183,    83,   155,-32768,-32768,   -28,-32768,   193,   199,
--32768,-32768,-32768,    57,    57,    57,-32768,-32768,   174,    -1,
--32768,-32768,   184,   -29,   191,   163,-32768,-32768,-32768,-32768,
--32768,-32768,-32768,   194,   167,-32768,-32768,-32768,-32768,-32768,
--32768,-32768,-32768,-32768,-32768,-32768,   -13,   187,-32768,-32768,
--32768,    27,-32768,-32768,    28,   103,   282,   282,   282,-32768,
--32768,-32768,   282,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
-   282,   197,   169,   201,   170,-32768,-32768,-32768,-32768,-32768,
-   217,   218,-32768
+   -25,   216,-32768,-32768,-32768,    14,-32768,-32768,-32768,-32768,
+    15,   128,   298,   298,   298,-32768,-32768,-32768,   298,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,   298,   230,   196,   232,
+   198,-32768,-32768,-32768,-32768,-32768,   249,   251,-32768
 };
 
 static const short yypgoto[] = {-32768,
-    74,   -26,   195,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
--32768,-32768,-32768,   -97,   -12,-32768,    58,-32768,    30,    -3,
-     5,-32768,   -82,    45,    -2,-32768,     3,    22,    12,   220
+    90,   -28,   224,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,  -118,-32768,-32768,     1,-32768,    76,
+-32768,    44,   -20,    -6,-32768,   -64,  -154,   -24,-32768,     5,
+     2,     7,   250
 };
 
 
-#define        YYLAST          540
-
-
-static const short yytable[] = {    48,
-   127,   201,    41,    48,    48,    87,   142,   226,    98,   228,
-    52,    53,   154,   202,    26,   144,   229,    45,   145,   202,
-    55,    42,    82,    57,    48,   228,    98,   148,    49,    98,
-   149,    84,   240,    90,    91,    98,   174,   203,    98,   180,
-   244,   246,    89,   203,   146,    50,   102,   104,   106,    51,
-    98,   110,    70,    54,    71,    96,   150,   188,    73,    98,
-    74,   129,    98,    98,    98,   175,    68,   111,   181,   245,
-   247,    69,   115,    72,   116,   118,    76,   119,    58,    75,
-   137,   138,   192,   193,   194,   195,   196,   130,   131,   219,
-    77,   134,    78,   117,    48,   133,   120,   161,   162,   163,
-   143,   136,   147,   208,    48,    48,   135,   248,   162,   155,
-    79,   151,   152,    42,    42,   137,   138,    80,   209,   210,
-   211,    81,    94,    97,   103,   107,   139,   140,   141,   105,
-   108,   109,   156,   157,   165,   166,   167,   168,   169,   173,
-   176,   112,   179,   113,   182,   160,   184,   114,   121,   122,
-   187,    42,    42,   123,   194,   195,   196,   124,    48,    48,
-   125,   133,    90,    91,   126,   189,   190,   128,   177,   200,
-   205,   206,   185,    92,    93,   153,   214,   215,   186,    42,
-    42,    85,    12,    13,   191,   197,    14,    15,    16,    17,
-   207,    18,    19,    20,    21,   198,   213,   216,   218,   220,
-    24,    25,   221,   225,   202,   230,   231,   241,   233,   232,
-   234,   257,   258,   260,   235,   259,   262,   263,    48,   237,
-   238,   239,   183,   249,    86,   236,   243,   217,    56,   199,
-     0,     0,   227,   242,     0,     0,     0,   251,     0,     0,
-   252,   253,   254,   255,   250,    48,     1,     0,     2,     0,
-     0,     0,   256,     3,     0,     4,     5,     6,     7,     0,
-     0,     8,     0,     9,    10,     0,    11,    12,    13,     0,
-     0,    14,    15,    16,    17,     0,    18,    19,    20,    21,
-     0,     0,    22,    23,     2,    24,    25,     0,    26,     3,
-    27,     4,     5,     6,     7,     0,     0,     8,     0,     9,
-    10,     0,    11,    12,    13,     0,     0,    14,    15,    16,
-    17,     0,    18,    19,    20,    21,     0,     0,    98,     0,
-     2,    24,    25,     0,    26,     3,    27,     4,     5,     6,
-     7,     0,     0,     8,     0,     9,    10,     0,    11,    12,
-    13,     0,     0,    14,    15,    16,    17,     0,    18,    19,
-    20,    21,     0,     0,     0,     0,     2,    24,    25,     0,
-    26,     3,    27,     4,     5,     6,     7,     0,     0,     8,
-     0,     0,    10,     0,    11,    12,    13,     0,     0,    14,
-    15,    16,    17,     0,    18,    19,    20,    21,     0,     0,
-     0,     0,     2,    24,    25,     0,    26,     3,    27,     4,
-     5,     6,     7,     0,     0,     8,     0,    95,     0,     0,
-    11,    12,    13,     0,     0,    14,    15,    16,    17,     0,
-    18,    19,    20,    21,     0,     0,     0,     0,     2,    24,
-    25,     0,    26,     3,    27,     4,     5,     6,     7,     0,
-     0,     8,     0,     0,     0,     0,    11,    12,    13,     0,
-     0,    14,    15,    16,    17,     0,    18,    19,    20,    21,
-     0,     0,    98,     0,     2,    24,    25,     0,    26,     3,
-    27,     4,     5,     6,     7,     0,     0,     8,     0,     0,
-     0,     0,    11,    12,    13,     0,     0,    14,    15,    16,
-    17,     0,    18,    19,    20,    21,     0,     0,     0,     0,
-     0,    24,    25,     0,    26,    13,    27,     0,    14,    15,
-    16,    17,     0,    18,    19,    20,    21,     0,     0,     0,
-     0,     0,    24,    25,    59,    60,    61,    62,     0,    63,
-     0,    64,    65,     0,     0,     0,     0,     0,    66,    67
+#define        YYLAST          577
+
+
+static const short yytable[] = {    58,
+    59,    47,   167,    90,    46,    94,   216,    89,   240,   156,
+   187,   154,   161,   242,    61,   157,    62,   193,   162,   242,
+   243,   217,    91,   217,   195,   139,   256,   260,   262,   109,
+   111,   105,   117,    50,   105,   121,   224,    28,   105,   105,
+   105,   105,   105,   231,   158,   188,   105,   163,   218,   203,
+   218,    54,   194,   105,    57,   103,   105,   105,    77,   196,
+    78,    60,   261,   263,    75,    80,   141,    81,   127,   123,
+   128,    64,   142,   143,    65,   223,   146,    55,   130,    76,
+   131,    56,    79,   233,    83,   155,   174,   175,   176,    82,
+   159,   160,   129,   112,   113,   114,    84,   148,    85,   168,
+    47,    47,   132,   101,   145,   112,   113,   114,   147,   149,
+   150,   164,   165,   207,   208,   209,   210,   211,    97,    98,
+   151,   152,   153,    86,   178,   179,   180,   181,   182,   186,
+   149,   150,   264,   175,    87,    88,    90,    96,    90,   104,
+   197,   202,   199,    47,    47,   110,   169,   170,   116,   189,
+   118,   192,   173,    97,    98,   119,   120,   122,   125,   124,
+   215,   126,   133,   138,    99,   100,   134,   204,   205,   135,
+    90,    90,    47,    47,   228,   229,   145,   136,   137,   190,
+   220,   221,   140,   166,   200,   206,   226,   227,   209,   210,
+   211,   201,   212,   213,    92,    13,    14,   222,   225,   246,
+   230,   232,    16,    17,    18,    19,   251,    20,    21,    22,
+    23,   253,   254,   255,   234,   235,    26,    27,   259,    66,
+    67,    68,    69,   217,    70,   239,    71,    72,   252,   244,
+   245,   267,   247,    73,    74,   249,   258,    90,    90,   257,
+   248,   270,   271,   250,   273,   274,   275,   276,   278,   266,
+   279,   198,   265,   268,   269,    93,     1,   272,     2,    63,
+   214,   241,     0,     3,     0,     4,     5,     6,     7,     0,
+     0,     8,     9,     0,     0,     0,    10,    11,     0,    12,
+    13,    14,    15,     0,     0,     0,     0,    16,    17,    18,
+    19,     0,    20,    21,    22,    23,     0,     0,    24,    25,
+     2,    26,    27,     0,    28,     3,    29,     4,     5,     6,
+     7,     0,     0,     8,     9,     0,     0,     0,    10,    11,
+     0,    12,    13,    14,    15,     0,     0,     0,     0,    16,
+    17,    18,    19,     0,    20,    21,    22,    23,     0,     0,
+   105,     0,     2,    26,    27,     0,    28,     3,    29,     4,
+     5,     6,     7,     0,     0,     8,     9,     0,     0,     0,
+    10,    11,     0,    12,    13,    14,    15,     0,     0,     0,
+     0,    16,    17,    18,    19,     0,    20,    21,    22,    23,
+     0,     0,     0,     0,     2,    26,    27,     0,    28,     3,
+    29,     4,     5,     6,     7,     0,     0,     8,     9,     0,
+     0,     0,     0,    11,     0,    12,    13,    14,    15,     0,
+     0,     0,     0,    16,    17,    18,    19,     0,    20,    21,
+    22,    23,     0,     0,     0,     0,     2,    26,    27,     0,
+    28,     3,    29,     4,     5,     6,     7,     0,     0,     8,
+     9,     0,     0,     0,   102,     0,     0,    12,    13,    14,
+    15,     0,     0,     0,     0,    16,    17,    18,    19,     0,
+    20,    21,    22,    23,     0,     0,     0,     0,     2,    26,
+    27,     0,    28,     3,    29,     4,     5,     6,     7,     0,
+     0,     8,     9,     0,     0,     0,     0,     0,     0,    12,
+    13,    14,    15,     0,     0,     0,     0,    16,    17,    18,
+    19,     0,    20,    21,    22,    23,     0,     0,   105,     0,
+     2,    26,    27,     0,    28,     3,    29,     4,     5,     6,
+     7,     0,     0,     8,     9,     0,     0,     0,     0,     0,
+     0,    12,    13,    14,    15,     0,     0,     0,     0,    16,
+    17,    18,    19,     0,    20,    21,    22,    23,     0,     0,
+     0,     0,     0,    26,    27,    14,    28,     0,    29,     0,
+     0,    16,    17,    18,    19,     0,    20,    21,    22,    23,
+     0,     0,     0,     0,     0,    26,    27
 };
 
-static const short yycheck[] = {     2,
-    83,     9,     0,     6,     7,    32,    17,     9,    37,    39,
-     6,     7,   110,    21,    43,    14,    46,    37,    17,    21,
-     9,     0,    26,    20,    27,    39,    37,    14,    21,    37,
-    17,    27,    46,    24,    25,    37,    14,    45,    37,    14,
-    14,    14,    37,    45,    43,    21,    49,    50,    51,    21,
-    37,    54,    21,    21,    23,    44,    43,   155,    21,    37,
-    23,    88,    37,    37,    37,    43,    21,    56,    43,    43,
-    43,    21,    21,    42,    23,    21,    21,    23,    45,    42,
-    24,    25,   165,   166,   167,   168,   169,    90,    91,   187,
-    21,    94,    21,    42,    97,    93,    42,     5,     6,     7,
-   103,    97,   105,    21,   107,   108,    95,     5,     6,   112,
-    21,   107,   108,    92,    93,    24,    25,    21,    36,    37,
-    38,    21,    39,     4,    36,    14,    35,    36,    37,    36,
-    14,    45,   130,   131,   137,   138,   139,   140,   141,   142,
-   144,    46,   146,    21,   148,   134,   150,    21,    21,    21,
-   153,   130,   131,    21,   237,   238,   239,    21,   161,   162,
-    21,   159,    24,    25,    44,   161,   162,    46,    21,   172,
-   174,   175,    15,    35,    36,    46,   180,   181,    15,   158,
-   159,    21,    22,    23,     7,     9,    26,    27,    28,    29,
-    15,    31,    32,    33,    34,    30,    44,    15,    44,     7,
-    40,    41,     4,    30,    21,    15,    44,    21,    15,   212,
-    44,    15,    44,    44,   217,    15,     0,     0,   221,   222,
-   223,   224,   149,   236,    30,   221,   229,   183,     9,   172,
-    -1,    -1,   203,   229,    -1,    -1,    -1,   240,    -1,    -1,
-   244,   245,   246,   247,   240,   248,     1,    -1,     3,    -1,
-    -1,    -1,   248,     8,    -1,    10,    11,    12,    13,    -1,
-    -1,    16,    -1,    18,    19,    -1,    21,    22,    23,    -1,
-    -1,    26,    27,    28,    29,    -1,    31,    32,    33,    34,
-    -1,    -1,    37,    38,     3,    40,    41,    -1,    43,     8,
-    45,    10,    11,    12,    13,    -1,    -1,    16,    -1,    18,
-    19,    -1,    21,    22,    23,    -1,    -1,    26,    27,    28,
-    29,    -1,    31,    32,    33,    34,    -1,    -1,    37,    -1,
-     3,    40,    41,    -1,    43,     8,    45,    10,    11,    12,
-    13,    -1,    -1,    16,    -1,    18,    19,    -1,    21,    22,
-    23,    -1,    -1,    26,    27,    28,    29,    -1,    31,    32,
-    33,    34,    -1,    -1,    -1,    -1,     3,    40,    41,    -1,
-    43,     8,    45,    10,    11,    12,    13,    -1,    -1,    16,
-    -1,    -1,    19,    -1,    21,    22,    23,    -1,    -1,    26,
-    27,    28,    29,    -1,    31,    32,    33,    34,    -1,    -1,
-    -1,    -1,     3,    40,    41,    -1,    43,     8,    45,    10,
-    11,    12,    13,    -1,    -1,    16,    -1,    18,    -1,    -1,
-    21,    22,    23,    -1,    -1,    26,    27,    28,    29,    -1,
-    31,    32,    33,    34,    -1,    -1,    -1,    -1,     3,    40,
-    41,    -1,    43,     8,    45,    10,    11,    12,    13,    -1,
-    -1,    16,    -1,    -1,    -1,    -1,    21,    22,    23,    -1,
-    -1,    26,    27,    28,    29,    -1,    31,    32,    33,    34,
-    -1,    -1,    37,    -1,     3,    40,    41,    -1,    43,     8,
-    45,    10,    11,    12,    13,    -1,    -1,    16,    -1,    -1,
-    -1,    -1,    21,    22,    23,    -1,    -1,    26,    27,    28,
-    29,    -1,    31,    32,    33,    34,    -1,    -1,    -1,    -1,
-    -1,    40,    41,    -1,    43,    23,    45,    -1,    26,    27,
-    28,    29,    -1,    31,    32,    33,    34,    -1,    -1,    -1,
-    -1,    -1,    40,    41,    26,    27,    28,    29,    -1,    31,
-    -1,    33,    34,    -1,    -1,    -1,    -1,    -1,    40,    41
+static const short yycheck[] = {     6,
+     7,     0,   121,    28,     0,    34,     9,    28,     9,    14,
+    14,    20,    14,    45,    29,    20,    10,    14,    20,    45,
+    52,    24,    29,    24,    14,    90,    52,    14,    14,    54,
+    55,    43,    57,    43,    43,    60,   191,    49,    43,    43,
+    43,    43,    43,   198,    49,    49,    43,    49,    51,   168,
+    51,    24,    49,    43,    24,    49,    43,    43,    24,    49,
+    26,    24,    49,    49,    24,    24,    95,    26,    24,    63,
+    26,    23,    97,    98,    51,    24,   101,    24,    24,    24,
+    26,    28,    48,   202,    24,   110,     5,     6,     7,    48,
+   115,   116,    48,    42,    43,    44,    24,   104,    24,   124,
+    99,   100,    48,    45,   100,    42,    43,    44,   102,    30,
+    31,   118,   119,   178,   179,   180,   181,   182,    30,    31,
+    41,    42,    43,    24,   149,   150,   151,   152,   153,   154,
+    30,    31,     5,     6,    24,    24,   161,    43,   163,     4,
+   161,   166,   163,   142,   143,    42,   142,   143,    42,   156,
+    14,   158,   146,    30,    31,    14,    51,    18,    24,    52,
+   185,    24,    24,    50,    41,    42,    24,   174,   175,    24,
+   195,   196,   171,   172,   195,   196,   172,    24,    24,    24,
+   187,   188,    52,    52,    15,     7,   193,   194,   253,   254,
+   255,    15,     9,    36,    24,    25,    26,    15,    50,   224,
+    15,    50,    32,    33,    34,    35,   231,    37,    38,    39,
+    40,   236,   237,   238,     7,     4,    46,    47,   243,    32,
+    33,    34,    35,    24,    37,    36,    39,    40,   235,    15,
+    50,   256,    15,    46,    47,    15,   243,   262,   263,    24,
+    50,   262,   263,    50,    15,    50,    15,    50,     0,   256,
+     0,   162,   252,   260,   261,    32,     1,   264,     3,    10,
+   185,   218,    -1,     8,    -1,    10,    11,    12,    13,    -1,
+    -1,    16,    17,    -1,    -1,    -1,    21,    22,    -1,    24,
+    25,    26,    27,    -1,    -1,    -1,    -1,    32,    33,    34,
+    35,    -1,    37,    38,    39,    40,    -1,    -1,    43,    44,
+     3,    46,    47,    -1,    49,     8,    51,    10,    11,    12,
+    13,    -1,    -1,    16,    17,    -1,    -1,    -1,    21,    22,
+    -1,    24,    25,    26,    27,    -1,    -1,    -1,    -1,    32,
+    33,    34,    35,    -1,    37,    38,    39,    40,    -1,    -1,
+    43,    -1,     3,    46,    47,    -1,    49,     8,    51,    10,
+    11,    12,    13,    -1,    -1,    16,    17,    -1,    -1,    -1,
+    21,    22,    -1,    24,    25,    26,    27,    -1,    -1,    -1,
+    -1,    32,    33,    34,    35,    -1,    37,    38,    39,    40,
+    -1,    -1,    -1,    -1,     3,    46,    47,    -1,    49,     8,
+    51,    10,    11,    12,    13,    -1,    -1,    16,    17,    -1,
+    -1,    -1,    -1,    22,    -1,    24,    25,    26,    27,    -1,
+    -1,    -1,    -1,    32,    33,    34,    35,    -1,    37,    38,
+    39,    40,    -1,    -1,    -1,    -1,     3,    46,    47,    -1,
+    49,     8,    51,    10,    11,    12,    13,    -1,    -1,    16,
+    17,    -1,    -1,    -1,    21,    -1,    -1,    24,    25,    26,
+    27,    -1,    -1,    -1,    -1,    32,    33,    34,    35,    -1,
+    37,    38,    39,    40,    -1,    -1,    -1,    -1,     3,    46,
+    47,    -1,    49,     8,    51,    10,    11,    12,    13,    -1,
+    -1,    16,    17,    -1,    -1,    -1,    -1,    -1,    -1,    24,
+    25,    26,    27,    -1,    -1,    -1,    -1,    32,    33,    34,
+    35,    -1,    37,    38,    39,    40,    -1,    -1,    43,    -1,
+     3,    46,    47,    -1,    49,     8,    51,    10,    11,    12,
+    13,    -1,    -1,    16,    17,    -1,    -1,    -1,    -1,    -1,
+    -1,    24,    25,    26,    27,    -1,    -1,    -1,    -1,    32,
+    33,    34,    35,    -1,    37,    38,    39,    40,    -1,    -1,
+    -1,    -1,    -1,    46,    47,    26,    49,    -1,    51,    -1,
+    -1,    32,    33,    34,    35,    -1,    37,    38,    39,    40,
+    -1,    -1,    -1,    -1,    -1,    46,    47
 };
 /* -*-C-*-  Note some compilers choke on comments on `#line' lines.  */
-#line 3 "/usr/local/lib/bison.simple"
+#line 3 "/usr/share/misc/bison.simple"
 
 /* Skeleton output parser for bison,
    Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
@@ -765,7 +809,7 @@ __yy_memcpy (char *to, char *from, int count)
 #endif
 #endif
 \f
-#line 196 "/usr/local/lib/bison.simple"
+#line 196 "/usr/share/misc/bison.simple"
 
 /* The user can define YYPARSE_PARAM as the name of an argument to be passed
    into yyparse.  The argument should have type void *.
@@ -1070,7 +1114,7 @@ yyreduce:
   switch (yyn) {
 
 case 1:
-#line 210 "./parse.y"
+#line 238 "/usr/homes/chet/src/bash/src/parse.y"
 {
                          /* Case of regular command.  Discard the error
                             safety net,and return the command just parsed. */
@@ -1081,7 +1125,7 @@ case 1:
                        ;
     break;}
 case 2:
-#line 219 "./parse.y"
+#line 247 "/usr/homes/chet/src/bash/src/parse.y"
 {
                          /* Case of regular command, but not a very
                             interesting one.  Return a NULL command. */
@@ -1090,7 +1134,7 @@ case 2:
                        ;
     break;}
 case 3:
-#line 226 "./parse.y"
+#line 254 "/usr/homes/chet/src/bash/src/parse.y"
 {
                          /* Error during parsing.  Return NULL command. */
                          global_command = (COMMAND *)NULL;
@@ -1107,7 +1151,7 @@ case 3:
                        ;
     break;}
 case 4:
-#line 241 "./parse.y"
+#line 269 "/usr/homes/chet/src/bash/src/parse.y"
 {
                          /* Case of EOF seen by itself.  Do ignoreeof or
                             not. */
@@ -1117,57 +1161,57 @@ case 4:
                        ;
     break;}
 case 5:
-#line 251 "./parse.y"
+#line 279 "/usr/homes/chet/src/bash/src/parse.y"
 { yyval.word_list = make_word_list (yyvsp[0].word, (WORD_LIST *)NULL); ;
     break;}
 case 6:
-#line 253 "./parse.y"
+#line 281 "/usr/homes/chet/src/bash/src/parse.y"
 { yyval.word_list = make_word_list (yyvsp[0].word, yyvsp[-1].word_list); ;
     break;}
 case 7:
-#line 257 "./parse.y"
+#line 285 "/usr/homes/chet/src/bash/src/parse.y"
 {
                          redir.filename = yyvsp[0].word;
                          yyval.redirect = make_redirection (1, r_output_direction, redir);
                        ;
     break;}
 case 8:
-#line 262 "./parse.y"
+#line 290 "/usr/homes/chet/src/bash/src/parse.y"
 {
                          redir.filename = yyvsp[0].word;
                          yyval.redirect = make_redirection (0, r_input_direction, redir);
                        ;
     break;}
 case 9:
-#line 267 "./parse.y"
+#line 295 "/usr/homes/chet/src/bash/src/parse.y"
 {
                          redir.filename = yyvsp[0].word;
                          yyval.redirect = make_redirection (yyvsp[-2].number, r_output_direction, redir);
                        ;
     break;}
 case 10:
-#line 272 "./parse.y"
+#line 300 "/usr/homes/chet/src/bash/src/parse.y"
 {
                          redir.filename = yyvsp[0].word;
                          yyval.redirect = make_redirection (yyvsp[-2].number, r_input_direction, redir);
                        ;
     break;}
 case 11:
-#line 277 "./parse.y"
+#line 305 "/usr/homes/chet/src/bash/src/parse.y"
 {
                          redir.filename = yyvsp[0].word;
                          yyval.redirect = make_redirection (1, r_appending_to, redir);
                        ;
     break;}
 case 12:
-#line 282 "./parse.y"
+#line 310 "/usr/homes/chet/src/bash/src/parse.y"
 {
                          redir.filename = yyvsp[0].word;
                          yyval.redirect = make_redirection (yyvsp[-2].number, r_appending_to, redir);
                        ;
     break;}
 case 13:
-#line 287 "./parse.y"
+#line 315 "/usr/homes/chet/src/bash/src/parse.y"
 {
                          redir.filename = yyvsp[0].word;
                          yyval.redirect = make_redirection (0, r_reading_until, redir);
@@ -1175,7 +1219,7 @@ case 13:
                        ;
     break;}
 case 14:
-#line 293 "./parse.y"
+#line 321 "/usr/homes/chet/src/bash/src/parse.y"
 {
                          redir.filename = yyvsp[0].word;
                          yyval.redirect = make_redirection (yyvsp[-2].number, r_reading_until, redir);
@@ -1183,63 +1227,63 @@ case 14:
                        ;
     break;}
 case 15:
-#line 299 "./parse.y"
+#line 327 "/usr/homes/chet/src/bash/src/parse.y"
 {
                          redir.dest = yyvsp[0].number;
                          yyval.redirect = make_redirection (0, r_duplicating_input, redir);
                        ;
     break;}
 case 16:
-#line 304 "./parse.y"
+#line 332 "/usr/homes/chet/src/bash/src/parse.y"
 {
                          redir.dest = yyvsp[0].number;
                          yyval.redirect = make_redirection (yyvsp[-2].number, r_duplicating_input, redir);
                        ;
     break;}
 case 17:
-#line 309 "./parse.y"
+#line 337 "/usr/homes/chet/src/bash/src/parse.y"
 {
                          redir.dest = yyvsp[0].number;
                          yyval.redirect = make_redirection (1, r_duplicating_output, redir);
                        ;
     break;}
 case 18:
-#line 314 "./parse.y"
+#line 342 "/usr/homes/chet/src/bash/src/parse.y"
 {
                          redir.dest = yyvsp[0].number;
                          yyval.redirect = make_redirection (yyvsp[-2].number, r_duplicating_output, redir);
                        ;
     break;}
 case 19:
-#line 319 "./parse.y"
+#line 347 "/usr/homes/chet/src/bash/src/parse.y"
 {
                          redir.filename = yyvsp[0].word;
                          yyval.redirect = make_redirection (0, r_duplicating_input_word, redir);
                        ;
     break;}
 case 20:
-#line 324 "./parse.y"
+#line 352 "/usr/homes/chet/src/bash/src/parse.y"
 {
                          redir.filename = yyvsp[0].word;
                          yyval.redirect = make_redirection (yyvsp[-2].number, r_duplicating_input_word, redir);
                        ;
     break;}
 case 21:
-#line 329 "./parse.y"
+#line 357 "/usr/homes/chet/src/bash/src/parse.y"
 {
                          redir.filename = yyvsp[0].word;
                          yyval.redirect = make_redirection (1, r_duplicating_output_word, redir);
                        ;
     break;}
 case 22:
-#line 334 "./parse.y"
+#line 362 "/usr/homes/chet/src/bash/src/parse.y"
 {
                          redir.filename = yyvsp[0].word;
                          yyval.redirect = make_redirection (yyvsp[-2].number, r_duplicating_output_word, redir);
                        ;
     break;}
 case 23:
-#line 339 "./parse.y"
+#line 367 "/usr/homes/chet/src/bash/src/parse.y"
 {
                          redir.filename = yyvsp[0].word;
                          yyval.redirect = make_redirection
@@ -1248,7 +1292,7 @@ case 23:
                        ;
     break;}
 case 24:
-#line 346 "./parse.y"
+#line 374 "/usr/homes/chet/src/bash/src/parse.y"
 {
                          redir.filename = yyvsp[0].word;
                          yyval.redirect = make_redirection
@@ -1257,88 +1301,88 @@ case 24:
                        ;
     break;}
 case 25:
-#line 353 "./parse.y"
+#line 381 "/usr/homes/chet/src/bash/src/parse.y"
 {
                          redir.dest = 0L;
                          yyval.redirect = make_redirection (1, r_close_this, redir);
                        ;
     break;}
 case 26:
-#line 358 "./parse.y"
+#line 386 "/usr/homes/chet/src/bash/src/parse.y"
 {
                          redir.dest = 0L;
                          yyval.redirect = make_redirection (yyvsp[-2].number, r_close_this, redir);
                        ;
     break;}
 case 27:
-#line 363 "./parse.y"
+#line 391 "/usr/homes/chet/src/bash/src/parse.y"
 {
                          redir.dest = 0L;
                          yyval.redirect = make_redirection (0, r_close_this, redir);
                        ;
     break;}
 case 28:
-#line 368 "./parse.y"
+#line 396 "/usr/homes/chet/src/bash/src/parse.y"
 {
                          redir.dest = 0L;
                          yyval.redirect = make_redirection (yyvsp[-2].number, r_close_this, redir);
                        ;
     break;}
 case 29:
-#line 373 "./parse.y"
+#line 401 "/usr/homes/chet/src/bash/src/parse.y"
 {
                          redir.filename = yyvsp[0].word;
                          yyval.redirect = make_redirection (1, r_err_and_out, redir);
                        ;
     break;}
 case 30:
-#line 378 "./parse.y"
+#line 406 "/usr/homes/chet/src/bash/src/parse.y"
 {
                          redir.filename = yyvsp[0].word;
                          yyval.redirect = make_redirection (yyvsp[-2].number, r_input_output, redir);
                        ;
     break;}
 case 31:
-#line 383 "./parse.y"
+#line 411 "/usr/homes/chet/src/bash/src/parse.y"
 {
                          redir.filename = yyvsp[0].word;
                          yyval.redirect = make_redirection (0, r_input_output, redir);
                        ;
     break;}
 case 32:
-#line 388 "./parse.y"
+#line 416 "/usr/homes/chet/src/bash/src/parse.y"
 {
                          redir.filename = yyvsp[0].word;
                          yyval.redirect = make_redirection (1, r_output_force, redir);
                        ;
     break;}
 case 33:
-#line 393 "./parse.y"
+#line 421 "/usr/homes/chet/src/bash/src/parse.y"
 {
                          redir.filename = yyvsp[0].word;
                          yyval.redirect = make_redirection (yyvsp[-2].number, r_output_force, redir);
                        ;
     break;}
 case 34:
-#line 400 "./parse.y"
+#line 428 "/usr/homes/chet/src/bash/src/parse.y"
 { yyval.element.word = yyvsp[0].word; yyval.element.redirect = 0; ;
     break;}
 case 35:
-#line 402 "./parse.y"
+#line 430 "/usr/homes/chet/src/bash/src/parse.y"
 { yyval.element.word = yyvsp[0].word; yyval.element.redirect = 0; ;
     break;}
 case 36:
-#line 404 "./parse.y"
+#line 432 "/usr/homes/chet/src/bash/src/parse.y"
 { yyval.element.redirect = yyvsp[0].redirect; yyval.element.word = 0; ;
     break;}
 case 37:
-#line 408 "./parse.y"
+#line 436 "/usr/homes/chet/src/bash/src/parse.y"
 {
                          yyval.redirect = yyvsp[0].redirect;
                        ;
     break;}
 case 38:
-#line 412 "./parse.y"
+#line 440 "/usr/homes/chet/src/bash/src/parse.y"
 {
                          register REDIRECT *t;
 
@@ -1349,23 +1393,23 @@ case 38:
                        ;
     break;}
 case 39:
-#line 423 "./parse.y"
+#line 451 "/usr/homes/chet/src/bash/src/parse.y"
 { yyval.command = make_simple_command (yyvsp[0].element, (COMMAND *)NULL); ;
     break;}
 case 40:
-#line 425 "./parse.y"
+#line 453 "/usr/homes/chet/src/bash/src/parse.y"
 { yyval.command = make_simple_command (yyvsp[0].element, yyvsp[-1].command); ;
     break;}
 case 41:
-#line 429 "./parse.y"
+#line 457 "/usr/homes/chet/src/bash/src/parse.y"
 { yyval.command = clean_simple_command (yyvsp[0].command); ;
     break;}
 case 42:
-#line 431 "./parse.y"
+#line 459 "/usr/homes/chet/src/bash/src/parse.y"
 { yyval.command = yyvsp[0].command; ;
     break;}
 case 43:
-#line 433 "./parse.y"
+#line 461 "/usr/homes/chet/src/bash/src/parse.y"
 {
                          COMMAND *tc;
 
@@ -1375,6 +1419,14 @@ case 43:
                             be attached to the function and performed when
                             the function is executed, not as part of the
                             function definition command. */
+                         /* XXX - I don't think it matters, but we might
+                            want to change this in the future to avoid
+                            problems differentiating between a function
+                            definition with a redirection and a function
+                            definition containing a single command with a
+                            redirection.  The two are semantically equivalent,
+                            though -- the only difference is in how the
+                            command printing code displays the redirections. */
                          if (tc->type == cm_function_def)
                            {
                              tc = tc->value.Function_def->command;
@@ -1394,205 +1446,236 @@ case 43:
                        ;
     break;}
 case 44:
-#line 462 "./parse.y"
+#line 498 "/usr/homes/chet/src/bash/src/parse.y"
 { yyval.command = yyvsp[0].command; ;
     break;}
 case 45:
-#line 464 "./parse.y"
+#line 500 "/usr/homes/chet/src/bash/src/parse.y"
 { yyval.command = yyvsp[0].command; ;
     break;}
 case 46:
-#line 466 "./parse.y"
+#line 502 "/usr/homes/chet/src/bash/src/parse.y"
 { yyval.command = make_while_command (yyvsp[-3].command, yyvsp[-1].command); ;
     break;}
 case 47:
-#line 468 "./parse.y"
+#line 504 "/usr/homes/chet/src/bash/src/parse.y"
 { yyval.command = make_until_command (yyvsp[-3].command, yyvsp[-1].command); ;
     break;}
 case 48:
-#line 470 "./parse.y"
+#line 506 "/usr/homes/chet/src/bash/src/parse.y"
 { yyval.command = yyvsp[0].command; ;
     break;}
 case 49:
-#line 472 "./parse.y"
+#line 508 "/usr/homes/chet/src/bash/src/parse.y"
 { yyval.command = yyvsp[0].command; ;
     break;}
 case 50:
-#line 474 "./parse.y"
+#line 510 "/usr/homes/chet/src/bash/src/parse.y"
 { yyval.command = yyvsp[0].command; ;
     break;}
 case 51:
-#line 476 "./parse.y"
+#line 512 "/usr/homes/chet/src/bash/src/parse.y"
 { yyval.command = yyvsp[0].command; ;
     break;}
 case 52:
-#line 478 "./parse.y"
+#line 514 "/usr/homes/chet/src/bash/src/parse.y"
 { yyval.command = yyvsp[0].command; ;
     break;}
 case 53:
-#line 482 "./parse.y"
-{ yyval.command = make_for_command (yyvsp[-4].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command); ;
+#line 516 "/usr/homes/chet/src/bash/src/parse.y"
+{ yyval.command = yyvsp[0].command; ;
     break;}
 case 54:
-#line 484 "./parse.y"
-{ yyval.command = make_for_command (yyvsp[-4].word, add_string_to_list ("$@", (WORD_LIST *)NULL), yyvsp[-1].command); ;
+#line 518 "/usr/homes/chet/src/bash/src/parse.y"
+{ yyval.command = yyvsp[0].command; ;
     break;}
 case 55:
-#line 486 "./parse.y"
-{ yyval.command = make_for_command (yyvsp[-5].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command); ;
+#line 520 "/usr/homes/chet/src/bash/src/parse.y"
+{ yyval.command = yyvsp[0].command; ;
     break;}
 case 56:
-#line 488 "./parse.y"
-{ yyval.command = make_for_command (yyvsp[-5].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command); ;
+#line 524 "/usr/homes/chet/src/bash/src/parse.y"
+{ yyval.command = make_for_command (yyvsp[-4].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command); ;
     break;}
 case 57:
-#line 490 "./parse.y"
-{ yyval.command = make_for_command (yyvsp[-8].word, REVERSE_LIST (yyvsp[-5].word_list, WORD_LIST *), yyvsp[-1].command); ;
+#line 526 "/usr/homes/chet/src/bash/src/parse.y"
+{ yyval.command = make_for_command (yyvsp[-4].word, add_string_to_list ("$@", (WORD_LIST *)NULL), yyvsp[-1].command); ;
     break;}
 case 58:
-#line 492 "./parse.y"
-{ yyval.command = make_for_command (yyvsp[-8].word, REVERSE_LIST (yyvsp[-5].word_list, WORD_LIST *), yyvsp[-1].command); ;
+#line 528 "/usr/homes/chet/src/bash/src/parse.y"
+{ yyval.command = make_for_command (yyvsp[-5].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command); ;
     break;}
 case 59:
-#line 496 "./parse.y"
+#line 530 "/usr/homes/chet/src/bash/src/parse.y"
+{ yyval.command = make_for_command (yyvsp[-5].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command); ;
+    break;}
+case 60:
+#line 532 "/usr/homes/chet/src/bash/src/parse.y"
+{ yyval.command = make_for_command (yyvsp[-8].word, REVERSE_LIST (yyvsp[-5].word_list, WORD_LIST *), yyvsp[-1].command); ;
+    break;}
+case 61:
+#line 534 "/usr/homes/chet/src/bash/src/parse.y"
+{ yyval.command = make_for_command (yyvsp[-8].word, REVERSE_LIST (yyvsp[-5].word_list, WORD_LIST *), yyvsp[-1].command); ;
+    break;}
+case 62:
+#line 538 "/usr/homes/chet/src/bash/src/parse.y"
+{ yyval.command = make_arith_for_command (yyvsp[-5].word_list, yyvsp[-1].command, arith_for_lineno); ;
+    break;}
+case 63:
+#line 540 "/usr/homes/chet/src/bash/src/parse.y"
+{ yyval.command = make_arith_for_command (yyvsp[-5].word_list, yyvsp[-1].command, arith_for_lineno); ;
+    break;}
+case 64:
+#line 543 "/usr/homes/chet/src/bash/src/parse.y"
 {
                          yyval.command = make_select_command (yyvsp[-4].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command);
                        ;
     break;}
-case 60:
-#line 500 "./parse.y"
+case 65:
+#line 547 "/usr/homes/chet/src/bash/src/parse.y"
 {
                          yyval.command = make_select_command (yyvsp[-4].word, add_string_to_list ("$@", (WORD_LIST *)NULL), yyvsp[-1].command);
                        ;
     break;}
-case 61:
-#line 504 "./parse.y"
+case 66:
+#line 551 "/usr/homes/chet/src/bash/src/parse.y"
 {
                          yyval.command = make_select_command (yyvsp[-5].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command);
                        ;
     break;}
-case 62:
-#line 508 "./parse.y"
+case 67:
+#line 555 "/usr/homes/chet/src/bash/src/parse.y"
 {
                          yyval.command = make_select_command (yyvsp[-5].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command);
                        ;
     break;}
-case 63:
-#line 512 "./parse.y"
+case 68:
+#line 559 "/usr/homes/chet/src/bash/src/parse.y"
 {
                          yyval.command = make_select_command (yyvsp[-8].word, (WORD_LIST *)reverse_list (yyvsp[-5].word_list), yyvsp[-1].command);
                        ;
     break;}
-case 64:
-#line 516 "./parse.y"
+case 69:
+#line 563 "/usr/homes/chet/src/bash/src/parse.y"
 {
                          yyval.command = make_select_command (yyvsp[-8].word, (WORD_LIST *)reverse_list (yyvsp[-5].word_list), yyvsp[-1].command);
                        ;
     break;}
-case 65:
-#line 522 "./parse.y"
+case 70:
+#line 569 "/usr/homes/chet/src/bash/src/parse.y"
 { yyval.command = make_case_command (yyvsp[-4].word, (PATTERN_LIST *)NULL); ;
     break;}
-case 66:
-#line 524 "./parse.y"
+case 71:
+#line 571 "/usr/homes/chet/src/bash/src/parse.y"
 { yyval.command = make_case_command (yyvsp[-5].word, yyvsp[-2].pattern); ;
     break;}
-case 67:
-#line 526 "./parse.y"
+case 72:
+#line 573 "/usr/homes/chet/src/bash/src/parse.y"
 { yyval.command = make_case_command (yyvsp[-4].word, yyvsp[-1].pattern); ;
     break;}
-case 68:
-#line 530 "./parse.y"
+case 73:
+#line 577 "/usr/homes/chet/src/bash/src/parse.y"
 { yyval.command = make_function_def (yyvsp[-4].word, yyvsp[0].command, function_dstart, function_bstart); ;
     break;}
-case 69:
-#line 534 "./parse.y"
+case 74:
+#line 581 "/usr/homes/chet/src/bash/src/parse.y"
 { yyval.command = make_function_def (yyvsp[-4].word, yyvsp[0].command, function_dstart, function_bstart); ;
     break;}
-case 70:
-#line 537 "./parse.y"
+case 75:
+#line 584 "/usr/homes/chet/src/bash/src/parse.y"
 { yyval.command = make_function_def (yyvsp[-2].word, yyvsp[0].command, function_dstart, function_bstart); ;
     break;}
-case 71:
-#line 541 "./parse.y"
-{ yyvsp[-1].command->flags |= CMD_WANT_SUBSHELL; yyval.command = yyvsp[-1].command; ;
+case 76:
+#line 588 "/usr/homes/chet/src/bash/src/parse.y"
+{
+                         yyval.command = make_subshell_command (yyvsp[-1].command);
+                         yyval.command->flags |= CMD_WANT_SUBSHELL;
+                       ;
     break;}
-case 72:
-#line 545 "./parse.y"
+case 77:
+#line 595 "/usr/homes/chet/src/bash/src/parse.y"
 { yyval.command = make_if_command (yyvsp[-3].command, yyvsp[-1].command, (COMMAND *)NULL); ;
     break;}
-case 73:
-#line 547 "./parse.y"
+case 78:
+#line 597 "/usr/homes/chet/src/bash/src/parse.y"
 { yyval.command = make_if_command (yyvsp[-5].command, yyvsp[-3].command, yyvsp[-1].command); ;
     break;}
-case 74:
-#line 549 "./parse.y"
+case 79:
+#line 599 "/usr/homes/chet/src/bash/src/parse.y"
 { yyval.command = make_if_command (yyvsp[-4].command, yyvsp[-2].command, yyvsp[-1].command); ;
     break;}
-case 75:
-#line 554 "./parse.y"
+case 80:
+#line 604 "/usr/homes/chet/src/bash/src/parse.y"
 { yyval.command = make_group_command (yyvsp[-1].command); ;
     break;}
-case 76:
-#line 558 "./parse.y"
+case 81:
+#line 608 "/usr/homes/chet/src/bash/src/parse.y"
+{ yyval.command = make_arith_command (yyvsp[0].word_list); ;
+    break;}
+case 82:
+#line 612 "/usr/homes/chet/src/bash/src/parse.y"
+{ yyval.command = yyvsp[-1].command; ;
+    break;}
+case 83:
+#line 616 "/usr/homes/chet/src/bash/src/parse.y"
 { yyval.command = make_if_command (yyvsp[-2].command, yyvsp[0].command, (COMMAND *)NULL); ;
     break;}
-case 77:
-#line 560 "./parse.y"
+case 84:
+#line 618 "/usr/homes/chet/src/bash/src/parse.y"
 { yyval.command = make_if_command (yyvsp[-4].command, yyvsp[-2].command, yyvsp[0].command); ;
     break;}
-case 78:
-#line 562 "./parse.y"
+case 85:
+#line 620 "/usr/homes/chet/src/bash/src/parse.y"
 { yyval.command = make_if_command (yyvsp[-3].command, yyvsp[-1].command, yyvsp[0].command); ;
     break;}
-case 80:
-#line 567 "./parse.y"
+case 87:
+#line 625 "/usr/homes/chet/src/bash/src/parse.y"
 { yyvsp[0].pattern->next = yyvsp[-1].pattern; yyval.pattern = yyvsp[0].pattern; ;
     break;}
-case 81:
-#line 571 "./parse.y"
+case 88:
+#line 629 "/usr/homes/chet/src/bash/src/parse.y"
 { yyval.pattern = make_pattern_list (yyvsp[-2].word_list, yyvsp[0].command); ;
     break;}
-case 82:
-#line 573 "./parse.y"
+case 89:
+#line 631 "/usr/homes/chet/src/bash/src/parse.y"
 { yyval.pattern = make_pattern_list (yyvsp[-2].word_list, (COMMAND *)NULL); ;
     break;}
-case 83:
-#line 575 "./parse.y"
+case 90:
+#line 633 "/usr/homes/chet/src/bash/src/parse.y"
 { yyval.pattern = make_pattern_list (yyvsp[-2].word_list, yyvsp[0].command); ;
     break;}
-case 84:
-#line 577 "./parse.y"
+case 91:
+#line 635 "/usr/homes/chet/src/bash/src/parse.y"
 { yyval.pattern = make_pattern_list (yyvsp[-2].word_list, (COMMAND *)NULL); ;
     break;}
-case 86:
-#line 582 "./parse.y"
+case 93:
+#line 640 "/usr/homes/chet/src/bash/src/parse.y"
 { yyvsp[-1].pattern->next = yyvsp[-2].pattern; yyval.pattern = yyvsp[-1].pattern; ;
     break;}
-case 87:
-#line 586 "./parse.y"
+case 94:
+#line 644 "/usr/homes/chet/src/bash/src/parse.y"
 { yyval.word_list = make_word_list (yyvsp[0].word, (WORD_LIST *)NULL); ;
     break;}
-case 88:
-#line 588 "./parse.y"
+case 95:
+#line 646 "/usr/homes/chet/src/bash/src/parse.y"
 { yyval.word_list = make_word_list (yyvsp[0].word, yyvsp[-2].word_list); ;
     break;}
-case 89:
-#line 597 "./parse.y"
+case 96:
+#line 655 "/usr/homes/chet/src/bash/src/parse.y"
 {
                          yyval.command = yyvsp[0].command;
                          if (need_here_doc)
                            gather_here_documents ();
                         ;
     break;}
-case 91:
-#line 606 "./parse.y"
+case 98:
+#line 664 "/usr/homes/chet/src/bash/src/parse.y"
 {
                          yyval.command = yyvsp[0].command;
                        ;
     break;}
-case 93:
-#line 613 "./parse.y"
+case 100:
+#line 671 "/usr/homes/chet/src/bash/src/parse.y"
 {
                          if (yyvsp[-2].command->type == cm_connection)
                            yyval.command = connect_async_list (yyvsp[-2].command, (COMMAND *)NULL, '&');
@@ -1600,16 +1683,16 @@ case 93:
                            yyval.command = command_connect (yyvsp[-2].command, (COMMAND *)NULL, '&');
                        ;
     break;}
-case 95:
-#line 624 "./parse.y"
+case 102:
+#line 682 "/usr/homes/chet/src/bash/src/parse.y"
 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, AND_AND); ;
     break;}
-case 96:
-#line 626 "./parse.y"
+case 103:
+#line 684 "/usr/homes/chet/src/bash/src/parse.y"
 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, OR_OR); ;
     break;}
-case 97:
-#line 628 "./parse.y"
+case 104:
+#line 686 "/usr/homes/chet/src/bash/src/parse.y"
 {
                          if (yyvsp[-3].command->type == cm_connection)
                            yyval.command = connect_async_list (yyvsp[-3].command, yyvsp[0].command, '&');
@@ -1617,28 +1700,28 @@ case 97:
                            yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, '&');
                        ;
     break;}
-case 98:
-#line 635 "./parse.y"
+case 105:
+#line 693 "/usr/homes/chet/src/bash/src/parse.y"
 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, ';'); ;
     break;}
-case 99:
-#line 637 "./parse.y"
+case 106:
+#line 695 "/usr/homes/chet/src/bash/src/parse.y"
 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, ';'); ;
     break;}
-case 100:
-#line 639 "./parse.y"
+case 107:
+#line 697 "/usr/homes/chet/src/bash/src/parse.y"
 { yyval.command = yyvsp[0].command; ;
     break;}
-case 106:
-#line 658 "./parse.y"
+case 113:
+#line 716 "/usr/homes/chet/src/bash/src/parse.y"
 {
                          yyval.command = yyvsp[0].command;
                          if (need_here_doc)
                            gather_here_documents ();
                        ;
     break;}
-case 107:
-#line 664 "./parse.y"
+case 114:
+#line 722 "/usr/homes/chet/src/bash/src/parse.y"
 {
                          if (yyvsp[-1].command->type == cm_connection)
                            yyval.command = connect_async_list (yyvsp[-1].command, (COMMAND *)NULL, '&');
@@ -1648,24 +1731,24 @@ case 107:
                            gather_here_documents ();
                        ;
     break;}
-case 108:
-#line 673 "./parse.y"
+case 115:
+#line 731 "/usr/homes/chet/src/bash/src/parse.y"
 {
                          yyval.command = yyvsp[-1].command;
                          if (need_here_doc)
                            gather_here_documents ();
                        ;
     break;}
-case 109:
-#line 681 "./parse.y"
+case 116:
+#line 739 "/usr/homes/chet/src/bash/src/parse.y"
 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, AND_AND); ;
     break;}
-case 110:
-#line 683 "./parse.y"
+case 117:
+#line 741 "/usr/homes/chet/src/bash/src/parse.y"
 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, OR_OR); ;
     break;}
-case 111:
-#line 685 "./parse.y"
+case 118:
+#line 743 "/usr/homes/chet/src/bash/src/parse.y"
 {
                          if (yyvsp[-2].command->type == cm_connection)
                            yyval.command = connect_async_list (yyvsp[-2].command, yyvsp[0].command, '&');
@@ -1673,65 +1756,65 @@ case 111:
                            yyval.command = command_connect (yyvsp[-2].command, yyvsp[0].command, '&');
                        ;
     break;}
-case 112:
-#line 692 "./parse.y"
+case 119:
+#line 750 "/usr/homes/chet/src/bash/src/parse.y"
 { yyval.command = command_connect (yyvsp[-2].command, yyvsp[0].command, ';'); ;
     break;}
-case 113:
-#line 695 "./parse.y"
+case 120:
+#line 753 "/usr/homes/chet/src/bash/src/parse.y"
 { yyval.command = yyvsp[0].command; ;
     break;}
-case 114:
-#line 699 "./parse.y"
+case 121:
+#line 757 "/usr/homes/chet/src/bash/src/parse.y"
 { yyval.command = yyvsp[0].command; ;
     break;}
-case 115:
-#line 701 "./parse.y"
+case 122:
+#line 759 "/usr/homes/chet/src/bash/src/parse.y"
 {
                          yyvsp[0].command->flags |= CMD_INVERT_RETURN;
                          yyval.command = yyvsp[0].command;
                        ;
     break;}
-case 116:
-#line 706 "./parse.y"
+case 123:
+#line 764 "/usr/homes/chet/src/bash/src/parse.y"
 {
                          yyvsp[0].command->flags |= yyvsp[-1].number;
                          yyval.command = yyvsp[0].command;
                        ;
     break;}
-case 117:
-#line 711 "./parse.y"
+case 124:
+#line 769 "/usr/homes/chet/src/bash/src/parse.y"
 {
-                         yyvsp[0].command->flags |= yyvsp[-2].number;
+                         yyvsp[0].command->flags |= yyvsp[-2].number|CMD_INVERT_RETURN;
                          yyval.command = yyvsp[0].command;
                        ;
     break;}
-case 118:
-#line 716 "./parse.y"
+case 125:
+#line 774 "/usr/homes/chet/src/bash/src/parse.y"
 {
                          yyvsp[0].command->flags |= yyvsp[-1].number|CMD_INVERT_RETURN;
                          yyval.command = yyvsp[0].command;
                        ;
     break;}
-case 119:
-#line 724 "./parse.y"
+case 126:
+#line 782 "/usr/homes/chet/src/bash/src/parse.y"
 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, '|'); ;
     break;}
-case 120:
-#line 726 "./parse.y"
+case 127:
+#line 784 "/usr/homes/chet/src/bash/src/parse.y"
 { yyval.command = yyvsp[0].command; ;
     break;}
-case 121:
-#line 730 "./parse.y"
+case 128:
+#line 788 "/usr/homes/chet/src/bash/src/parse.y"
 { yyval.number = CMD_TIME_PIPELINE; ;
     break;}
-case 122:
-#line 732 "./parse.y"
+case 129:
+#line 790 "/usr/homes/chet/src/bash/src/parse.y"
 { yyval.number = CMD_TIME_PIPELINE|CMD_TIME_POSIX; ;
     break;}
 }
    /* the action file gets copied in in place of this dollarsign */
-#line 498 "/usr/local/lib/bison.simple"
+#line 498 "/usr/share/misc/bison.simple"
 \f
   yyvsp -= yylen;
   yyssp -= yylen;
@@ -1927,7 +2010,7 @@ yyerrhandle:
   yystate = yyn;
   goto yynewstate;
 }
-#line 734 "./parse.y"
+#line 792 "/usr/homes/chet/src/bash/src/parse.y"
 
 
 /* Possible states for the parser that require it to do special things. */
@@ -1939,17 +2022,24 @@ yyerrhandle:
 #define PST_SUBSHELL   0x020           /* ( ... ) subshell */
 #define PST_CMDSUBST   0x040           /* $( ... ) command substitution */
 #define PST_CASESTMT   0x080           /* parsing a case statement */
+#define PST_CONDCMD    0x100           /* parsing a [[...]] command */
+#define PST_CONDEXPR   0x200           /* parsing the guts of [[...]] */
+#define PST_ARITHFOR   0x400           /* parsing an arithmetic for command */
 
 /* Initial size to allocate for tokens, and the
    amount to grow them by. */
+#define TOKEN_DEFAULT_INITIAL_SIZE 496
 #define TOKEN_DEFAULT_GROW_SIZE 512
 
 /* Shell meta-characters that, when unquoted, separate words. */
-#define shellmeta(c)   (strchr ("()<>;&|", (c)) != 0)
-#define shellbreak(c)  (strchr ("()<>;&| \t\n", (c)) != 0)
+#define shellmeta(c)   (strchr (shell_meta_chars, (c)) != 0)
+#define shellbreak(c)  (strchr (shell_break_chars, (c)) != 0)
 #define shellquote(c)  ((c) == '"' || (c) == '`' || (c) == '\'')
 #define shellexp(c)    ((c) == '$' || (c) == '<' || (c) == '>')
 
+char *shell_meta_chars = "()<>;&|";
+char *shell_break_chars = "()<>;&| \t\n";
+
 /* The token currently being read. */
 static int current_token;
 
@@ -2023,7 +2113,7 @@ initialize_bash_input ()
 void
 init_yy_io (get, unget, type, name, location)
      Function *get, *unget;
-     int type;
+     enum stream_type type;
      char *name;
      INPUT_STREAM location;
 {
@@ -2224,20 +2314,21 @@ with_input_from_string (string, name)
 /*                                                                 */
 /* **************************************************************** */
 
+/* These two functions used to test the value of the HAVE_RESTARTABLE_SYSCALLS
+   define, and just use getc/ungetc if it was defined, but since bash
+   installs its signal handlers without the SA_RESTART flag, some signals
+   (like SIGCHLD, SIGWINCH, etc.) received during a read(2) will not cause
+   the read to be restarted.  We need to restart it ourselves. */
+
 static int
 yy_stream_get ()
 {
-  int result = EOF;
+  int result;
 
+  result = EOF;
   if (bash_input.location.file)
-    {
-#if !defined (HAVE_RESTARTABLE_SYSCALLS)
-      result = getc_with_restart (bash_input.location.file);
-#else /* HAVE_RESTARTABLE_SYSCALLS */
-      result = getc (bash_input.location.file);
-      result = (feof (bash_input.location.file)) ? EOF : (unsigned char)result;
-#endif /* HAVE_RESTARTABLE_SYSCALLS */
-    }
+    result = getc_with_restart (bash_input.location.file);
+
   return (result);
 }
 
@@ -2245,11 +2336,7 @@ static int
 yy_stream_unget (c)
      int c;
 {
-#if !defined (HAVE_RESTARTABLE_SYSCALLS)
   return (ungetc_with_restart (c, bash_input.location.file));
-#else /* HAVE_RESTARTABLE_SYSCALLS */
-  return (ungetc (c, bash_input.location.file));
-#endif /* HAVE_RESTARTABLE_SYSCALLS */
 }
 
 void
@@ -2275,6 +2362,11 @@ typedef struct stream_saver {
 /* The globally known line number. */
 int line_number = 0;
 
+#if defined (COND_COMMAND)
+static int cond_lineno;
+static int cond_token;
+#endif
+
 STREAM_SAVER *stream_list = (STREAM_SAVER *)NULL;
 
 void
@@ -2289,10 +2381,8 @@ push_stream (reset_lineno)
   saver->bstream = (BUFFERED_STREAM *)NULL;
   /* If we have a buffered stream, clear out buffers[fd]. */
   if (bash_input.type == st_bstream && bash_input.location.buffered_fd >= 0)
-    {
-      saver->bstream = buffers[bash_input.location.buffered_fd];
-      buffers[bash_input.location.buffered_fd] = (BUFFERED_STREAM *)NULL;
-    }
+    saver->bstream = set_buffered_stream (bash_input.location.buffered_fd,
+                                         (BUFFERED_STREAM *)NULL);
 #endif /* BUFFERED_INPUT */
 
   saver->line = line_number;
@@ -2338,7 +2428,7 @@ pop_stream ()
                  saver->bstream->b_fd = default_buffered_input;
                }
            }
-         buffers[bash_input.location.buffered_fd] = saver->bstream;
+         set_buffered_stream (bash_input.location.buffered_fd, saver->bstream);
         }
 #endif /* BUFFERED_INPUT */
 
@@ -2362,6 +2452,30 @@ stream_on_stack (type)
   return 0;
 }
 
+/* Save the current token state and return it in a malloced array. */
+int *
+save_token_state ()
+{
+  int *ret;
+
+  ret = (int *)xmalloc (3 * sizeof (int));
+  ret[0] = last_read_token;
+  ret[1] = token_before_that;
+  ret[2] = two_tokens_ago;
+  return ret;
+}
+
+void
+restore_token_state (ts)
+     int *ts;
+{
+  if (ts == 0)
+    return;
+  last_read_token = ts[0];
+  token_before_that = ts[1];
+  two_tokens_ago = ts[2];
+}
+
 /*
  * This is used to inhibit alias expansion and reserved word recognition
  * inside case statement pattern lists.  A `case statement pattern list' is:
@@ -2371,7 +2485,11 @@ stream_on_stack (type)
  *     everything between a `;;' and the next `)' or `esac'
  */
 
-#if defined (ALIAS)
+#if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
+
+#if !defined (ALIAS)
+typedef void *alias_t;
+#endif
 
 #define END_OF_ALIAS 0
 
@@ -2388,7 +2506,9 @@ typedef struct string_saver {
   struct string_saver *next;
   int expand_alias;  /* Value to set expand_alias to when string is popped. */
   char *saved_line;
+#if defined (ALIAS)
   alias_t *expander;   /* alias that caused this line to be pushed. */
+#endif
   int saved_line_size, saved_line_index, saved_line_terminator;
 } STRING_SAVER;
 
@@ -2415,11 +2535,16 @@ push_string (s, expand, ap)
   temp->saved_line_size = shell_input_line_size;
   temp->saved_line_index = shell_input_line_index;
   temp->saved_line_terminator = shell_input_line_terminator;
+#if defined (ALIAS)
   temp->expander = ap;
+#endif
   temp->next = pushed_string_list;
   pushed_string_list = temp;
 
-  ap->flags |= AL_BEINGEXPANDED;
+#if defined (ALIAS)
+  if (ap)
+    ap->flags |= AL_BEINGEXPANDED;
+#endif
 
   shell_input_line = s;
   shell_input_line_size = strlen (s);
@@ -2453,7 +2578,10 @@ pop_string ()
   t = pushed_string_list;
   pushed_string_list = pushed_string_list->next;
 
-  t->expander->flags &= ~AL_BEINGEXPANDED;
+#if defined (ALIAS)
+  if (t->expander)
+    t->expander->flags &= ~AL_BEINGEXPANDED;
+#endif
 
   free ((char *)t);
 }
@@ -2467,14 +2595,17 @@ free_string_list ()
     {
       t1 = t->next;
       FREE (t->saved_line);
-      t->expander->flags &= ~AL_BEINGEXPANDED;
+#if defined (ALIAS)
+      if (t->expander)
+       t->expander->flags &= ~AL_BEINGEXPANDED;
+#endif
       free ((char *)t);
       t = t1;
     }
   pushed_string_list = (STRING_SAVER *)NULL;
 }
 
-#endif /* ALIAS */
+#endif /* ALIAS || DPAREN_ARITHMETIC */
 
 /* Return a line of text, taken from wherever yylex () reads input.
    If there is no more input, then we return NULL.  If REMOVE_QUOTED_NEWLINE
@@ -2599,9 +2730,17 @@ STRING_INT_ALIST word_token_alist[] = {
   { "{", '{' },
   { "}", '}' },
   { "!", BANG },
+#if defined (COND_COMMAND)
+  { "[[", COND_START },
+  { "]]", COND_END },
+#endif
   { (char *)NULL, 0}
 };
 
+/* XXX - we should also have an alist with strings for other tokens, so we
+         can give more descriptive error messages.  Look at y.tab.h for the
+         other tokens. */
+
 /* These are used by read_token_word, but appear up here so that shell_getc
    can use them to decide when to add otherwise blank lines to the history. */
 
@@ -2646,16 +2785,16 @@ shell_getc (remove_quoted_newline)
 
   QUIT;
 
-#if defined (ALIAS)
+#if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
   /* If shell_input_line[shell_input_line_index] == 0, but there is
      something on the pushed list of strings, then we don't want to go
      off and get another line.  We let the code down below handle it. */
 
   if (!shell_input_line || ((!shell_input_line[shell_input_line_index]) &&
                            (pushed_string_list == (STRING_SAVER *)NULL)))
-#else /* !ALIAS */
+#else /* !ALIAS && !DPAREN_ARITHMETIC */
   if (!shell_input_line || !shell_input_line[shell_input_line_index])
-#endif /* !ALIAS */
+#endif /* !ALIAS && !DPAREN_ARITHMETIC */
     {
       line_number++;
 
@@ -2736,18 +2875,19 @@ shell_getc (remove_quoted_newline)
 #  if defined (BANG_HISTORY)
          history_expansion_inhibited = old_hist;
 #  endif
-
-         free (shell_input_line);
-         shell_input_line = expansions;
-         shell_input_line_len = shell_input_line ?
-                                strlen (shell_input_line) :
-                                0;
-         if (!shell_input_line_len)
-           current_command_line_count--;
-
-         /* We have to force the xrealloc below because we don't know the
-            true allocated size of shell_input_line anymore. */
-         shell_input_line_size = shell_input_line_len;
+         if (expansions != shell_input_line)
+           {
+             free (shell_input_line);
+             shell_input_line = expansions;
+             shell_input_line_len = shell_input_line ?
+                                       strlen (shell_input_line) : 0;
+             if (!shell_input_line_len)
+               current_command_line_count--;
+
+             /* We have to force the xrealloc below because we don't know
+                the true allocated size of shell_input_line anymore. */
+             shell_input_line_size = shell_input_line_len;
+           }
        }
       /* XXX - this is grotesque */
       else if (remember_on_history && shell_input_line &&
@@ -2805,7 +2945,7 @@ shell_getc (remove_quoted_newline)
        goto restart_read;
     }
 
-#if defined (ALIAS)
+#if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
   /* If C is NULL, we have reached the end of the current input string.  If
      pushed_string_list is non-empty, it's time to pop to the previous string
      because we have fully consumed the result of the last alias expansion.
@@ -2827,7 +2967,7 @@ shell_getc (remove_quoted_newline)
           c = ' ';
         }
     }
-#endif /* ALIAS */
+#endif /* ALIAS || DPAREN_ARITHMETIC */
 
   if (!c && shell_input_line_terminator == EOF)
     return ((shell_input_line_index != 0) ? '\n' : EOF);
@@ -2882,7 +3022,7 @@ execute_prompt_command (command)
   if (last_lastarg)
     last_lastarg = savestring (last_lastarg);
 
-  parse_and_execute (savestring (command), "PROMPT_COMMAND", 0);
+  parse_and_execute (savestring (command), "PROMPT_COMMAND", SEVAL_NONINT|SEVAL_NOHIST);
 
   last_shell_builtin = temp_last;
   this_shell_builtin = temp_this;
@@ -2978,10 +3118,16 @@ static int open_brace_count;
            { \
              if ((parser_state & PST_CASEPAT) && (word_token_alist[i].token != ESAC)) \
                break; \
+             if (word_token_alist[i].token == TIME) \
+               break; \
              if (word_token_alist[i].token == ESAC) \
                parser_state &= ~(PST_CASEPAT|PST_CASESTMT); \
              else if (word_token_alist[i].token == CASE) \
                parser_state |= PST_CASESTMT; \
+             else if (word_token_alist[i].token == COND_END) \
+               parser_state &= ~(PST_CONDCMD|PST_CONDEXPR); \
+             else if (word_token_alist[i].token == COND_START) \
+               parser_state |= PST_CONDCMD; \
              else if (word_token_alist[i].token == '{') \
                open_brace_count++; \
              else if (word_token_alist[i].token == '}' && open_brace_count) \
@@ -3035,6 +3181,32 @@ alias_expand_token (token)
 }
 #endif /* ALIAS */
 
+static int
+time_command_acceptable ()
+{
+#if defined (COMMAND_TIMING)
+  switch (last_read_token)
+    {
+    case 0:
+    case ';':
+    case '\n':
+    case AND_AND:
+    case OR_OR:
+    case '&':
+    case DO:
+    case THEN:
+    case ELSE:
+    case '{':
+    case '(':
+      return 1;
+    default:
+      return 0;
+    }
+#else
+  return 0;
+#endif /* COMMAND_TIMING */
+}
+
 /* Handle special cases of token recognition:
        IN is recognized if the last token was WORD and the token
        before that was FOR or CASE or SELECT.
@@ -3049,6 +3221,14 @@ alias_expand_token (token)
        before that was FUNCTION.
 
        `}' is recognized if there is an unclosed `{' prsent.
+
+       `-p' is returned as TIMEOPT if the last read token was TIME.
+
+       ']]' is returned as COND_END if the parser is currently parsing
+       a conditional expression ((parser_state & PST_CONDEXPR) != 0)
+
+       `time' is returned as TIME if and only if it is immediately
+       preceded by one of `;', `\n', `||', `&&', or `&'.
 */
 
 static int
@@ -3114,9 +3294,21 @@ special_case_tokens (token)
       return ('}');
     }
 
+#if defined (COMMAND_TIMING)
   /* Handle -p after `time'. */
   if (last_read_token == TIME && token[0] == '-' && token[1] == 'p' && !token[2])
     return (TIMEOPT);
+#endif
+
+#if defined (COMMAND_TIMING)
+  if (STREQ (token, "time") && ((parser_state & PST_CASEPAT) == 0) && time_command_acceptable ())
+    return (TIME);
+#endif /* COMMAND_TIMING */
+
+#if defined (COND_COMMAND) /* [[ */
+  if ((parser_state & PST_CONDEXPR) && token[0] == ']' && token[1] == ']' && token[2] == '\0')
+    return (COND_END);
+#endif
 
   return (-1);
 }
@@ -3131,13 +3323,10 @@ reset_parser ()
 
   parser_state = 0;
 
-#if defined (ALIAS)
+#if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
   if (pushed_string_list)
-    {
-      free_string_list ();
-      pushed_string_list = (STRING_SAVER *)NULL;
-    }
-#endif /* ALIAS */
+    free_string_list ();
+#endif /* ALIAS || DPAREN_ARITHMETIC */
 
   if (shell_input_line)
     {
@@ -3173,11 +3362,34 @@ read_token (command)
     {
       result = token_to_read;
       if (token_to_read == WORD || token_to_read == ASSIGNMENT_WORD)
-       yylval.word = word_desc_to_read;
+       {
+         yylval.word = word_desc_to_read;
+         word_desc_to_read = (WORD_DESC *)NULL;
+       }
       token_to_read = 0;
       return (result);
     }
 
+#if defined (COND_COMMAND)
+  if ((parser_state & (PST_CONDCMD|PST_CONDEXPR)) == PST_CONDCMD)
+    {
+      cond_lineno = line_number;
+      parser_state |= PST_CONDEXPR;
+      yylval.command = parse_cond_command ();
+      if (cond_token != COND_END)
+       {
+         if (EOF_Reached && cond_token != COND_ERROR)          /* [[ */
+           parser_error (cond_lineno, "unexpected EOF while looking for `]]'");
+         else if (cond_token != COND_ERROR)
+           parser_error (cond_lineno, "syntax error in conditional expression");
+         return (-1);
+       }
+      token_to_read = COND_END;
+      parser_state &= ~(PST_CONDEXPR|PST_CONDCMD);
+      return (COND_CMD);
+    }
+#endif
+
 #if defined (ALIAS)
   /* This is a place to jump back to once we have successfully expanded a
      token with an alias and pushed the string with push_string () */
@@ -3259,15 +3471,64 @@ read_token (command)
            case '|':
              return (OR_OR);
 
-#if defined (DPAREN_ARITHMETIC)
+#if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND)
            case '(':           /* ) */
+#  if defined (ARITH_FOR_COMMAND)
+             if (last_read_token == FOR)
+               {
+                 int cmdtyp, len;
+                 char *wval, *wv2;
+                 WORD_DESC *wd;
+
+                 arith_for_lineno = line_number;
+                 cmdtyp = parse_arith_cmd (&wval);
+                 if (cmdtyp == 1)
+                   {
+                     /* parse_arith_cmd adds quotes at the beginning and end
+                        of the string it returns; we need to take those out. */
+                     len = strlen (wval);
+                     wv2 = xmalloc (len);
+                     strncpy (wv2, wval + 1, len - 2);
+                     wv2[len - 2] = '\0';
+                     wd = make_word (wv2);
+                     yylval.word_list = make_word_list (wd, (WORD_LIST *)NULL);
+                     free (wval);
+                     free (wv2);
+                     return (ARITH_FOR_EXPRS);
+                   }
+                 else
+                   return -1;          /* ERROR */
+               }
+#  endif
+#  if defined (DPAREN_ARITHMETIC)
              if (reserved_word_acceptable (last_read_token))
                {
-                 parser_state |= PST_DBLPAREN;
-                 yylval.word = make_word ("let");
-                 return (WORD);          
+                 int cmdtyp, sline;
+                 char *wval;
+                 WORD_DESC *wd;
+
+                 sline = line_number;
+                 cmdtyp = parse_arith_cmd (&wval);
+                 if (cmdtyp == 1)      /* arithmetic command */
+                   {
+                     wd = make_word (wval);
+                     wd->flags = W_QUOTED;
+                     yylval.word_list = make_word_list (wd, (WORD_LIST *)NULL);
+                     free (wval);      /* make_word copies it */
+                     return (ARITH_CMD);
+                   }
+                 else if (cmdtyp == 0) /* nested subshell */
+                   {
+                     push_string (wval, 0, (alias_t *)NULL);
+                     if ((parser_state & PST_CASEPAT) == 0)
+                       parser_state |= PST_SUBSHELL;
+                     return (character);
+                   }
+                 else                  /* ERROR */
+                   return -1;
                }
              break;
+#  endif
 #endif
            }
        }
@@ -3335,6 +3596,10 @@ read_token (command)
    quoted strings ('', ``, "") and nested constructs.  It also must handle
    reprompting the user, if necessary, after reading a newline, and returning
    correct error values if it reads EOF. */
+
+#define P_FIRSTCLOSE   0x01
+#define P_ALLOWESC     0x02
+
 static char matched_pair_error;
 static char *
 parse_matched_pair (qc, open, close, lenp, flags)
@@ -3356,7 +3621,7 @@ parse_matched_pair (qc, open, close, lenp, flags)
   start_lineno = line_number;
   while (count)
     {
-      ch = shell_getc (qc != '\'' && pass_next_character == 0);
+      ch = shell_getc ((qc != '\'' || (flags & P_ALLOWESC)) && pass_next_character == 0);
       if (ch == EOF)
        {
          free (ret);
@@ -3394,7 +3659,12 @@ parse_matched_pair (qc, open, close, lenp, flags)
        }
       else if (ch == close)            /* ending delimiter */
        count--;
-      else if (ch == open)             /* nested begin */
+#if 1
+      /* handle nested ${...} specially. */
+      else if (open != close && was_dollar && open == '{' && ch == open) /* } */
+        count++;
+#endif
+      else if (((flags & P_FIRSTCLOSE) == 0) && ch == open)            /* nested begin */
        count++;
 
       /* Add this character. */
@@ -3402,7 +3672,11 @@ parse_matched_pair (qc, open, close, lenp, flags)
       ret[retind++] = ch;
 
       if (open == '\'')                        /* '' inside grouping construct */
-       continue;
+       {
+         if ((flags & P_ALLOWESC) && ch == '\\')
+           pass_next_character++;
+         continue;
+       }
 
       if (ch == '\\')                  /* backslashes */
        pass_next_character++;
@@ -3456,7 +3730,7 @@ parse_matched_pair (qc, open, close, lenp, flags)
          if (ch == '(')                /* ) */
            nestret = parse_matched_pair (0, '(', ')', &nestlen, 0);
          else if (ch == '{')           /* } */
-           nestret = parse_matched_pair (0, '{', '}', &nestlen, 0);
+           nestret = parse_matched_pair (0, '{', '}', &nestlen, P_FIRSTCLOSE);
          else if (ch == '[')           /* ] */
            nestret = parse_matched_pair (0, '[', ']', &nestlen, 0);
          if (nestret == &matched_pair_error)
@@ -3481,6 +3755,229 @@ parse_matched_pair (qc, open, close, lenp, flags)
   return ret;
 }
 
+#if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND)
+/* We've seen a `(('.  Look for the matching `))'.  If we get it, return 1.
+   If not, assume it's a nested subshell for backwards compatibility and
+   return 0.  In any case, put the characters we've consumed into a locally-
+   allocated buffer and make *ep point to that buffer.  Return -1 on an
+   error, for example EOF. */
+static int
+parse_arith_cmd (ep)
+     char **ep;
+{
+  int exp_lineno, rval, c;
+  char *ttok, *token;
+  int ttoklen;
+
+  exp_lineno = line_number;
+  ttok = parse_matched_pair (0, '(', ')', &ttoklen, 0);
+  rval = 1;
+  if (ttok == &matched_pair_error)
+    return -1;
+  /* Check that the next character is the closing right paren.  If
+     not, this is a syntax error. ( */
+  if ((c = shell_getc (0)) != ')')
+    rval = 0;
+
+  token = xmalloc (ttoklen + 4);
+
+  /* (( ... )) -> "..." */
+  token[0] = (rval == 1) ? '"' : '(';
+  strncpy (token + 1, ttok, ttoklen - 1);      /* don't copy the final `)' */
+  if (rval == 1)
+    {
+      token[ttoklen] = '"';
+      token[ttoklen+1] = '\0';
+    }
+  else
+    {
+      token[ttoklen] = ')';
+      token[ttoklen+1] = c;
+      token[ttoklen+2] = '\0';
+    }
+  *ep = token;
+  FREE (ttok);
+  return rval;
+}
+#endif /* DPAREN_ARITHMETIC || ARITH_FOR_COMMAND */
+
+#if defined (COND_COMMAND)
+static COND_COM *cond_term ();
+static COND_COM *cond_and ();
+static COND_COM *cond_or ();
+static COND_COM *cond_expr ();
+
+static COND_COM *
+cond_expr ()
+{
+  return (cond_or ());  
+}
+
+static COND_COM *
+cond_or ()
+{
+  COND_COM *l, *r;
+
+  l = cond_and ();
+  if (cond_token == OR_OR)
+    {
+      r = cond_or ();
+      l = make_cond_node (COND_OR, (WORD_DESC *)NULL, l, r);
+    }
+  return l;
+}
+
+static COND_COM *
+cond_and ()
+{
+  COND_COM *l, *r;
+
+  l = cond_term ();
+  if (cond_token == AND_AND)
+    {
+      r = cond_and ();
+      l = make_cond_node (COND_AND, (WORD_DESC *)NULL, l, r);
+    }
+  return l;
+}
+
+static int
+cond_skip_newlines ()
+{
+  while ((cond_token = read_token (READ)) == '\n')
+    {
+      if (interactive && (bash_input.type == st_stdin || bash_input.type == st_stream))
+       prompt_again ();
+    }
+  return (cond_token);
+}
+
+#define COND_RETURN_ERROR() \
+  do { cond_token = COND_ERROR; return ((COND_COM *)NULL); } while (0)
+
+static COND_COM *
+cond_term ()
+{
+  WORD_DESC *op;
+  COND_COM *term, *tleft, *tright;
+  int tok, lineno;
+
+  /* Read a token.  It can be a left paren, a `!', a unary operator, or a
+     word that should be the first argument of a binary operator.  Start by
+     skipping newlines, since this is a compound command. */
+  tok = cond_skip_newlines ();
+  lineno = line_number;
+  if (tok == COND_END)
+    {
+      COND_RETURN_ERROR ();
+    }
+  else if (tok == '(')
+    {
+      term = cond_expr ();
+      if (cond_token != ')')
+       {
+         if (term)
+           dispose_cond_node (term);           /* ( */
+         parser_error (lineno, "expected `)'");
+         COND_RETURN_ERROR ();
+       }
+      term = make_cond_node (COND_EXPR, (WORD_DESC *)NULL, term, (COND_COM *)NULL);
+      (void)cond_skip_newlines ();
+    }
+  else if (tok == BANG || (tok == WORD && (yylval.word->word[0] == '!' && yylval.word->word[1] == '\0')))
+    {
+      if (tok == WORD)
+       dispose_word (yylval.word);     /* not needed */
+      term = cond_term ();
+      if (term)
+       term->flags |= CMD_INVERT_RETURN;
+    }
+  else if (tok == WORD && test_unop (yylval.word->word))
+    {
+      op = yylval.word;
+      tok = read_token (READ);
+      if (tok == WORD)
+       {
+         tleft = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
+         term = make_cond_node (COND_UNARY, op, tleft, (COND_COM *)NULL);
+       }
+      else
+       {
+         dispose_word (op);
+         parser_error (line_number, "unexpected argument to conditional unary operator");
+         COND_RETURN_ERROR ();
+       }
+
+      (void)cond_skip_newlines ();
+    }
+  else if (tok == WORD)                /* left argument to binary operator */
+    {
+      /* lhs */
+      tleft = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
+
+      /* binop */
+      tok = read_token (READ);
+      if (tok == WORD && test_binop (yylval.word->word))
+        op = yylval.word;
+      else if (tok == '<' || tok == '>')
+        op = make_word_from_token (tok);
+      else if (tok == COND_END || tok == AND_AND || tok == OR_OR)
+       {
+         /* Special case.  [[ x ]] is equivalent to [[ -n x ]], just like
+            the test command.  Similarly for [[ x && expr ]] or
+            [[ x || expr ]] */
+         op = make_word ("-n");
+         term = make_cond_node (COND_UNARY, op, tleft, (COND_COM *)NULL);
+         cond_token = tok;
+         return (term);
+       }
+      else
+       {
+         parser_error (line_number, "conditional binary operator expected");
+         dispose_cond_node (tleft);
+         COND_RETURN_ERROR ();
+       }
+
+      /* rhs */
+      tok = read_token (READ);
+      if (tok == WORD)
+       {
+         tright = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
+         term = make_cond_node (COND_BINARY, op, tleft, tright);
+       }
+      else
+       {
+         parser_error (line_number, "unexpected argument to conditional binary operator");
+         dispose_cond_node (tleft);
+         dispose_word (op);
+         COND_RETURN_ERROR ();
+       }
+
+      (void)cond_skip_newlines ();
+    }
+  else
+    {
+      if (tok < 256)
+       parser_error (line_number, "unexpected token `%c' in conditional command", tok);
+      else
+       parser_error (line_number, "unexpected token %d in conditional command", tok);
+      COND_RETURN_ERROR ();
+    }
+  return (term);
+}      
+
+/* This is kind of bogus -- we slip a mini recursive-descent parser in
+   here to handle the conditional statement syntax. */
+static COMMAND *
+parse_cond_command ()
+{
+  COND_COM *cexp;
+
+  cexp = cond_expr ();
+  return (make_cond_command (cexp));
+}
+#endif
+
 static int
 read_token_word (character)
      int character;
@@ -3510,11 +4007,8 @@ read_token_word (character)
   char *ttok, *ttrans;
   int ttoklen, ttranslen;
 
-  if (token_buffer_size < TOKEN_DEFAULT_GROW_SIZE)
-    {
-      FREE (token);
-      token = xmalloc (token_buffer_size = TOKEN_DEFAULT_GROW_SIZE);
-    }
+  if (token_buffer_size < TOKEN_DEFAULT_INITIAL_SIZE)
+    token = xrealloc (token, token_buffer_size = TOKEN_DEFAULT_INITIAL_SIZE);
 
   token_index = 0;
   all_digits = digit (character);
@@ -3560,45 +4054,6 @@ read_token_word (character)
            }
        }
 
-#if defined (DPAREN_ARITHMETIC)
-      /* Parse a ksh-style ((...)) expression. */
-      if (parser_state & PST_DBLPAREN)
-       {
-         int exp_lineno;
-
-         /* If we've already consumed a right paren that should be part of
-            the expression, push it back so the paren matching code won't
-            return prematurely. */
-         if (character == '(')         /* ) */
-           shell_ungetc (character);
-         exp_lineno = line_number;
-         ttok = parse_matched_pair (0, '(', ')', &ttoklen, 0);
-         parser_state &= ~PST_DBLPAREN;
-         if (ttok == &matched_pair_error)
-           return -1;
-         /* Check that the next character is the closing right paren.  If
-            not, this is a syntax error. ( */
-         if (shell_getc (0) != ')')
-           {
-             FREE (ttok);      /* ( */
-             parser_error (exp_lineno, "missing closing `)' for arithmetic expression");
-             return -1;
-           }
-         RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 4,
-                                 token_buffer_size, TOKEN_DEFAULT_GROW_SIZE);
-         token[token_index++] = '"';
-         if (character != '(')         /* ) */
-           token[token_index++] = character;
-         strncpy (token + token_index, ttok, ttoklen - 1);
-         token_index += ttoklen - 1;
-         token[token_index++] = '"';
-         FREE (ttok);
-         dollar_present = all_digits = 0;
-         quoted = 1;
-         goto got_token;
-       }
-#endif /* DPAREN_ARITHMETIC */
-
       /* Parse a matched pair of quote characters. */
       if (shellquote (character))
        {
@@ -3619,6 +4074,34 @@ read_token_word (character)
          goto next_character;
        }
 
+#ifdef EXTENDED_GLOB
+      /* Parse a ksh-style extended pattern matching specification. */
+      if (extended_glob && PATTERN_CHAR(character))
+       {
+         peek_char = shell_getc (1);
+         if (peek_char == '(')         /* ) */
+           {
+             push_delimiter (dstack, peek_char);
+             ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0);
+             pop_delimiter (dstack);
+             if (ttok == &matched_pair_error)
+               return -1;              /* Bail immediately. */
+             RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
+                                     token_buffer_size,
+                                     TOKEN_DEFAULT_GROW_SIZE);
+             token[token_index++] = character;
+             token[token_index++] = peek_char;
+             strcpy (token + token_index, ttok);
+             token_index += ttoklen;
+             FREE (ttok);
+             dollar_present = all_digits = 0;
+             goto next_character;
+           }
+         else
+           shell_ungetc (peek_char);
+       }
+#endif /* EXTENDED_GLOB */
+
       /* If the delimiter character is not single quote, parse some of
         the shell expansions that must be read as a single word. */
 #if defined (PROCESS_SUBSTITUTION)
@@ -3633,9 +4116,18 @@ read_token_word (character)
                ((peek_char == '{' || peek_char == '[') && character == '$'))   /* ) ] } */
            {
              if (peek_char == '{')             /* } */
-               ttok = parse_matched_pair (cd, '{', '}', &ttoklen, 0);
+               ttok = parse_matched_pair (cd, '{', '}', &ttoklen, P_FIRSTCLOSE);
              else if (peek_char == '(')                /* ) */
-               ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0);
+               {
+                 /* XXX - push and pop the `(' as a delimiter for use by
+                    the command-oriented-history code.  This way newlines
+                    appearing in the $(...) string get added to the
+                    history literally rather than causing a possibly-
+                    incorrect `;' to be added. ) */
+                 push_delimiter (dstack, peek_char);
+                 ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0);
+                 pop_delimiter (dstack);
+               }
              else
                ttok = parse_matched_pair (cd, '[', ']', &ttoklen, 0);
              if (ttok == &matched_pair_error)
@@ -3655,33 +4147,78 @@ read_token_word (character)
          /* This handles $'...' and $"..." new-style quoted strings. */
          else if (character == '$' && (peek_char == '\'' || peek_char == '"'))
            {
-             ttok = parse_matched_pair (peek_char, peek_char, peek_char, &ttoklen, 0);
+             int first_line;
+
+             first_line = line_number;
+             push_delimiter (dstack, peek_char);
+             ttok = parse_matched_pair (peek_char, peek_char, peek_char,
+                                        &ttoklen,
+                                        (peek_char == '\'') ? P_ALLOWESC : 0);
+             pop_delimiter (dstack);
              if (ttok == &matched_pair_error)
                return -1;
              if (peek_char == '\'')
-               ttrans = ansiexpand (ttok, 0, ttoklen - 1, &ttranslen);
+               {
+                 ttrans = ansiexpand (ttok, 0, ttoklen - 1, &ttranslen);
+                 free (ttok);
+                 /* Insert the single quotes and correctly quote any
+                    embedded single quotes (allowed because P_ALLOWESC was
+                    passed to parse_matched_pair). */
+                 ttok = single_quote (ttrans);
+                 free (ttrans);
+                 ttrans = ttok;
+                 ttranslen = strlen (ttrans);
+               }
              else
-               ttrans = localeexpand (ttok, 0, ttoklen - 1, &ttranslen);
-             free (ttok);
+               {
+                 /* Try to locale-expand the converted string. */
+                 ttrans = localeexpand (ttok, 0, ttoklen - 1, first_line, &ttranslen);
+                 free (ttok);
+
+                 /* Add the double quotes back */
+                 ttok = xmalloc (ttranslen + 3);
+                 ttok[0] = '"';
+                 strcpy (ttok + 1, ttrans);
+                 ttok[ttranslen + 1] = '"';
+                 ttok[ttranslen += 2] = '\0';
+                 free (ttrans);
+                 ttrans = ttok;
+               }
+
              RESIZE_MALLOCED_BUFFER (token, token_index, ttranslen + 2,
                                      token_buffer_size,
                                      TOKEN_DEFAULT_GROW_SIZE);
-             token[token_index++] = peek_char;
              strcpy (token + token_index, ttrans);
              token_index += ttranslen;
-             token[token_index++] = peek_char;
              FREE (ttrans);
              quoted = 1;
              all_digits = 0;
              goto next_character;
            }
+         /* This could eventually be extended to recognize all of the
+            shell's single-character parameter expansions, and set flags.*/
+         else if (character == '$' && peek_char == '$')
+           {
+             ttok = xmalloc (3);
+             ttok[0] = ttok[1] = '$';
+             ttok[2] = '\0';
+             RESIZE_MALLOCED_BUFFER (token, token_index, 3,
+                                     token_buffer_size,
+                                     TOKEN_DEFAULT_GROW_SIZE);
+             strcpy (token + token_index, ttok);
+             token_index += 2;
+             dollar_present = 1;
+             all_digits = 0;
+             FREE (ttok);
+             goto next_character;
+           }
          else
            shell_ungetc (peek_char);
        }
 
 #if defined (ARRAY_VARS)
       /* Identify possible compound array variable assignment. */
-      else if (character == '=')
+      else if (character == '=' && token_index > 0)
        {
          peek_char = shell_getc (1);
          if (peek_char == '(')         /* ) */
@@ -3689,6 +4226,11 @@ read_token_word (character)
              ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0);
              if (ttok == &matched_pair_error)
                return -1;              /* Bail immediately. */
+             if (ttok[0] == '(')       /* ) */
+               {
+                 FREE (ttok);
+                 return -1;
+               }
              RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
                                      token_buffer_size,
                                      TOKEN_DEFAULT_GROW_SIZE);
@@ -3833,10 +4375,8 @@ ansiexpand (string, start, end, lenp)
 
   if (*temp)
     {
-      t = ansicstr (temp, tlen, (int *)NULL);
+      t = ansicstr (temp, tlen, 0, (int *)NULL, lenp);
       free (temp);
-      if (lenp)
-       *lenp = strlen (t);
       return (t);
     }
   else
@@ -3847,6 +4387,52 @@ ansiexpand (string, start, end, lenp)
     }
 }
 
+/* Change a bash string into a string suitable for inclusion in a `po' file.
+   This backslash-escapes `"' and `\' and changes newlines into \\\n"\n". */
+static char *
+mk_msgstr (string, foundnlp)
+     char *string;
+     int *foundnlp;
+{
+  register int c, len;
+  char *result, *r, *s;
+
+  for (len = 0, s = string; s && *s; s++)
+    {
+      len++;
+      if (*s == '"' || *s == '\\')
+       len++;
+      else if (*s == '\n')
+        len += 5;
+    }
+  
+  r = result = xmalloc (len + 3);
+  *r++ = '"';
+
+  for (s = string; s && (c = *s); s++)
+    {
+      if (c == '\n')   /* <NL> -> \n"<NL>" */
+       {
+         *r++ = '\\';
+         *r++ = 'n';
+         *r++ = '"';
+         *r++ = '\n';
+         *r++ = '"';
+         if (foundnlp)
+           *foundnlp = 1;
+         continue;
+       }
+      if (c == '"' || c == '\\')
+       *r++ = '\\';
+      *r++ = c;
+    }
+
+  *r++ = '"';
+  *r++ = '\0';
+
+  return result;
+}
+
 /* $"..." -- Translate the portion of STRING between START and END
    according to current locale using gettext (if available) and return
    the result.  The caller will take care of leaving the quotes intact.
@@ -3855,22 +4441,39 @@ ansiexpand (string, start, end, lenp)
    by the caller.  The length of the translated string is returned in LENP,
    if non-null. */
 static char *
-localeexpand (string, start, end, lenp)
+localeexpand (string, start, end, lineno, lenp)
      char *string;
-     int start, end, *lenp;
+     int start, end, lineno, *lenp;
 {
-  int len, tlen;
-  char *temp, *t;
+  int len, tlen, foundnl;
+  char *temp, *t, *t2;
 
   temp = xmalloc (end - start + 1);
   for (tlen = 0, len = start; len < end; )
     temp[tlen++] = string[len++];
   temp[tlen] = '\0';
 
-  /* If we're just dumping translatable strings, don't do anything. */
+  /* If we're just dumping translatable strings, don't do anything with the
+     string itself, but if we're dumping in `po' file format, convert it into a form more palatable to gettext(3)
+     and friends by quoting `"' and `\' with backslashes and converting <NL>
+     into `\n"<NL>"'.  If we find a newline in TEMP, we first output a
+     `msgid ""' line and then the translated string; otherwise we output the
+     `msgid' and translated string all on one line. */
   if (dump_translatable_strings)
     {
-      printf ("\"%s\"\n", temp);
+      if (dump_po_strings)
+       {
+         foundnl = 0;
+         t = mk_msgstr (temp, &foundnl);
+         t2 = foundnl ? "\"\"\n" : "";
+
+         printf ("#: %s:%d\nmsgid %s%s\nmsgstr \"\"\n",
+                 (bash_input.name ? bash_input.name : "stdin"), lineno, t2, t);
+         free (t);
+       }
+      else
+       printf ("\"%s\"\n", temp);
+
       if (lenp)
        *lenp = tlen;
       return (temp);
@@ -4003,6 +4606,19 @@ history_delimiting_chars ()
       else     
         return "; ";                           /* (...) subshell */
     }
+  else if (token_before_that == WORD && two_tokens_ago == FUNCTION)
+    return " ";                /* function def using `function name' without `()' */
+
+  else if (token_before_that == WORD && two_tokens_ago == FOR)
+    {
+      /* Tricky.  `for i\nin ...' should not have a semicolon, but
+        `for i\ndo ...' should.  We do what we can. */
+      for (i = shell_input_line_index; whitespace(shell_input_line[i]); i++)
+        ;
+      if (shell_input_line[i] && shell_input_line[i] == 'i' && shell_input_line[i+1] == 'n')
+       return " ";
+      return ";";
+    }
 
   for (i = 0; no_semi_successors[i]; i++)
     {
@@ -4057,6 +4673,20 @@ prompt_again ()
     }
 }
 
+int
+get_current_prompt_level ()
+{
+  return ((current_prompt_string && current_prompt_string == ps2_prompt) ? 2 : 1);
+}
+
+void
+set_current_prompt_level (x)
+     int x;
+{
+  prompt_string_pointer = (x == 2) ? &ps2_prompt : &ps1_prompt;
+  current_prompt_string = *prompt_string_pointer;
+}
+      
 static void
 print_prompt ()
 {
@@ -4072,6 +4702,8 @@ print_prompt ()
        \d      the date in Day Mon Date format
        \h      the hostname up to the first `.'
        \H      the hostname
+       \j      the number of active jobs
+       \l      the basename of the shell's tty device name
        \n      CRLF
        \s      the name of the shell
        \t      the time in 24-hour hh:mm:ss format
@@ -4090,7 +4722,7 @@ print_prompt ()
        \[      begin a sequence of non-printing chars
        \]      end a sequence of non-printing chars
 */
-#define PROMPT_GROWTH 50
+#define PROMPT_GROWTH 48
 char *
 decode_prompt_string (string)
      char *string;
@@ -4205,6 +4837,12 @@ decode_prompt_string (string)
                }
              goto add_string;
 
+           case 'r':
+             temp = xmalloc (2);
+             temp[0] = '\r';
+             temp[1] = '\0';
+             goto add_string;
+
            case 'n':
              temp = xmalloc (3);
              temp[0] = no_line_editing ? '\n' : '\r';
@@ -4231,6 +4869,7 @@ decode_prompt_string (string)
              {
                /* Use the value of PWD because it is much more efficient. */
                char t_string[PATH_MAX];
+               int tlen;
 
                temp = get_string_value ("PWD");
 
@@ -4239,11 +4878,17 @@ decode_prompt_string (string)
                    if (getcwd (t_string, sizeof(t_string)) == 0)
                      {
                        t_string[0] = '.';
-                       t_string[1] = '\0';
+                       tlen = 1;
                      }
+                   else
+                     tlen = strlen (t_string);
                  }
                else
-                 strcpy (t_string, temp);
+                 {
+                   tlen = sizeof (t_string) - 1;
+                   strncpy (t_string, temp, tlen);
+                 }
+               t_string[tlen] = '\0';
 
                if (c == 'W')
                  {
@@ -4252,12 +4897,21 @@ decode_prompt_string (string)
                      strcpy (t_string, t + 1);
                  }
                else
+                 /* polite_directory_format is guaranteed to return a string
+                    no longer than PATH_MAX - 1 characters. */
                  strcpy (t_string, polite_directory_format (t_string));
 
                /* If we're going to be expanding the prompt string later,
                   quote the directory name. */
                if (promptvars || posixly_correct)
+#if 0
                  temp = backslash_quote (t_string);
+#else
+                 /* Make sure that expand_prompt_string is called with a
+                    second argument of Q_DOUBLE_QUOTE if we use this
+                    function here. */
+                 temp = backslash_quote_for_double_quotes (t_string);
+#endif
                else
                  temp = savestring (t_string);
 
@@ -4265,6 +4919,8 @@ decode_prompt_string (string)
              }
 
            case 'u':
+             if (current_user.user_name == 0)
+               get_current_user_info ();
              temp = savestring (current_user.user_name);
              goto add_string;
 
@@ -4288,9 +4944,25 @@ decode_prompt_string (string)
              goto add_string;
 
            case '$':
-             temp = xmalloc (2);
-             temp[0] = current_user.euid == 0 ? '#' : '$';
-             temp[1] = '\0';
+             t = temp = xmalloc (3);
+             if ((promptvars || posixly_correct) && (current_user.euid != 0))
+               *t++ = '\\';
+             *t++ = current_user.euid == 0 ? '#' : '$';
+             *t = '\0';
+             goto add_string;
+
+           case 'j':
+             temp = itos (count_all_jobs ());
+             goto add_string;
+
+           case 'l':
+#if defined (HAVE_TTYNAME)
+             temp = (char *)ttyname (fileno (stdin));
+             t = temp ? base_pathname (temp) : "tty";
+             temp = savestring (t);
+#else
+             temp = savestring ("tty");
+#endif /* !HAVE_TTYNAME */
              goto add_string;
 
 #if defined (READLINE)
@@ -4354,7 +5026,11 @@ decode_prompt_string (string)
      the prompt string. */
   if (promptvars || posixly_correct)
     {
+#if 0
       list = expand_string_unsplit (result, Q_DOUBLE_QUOTES);
+#else
+      list = expand_prompt_string (result, Q_DOUBLE_QUOTES);
+#endif
       free (result);
       result = string_list (list);
       dispose_words (list);
@@ -4429,11 +5105,7 @@ report_syntax_error (message)
       if (token_end || (i == 0 && token_end == 0))
        {
          if (token_end)
-           {
-             msg = xmalloc (1 + (token_end - i));
-             strncpy (msg, t + i, token_end - i);
-             msg[token_end - i] = '\0';
-           }
+           msg = substring (t, i, token_end);
          else  /* one-character token */
            {
              msg2[0] = t[i];
@@ -4537,3 +5209,73 @@ handle_eof_input_unit ()
       EOF_Reached = 1;
     }
 }
+
+static WORD_LIST parse_string_error;
+
+/* Take a string and run it through the shell parser, returning the
+   resultant word list.  Used by compound array assignment. */
+WORD_LIST *
+parse_string_to_word_list (s, whom)
+     char *s, *whom;
+{
+  WORD_LIST *wl;
+  int tok, orig_line_number, orig_input_terminator;
+#if defined (HISTORY)
+  int old_remember_on_history, old_history_expansion_inhibited;
+#endif
+
+#if defined (HISTORY)
+  old_remember_on_history = remember_on_history;
+#  if defined (BANG_HISTORY)
+  old_history_expansion_inhibited = history_expansion_inhibited;
+#  endif
+  bash_history_disable ();
+#endif
+
+  orig_line_number = line_number;
+  orig_input_terminator = shell_input_line_terminator;
+
+  push_stream (1);
+  last_read_token = '\n';
+
+  with_input_from_string (s, whom);
+  wl = (WORD_LIST *)NULL;
+  while ((tok = read_token (READ)) != yacc_EOF)
+    {
+      if (tok == '\n' && *bash_input.location.string == '\0')
+       break;
+      if (tok != WORD && tok != ASSIGNMENT_WORD)
+       {
+         line_number = orig_line_number + line_number - 1;
+         yyerror ();   /* does the right thing */
+         if (wl)
+           dispose_words (wl);
+         wl = &parse_string_error;
+         break;
+       }
+      wl = make_word_list (yylval.word, wl);
+    }
+  
+  last_read_token = '\n';
+  pop_stream ();
+
+#if defined (HISTORY)
+  remember_on_history = old_remember_on_history;
+#  if defined (BANG_HISTORY)
+  history_expansion_inhibited = old_history_expansion_inhibited;
+#  endif /* BANG_HISTORY */
+#endif /* HISTORY */
+
+  shell_input_line_terminator = orig_input_terminator;
+
+  if (wl == &parse_string_error)
+    {
+      last_command_exit_value = EXECUTION_FAILURE;
+      if (interactive_shell == 0 && posixly_correct)
+       jump_to_top_level (FORCE_EOF);
+      else
+       jump_to_top_level (DISCARD);
+    }
+
+  return (REVERSE_LIST (wl, WORD_LIST *));
+}