/* make_cmd.c -- Functions for making instances of the various
   parser constructs. */

/* Copyright (C) 1989-2009 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 <http://www.gnu.org/licenses/>.
*/

#include "config.h"

#include <stdio.h>
#include "bashtypes.h"
#if !defined (_MINIX) && defined (HAVE_SYS_FILE_H)
#  include <sys/file.h>
#endif
#include "filecntl.h"
#include "bashansi.h"
#if defined (HAVE_UNISTD_H)
#  include <unistd.h>
#endif

#include "bashintl.h"

#include "parser.h"
#include "syntax.h"
#include "command.h"
#include "general.h"
#include "error.h"
#include "flags.h"
#include "make_cmd.h"
#include "dispose_cmd.h"
#include "variables.h"
#include "subst.h"
#include "input.h"
#include "ocache.h"
#include "externs.h"

#if defined (JOB_CONTROL)
#include "jobs.h"
#endif

#include "shmbutil.h"

extern int line_number, current_command_line_count, parser_state;
extern int last_command_exit_value;

/* Object caching */
sh_obj_cache_t wdcache = {0, 0, 0};
sh_obj_cache_t wlcache = {0, 0, 0};

#define WDCACHESIZE	60
#define WLCACHESIZE	60

static COMMAND *make_for_or_select __P((enum command_type, WORD_DESC *, WORD_LIST *, COMMAND *, int));
#if defined (ARITH_FOR_COMMAND)
static WORD_LIST *make_arith_for_expr __P((char *));
#endif
static COMMAND *make_until_or_while __P((enum command_type, COMMAND *, COMMAND *));

void
cmd_init ()
{
  ocache_create (wdcache, WORD_DESC, WDCACHESIZE);
  ocache_create (wlcache, WORD_LIST, WLCACHESIZE);
}

WORD_DESC *
alloc_word_desc ()
{
  WORD_DESC *temp;

  ocache_alloc (wdcache, WORD_DESC, temp);
  temp->flags = 0;
  temp->word = 0;
  return temp;
}

WORD_DESC *
make_bare_word (string)
     const char *string;
{
  WORD_DESC *temp;

  temp = alloc_word_desc ();

  if (*string)
    temp->word = savestring (string);
  else
    {
      temp->word = (char *)xmalloc (1);
      temp->word[0] = '\0';
    }

  return (temp);
}

WORD_DESC *
make_word_flags (w, string)
     WORD_DESC *w;
     const char *string;
{
  register int i;
  size_t slen;
  DECLARE_MBSTATE;

  i = 0;
  slen = strlen (string);
  while (i < slen)
    {
      switch (string[i])
	{
	case '$':
	  w->flags |= W_HASDOLLAR;
	  break;
	case '\\':
	  break;	/* continue the loop */
	case '\'':
	case '`':
	case '"':
	  w->flags |= W_QUOTED;
	  break;
	}

      ADVANCE_CHAR (string, slen, i);
    }

  return (w);
}

WORD_DESC *
make_word (string)
     const char *string;
{
  WORD_DESC *temp;

  temp = make_bare_word (string);
  return (make_word_flags (temp, string));
}

WORD_DESC *
make_word_from_token (token)
     int token;
{
  char tokenizer[2];

  tokenizer[0] = token;
  tokenizer[1] = '\0';

  return (make_word (tokenizer));
}

WORD_LIST *
make_word_list (word, wlink)
     WORD_DESC *word;
     WORD_LIST *wlink;
{
  WORD_LIST *temp;

  ocache_alloc (wlcache, WORD_LIST, temp);

  temp->word = word;
  temp->next = wlink;
  return (temp);
}

COMMAND *
make_command (type, pointer)
     enum command_type type;
     SIMPLE_COM *pointer;
{
  COMMAND *temp;

  temp = (COMMAND *)xmalloc (sizeof (COMMAND));
  temp->type = type;
  temp->value.Simple = pointer;
  temp->value.Simple->flags = temp->flags = 0;
  temp->redirects = (REDIRECT *)NULL;
  return (temp);
}

COMMAND *
command_connect (com1, com2, connector)
     COMMAND *com1, *com2;
     int connector;
{
  CONNECTION *temp;

  temp = (CONNECTION *)xmalloc (sizeof (CONNECTION));
  temp->connector = connector;
  temp->first = com1;
  temp->second = com2;
  return (make_command (cm_connection, (SIMPLE_COM *)temp));
}

static COMMAND *
make_for_or_select (type, name, map_list, action, lineno)
     enum command_type type;
     WORD_DESC *name;
     WORD_LIST *map_list;
     COMMAND *action;
     int lineno;
{
  FOR_COM *temp;

  temp = (FOR_COM *)xmalloc (sizeof (FOR_COM));
  temp->flags = 0;
  temp->name = name;
  temp->line = lineno;
  temp->map_list = map_list;
  temp->action = action;
  return (make_command (type, (SIMPLE_COM *)temp));
}

COMMAND *
make_for_command (name, map_list, action, lineno)
     WORD_DESC *name;
     WORD_LIST *map_list;
     COMMAND *action;
     int lineno;
{
  return (make_for_or_select (cm_for, name, map_list, action, lineno));
}

COMMAND *
make_select_command (name, map_list, action, lineno)
     WORD_DESC *name;
     WORD_LIST *map_list;
     COMMAND *action;
     int lineno;
{
#if defined (SELECT_COMMAND)
  return (make_for_or_select (cm_select, name, map_list, action, lineno));
#else
  last_command_exit_value = 2;
  return ((COMMAND *)NULL);
#endif
}

#if defined (ARITH_FOR_COMMAND)
static WORD_LIST *
make_arith_for_expr (s)
     char *s;
{
  WORD_LIST *result;
  WORD_DESC *wd;

  if (s == 0 || *s == '\0')
    return ((WORD_LIST *)NULL);
  wd = make_word (s);
  wd->flags |= W_NOGLOB|W_NOSPLIT|W_QUOTED|W_DQUOTE;	/* no word splitting or globbing */
  result = make_word_list (wd, (WORD_LIST *)NULL);
  return result;
}
#endif

/* Note that this function calls dispose_words on EXPRS, since it doesn't
   use the word list directly.  We free it here rather than at the caller
   because no other function in this file requires that the caller free
   any arguments. */
COMMAND *
make_arith_for_command (exprs, action, lineno)
     WORD_LIST *exprs;
     COMMAND *action;
     int lineno;
{
#if defined (ARITH_FOR_COMMAND)
  ARITH_FOR_COM *temp;
  WORD_LIST *init, *test, *step;
  char *s, *t, *start;
  int nsemi;

  init = test = step = (WORD_LIST *)NULL;
  /* Parse the string into the three component sub-expressions. */
  start = t = s = exprs->word->word;
  for (nsemi = 0; ;)
    {
      /* skip whitespace at the start of each sub-expression. */
      while (whitespace (*s))
	s++;
      start = s;
      /* skip to the semicolon or EOS */
      while (*s && *s != ';')
	s++;

      t = (s > start) ? substring (start, 0, s - start) : (char *)NULL;

      nsemi++;
      switch (nsemi)
	{
	case 1:
	  init = make_arith_for_expr (t);
	  break;
	case 2:
	  test = make_arith_for_expr (t);
	  break;
	case 3:
	  step = make_arith_for_expr (t);
	  break;
	}

      FREE (t);
      if (*s == '\0')
	break;
      s++;	/* skip over semicolon */
    }

  if (nsemi != 3)
    {
      if (nsemi < 3)
	parser_error (lineno, _("syntax error: arithmetic expression required"));
      else
	parser_error (lineno, _("syntax error: `;' unexpected"));
      parser_error (lineno, _("syntax error: `((%s))'"), exprs->word->word);
      last_command_exit_value = 2;
      return ((COMMAND *)NULL);
    }

  temp = (ARITH_FOR_COM *)xmalloc (sizeof (ARITH_FOR_COM));
  temp->flags = 0;
  temp->line = lineno;
  temp->init = init ? init : make_arith_for_expr ("1");
  temp->test = test ? test : make_arith_for_expr ("1");
  temp->step = step ? step : make_arith_for_expr ("1");
  temp->action = action;

  dispose_words (exprs);
  return (make_command (cm_arith_for, (SIMPLE_COM *)temp));
#else
  dispose_words (exprs);
  last_command_exit_value = 2;
  return ((COMMAND *)NULL);
#endif /* ARITH_FOR_COMMAND */
}

COMMAND *
make_group_command (command)
     COMMAND *command;
{
  GROUP_COM *temp;

  temp = (GROUP_COM *)xmalloc (sizeof (GROUP_COM));
  temp->command = command;
  return (make_command (cm_group, (SIMPLE_COM *)temp));
}

COMMAND *
make_case_command (word, clauses, lineno)
     WORD_DESC *word;
     PATTERN_LIST *clauses;
     int lineno;
{
  CASE_COM *temp;

  temp = (CASE_COM *)xmalloc (sizeof (CASE_COM));
  temp->flags = 0;
  temp->line = lineno;
  temp->word = word;
  temp->clauses = REVERSE_LIST (clauses, PATTERN_LIST *);
  return (make_command (cm_case, (SIMPLE_COM *)temp));
}

PATTERN_LIST *
make_pattern_list (patterns, action)
     WORD_LIST *patterns;
     COMMAND *action;
{
  PATTERN_LIST *temp;

  temp = (PATTERN_LIST *)xmalloc (sizeof (PATTERN_LIST));
  temp->patterns = REVERSE_LIST (patterns, WORD_LIST *);
  temp->action = action;
  temp->next = NULL;
  temp->flags = 0;
  return (temp);
}

COMMAND *
make_if_command (test, true_case, false_case)
     COMMAND *test, *true_case, *false_case;
{
  IF_COM *temp;

  temp = (IF_COM *)xmalloc (sizeof (IF_COM));
  temp->flags = 0;
  temp->test = test;
  temp->true_case = true_case;
  temp->false_case = false_case;
  return (make_command (cm_if, (SIMPLE_COM *)temp));
}

static COMMAND *
make_until_or_while (which, test, action)
     enum command_type which;
     COMMAND *test, *action;
{
  WHILE_COM *temp;

  temp = (WHILE_COM *)xmalloc (sizeof (WHILE_COM));
  temp->flags = 0;
  temp->test = test;
  temp->action = action;
  return (make_command (which, (SIMPLE_COM *)temp));
}

COMMAND *
make_while_command (test, action)
     COMMAND *test, *action;
{
  return (make_until_or_while (cm_while, test, action));
}

COMMAND *
make_until_command (test, action)
     COMMAND *test, *action;
{
  return (make_until_or_while (cm_until, test, action));
}

COMMAND *
make_arith_command (exp)
     WORD_LIST *exp;
{
#if defined (DPAREN_ARITHMETIC)
  COMMAND *command;
  ARITH_COM *temp;

  command = (COMMAND *)xmalloc (sizeof (COMMAND));
  command->value.Arith = temp = (ARITH_COM *)xmalloc (sizeof (ARITH_COM));

  temp->flags = 0;
  temp->line = line_number;
  temp->exp = exp;

  command->type = cm_arith;
  command->redirects = (REDIRECT *)NULL;
  command->flags = 0;

  return (command);
#else
  last_command_exit_value = 2;
  return ((COMMAND *)NULL);
#endif
}

#if defined (COND_COMMAND)
struct cond_com *
make_cond_node (type, op, left, right)
     int type;
     WORD_DESC *op;
     struct cond_com *left, *right;
{
  COND_COM *temp;

  temp = (COND_COM *)xmalloc (sizeof (COND_COM));
  temp->flags = 0;
  temp->line = line_number;
  temp->type = type;
  temp->op = op;
  temp->left = left;
  temp->right = right;

  return (temp);
}
#endif

COMMAND *
make_cond_command (cond_node)
     COND_COM *cond_node;
{
#if defined (COND_COMMAND)
  COMMAND *command;

  command = (COMMAND *)xmalloc (sizeof (COMMAND));
  command->value.Cond = cond_node;

  command->type = cm_cond;
  command->redirects = (REDIRECT *)NULL;
  command->flags = 0;
  command->line = cond_node ? cond_node->line : 0;

  return (command);
#else
  last_command_exit_value = 2;
  return ((COMMAND *)NULL);
#endif
}

COMMAND *
make_bare_simple_command ()
{
  COMMAND *command;
  SIMPLE_COM *temp;

  command = (COMMAND *)xmalloc (sizeof (COMMAND));
  command->value.Simple = temp = (SIMPLE_COM *)xmalloc (sizeof (SIMPLE_COM));

  temp->flags = 0;
  temp->line = line_number;
  temp->words = (WORD_LIST *)NULL;
  temp->redirects = (REDIRECT *)NULL;

  command->type = cm_simple;
  command->redirects = (REDIRECT *)NULL;
  command->flags = 0;

  return (command);
}

/* Return a command which is the connection of the word or redirection
   in ELEMENT, and the command * or NULL in COMMAND. */
COMMAND *
make_simple_command (element, command)
     ELEMENT element;
     COMMAND *command;
{
  /* If we are starting from scratch, then make the initial command
     structure.  Also note that we have to fill in all the slots, since
     malloc doesn't return zeroed space. */
  if (command == 0)
    {
      command = make_bare_simple_command ();
      parser_state |= PST_REDIRLIST;
    }

  if (element.word)
    {
      command->value.Simple->words = make_word_list (element.word, command->value.Simple->words);
      parser_state &= ~PST_REDIRLIST;
    }
  else if (element.redirect)
    {
      REDIRECT *r = element.redirect;
      /* Due to the way <> is implemented, there may be more than a single
	 redirection in element.redirect.  We just follow the chain as far
	 as it goes, and hook onto the end. */
      while (r->next)
	r = r->next;
      r->next = command->value.Simple->redirects;
      command->value.Simple->redirects = element.redirect;
    }

  return (command);
}

/* Because we are Bourne compatible, we read the input for this
   << or <<- redirection now, from wherever input is coming from.
   We store the input read into a WORD_DESC.  Replace the text of
   the redirectee.word with the new input text.  If <<- is on,
   then remove leading TABS from each line. */
void
make_here_document (temp, lineno)
     REDIRECT *temp;
     int lineno;
{
  int kill_leading, redir_len;
  char *redir_word, *document, *full_line;
  int document_index, document_size, delim_unquoted;

  if (temp->instruction != r_deblank_reading_until &&
      temp->instruction != r_reading_until)
    {
      internal_error (_("make_here_document: bad instruction type %d"), temp->instruction);
      return;
    }

  kill_leading = temp->instruction == r_deblank_reading_until;

  document = (char *)NULL;
  document_index = document_size = 0;

  /* Quote removal is the only expansion performed on the delimiter
     for here documents, making it an extremely special case. */
  redir_word = string_quote_removal (temp->redirectee.filename->word, 0);

  /* redirection_expand will return NULL if the expansion results in
     multiple words or no words.  Check for that here, and just abort
     this here document if it does. */
  if (redir_word)
    redir_len = strlen (redir_word);
  else
    {
      temp->here_doc_eof = (char *)xmalloc (1);
      temp->here_doc_eof[0] = '\0';
      goto document_done;
    }

  free (temp->redirectee.filename->word);
  temp->here_doc_eof = redir_word;

  /* Read lines from wherever lines are coming from.
     For each line read, if kill_leading, then kill the
     leading tab characters.
     If the line matches redir_word exactly, then we have
     manufactured the document.  Otherwise, add the line to the
     list of lines in the document. */

  /* If the here-document delimiter was quoted, the lines should
     be read verbatim from the input.  If it was not quoted, we
     need to perform backslash-quoted newline removal. */
  delim_unquoted = (temp->redirectee.filename->flags & W_QUOTED) == 0;
  while (full_line = read_secondary_line (delim_unquoted))
    {
      register char *line;
      int len;

      line = full_line;
      line_number++;

      /* If set -v is in effect, echo the line read.  read_secondary_line/
	 read_a_line leaves the newline at the end, so don't print another. */
      if (echo_input_at_read)
	fprintf (stderr, "%s", line);

      if (kill_leading && *line)
	{
	  /* Hack:  To be compatible with some Bourne shells, we
	     check the word before stripping the whitespace.  This
	     is a hack, though. */
	  if (STREQN (line, redir_word, redir_len) && line[redir_len] == '\n')
	    goto document_done;

	  while (*line == '\t')
	    line++;
	}

      if (*line == 0)
	continue;

      if (STREQN (line, redir_word, redir_len) && line[redir_len] == '\n')
	goto document_done;

      len = strlen (line);
      if (len + document_index >= document_size)
	{
	  document_size = document_size ? 2 * (document_size + len) : len + 2;
	  document = (char *)xrealloc (document, document_size);
	}

      /* len is guaranteed to be > 0 because of the check for line
	 being an empty string before the call to strlen. */
      FASTCOPY (line, document + document_index, len);
      document_index += len;
    }

  if (full_line == 0)
    internal_warning (_("here-document at line %d delimited by end-of-file (wanted `%s')"), lineno, redir_word);

document_done:
  if (document)
    document[document_index] = '\0';
  else
    {
      document = (char *)xmalloc (1);
      document[0] = '\0';
    }
  temp->redirectee.filename->word = document;
}

/* Generate a REDIRECT from SOURCE, DEST, and INSTRUCTION.
   INSTRUCTION is the instruction type, SOURCE is a file descriptor,
   and DEST is a file descriptor or a WORD_DESC *. */
REDIRECT *
make_redirection (source, instruction, dest_and_filename, flags)
     REDIRECTEE source;
     enum r_instruction instruction;
     REDIRECTEE dest_and_filename;
     int flags;
{
  REDIRECT *temp;
  WORD_DESC *w;
  int wlen;
  intmax_t lfd;

  temp = (REDIRECT *)xmalloc (sizeof (REDIRECT));

  /* First do the common cases. */
  temp->redirector = source;
  temp->redirectee = dest_and_filename;
  temp->instruction = instruction;
  temp->flags = 0;
  temp->rflags = flags;
  temp->next = (REDIRECT *)NULL;

  switch (instruction)
    {

    case r_output_direction:		/* >foo */
    case r_output_force:		/* >| foo */
    case r_err_and_out:			/* &>filename */
      temp->flags = O_TRUNC | O_WRONLY | O_CREAT;
      break;

    case r_appending_to:		/* >>foo */
    case r_append_err_and_out:		/* &>> filename */
      temp->flags = O_APPEND | O_WRONLY | O_CREAT;
      break;

    case r_input_direction:		/* <foo */
    case r_inputa_direction:		/* foo & makes this. */
      temp->flags = O_RDONLY;
      break;

    case r_input_output:		/* <>foo */
      temp->flags = O_RDWR | O_CREAT;
      break;

    case r_deblank_reading_until: 	/* <<-foo */
    case r_reading_until:		/* << foo */
    case r_reading_string:		/* <<< foo */
    case r_close_this:			/* <&- */
    case r_duplicating_input:		/* 1<&2 */
    case r_duplicating_output:		/* 1>&2 */
      break;

    /* the parser doesn't pass these. */
    case r_move_input:			/* 1<&2- */
    case r_move_output:			/* 1>&2- */
    case r_move_input_word:		/* 1<&$foo- */
    case r_move_output_word:		/* 1>&$foo- */
      break;

    /* The way the lexer works we have to do this here. */
    case r_duplicating_input_word:	/* 1<&$foo */
    case r_duplicating_output_word:	/* 1>&$foo */
      w = dest_and_filename.filename;
      wlen = strlen (w->word) - 1;
      if (w->word[wlen] == '-')		/* Yuck */
        {
          w->word[wlen] = '\0';
	  if (all_digits (w->word) && legal_number (w->word, &lfd) && lfd == (int)lfd)
	    {
	      dispose_word (w);
	      temp->instruction = (instruction == r_duplicating_input_word) ? r_move_input : r_move_output;
	      temp->redirectee.dest = lfd;
	    }
	  else
	    temp->instruction = (instruction == r_duplicating_input_word) ? r_move_input_word : r_move_output_word;
        }
          
      break;

    default:
      programming_error (_("make_redirection: redirection instruction `%d' out of range"), instruction);
      abort ();
      break;
    }
  return (temp);
}

COMMAND *
make_function_def (name, command, lineno, lstart)
     WORD_DESC *name;
     COMMAND *command;
     int lineno, lstart;
{
  FUNCTION_DEF *temp;
#if defined (ARRAY_VARS)
  SHELL_VAR *bash_source_v;
  ARRAY *bash_source_a;
#endif

  temp = (FUNCTION_DEF *)xmalloc (sizeof (FUNCTION_DEF));
  temp->command = command;
  temp->name = name;
  temp->line = lineno;
  temp->flags = 0;
  command->line = lstart;

  /* Information used primarily for debugging. */
  temp->source_file = 0;
#if defined (ARRAY_VARS)
  GET_ARRAY_FROM_VAR ("BASH_SOURCE", bash_source_v, bash_source_a);
  if (bash_source_a && array_num_elements (bash_source_a) > 0)
    temp->source_file = array_reference (bash_source_a, 0);
#endif
#if defined (DEBUGGER)
  bind_function_def (name->word, temp);
#endif

  temp->source_file = 0;
  return (make_command (cm_function_def, (SIMPLE_COM *)temp));
}

COMMAND *
make_subshell_command (command)
     COMMAND *command;
{
  SUBSHELL_COM *temp;

  temp = (SUBSHELL_COM *)xmalloc (sizeof (SUBSHELL_COM));
  temp->command = command;
  temp->flags = CMD_WANT_SUBSHELL;
  return (make_command (cm_subshell, (SIMPLE_COM *)temp));
}

COMMAND *
make_coproc_command (name, command)
     char *name;
     COMMAND *command;
{
  COPROC_COM *temp;

  temp = (COPROC_COM *)xmalloc (sizeof (COPROC_COM));
  temp->name = savestring (name);
  temp->command = command;
  temp->flags = CMD_WANT_SUBSHELL|CMD_COPROC_SUBSHELL;
  return (make_command (cm_coproc, (SIMPLE_COM *)temp));
}

/* Reverse the word list and redirection list in the simple command
   has just been parsed.  It seems simpler to do this here the one
   time then by any other method that I can think of. */
COMMAND *
clean_simple_command (command)
     COMMAND *command;
{
  if (command->type != cm_simple)
    command_error ("clean_simple_command", CMDERR_BADTYPE, command->type, 0);
  else
    {
      command->value.Simple->words =
	REVERSE_LIST (command->value.Simple->words, WORD_LIST *);
      command->value.Simple->redirects =
	REVERSE_LIST (command->value.Simple->redirects, REDIRECT *);
    }

  parser_state &= ~PST_REDIRLIST;
  return (command);
}

/* The Yacc grammar productions have a problem, in that they take a
   list followed by an ampersand (`&') and do a simple command connection,
   making the entire list effectively asynchronous, instead of just
   the last command.  This means that when the list is executed, all
   the commands have stdin set to /dev/null when job control is not
   active, instead of just the last.  This is wrong, and needs fixing
   up.  This function takes the `&' and applies it to the last command
   in the list.  This is done only for lists connected by `;'; it makes
   `;' bind `tighter' than `&'. */
COMMAND *
connect_async_list (command, command2, connector)
     COMMAND *command, *command2;
     int connector;
{
  COMMAND *t, *t1, *t2;

  t1 = command;
  t = command->value.Connection->second;

  if (!t || (command->flags & CMD_WANT_SUBSHELL) ||
      command->value.Connection->connector != ';')
    {
      t = command_connect (command, command2, connector);
      return t;
    }

  /* This is just defensive programming.  The Yacc precedence rules
     will generally hand this function a command where t points directly
     to the command we want (e.g. given a ; b ; c ; d &, t1 will point
     to the `a ; b ; c' list and t will be the `d').  We only want to do
     this if the list is not being executed as a unit in the background
     with `( ... )', so we have to check for CMD_WANT_SUBSHELL.  That's
     the only way to tell. */
  while (((t->flags & CMD_WANT_SUBSHELL) == 0) && t->type == cm_connection &&
	 t->value.Connection->connector == ';')
    {
      t1 = t;
      t = t->value.Connection->second;
    }
  /* Now we have t pointing to the last command in the list, and
     t1->value.Connection->second == t. */
  t2 = command_connect (t, command2, connector);
  t1->value.Connection->second = t2;
  return command;
}
