
/*
 * Copyright (C) 1990 by Jay Konigsberg. mail: jak@sactoh0
 *
 * Permission to use, copy, modify, and distribute this  software  and  its
 * documentation is hereby  granted,  provided  that  the  above  copyright
 * notice appear in all copies  and that  both  the  copyright  notice  and
 * this permission notice appear in supporting documentation. This software
 * is provided "as is" without express or implied  warranty.  However,  the
 * author retains all Copyright priviliges and rights  to  renumeration  if
 * this software is sold.
 */

/*
 * commands - main command loop
 */

/* global to replace \b */
extern unsigned char bs_char;	/* BS char picked up from termio */

#include "simped.h"
#include "sys/stat.h"

void commands(editfile, newfile, fd, postnews, append)
char *editfile;		/* the name of the file being edited, NULL
			 * if no file name was specified. Aslo,
			 * 'newfile' will be TRUE
			 */
int  *newfile;		/* boolean TRUE if a file is created, FALSE
			 * if the file was read in.
			 */
FILE *fd;
int  postnews;
int append;
{
extern char *malloc();

int	printf(),
	fprintf(),
	fflush(),
	getlinenum(),
	fputs(),
	puts(),
	stat(),
	unlink(),
	free(),
	cleanup();

char 	**addlines(),		/* add lines to the text area */
	**allocate(),		/* make space in buffer for text */
	**editline(),		/* edit a line (subsutite) command */
	**deleteline(),		/* delete a line in the text buffer */
	**modify();		/* modify a line of text */

void	listtext(),
	savefile(),
	help();

struct  stat  *buf;		/* check for 0 len file when A)bort */

char	**text,			/* text entered in the editor */
	*overflow=NULL,		/* pointer for autowrap */
	*delimiter=NULL,	/* passed back from getlinenum for edit */
	inpchar;		/* command input character */

int	count=0,		/* line count */
	startlist,		/* line number to start a listing */
	abort=1,		/* command aborted - don't print menu */
	linenum=0,		/* line number for insert */
	valid_command=FALSE;	/* boolean for command loop */

/*
initilize the text buffer area
*/
if ( (text = (char **)malloc(PTR_CHUNK * sizeof(char *)+1)) == (char **)0 )
    {
    fprintf(stderr, "malloc: error=%d\n", errno);
    cleanup(2);
    }

/*
 * Copyright
 */
puts("\nSimped version 2, Copyright (C) 1990 - Jay Konigsberg (jak@sactoh0)\n");

if (fd != stdin)
    {
    printf("%s: ", editfile);
    }
if (*newfile)
    {
    puts("New file.\n");
    puts("Please enter your text now. The text will automatically wrap");
    puts("around to the next line when a line is full. Enter a Carriage");
    puts("Return on a new line to end.\n");
    }
text = addlines(text, overflow, &count, 1, fd, *newfile, postnews);

if (fd != stdin && ! *newfile)
    {
    if (count >= PAUSE)
	{
	startlist = count - PAUSE + 1;
	printf("\nThe last %d lines read in:\n", PAUSE);
	}
    else
	{
	startlist = 1;
	}
    listtext(text, count, startlist);
    }

if (append)
    text = addlines(text, overflow, &count, count+1, stdin, FALSE, FALSE);

while (! valid_command)
    {
    /*
     * abort will be 0 when returning from a function via a bs,
     * thus the strange looking test.
     */
    if (abort)
	{
   puts("\nOptions: S)ave and quit, A)bort/cancel, L)ist message, E)dit line,");
   puts("         I)nsert line, D)elete line, C)ontinue, M)odify, H)elp\n");
   fputs("Command? ", stdout);
	}

    abort=1;
    fflush(stdout);
    valid_command=FALSE;
    inpchar = getchar();
    putchar(inpchar);
    fflush(stdout);

    switch (inpchar)
	{
	case 'S': /* save the file and quit */
	case 's':
	    for (;;)
		{
		if ( (inpchar=getchar()) == bs_char )
		    {
		    putchar(inpchar);
		    putchar(' ');
		    putchar(inpchar);
		    abort=0;
		    break;
		    }
		else if ( inpchar == '\n' )
		    {
		    savefile(editfile, newfile, fd, text, count);
		    break;
		    }
		else
		    putchar(BELL);
		}
	    break;
	case 'A': /* abort editing session */
	case 'a':
	    for (;;)
		{
		if ( (inpchar=getchar()) == bs_char )
		    {
		    putchar(inpchar);
		    putchar(' ');
		    putchar(inpchar);
		    abort=0;
		    break;
		    }
		else if ( inpchar == '\n' )
		    {
		    fputs("\nQuit without saving (return=n/Y)? ", stdout);
		    if ( (inpchar=getchar()) == 'Y' || inpchar == 'y' )
			{
			putchar(inpchar);
			fflush(stdout);
			buf = (struct stat *)malloc(sizeof(buf));
			/* remove file if its empty - note: the errors are
			ignored intentionally */
			if ( stat(editfile, buf) == 0 )
			    {
			    if (buf->st_size == (off_t)0 )
				{
				unlink(editfile);
				}
			    }
			cleanup(2);
			break;
			}
		    else
			{
			putchar(inpchar);
			fflush(stdout);
			puts("");
			break;
			}
		    }
		}
	    break;
	case 'Q': /* because q to quit is so common */
	case 'q':
	    cleanup(2);
	    break;
	case 'L': /* list the file */
	case 'l':
	    if ( (linenum=getlinenum(count, "cr=1", "")) != -1 )
		{
		if ( linenum != 0 )
		    {
		    puts("");
		    listtext(text, count, linenum);
		    }
		else
		    abort=0;
		}
	    break;
	case 'E': /* edit a line - sudsutite command */
	case 'e':
	    if (delimiter)
		{
		free(delimiter);
		}
	    else
		{
		if ( (delimiter=malloc(2)) == NULL )
		    {
		    fprintf(stderr, "malloc: error=%d\n", errno);
		    cleanup(2);
		    }
		*delimiter='\0';
		}

	    if ((linenum=getlinenum(count, "/?=cr", delimiter)) != -1)
		{
		if ( linenum != 0 )
		    {
		    if ( ! *delimiter )
			puts("");
		    text = editline(text, linenum, *delimiter);
		    }
		else
		    abort=0;
		}
	    break;
	case 'I': /* insert a line */
	case 'i':
	    if ( (linenum=getlinenum(count, "", "")) != -1)
		{
		if ( linenum != 0 )
		  {
		  puts("");
		  text=addlines(text,overflow,&count,linenum,stdin,FALSE,FALSE);
		  }
		else
		    abort=0;
		}
	    break;
	case 'D': /* delete a line */
	case 'd':
	    if ( (linenum=getlinenum(count, "", "")) != -1)
		{
		if (linenum != 0)
		    {
		    puts("");
		    text=deleteline(text, &count, linenum);
		    }
		else
		    abort=0;
		}
	    break;
	case 'C': /* continue editing at EOF */
	case 'c':
	    for (;;)
		{
		if ( (inpchar=getchar()) == bs_char )
		{
		    putchar(inpchar);
		    putchar(' ');
		    putchar(inpchar);
		    abort=0;
		    break;
		}
		else if ( inpchar == '\n' )
		  {
		  puts("");
		  text=addlines(text,overflow,&count,count+1,stdin,FALSE,FALSE);
		  break;
		  }
		else
		    putchar(BELL);
		}
	    break;
	case 'M': /* modify - multi use line editing */
	case 'm':
	    if ( (linenum=getlinenum(count, "", "")) != -1 )
		{
		if ( linenum != 0 )
		    {
		    puts("");
		    text=modify(text, linenum);
		    }
		else
		    abort=0;
		}
	    break;
	case '\n':
	    fputs("Command? ", stdout);
	    abort=0; /* do not print menu again */
	    break;
	case 'H':
	case 'h':
	    for (;;)
		{
		if ( (inpchar=getchar()) == bs_char )
		    {
		    putchar(inpchar);
		    putchar(' ');
		    putchar(inpchar);
		    abort=0;
		    break;
		    }
		else if ( inpchar == '\n' )
		    {
		    help();
		    break;
		    }
		else
		    putchar(BELL);
		}
	    break;
	case 'j':
	    puts("\n\nAuthor   : Jay Konigsberg\n");
	    puts("Copyright: June 1990");
	    puts("Date     : June 1990\n");
	    puts("uucp     : jak@sactoh0\n");
	    break;
	default :
	    if (inpchar == (int)bs_char)
		{
		putchar(' ');
		putchar(BELL);
		fflush(stdout);
		abort=0; /* do not print menu again */
		}
	    else
		printf("%c: not a valid command.\n", inpchar);
	}
    }
}
