/*
* Copyright (C) 1995-1997 Christopher D. Granz
*
* This header may not be removed.
*
* Refer to the file "License" included in this package for further
* information and before using any of the following.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "sapphire.h"
/*
* Prototypes
*/
static int goto_line ( char *, int, char ** );
static void finish_text_editor ( TERM_DATA *pTerm );
/*
* Functions
*/
void process_text_editor_string( TERM_DATA *pTerm, char *pString )
{
char cBuf[MAX_STRING];
char *pBuf;
char *pBuf2;
int i;
/* if ( next_char( pString ) == '\0' )
return; */
if ( pString[0] == '-' )
{
switch ( pString[1] )
{
case 'h':
write_string_buffer( pTerm,
"Valid text-editor options:\n\r"
" -- - `-'.\n\r"
" -h - This help.\n\r"
" -d - Finish editing.\n\r"
" -s - Show string.\n\r"
" -c - Clear string.\n\r"
" -f - Format string.\n\r"
" -l - Show current line.\n\r"
" -g<num> - Goto line <num>.\n\r"
" -a - Current line is pushed down and a new "
"line is added\n\r"
" in it's place.\n\r"
" -e<str> - Change current line to <str>.\n\r"
" -r - Remove current line and move following line "
"up.\n\r"
/* " -x<str> - Execute <str> as a command.\n\r" */ );
break;
case 'd':
finish_text_editor( pTerm );
break;
case 's':
setup_string_pager( pTerm );
page_string( pTerm, pTerm->pEditString );
page_string( pTerm, "\n\r" );
finish_string_pager( pTerm );
break;
case 'c':
pTerm->pEditString[0] = '\0';
pTerm->iEditLine = 1;
break;
case 'f':
strcpy( pTerm->pEditString,
format_string( pTerm->pEditString ) );
pTerm->iEditLine = goto_line( pTerm->pEditString,
pTerm->iEditLine, &pBuf );
break;
case 'l':
goto_line( pTerm->pEditString, pTerm->iEditLine, &pBuf );
for ( i = 0; pBuf[i] != '\0'; i++ )
{
if ( pBuf[i] == '\n' || pBuf[i] == '\r' )
break;
cBuf[i] = pBuf[i];
}
cBuf[i] = '\0';
write_string_buffer( pTerm, cBuf );
write_string_buffer( pTerm, "\n\r" );
break;
case 'g':
one_arg( &pString[2], cBuf );
pTerm->iEditLine = goto_line( pTerm->pEditString,
atoi( cBuf ), &pBuf );
break;
case 'a':
goto_line( pTerm->pEditString, pTerm->iEditLine, &pBuf );
pBuf2 = pBuf;
for ( i = 0; *pBuf2 != '\0'; pBuf2++, i++ )
cBuf[i] = *pBuf2;
cBuf[i] = '\0';
strcpy( pBuf, "\n\r" );
if ( ( strlen( pTerm->pEditString ) + i ) >= MAX_STRING )
{
write_string_buffer( pTerm, "String too long.\n\r" );
finish_text_editor( pTerm );
break;
}
strcat( pBuf, cBuf );
break;
case 'e':
goto_line( pTerm->pEditString, pTerm->iEditLine, &pBuf );
pBuf2 = pBuf;
while ( *pBuf2 != '\0' )
{
if ( *pBuf2 == '\n' )
break;
pBuf2++;
}
for ( i = 0; *pBuf2 != '\0'; pBuf2++, i++ )
cBuf[i] = *pBuf2;
cBuf[i] = '\0';
strcpy( pBuf, &pString[2] );
if ( ( strlen( pTerm->pEditString ) + i ) >= MAX_STRING )
{
write_string_buffer( pTerm, "String too long.\n\r" );
finish_text_editor( pTerm );
break;
}
strcat( pBuf, cBuf );
break;
case 'r':
goto_line( pTerm->pEditString, pTerm->iEditLine, &pBuf );
pBuf2 = pBuf;
while ( *pBuf2 != '\0' )
{
if ( *pBuf2 == '\n' )
break;
pBuf2++;
}
if ( *pBuf2 == '\n' )
pBuf2 += 2;
for ( i = 0; *pBuf2 != '\0'; pBuf2++, i++ )
cBuf[i] = *pBuf2;
cBuf[i] = '\0';
strcpy( pBuf, cBuf );
if ( pTerm->iEditLine > 1 && cBuf[0] == '\0' )
{
pTerm->iEditLine--;
goto_line( pTerm->pEditString, pTerm->iEditLine, &pBuf );
while ( *pBuf != '\0' )
{
if ( *pBuf == '\n' )
break;
pBuf++;
}
*pBuf = '\0';
}
break;
#if 0
case 'x':
switch ( pTerm->iConState )
{
case CON_PLAYING :
process_cmd( pTerm, &pString[2] );
break;
case CON_NPC_EDITOR :
process_npc_editor_cmd( pTerm, &pString[2] );
break;
case CON_OBJECT_EDITOR:
process_object_editor_cmd( pTerm, &pString[2] );
break;
case CON_ROOM_EDITOR :
process_room_editor_cmd( pTerm, &pString[2] );
break;
case CON_SYSTEM_SHELL :
process_shell_cmd( pTerm, &pString[2] );
break;
}
break;
#endif
case '-':
pString = &pString[1];
goto end;
default :
write_string_buffer( pTerm,
"Invalid option. Type `-h' for help.\n\r\n\r" );
break;
}
return;
}
end:
if ( ( strlen( pString ) + strlen( pTerm->pEditString ) + 3 )
> MAX_STRING )
{
write_string_buffer( pTerm, "String too long.\n\r" );
finish_text_editor( pTerm );
return;
}
strcat( pTerm->pEditString, "\n\r" );
strcat( pTerm->pEditString, pString );
}
static int goto_line( char *pStr, int iLine, char **ppPos )
{
int iCurrLine = 1;
int i;
if ( iLine < 1 )
{
*ppPos = pStr;
return ( 1 );
}
for ( i = 0; ( pStr[i] != '\0' && iCurrLine != iLine ); i++ )
{
if ( pStr[i] == '\n' )
iCurrLine++;
}
if ( pStr[i] == '\r' )
i++;
*ppPos = &pStr[i];
return ( MIN( iCurrLine, iLine ) );
}
void process_page_string( TERM_DATA *pTerm, char *pCommand )
{
char cBuf[MAX_STRING];
int iLines = 1;
int i;
if ( next_char( pCommand ) != '\0' )
{
free_mem( (void **) &pTerm->pPageString );
pTerm->pPagePos = NULL;
pTerm->iPageMemSize = 0;
return;
}
for ( i = 0; *pTerm->pPagePos != '\0'; i++ )
{
if ( *pTerm->pPagePos == '\n' )
iLines++;
if ( iLines == pTerm->iPageLines || ( i + 3 ) >= MAX_STRING )
break;
cBuf[i] = *pTerm->pPagePos++;
}
if ( *pTerm->pPagePos != '\0' )
{
cBuf[i++] = '\n';
cBuf[i++] = '\r';
}
else
{
free_mem( (void **) &pTerm->pPageString );
pTerm->pPagePos = NULL;
pTerm->iPageMemSize = 0;
}
cBuf[i] = '\0';
write_string_buffer( pTerm, cBuf );
}
/*
* Setup a terminal to use the string editor.
*/
void setup_text_editor( TERM_DATA *pTerm, char **ppText, bool bAppend )
{
int i;
pTerm->pEditString = alloc_mem( MAX_STRING );
pTerm->pEditString[0] = '\0';
if ( *ppText != NULL && bAppend != TRUE )
{
strncpy( pTerm->pEditString, *ppText, ( MAX_STRING - 1 ) );
pTerm->pEditString[MAX_STRING - 1] = '\0';
}
pTerm->ppEditString = ppText;
pTerm->iEditLine = 1;
pTerm->bEditAppend = bAppend;
for ( i = 0; pTerm->pEditString[i] != '\0'; i++ )
{
if ( pTerm->pEditString[i] == '\n' )
pTerm->iEditLine++;
}
process_text_editor_string( pTerm, "-h" );
}
/*
* Setup the string pager.
*/
void setup_string_pager( TERM_DATA *pTerm )
{
pTerm->pPageString = alloc_mem( MAX_STRING );
pTerm->pPagePos = pTerm->pPageString;
pTerm->iPageMemSize = MAX_STRING;
}
void page_string( TERM_DATA *pTerm, char *pStr )
{
int i;
if ( pStr == NULL || pStr[0] == '\0' )
return;
i = ( strlen( pTerm->pPageString ) + strlen( pStr ) + 1 );
if ( i > pTerm->iPageMemSize )
pTerm->pPageString = realloc_mem( pTerm->pPageString,
( pTerm->iPageMemSize = i ) );
pTerm->pPagePos = pTerm->pPageString;
strcat( pTerm->pPageString, pStr );
}
void finish_string_pager( TERM_DATA *pTerm )
{
pTerm->pPagePos = pTerm->pPageString;
process_page_string( pTerm, "" );
}
static void finish_text_editor( TERM_DATA *pTerm )
{
if ( pTerm->bEditAppend == TRUE && *pTerm->ppEditString != NULL )
snprintf( pTerm->pEditString, MAX_STRING, "%s\n\r%s",
*pTerm->ppEditString, pTerm->pEditString );
free_string( pTerm->ppEditString );
*pTerm->ppEditString = save_string( pTerm->pEditString );
free_mem( (void **) &pTerm->pEditString );
pTerm->pEditString = NULL;
pTerm->ppEditString = NULL;
}
/*
* End of text.c
*/