#include "cs697lsh.h"

char *triml(char *str)
{
  while(str && ((*str == ' ') || (*str == '\t'))) {str++;}
  return str;
}

void cmd::addarg(const char *s)
{
  String st = s;
  args.listappend(st);
}

void cmd::parse(char *str, cmd *from)
{
  int i;
  char buf[256], *bp;

  parseerr=1;
  background=0;
  args.clear();
  pipefrom=from;
  pipeto=0;
  stdin_redir_type=0;
  stdout_redir_type=0;

  str=triml(str);

  if(!str[0])
  {
    parseerr = -1;
    return;
  }

  bp=buf;
  while(*str)
  {
    switch (*str)
    {
      case ' ':
        if(bp-buf)
        { addarg(buf); bp=buf; }
        break;

      case '|':
        if(bp-buf)
        { addarg(buf); bp=buf; }

        str++;
        pipeto = new cmd;
        pipeto->parse(str, this);
        parseerr = pipeto->parseerr;
        background = pipeto->background;
        goto endwhile;
        break;

      case '&':
        if(bp-buf)
        { addarg(buf); bp=buf; }
        addarg("&");
        break;

      case '<':
        if(bp-buf)
        { addarg(buf); bp=buf; }
        addarg("<");
        stdin_redir_type=1;
        break;

      case '>':
        if(bp-buf)
        { addarg(buf); bp=buf; }
        if(*(str+1) == '>')
        {
          str++;
          addarg(">>");
          stdout_redir_type=2;
        } else {
          addarg(">");
          stdout_redir_type=1;
        }
        break;

      default:
        *bp++ = str[0];
        *bp = 0;
    }
    str++;
  }
endwhile:
  if(bp-buf)
    { addarg(buf); bp=buf; }

  if(i=args.in("<"))
  {
    if(i+1 >= args.len())
    {
      parseerr = 3;
      cerr << "Missing redirect.\n";
    } else {
      stdin_redir = args[i+1];
      args.listdelete(i+1);args.listdelete(i);
      if(pipefrom) {
        parseerr = 4;
        cerr << "Ambigous redirect.\n";
      }
    }
  }

  if((i=args.in(">")) || (i=args.in(">>")))
  {
    if(i+1 >= args.len())
    {
      parseerr = 3;
      cerr << "Missing redirect.\n";
    } else {
      stdout_redir = args[i+1];
      args.listdelete(i+1);args.listdelete(i);
      if(pipeto) {
        parseerr = 4;
        cerr << "Ambiguous redirect.\n";
      }
    }
  }
  if(i=args.in("&"))
  {
    if((i!=args.len()-1) || pipeto)
    {
      parseerr = 6;
      cerr << "Badly placed '&'.\n";
    }
    background = 1;
    args.listdelete(i);
  }

  if(parseerr == 1)
    parseerr = 0;
}

