/*********************************************************************/
/* file: parse.c - some utility-functions */
/* TINTIN III */
/* (T)he K(I)cki(N) (T)ickin D(I)kumud Clie(N)t */
/* coded by peter unold 1992 */
/*********************************************************************/
#include <string.h>
#include <ctype.h>
#include "tintin.h"
extern struct session *sessionlist, *activesession;
extern struct listnode *common_aliases, *common_actions, *common_subs;
extern char vars[10][BUFFER_SIZE]; /* the &0, &1, &2,....&9 variables */
extern char tintin_char;
extern int term_echoing;
extern int speedwalk;
/**************************************************************************/
/* parse input, check for TINTIN commands and aliases and send to session */
/**************************************************************************/
struct session *parse_input(char *input, struct session *ses)
{
char command[BUFFER_SIZE], arg[BUFFER_SIZE];
char *cptr;
struct listnode *ln;
if(!term_echoing) {
term_echo();
term_echoing=TRUE;
}
if(*input=='\0') {
if(ses)
write_line_mud("", ses);
else
write_com_arg_mud("", "", ses);
return ses;
}
while(*input) {
if(*input==';')
input++;
input=get_arg_stop_spaces(input, command);
input=get_arg_all(input, arg);
if(*command==tintin_char)
ses=parse_tintin_command(command+1, arg, ses);
else if((ln=searchnode_list((ses) ? ses->aliases : common_aliases, command))!=NULL) {
int i;
char *cpsource, *cpsource2, newcommand[BUFFER_SIZE];
strcpy(vars[0], arg);
for(i=1, cpsource=arg; i<10; i++) {
for(cpsource2=cpsource; *cpsource2 && *cpsource2!=' '; cpsource2++);
strncpy(vars[i], cpsource, cpsource2-cpsource);
cpsource=cpsource2;
if(*cpsource==' ')
cpsource++;
}
prepare_actionalias(ln->right, newcommand);
if(!strcmp(ln->right, newcommand) && *arg) {
strcat(newcommand, " ");
strcat(newcommand, arg);
}
ses=parse_input(newcommand, ses);
}
else if(speedwalk && !*arg && is_speedwalk_dirs(command))
do_speedwalk(command, ses);
else {
get_arg_with_spaces(arg, arg);
write_com_arg_mud(command, arg, ses);
}
}
return(ses);
}
/**********************************************************************/
/* return TRUE if commands only consists of capital letters N,S,E ... */
/**********************************************************************/
int is_speedwalk_dirs(char *cp)
{
while(*cp) {
if(*cp!='n' && *cp!='e' && *cp!='s' && *cp!='w' && *cp!='u' && *cp!='d')
return FALSE;
cp++;
}
return TRUE;
}
/**************************/
/* do the speedwalk thing */
/**************************/
void do_speedwalk(char *cp, struct session *ses)
{
char sc[2]={'x', '\0'};
while(*cp) {
sc[0]=*cp;
write_com_arg_mud(sc, "", ses);
cp++;
}
}
/*************************************/
/* parse most of the tintin-commands */
/*************************************/
struct session *parse_tintin_command(char *command, char *arg, struct session *ses)
{
struct session *sesptr;
for(sesptr=sessionlist; sesptr; sesptr=sesptr->next)
if(strcmp(sesptr->name, command)==0) {
if(*arg){
get_arg_with_spaces(arg, arg);
parse_input(arg, sesptr); /* was: #sessioname commands */
return(ses);
}
else {
char buf[BUFFER_SIZE];
activesession=sesptr;
sprintf(buf, "#SESSION '%s' ACTIVATED.", sesptr->name);
tintin_puts(buf, sesptr);
return(sesptr);
}
}
if(isdigit(*command)) {
int i=atoi(command);
if(i>0) {
get_arg_with_spaces(arg, arg);
while(i-->0)
ses=parse_input(arg, ses);
}
else
tintin_puts("#YEAH RIGHT! GO REPEAT THAT YOURSELF DUDE.", ses);
return(ses);
}
else if(is_abrev(command, "action"))
action_command(arg, ses);
else if(is_abrev(command, "alias"))
alias_command(arg, ses);
else if(is_abrev(command, "all"))
ses=all_command(arg, ses);
else if(is_abrev(command, "bell"))
bell_command(ses);
else if(is_abrev(command, "boss"))
boss_command(ses);
else if(is_abrev(command, "char"))
char_command(arg, ses);
else if(is_abrev(command, "echo"))
echo_command(ses);
else if(is_abrev(command, "end"))
end_command(command, ses);
else if(is_abrev(command, "help"))
help_command(ses);
else if(is_abrev(command, "history"))
history_command(ses);
else if(is_abrev(command, "ignore"))
ignore_command(ses);
else if(is_abrev(command, "log"))
log_command(arg, ses);
else if(is_abrev(command, "nop"));
else if(is_abrev(command, "mark"))
mark_command(ses);
else if(is_abrev(command, "path"))
path_command(ses);
else if(is_abrev(command, "return"))
return_command(ses);
else if(is_abrev(command, "read"))
ses=read_command(arg, ses);
else if(is_abrev(command, "session"))
ses=session_command(arg, ses);
else if(is_abrev(command, "snoop"))
snoop_command(arg, ses);
else if(is_abrev(command, "speedwalk"))
speedwalk_command(ses);
else if(is_abrev(command, "substitute"))
parse_sub(arg, ses);
else if(is_abrev(command, "system"))
system_command(arg, ses);
else if(is_abrev(command, "tick"))
tick_command(ses);
else if(is_abrev(command, "tickoff"))
tickoff_command(ses);
else if(is_abrev(command, "tickon"))
tickon_command(ses);
else if(is_abrev(command, "tickset"))
tickset_command(ses);
else if(is_abrev(command, "ticksize"))
ticksize_command(arg, ses);
else if(is_abrev(command, "unaction"))
unaction_command(arg, ses);
else if(is_abrev(command, "unalias"))
unalias_command(arg, ses);
else if(is_abrev(command, "unsubstitute"))
unsubstitute_command(arg, ses);
else if(is_abrev(command, "unpath"))
unpath_command(ses);
else if(is_abrev(command, "wizlist"))
wizlist_command(ses);
else if(is_abrev(command, "write"))
ses=write_command(arg, ses);
else if(is_abrev(command, "writesession"))
ses=writesession_command(arg, ses);
else if(is_abrev(command, "zap"))
ses=zap_command(ses);
else
tintin_puts("#UNKNOWN TINTIN-COMMAND.", ses);
return(ses);
}
/**********************************************/
/* get all arguments - don't remove "s and \s */
/**********************************************/
char *get_arg_all(char *s, char *arg)
{
int inside=FALSE;
s=space_out(s);
while(*s) {
if(*s=='\\') {
*arg++=*s++;
if(*s)
*arg++=*s++;
}
else if(*s=='"') {
*arg++=*s++;
inside=!inside;
}
else if(*s==';') {
if(inside)
*arg++=*s++;
else
break;
}
else
*arg++=*s++;
}
*arg='\0';
return s;
}
/**************************************/
/* get all arguments - remove "s etc. */
/* Example: */
/* In: "this is it" way way hmmm; */
/* Out: this is it way way hmmm */
/**************************************/
char *get_arg_with_spaces(char *s, char *arg)
{
int inside=FALSE;
s=space_out(s);
while(*s) {
if(*s=='\\') {
if(*++s)
*arg++=*s++;
}
else if(*s=='"') {
s++;
inside=!inside;
}
else if(*s==';') {
if(inside)
*arg++=*s++;
else
break;
}
else
*arg++=*s++;
}
*arg='\0';
return s;
}
/******************************************************/
/* get one argument - stop at spaces - remove "s etc. */
/* example: */
/* in: "yo yo" wayout and no more; */
/* out: yo yo */
/******************************************************/
char *get_arg_stop_spaces(char *s, char *arg)
{
int inside=FALSE;
s=space_out(s);
while(*s) {
if(*s=='\\') {
if(*++s)
*arg++=*s++;
}
else if(*s=='"') {
s++;
inside=!inside;
}
else if(*s==';') {
if(inside)
*arg++=*s++;
else
break;
}
else if(!inside && isspace(*s))
break;
else
*arg++=*s++;
}
*arg='\0';
return s;
}
/*********************************************/
/* spaceout - advance ptr to next none-space */
/* return: ptr to the first none-space */
/*********************************************/
char *space_out(char *s)
{
while(isspace(*s))
s++;
return s;
}
/************************************/
/* send command+argument to the mud */
/************************************/
void write_com_arg_mud(char *command, char *argument, struct session *ses)
{
char outtext[BUFFER_SIZE];
int i;
if(!ses) {
char buf[100];
sprintf(buf, "#NO SESSION ACTIVE. USE THE %cSESSION-COMMAND TO START ONE.", tintin_char);
tintin_puts(buf, ses);
}
else {
check_insert_path(command, ses);
strncpy(outtext, command, BUFFER_SIZE);
if(*argument) {
strncat(outtext, " ", BUFFER_SIZE-strlen(command)-1);
strncat(outtext, argument, BUFFER_SIZE-strlen(command)-2);
}
write_line_mud(outtext, ses);
outtext[i=strlen(outtext)]='\n';
if(ses->logfile)
fwrite(outtext, i+1, 1, ses->logfile);
}
}
/***************************************************************/
/* show a prompt - mud prompt if we're connected/else just a > */
/***************************************************************/
void prompt(struct session *ses)
{
if(ses && !PSEUDO_PROMPT)
write_line_mud("", ses);
else {
printf("> ");
fflush(stdout);
}
}