/*********************************************************************/ /* 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 <signal.h> #include "tintin.h" #if IRIX #include <stdlib.h> #endif struct session *parse_tintin_command(); void do_speedwalk(); char *get_arg_with_spaces(); extern struct listnode *searchnode_list_begin(); extern struct session *all_command(); extern struct session *read_command(); extern struct session *session_command(); extern struct session *write_command(); extern struct session *writesession_command(); extern struct session *zap_command(); extern struct completenode *complete_head; extern char *space_out(); extern char *get_arg_in_braces(); void write_com_arg_mud(); void prompt(); extern char k_input[240]; extern struct session *sessionlist, *activesession; extern struct listnode *common_aliases, *common_actions, *common_subs; extern struct listnode *common_myvars, *common_antisubs; extern char vars[10][BUFFER_SIZE]; /* the %0, %1, %2,....%9 variables */ extern char tintin_char, verbatim_char; extern int term_echoing, verbatim; extern int speedwalk, is_split, display_row, display_col, input_row, input_col; extern char system_com[80]; extern void action_command(); extern void unhighlight_command(); extern char *get_arg_stop_spaces(); extern char *cryptkey; extern char *get_arg_all(); extern void tstphandler(); /**************************************************************************/ /* parse input, check for TINTIN commands and aliases and send to session */ /**************************************************************************/ struct session *parse_input(input, ses) char *input; struct session *ses; { char command[BUFFER_SIZE], arg[BUFFER_SIZE], result[BUFFER_SIZE]; char *input2; struct listnode *ln; if(!term_echoing && activesession==ses) { term_echoing=TRUE; } if(*input=='\0') { if(ses) write_line_mud("", ses); else write_com_arg_mud("", "", ses); return ses; } if (is_abrev(input+1, "verbatim") && *input==tintin_char) { verbatim_command(); return ses; } if (verbatim && ses) { write_line_mud(input,ses); return ses; } if (*input==verbatim_char) { input++; write_line_mud(input,ses); return ses; } substitute_myvars(input, result,ses); input2=result; while(*input2) { if(*input2==';') input2++; input2=get_arg_stop_spaces(input2, command); input2=get_arg_all(input2, arg); if(*command==tintin_char) ses=parse_tintin_command(command+1, arg, ses); else if((ln=searchnode_list_begin((ses) ? ses->aliases : common_aliases, command, ALPHA))!=NULL) { int i; char *cpsource, *cpsource2, newcommand[BUFFER_SIZE], end; strcpy(vars[0], arg); for(i=1, cpsource=arg; i<10; i++) { /* Next lines CHANGED to allow argument grouping with aliases */ while (*cpsource == ' ') cpsource++; end = (*cpsource == '{') ? '}' : ' '; cpsource = (*cpsource == '{') ? cpsource+1 : cpsource; for(cpsource2=cpsource; *cpsource2 && *cpsource2!=end; cpsource2++); strncpy(vars[i], cpsource, cpsource2-cpsource); *(vars[i]+(cpsource2-cpsource))='\0'; cpsource=(*cpsource2) ? cpsource2+1 : cpsource2; } prepare_actionalias(ln->right, newcommand, ses); 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(cp) char *cp; { int flag; flag=FALSE; while(*cp) { if(*cp!='n' && *cp!='e' && *cp!='s' && *cp!='w' && *cp!='u' && *cp!='d' && !isdigit(*cp)) return FALSE; if(!isdigit(*cp)) flag=TRUE; cp++; } return flag; } /**************************/ /* do the speedwalk thing */ /**************************/ void do_speedwalk(cp, ses) char *cp; struct session *ses; { char sc[2]; char *loc; int multflag,loopcnt,i; strcpy(sc, "x"); while(*cp) { loc=cp; multflag=FALSE; while(isdigit(*cp)) { cp++; multflag=TRUE; } if(multflag && *cp) { sscanf(loc,"%d%c",&loopcnt,sc); i=0; while(i++<loopcnt) write_com_arg_mud(sc, "", ses); } else if (*cp) { sc[0]=*cp; write_com_arg_mud(sc, "", ses); } cp++; } } /*************************************/ /* parse most of the tintin-commands */ /*************************************/ struct session *parse_tintin_command(command, arg, ses) 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); prompt(NULL); return(sesptr); } } if(isdigit(*command)) { int i=atoi(command); if(i>0) { get_arg_in_braces(arg, arg, 1); while(i-->0) ses=parse_input(arg, ses); } else { tintin_puts("#YEAH RIGHT! GO REPEAT THAT YOURSELF DUDE.", ses); prompt(NULL); } 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, "antisubstitute")) parse_antisub(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, "cr")) cr_command(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(arg); else if(is_abrev(command, "highlight")) parse_high(arg, ses); else if(is_abrev(command, "history")) history_command(ses); else if(is_abrev(command, "if")) if_command(arg, ses); else if(is_abrev(command, "ignore")) ignore_command(ses); else if(is_abrev(command, "info")) display_info(ses); else if(is_abrev(command, "killall")) kill_all(ses, CLEAN); else if(is_abrev(command, "log")) log_command(arg, ses); else if(is_abrev(command, "loop")) loop_command(arg, ses); else if(is_abrev(command, "nop")); else if(is_abrev(command, "map")) map_command(arg,ses); else if(is_abrev(command, "math")) math_command(arg, ses); else if(is_abrev(command, "mark")) mark_command(ses); else if(is_abrev(command, "message")) message_command(arg, ses); else if(is_abrev(command, "path")) path_command(ses); else if(is_abrev(command, "pathdir")) pathdir_command(arg, ses); else if(is_abrev(command, "presub")) presub_command(ses); else if(is_abrev(command, "redraw")) redraw_command(); else if(is_abrev(command, "retab")) read_complete(); 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, "savepath")) savepath_command(arg, ses); else if(is_abrev(command, "session")) ses=session_command(arg, ses); else if(is_abrev(command, "showme")) showme_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, "split")) split_command(arg); /* CHANGED to allow suspending from within tintin. */ /* I know, I know, this is a hack *yawn* */ else if(is_abrev(command, "suspend")) tstphandler(SIGTSTP,0,NULL,NULL); else if(is_abrev(command, "tablist")) tablist(complete_head); else if(is_abrev(command, "tabadd")) tab_add(arg); else if(is_abrev(command, "tabdelete")) tab_delete(arg); else if(is_abrev(command, "textin")) read_file(arg, ses); else if(is_abrev(command, "unsplit")) unsplit_command(); else if(is_abrev(command, "substitute")) parse_sub(arg, ses); else if(is_abrev(command, "gag")) { if (*arg!='{') { strcpy(command,arg); strcpy(arg,"{"); strcat(arg,command); strcat(arg,"} "); } strcat(arg, " ."); parse_sub(arg,ses); } else if(is_abrev(command, system_com)) 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, "togglesubs")) togglesubs_command(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, "unantisubstitute")) unantisubstitute_command(arg,ses); else if(is_abrev(command, "unhighlight")) unhighlight_command(arg,ses); else if(is_abrev(command, "unsubstitute")) unsubstitute_command(arg, ses); else if(is_abrev(command, "ungag")) unsubstitute_command(arg,ses); else if(is_abrev(command, "unpath")) unpath_command(ses); else if(is_abrev(command, "variable")) var_command(arg,ses); else if(is_abrev(command, "version")) version_command(); else if(is_abrev(command, "unvariable")) unvar_command(arg,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); prompt(NULL); } return(ses); } /**********************************************/ /* get all arguments - don't remove "s and \s */ /**********************************************/ char *get_arg_all(s, arg) char *s; char *arg; { /* int inside=FALSE; */ int nest=0; s=space_out(s); while(*s) { if(*s=='\\') { *arg++=*s++; if(*s) *arg++=*s++; } else if(*s==';' && nest<1) { break; } else if(*s==DEFAULT_OPEN) { nest++; *arg++=*s++; } else if(*s==DEFAULT_CLOSE) { nest--; *arg++=*s++; } 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(s, arg) char *s; char *arg; { int nest=0; /* int inside=FALSE; */ s=space_out(s); while(*s) { if(*s=='\\') { if(*++s) *arg++=*s++; } else if(*s==';' && nest==0) { break; } else if(*s==DEFAULT_OPEN) { nest++; *arg++=*s++; } else if(*s==DEFAULT_CLOSE) { *arg++=*s++; nest--; } else *arg++=*s++; } *arg='\0'; return s; } /********************/ /* my own routine */ /********************/ char *get_arg_in_braces(s, arg, flag) char *s; char *arg; int flag; { int nest=0; char *ptr; s=space_out(s); ptr=s; if (*s!=DEFAULT_OPEN) { if (flag==0) s=get_arg_stop_spaces(ptr,arg); else s=get_arg_with_spaces(ptr,arg); return s; } s++; while(*s!='\0' && !(*s==DEFAULT_CLOSE && nest==0)) { if(*s==DEFAULT_OPEN) { nest++; } else if(*s==DEFAULT_CLOSE) { nest--; } *arg++=*s++; } if (!*s) tintin_puts2("#Unmatched braces error!", (struct session *)NULL); else s++; *arg='\0'; return s; } /**********************************************/ /* get one arg, stop at spaces */ /* remove quotes */ /**********************************************/ char *get_arg_stop_spaces(s, arg) 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 && *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(s) char *s; { while(isspace(*s)) s++; return s; } /************************************/ /* send command+argument to the mud */ /************************************/ void write_com_arg_mud(command, argument, ses) 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); prompt(NULL); } 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(ses) struct session *ses; { char strng[80]; if(ses && !PSEUDO_PROMPT) write_line_mud("", ses); else if (!is_split) write(1,"> ", 3); else { sprintf(strng,"8> 7[%d;%df", input_row, input_col); write(1,strng, strlen(strng)+1); display_col+=2; } }