/* command.h -- The structures used internally to represent commands, and
   the extern declarations of the functions used to create them. */
/* Copyright (C) 1993-2010 Free Software Foundation, Inc.
   This file is part of GNU Bash, the Bourne Again SHell.
   Bash is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
   Bash is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   You should have received a copy of the GNU General Public License
   along with Bash.  If not, see .
*/
#if !defined (_COMMAND_H_)
#define _COMMAND_H_
#include "stdc.h"
/* Instructions describing what kind of thing to do for a redirection. */
enum r_instruction {
  r_output_direction, r_input_direction, r_inputa_direction,
  r_appending_to, r_reading_until, r_reading_string,
  r_duplicating_input, r_duplicating_output, r_deblank_reading_until,
  r_close_this, r_err_and_out, r_input_output, r_output_force,
  r_duplicating_input_word, r_duplicating_output_word,
  r_move_input, r_move_output, r_move_input_word, r_move_output_word,
  r_append_err_and_out
};
/* Redirection flags; values for rflags */
#define REDIR_VARASSIGN		0x01
/* Redirection errors. */
#define AMBIGUOUS_REDIRECT  -1
#define NOCLOBBER_REDIRECT  -2
#define RESTRICTED_REDIRECT -3	/* can only happen in restricted shells. */
#define HEREDOC_REDIRECT    -4  /* here-doc temp file can't be created */
#define BADVAR_REDIRECT	    -5  /* something wrong with {varname}redir */
#define CLOBBERING_REDIRECT(ri) \
  (ri == r_output_direction || ri == r_err_and_out)
#define OUTPUT_REDIRECT(ri) \
  (ri == r_output_direction || ri == r_input_output || ri == r_err_and_out || ri == r_append_err_and_out)
#define INPUT_REDIRECT(ri) \
  (ri == r_input_direction || ri == r_inputa_direction || ri == r_input_output)
#define WRITE_REDIRECT(ri) \
  (ri == r_output_direction || \
	ri == r_input_output || \
	ri == r_err_and_out || \
	ri == r_appending_to || \
	ri == r_append_err_and_out || \
	ri == r_output_force)
/* redirection needs translation */
#define TRANSLATE_REDIRECT(ri) \
  (ri == r_duplicating_input_word || ri == r_duplicating_output_word || \
   ri == r_move_input_word || ri == r_move_output_word)
/* Command Types: */
enum command_type { cm_for, cm_case, cm_while, cm_if, cm_simple, cm_select,
		    cm_connection, cm_function_def, cm_until, cm_group,
		    cm_arith, cm_cond, cm_arith_for, cm_subshell, cm_coproc };
/* Possible values for the `flags' field of a WORD_DESC. */
#define W_HASDOLLAR	0x000001	/* Dollar sign present. */
#define W_QUOTED	0x000002	/* Some form of quote character is present. */
#define W_ASSIGNMENT	0x000004	/* This word is a variable assignment. */
#define W_SPLITSPACE	0x000008	/* Split this word on " " regardless of IFS */
#define W_NOSPLIT	0x000010	/* Do not perform word splitting on this word because ifs is empty string. */
#define W_NOGLOB	0x000020	/* Do not perform globbing on this word. */
#define W_NOSPLIT2	0x000040	/* Don't split word except for $@ expansion (using spaces) because context does not allow it. */
#define W_TILDEEXP	0x000080	/* Tilde expand this assignment word */
#define W_DOLLARAT	0x000100	/* $@ and its special handling */
#define W_DOLLARSTAR	0x000200	/* $* and its special handling */
#define W_NOCOMSUB	0x000400	/* Don't perform command substitution on this word */
#define W_ASSIGNRHS	0x000800	/* Word is rhs of an assignment statement */
#define W_NOTILDE	0x001000	/* Don't perform tilde expansion on this word */
#define W_ITILDE	0x002000	/* Internal flag for word expansion */
#define W_NOEXPAND	0x004000	/* Don't expand at all -- do quote removal */
#define W_COMPASSIGN	0x008000	/* Compound assignment */
#define W_ASSNBLTIN	0x010000	/* word is a builtin command that takes assignments */
#define W_ASSIGNARG	0x020000	/* word is assignment argument to command */
#define W_HASQUOTEDNULL	0x040000	/* word contains a quoted null character */
#define W_DQUOTE	0x080000	/* word should be treated as if double-quoted */
#define W_NOPROCSUB	0x100000	/* don't perform process substitution */
#define W_HASCTLESC	0x200000	/* word contains literal CTLESC characters */
#define W_ASSIGNASSOC	0x400000	/* word looks like associative array assignment */
#define W_ASSIGNARRAY	0x800000	/* word looks like a compound indexed array assignment */
#define W_ARRAYIND	0x1000000	/* word is an array index being expanded */
#define W_ASSNGLOBAL	0x2000000	/* word is a global assignment to declare (declare/typeset -g) */
#define W_NOBRACE	0x4000000	/* Don't perform brace expansion */
#define W_ASSIGNINT	0x8000000	/* word is an integer assignment to declare */
/* Possible values for subshell_environment */
#define SUBSHELL_ASYNC	0x01	/* subshell caused by `command &' */
#define SUBSHELL_PAREN	0x02	/* subshell caused by ( ... ) */
#define SUBSHELL_COMSUB	0x04	/* subshell caused by `command` or $(command) */
#define SUBSHELL_FORK	0x08	/* subshell caused by executing a disk command */
#define SUBSHELL_PIPE	0x10	/* subshell from a pipeline element */
#define SUBSHELL_PROCSUB 0x20	/* subshell caused by <(command) or >(command) */
#define SUBSHELL_COPROC	0x40	/* subshell from a coproc pipeline */
#define SUBSHELL_RESETTRAP 0x80	/* subshell needs to reset trap strings on first call to trap */
/* A structure which represents a word. */
typedef struct word_desc {
  char *word;		/* Zero terminated string. */
  int flags;		/* Flags associated with this word. */
} WORD_DESC;
/* A linked list of words. */
typedef struct word_list {
  struct word_list *next;
  WORD_DESC *word;
} WORD_LIST;
/* **************************************************************** */
/*								    */
/*			Shell Command Structs			    */
/*								    */
/* **************************************************************** */
/* What a redirection descriptor looks like.  If the redirection instruction
   is ri_duplicating_input or ri_duplicating_output, use DEST, otherwise
   use the file in FILENAME.  Out-of-range descriptors are identified by a
   negative DEST. */
typedef union {
  int dest;			/* Place to redirect REDIRECTOR to, or ... */
  WORD_DESC *filename;		/* filename to redirect to. */
} REDIRECTEE;
/* Structure describing a redirection.  If REDIRECTOR is negative, the parser
   (or translator in redir.c) encountered an out-of-range file descriptor. */
typedef struct redirect {
  struct redirect *next;	/* Next element, or NULL. */
  REDIRECTEE redirector;	/* Descriptor or varname to be redirected. */
  int rflags;			/* Private flags for this redirection */
  int flags;			/* Flag value for `open'. */
  enum r_instruction  instruction; /* What to do with the information. */
  REDIRECTEE redirectee;	/* File descriptor or filename */
  char *here_doc_eof;		/* The word that appeared in <flags. */
#define CMD_WANT_SUBSHELL  0x01	/* User wants a subshell: ( command ) */
#define CMD_FORCE_SUBSHELL 0x02	/* Shell needs to force a subshell. */
#define CMD_INVERT_RETURN  0x04	/* Invert the exit value. */
#define CMD_IGNORE_RETURN  0x08	/* Ignore the exit value.  For set -e. */
#define CMD_NO_FUNCTIONS   0x10 /* Ignore functions during command lookup. */
#define CMD_INHIBIT_EXPANSION 0x20 /* Do not expand the command words. */
#define CMD_NO_FORK	   0x40	/* Don't fork; just call execve */
#define CMD_TIME_PIPELINE  0x80 /* Time a pipeline */
#define CMD_TIME_POSIX	   0x100 /* time -p; use POSIX.2 time output spec. */
#define CMD_AMPERSAND	   0x200 /* command & */
#define CMD_STDIN_REDIR	   0x400 /* async command needs implicit