/*
 * WCMD - Wine-compatible command line interface - batch interface.
 *
 * Copyright (C) 1999 D A Pickles
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "wcmd.h"

void WCMD_batch_command (char *line);

extern int echo_mode;
extern char quals[MAX_PATH], param1[MAX_PATH], param2[MAX_PATH];
extern BATCH_CONTEXT *context;
extern DWORD errorlevel;

#define MAXSTRING 1024

/****************************************************************************
 * WCMD_batch
 *
 * Open and execute a batch file.
 * On entry *command includes the complete command line beginning with the name
 * of the batch file (if a CALL command was entered the CALL has been removed).
 * *file is the name of the file, which might not exist and may not have the
 * .BAT suffix on. Called is 1 for a CALL, 0 otherwise.
 *
 * We need to handle recursion correctly, since one batch program might call another.
 * So parameters for this batch file are held in a BATCH_CONTEXT structure.
 */

void WCMD_batch (char *file, char *command, int called) {

#define WCMD_BATCH_EXT_SIZE 5

HANDLE h = INVALID_HANDLE_VALUE;
char string[MAXSTRING];
char extension_batch[][WCMD_BATCH_EXT_SIZE] = {".bat",".cmd"};
char extension_exe[WCMD_BATCH_EXT_SIZE] = ".exe";
unsigned int  i;
BATCH_CONTEXT *prev_context;

  for(i=0; (i<(sizeof(extension_batch)/WCMD_BATCH_EXT_SIZE)) && 
           (h == INVALID_HANDLE_VALUE); i++) {
  strcpy (string, file);
  CharLower (string);
    if (strstr (string, extension_batch[i]) == NULL) strcat (string, extension_batch[i]);
  h = CreateFile (string, GENERIC_READ, FILE_SHARE_READ,
                  NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  }
  if (h == INVALID_HANDLE_VALUE) {
    strcpy (string, file);
    CharLower (string);
    if (strstr (string, extension_exe) == NULL) strcat (string, extension_exe);
    h = CreateFile (string, GENERIC_READ, FILE_SHARE_READ,
                    NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (h != INVALID_HANDLE_VALUE) {
      WCMD_run_program (command);
    } else {
      SetLastError (ERROR_FILE_NOT_FOUND);
      WCMD_print_error ();
    }
    return;
  }

/*
 *	Create a context structure for this batch file.
 */

  prev_context = context;
  context = (BATCH_CONTEXT *)LocalAlloc (LMEM_FIXED, sizeof (BATCH_CONTEXT));
  context -> h = h;
  context -> command = command;
  context -> shift_count = 0;
  context -> prev_context = prev_context;

/*
 * 	Work through the file line by line. Specific batch commands are processed here,
 * 	the rest are handled by the main command processor.
 */

  while (WCMD_fgets (string, sizeof(string), h)) {
    if (strlen(string) == MAXSTRING -1)
      WCMD_output_asis( "Line in Batch processing possible truncated. Using:\n");
      WCMD_output_asis( string);
      WCMD_output_asis( "\n");
    if (string[0] != ':') {                      /* Skip over labels */
      WCMD_batch_command (string);
    }
  }
  CloseHandle (h);

/*
 *	If invoked by a CALL, we return to the context of our caller. Otherwise return
 *	to the caller's caller.
 */

  LocalFree ((HANDLE)context);
  if ((prev_context != NULL) && (!called)) {
    CloseHandle (prev_context -> h);
    context = prev_context -> prev_context;
    LocalFree ((HANDLE)prev_context);
  }
  else {
    context = prev_context;
  }
}

/****************************************************************************
 * WCMD_batch_command
 *
 * Execute one line from a batch file, expanding parameters.
 */

void WCMD_batch_command (char *line) {

DWORD status;
char cmd1[MAXSTRING],cmd2[MAXSTRING];
char *p, *s, *t;
int i;

  /* Get working version of command line */
  strcpy(cmd1, line);

  /* Expand environment variables in a batch file %{0-9} first  */
  /*   Then env vars, and if any left (ie use of undefined vars,*/
  /*   replace with spaces                                      */
  /* FIXME: Winnt would replace %1%fred%1 with first parm, then */
  /*   contents of fred, then the digit 1. Would need to remove */
  /*   ExpandEnvStrings to achieve this                         */

  /* Replace use of %0...%9 */
  p = cmd1;
  while ((p = strchr(p, '%'))) {
    i = *(p+1) - '0';
    if ((i >= 0) && (i <= 9)) {
      s = strdup (p+2);
      t = WCMD_parameter (context -> command, i + context -> shift_count, NULL);
      strcpy (p, t);
      strcat (p, s);
      free (s);
    } else {
      p++;
    }
  }

  /* Now replace environment variables */
  status = ExpandEnvironmentStrings(cmd1, cmd2, sizeof(cmd2));
  if (!status) {
    WCMD_print_error ();
    return;
  }

  /* In a batch program, unknown variables are replace by nothing */
  /* so remove any remaining %var%                                */
  p = cmd2;
  while ((p = strchr(p, '%'))) {
    s = strchr(p+1, '%');
    if (!s) {
      *p=0x00;
    } else {
      t = strdup(s+1);
      strcpy(p, t);
      free(t);
    }
  }

  /* Show prompt before batch line IF echo is on */
  if (echo_mode && (line[0] != '@')) {
    WCMD_show_prompt();
    WCMD_output_asis ( cmd2);
    WCMD_output_asis ( "\n");
  }

  WCMD_process_command (cmd2);
}

/*******************************************************************
 * WCMD_parameter - extract a parameter from a command line.
 *
 *	Returns the 'n'th space-delimited parameter on the command line (zero-based).
 *	Parameter is in static storage overwritten on the next call.
 *	Parameters in quotes (and brackets) are handled.
 *	Also returns a pointer to the location of the parameter in the command line.
 */

char *WCMD_parameter (char *s, int n, char **where) {

int i = 0;
static char param[MAX_PATH];
char *p;

  p = param;
  while (TRUE) {
    switch (*s) {
      case ' ':
	s++;
	break;
      case '"':
        if (where != NULL) *where = s;
	s++;
	while ((*s != '\0') && (*s != '"')) {
	  *p++ = *s++;
	}
        if (i == n) {
          *p = '\0';
          return param;
        }
	if (*s == '"') s++;
          param[0] = '\0';
          i++;
        p = param;
	break;
      case '(':
        if (where != NULL) *where = s;
	s++;
	while ((*s != '\0') && (*s != ')')) {
	  *p++ = *s++;
	}
        if (i == n) {
          *p = '\0';
          return param;
        }
	if (*s == ')') s++;
          param[0] = '\0';
          i++;
        p = param;
	break;
      case '\0':
        return param;
      default:
        if (where != NULL) *where = s;
	while ((*s != '\0') && (*s != ' ')) {
	  *p++ = *s++;
	}
        if (i == n) {
          *p = '\0';
          return param;
        }
          param[0] = '\0';
          i++;
        p = param;
    }
  }
}

/****************************************************************************
 * WCMD_fgets
 *
 * Get one line from a batch file. We can't use the native f* functions because
 * of the filename syntax differences between DOS and Unix. Also need to lose
 * the LF (or CRLF) from the line.
 */

char *WCMD_fgets (char *s, int n, HANDLE h) {

DWORD bytes;
BOOL status;
char *p;

  p = s;
  do {
    status = ReadFile (h, s, 1, &bytes, NULL);
    if ((status == 0) || ((bytes == 0) && (s == p))) return NULL;
    if (*s == '\n') bytes = 0;
    else if (*s != '\r') {
      s++;
      n--;
    }
    *s = '\0';
  } while ((bytes == 1) && (n > 1));
  return p;
}
