# include "opihi.h"

int command (char *line, char **outline) {

  int i, status, argc, targc;
  char **argv, **targv;
  Command *cmd;

  /* force a space between ! and first word: !ls becomes ! ls */
  if (line[0] == '!') {
    REALLOCATE (line, char, strlen(line) + 5);
    memmove (&line[2], &line[1], strlen(&line[1]) + 1);
    line[1] = ' ';
  }

  /* expand anything of the form $fred or $fred$sam, etc */ 
  line = expand_vars (line);     /* line is freed here, new one allocated */
  /* expand anything of the form fred[N] */ 
  line = expand_vectors (line);  /* line is freed here, new one allocated */
  /* solve math expresions, assign variable, if needed */
  line = parse (line);        /* line is freed here, new one allocated */
  /* any entry in line of the form {foo} returns value or tmp vector / buffer */
  
  targv = parse_commands (line, &targc);
  if (targc == 0) {
    /* empty command or assignment */
    if (line != (char *) NULL) free (line);
    *outline = (char *) NULL;
    return (TRUE);
  }

  /* this needs some work to use multicommand correctly */
  ALLOCATE (argv, char *, targc);
  argc = 0;
  status = TRUE;
  for (i = 0; status && (i < targc); i++) {
    if (targv[i][0] != ';') {
      argv[argc] = targv[i];
      argc ++;
    }
    if ((targv[i][0] == ';') || (i == targc - 1)) {

      if (argc == 0) continue;

      cmd = MatchCommand (argv[0], TRUE, FALSE);
      if (cmd != NULL) {
	REALLOCATE (argv[0], char, strlen(cmd[0].name) + 1);
	strcpy (argv[0], cmd[0].name);
	status &= (*cmd[0].func) (argc, argv);
	if (auto_break && !status) break;
      }
      argc = 0;
    }
  }
  for (i = 0; i < targc; i++) free (targv[i]);
  free (argv);
  free (targv);
  *outline = line;
  if (!status) {
    char *msg;
    msg = get_variable ("ERRORMSG");
    if (msg != (char *) NULL) {
      fprintf (stderr, "%s\n", msg);
      free (msg);
    }
  }
  set_int_variable ("STATUS", status);
  return (status);

}
