
/*
 * 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.
 */

/*
 * modify - a multi-capability line editing function.
 */

#include "simped.h"

char **modify(text, linenum)
char **text;
int  linenum;
{
extern	char	*realloc();

char	*getline();

int	printf(),
	fprintf(),
	fputs(),
	puts(),
	cleanup();

int	modifylen,	/* length of the modify directive string */
	modifyinx,	/* pointer inside the directive string */
	loopinx,	/* for inserts and deletes */
	newlen,		/* length of the new text */
	newinx,		/* index for newtext */
	adjust=0,	/* ins & del change text[], so text ref must adjust
			   Note: adjust may be positive *or* negitive */
	text_entered=0;

char	modifybuf[LINELEN+2],	/* the modify directives */
	*newtext;		/* a pointer into modifybuf for inserts */

printf("%3d> ", linenum);
fputs(text[linenum-1], stdout);
printf("edit>");
if (getline(modifybuf, &text_entered, stdin, '\0', TRUE))
    {
    puts("\nWarning: modify directive overflow, continuing");
    }

/* remove the trailing '\n' */
modifylen=strlen(modifybuf);
modifybuf[--modifylen]='\0';

/* now parse modify's buffer for the changes to text[linenum-1] */
for(modifyinx=0; modifyinx < modifylen; ++modifyinx)
    {
    if (modifybuf[modifyinx] == ' ')
        {
        /* do nothing */
        }
/*    else if ((modifybuf[modifyinx] >= 'a' && modifybuf[modifyinx] <= 'z' ||
	      modifybuf[modifyinx] >= 'A' && modifybuf[modifyinx] <= 'Z')&&
	      modifyinx+adjust != strlen(text[linenum-1])-1)
	{
	* replace that char in text[] *
	text[linenum-1][modifyinx + adjust]=modifybuf[modifyinx];
	}
*/
    else if (modifybuf[modifyinx] == '&')
	{
	/* replace char with a sp */
	text[linenum-1][modifyinx+adjust]=' ';
	}
    else if (modifybuf[modifyinx] == '#')
	{
	if (modifyinx+adjust != strlen(text[linenum-1])-1)
	    {
	    /* delete char - requires roll back. Note: adjust may be negitive */
	    for (loopinx=modifyinx+adjust; loopinx <= strlen(text[linenum-1]);
		++loopinx)
		{
		text[linenum-1][loopinx]=text[linenum-1][loopinx+1];
		}
	    --adjust;
	    }
	}
    else if (modifybuf[modifyinx] == '^' ||
	modifyinx+adjust == strlen(text[linenum-1])-1)
	{
	/* insert char(s) - requires a roll out and maybe a realloc */
	if (modifyinx+adjust != strlen(text[linenum-1])-1)
	    newtext=(char *)&modifybuf[modifyinx+1];
	else
	    {
	    newtext=(char *)&modifybuf[modifyinx];
	    }
	if (newtext[0]=='#') /* insert a # */
	    {
	    newlen=1;
	    }
	else
	    {
	    for (newlen=0; newtext[newlen] != '#'; ++newlen)
		{
		if (newtext[newlen] == '\0')
		    break;
		}
	    }
	/* create the space needed */
	if((text[linenum-1]=realloc(text[linenum-1],
	    (unsigned int)(strlen(text[linenum-1])+newlen+adjust)))==NULL)
	    {
	    fprintf(stderr, "realloc: error=%d\n", errno);
	    cleanup(2);
	    }
	/* do the roll out */
	for (loopinx=strlen(text[linenum-1])+newlen;
	    loopinx >= modifyinx-1+newlen; --loopinx)
	    {
	    text[linenum-1][loopinx]=text[linenum-1][loopinx-newlen];
	    }
	/* copy in the new text */
	newinx=0;
	for (loopinx=modifyinx+adjust;loopinx<modifyinx+adjust+newlen;++loopinx)
	    {
	    text[linenum-1][loopinx]=newtext[newinx++];
	    }
	/* adjust the modifyinx pointer to skip insert command */
	if (newtext[0] == '#')
	    ++modifyinx; /* special case, inserting a # */
	else
	    modifyinx += newlen + 1; /* one more will be added on the for */
	adjust += newlen;
	}
    else /* replace that character directly into the text */
	{
	text[linenum-1][modifyinx + adjust]=modifybuf[modifyinx];
	}
    }
printf("\n%3d> ", linenum);
fputs(text[linenum-1], stdout);
return (text);
}
