/* file.c  94.07.29
 * Copyright 1983-1992   Albert Davis
 * route output to & from files, get command
 */
#include "ecah.h"
#include "error.h"
#include "io.h"
#include "declare.h"
/*--------------------------------------------------------------------------*/
	void	cmd_log(const char*,int*);
	void	cmd_file(const char*,int*);
	char*	getcmd(const char*,char*,int);
/*--------------------------------------------------------------------------*/
extern struct ioctrl io;
extern char e_int[];

static FILE *fin = (FILE*)NULL;	/* file to use for stdin	*/
static int   mout;		/* > file bitmap		*/
static int   mlog;		/* log file bitmap		*/
/*--------------------------------------------------------------------------*/
/* cmd_log: "log" command processing
 * open a file for logging (history)
 * arg is name of file (.eca is appended)
 * no arg closes the one most recently opened
 * the file will contain a list of commands executed, for use by "<"
 * multiple files can be open, they are nested, output to all.
 */
void cmd_log(const char *cmd, int *cnt)
{
 const char *access;
 static FILE *files[RECURSE];
 static int nest = 0;

 if (cmd[*cnt]){
    if (nest >= RECURSE){
       error(bWARNING, "too many files open\n");
    }else{
       access = "w";
       while (cmd[*cnt] == '>'){
          access = "a";
          ++*cnt;
          skipbl(cmd,cnt);
       }
       files[nest] = xopen(cmd,cnt,"",access);
       if (files[nest]){
          mlog |= 1<<fileno(files[nest]);
          nest++;
       }
    }
 }else{				    /* empty command			    */
    if (nest == 0){		    /* close it.			    */
       error(bWARNING, "no files open\n");
    }else{
       nest--;
       mlog &= ~(1<<fileno(files[nest]));
       (void)fclose(files[nest]);
       files[nest] = (FILE*)NULL;
    }
 }
}
/*--------------------------------------------------------------------------*/
/* cmd_file: ">" command processing
 * open a file for all output
 * the file will contain a copy of all screen output.
 * arg is name of file (.eca is appended)
 * no arg closes it
 * the file will contain all that would go to stdout
 */
void cmd_file(const char *cmd, int *cnt)
{
 const char *access;
 static FILE *files[RECURSE];
 static int nest = 0;

 if (cmd[*cnt]){                   /* if there is more to the command,     */
    if (nest >= RECURSE){          /* open a new file.                     */
       error(bWARNING, "too many files open\n");
    }else{
       access = "w";
       while (cmd[*cnt] == '>'){
          access = "a";
          ++*cnt;
          skipbl(cmd,cnt);
       }
       files[nest] = xopen(cmd,cnt,"",access);
       if (files[nest]){
          mout       |= 1<<fileno(files[nest]);
          io.mstdout |= 1<<fileno(files[nest]);
          nest++;
       }
    }
 }else{                            /* empty command                        */
    if (nest == 0){                /* close it.                            */
       error(bWARNING, "no files open\n");
    }else{
       nest--;
       mout       &= ~(1<<fileno(files[nest]));
       io.mstdout &= ~(1<<fileno(files[nest]));
       (void)fclose(files[nest]);
       files[nest] = (FILE*)NULL;
    }
 }
}
/*--------------------------------------------------------------------------*/
/* getcmd: get a command.
 * if "fin" is stdin, display a prompt first.
 * Also, actually do logging, echo, etc.
 */
char *getcmd(const char *prompt, char *buffer, int buflen)
{
 pllocate();
 if (!fin) /* 1st time thru */
    fin = stdin;
 if (fin == stdin){
    mputs( prompt, io.mstdout );
    mputs( " \b",  io.mstdout );
 }

 if (!fgets(buffer, buflen, fin)){
    if (fin == stdin)
       error(bEXIT, "\n");
    buffer[0] = '\0';
 }

 (void)trim(buffer);
 mprintf(mlog, "%s\n", buffer);
 if (fin == stdin){
    mputc('\r', io.mstdout&~mout);     /* reset col counter */
    mprintf(mout, "%s\n", buffer);
 }else{                             /* echo disk reads, if reading a file   */
    int n = 0;
    skipbl(buffer,&n);              /* normally, print the prompt first     */
    switch (buffer[n]){             /* (default) but if the line is a blank */
       case '\0':		    /* or comment, do not print the prompt  */
          mputc('\n', io.mstdout);
          break;
       case '\'':
          mprintf(io.mstdout, "%s\n", &buffer[n+1]);
          break;
       default:
          mprintf(io.mstdout, "%s%s\n", prompt, buffer);
          break;
    }
 }
 return buffer;
}
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
