#include <alias.h>
inherit COMMAND_BASE;
private nosave string gfilter;
/**
* Turn the compiled alias array into a string.
* @param al the alias array
* @return the string value of the alias array
* @see compile_alias()
*/
string alias_string( mixed al ) {
int i, num, *add_thing;
string str;
str = "";
add_thing = ({ });
for( i = 0; i < sizeof(al); i++ ) {
if( stringp(al[i]) ) {
str += replace( al[i], ({";", "\\;"}) );
} else {
num = al[i] & ALIAS_MASK;
switch( al[i] - num ) {
case NEW_LINE :
str += ";";
break;
case ALL_ARGS :
str += "$*$";
break;
case ONE_ARG :
str += "$"+num+"$";
break;
case TO_ARG :
str += "$*"+num+"$";
break;
case FROM_ARG :
str += "$"+num+"*$";
break;
case ALL_ARG :
str += "$arg:"+al[++i]+"$";
break;
case ARG_THING :
str += "$arg"+num+":"+al[++i]+"$";
break;
case ELSE_THING :
str += "$else$";
break;
case ALL_IFARG :
str += "$ifarg:";
break;
case IFARG_THING :
str += "$ifarg"+num+":";
break;
case CURR_LOC :
str += "$!$";
break;
case END_IF :
str += "$endif$";
break;
}
}
}
return str;
} /* alias_string() */
/**
* Prints out all the aliases on the player object. This is called by the
* alias command when no arguments are specified.
* @return 0 if no aliases are defined, 1 if they are
* @see alias()
*/
int print_aliases( string filter, int sorted ) {
int len, cols;
string str, str1, str2, *tmp, bing, key;
mapping aliases;
string ret;
aliases = TP->query_aliases();
if( !sizeof(aliases) )
return notify_fail("You have defined no aliases.\n");
str1 = "";
str2 = "";
tmp = keys(aliases);
if( filter && !regexp( filter, "[\\[\\]\\(\\)]+") ) {
gfilter = "^" + filter;
tmp = filter( tmp, (: regexp( $1, gfilter ) :) );
}
tmp = sort_array( tmp, 1 );
ret = "";
cols = (int)TP->query_cols();
foreach( key in tmp ) {
if( !key ) {
map_delete( aliases, 0 );
continue;
}
bing = alias_string( aliases[key] );
if( !bing )
bing = "Error in the alias!";
str = key+": "+bing;
if( strlen(str) > 39 || sorted ) {
len = cols - strlen(key) - 2;
if( len < 0 )
len = 10;
// If it is too long, print it right now.
ret += sprintf( key+": %-=*s\n", len, bing );
} else if( strlen(str) > 19 ) {
str1 += str+"\n";
} else {
str2 += str+"\n";
}
}
if( strlen(str1) )
ret += sprintf("%-#*s\n", cols, str1 );
if( strlen(str2) )
ret += sprintf("%-#*s\n", cols, str2 );
ret += sprintf("A total of %d aliases.\n", sizeof(tmp) );
TP->more_string(ret);
return 1;
} /* print_aliases() */
/**
* Creates the compiled alias array. See the alias.h file for the
* definitions of thevalues in the alias array.
* @param str the string to compile
* @return the compiled alias array
* @see /include/alias.h
*/
mixed compile_alias( string str ) {
int i, space, tmp, gumby, nodollar;
mixed ret, ifargs;
string *frog, s1;
str = replace( str, ({"\\;", "$escaped$", ";", "$new_line$", " ", " "}) );
str = replace( str, "$escaped$", ";");
str = "&"+str+"&";
frog = explode( str, "$");
if( frog[0] == "&")
frog = frog[1..];
else
frog[ 0 ] = frog[ 0 ][ 1 .. ];
s1 = frog[<1];
if( s1 == "&" )
frog = frog[0..<2];
else
frog[<1] = s1[0..<2];
ret = ({ });
ifargs = ({ });
nodollar = 1;
for( i = 0; i < sizeof(frog); i++ ) {
switch( frog[i] ) {
case "new_line" :
ret += ({ NEW_LINE });
nodollar = 1;
break;
case "*" :
ret += ({ ALL_ARGS });
gumby = 1;
nodollar = 1;
break;
case "!" :
if( creatorp(TO) ) {
ret += ({ CURR_LOC });
nodollar = 1;
}
break;
case "else" :
if( sizeof(ifargs) ) {
ret[ifargs[sizeof(ifargs)-1]] = sizeof(ret)-
ifargs[sizeof(ifargs)-1]+1;
ret += ({ ELSE_THING, 0, ""});
ifargs[sizeof(ifargs)-1] = sizeof(ret)-2;
nodollar = 1;
}
break;
case "~" :
case "endif" :
if( sizeof(ifargs) ) {
ret += ({ END_IF });
ret[ifargs[sizeof(ifargs)-1]] = sizeof(ret)-
ifargs[sizeof(ifargs)-1];
ifargs = delete( ifargs, sizeof(ifargs)-1, 1 );
nodollar = 1;
space = 1;
}
break;
default :
if( frog[i][0..4] == "ifarg") {
if( sscanf( frog[i], "ifarg%d:%s", tmp, s1 ) == 2 ) {
if( tmp < 0 )
tmp = 0;
if( tmp > ALIAS_MASK )
tmp = ALIAS_MASK;
ret += ({ IFARG_THING+ tmp, 0, ""});
frog[i--] = s1;
nodollar = 1;
ifargs += ({ sizeof(ret)-2 });
space = 0;
gumby = 1;
} else if( frog[i][5] == ':') {
ret += ({ ALL_IFARG, 0, ""});
frog[i] = frog[i][6..];
nodollar = 1;
ifargs += ({ sizeof(ret)-2 });
space = 0;
gumby = 1;
i--;
} else {
if( sizeof(ret) && stringp(ret[sizeof(ret)-1]) && !space ) {
ret[sizeof(ret)-1] += "$"+frog[i];
} else if( nodollar ) {
ret += ({ frog[i] });
nodollar = 0;
} else {
ret += ({ "$"+frog[i] });
}
}
} else if( frog[i][0..2] == "arg") {
if( sscanf(frog[i], "arg%d:%s", tmp, s1 ) == 2 ) {
if( tmp < 0 )
tmp = 0;
if( tmp > ALIAS_MASK)
tmp = ALIAS_MASK;
ret += ({ ARG_THING+ tmp, s1, ""});
nodollar = 1;
gumby = 1;
} else if( frog[i][3] == ':') {
ret += ({ ALL_ARG, frog[i][4..100], ""});
nodollar = 1;
gumby = 1;
} else {
if( sizeof(ret) && stringp(ret[sizeof(ret)-1]) && !space ) {
ret[sizeof(ret)-1] += "$"+frog[i];
} else if( nodollar ) {
ret += ({ frog[i] });
nodollar = 0;
} else {
ret += ({ "$"+frog[i] });
}
gumby = 1;
space = 0;
}
} else if( strlen(frog[i]) && frog[i][<1] == '*' &&
sscanf( frog[i], "%d%s*", tmp, s1 ) == 2 && s1 == "") {
if( tmp < 0 )
tmp = 0;
if( tmp > ALIAS_MASK )
tmp = ALIAS_MASK;
ret += ({ FROM_ARG + tmp });
gumby = 1;
nodollar = 1;
} else if( strlen(frog[i]) && frog[i][0] == '*' &&
sscanf( frog[i][1..1000], "%d%s", tmp, s1 ) == 2 && s1 == "") {
if( tmp < 0 )
tmp = 0;
if( tmp > ALIAS_MASK )
tmp = ALIAS_MASK;
ret += ({ TO_ARG + tmp });
gumby = 1;
nodollar = 1;
} else if( sscanf( frog[i], "%d%s", tmp, s1 ) == 2 && s1 == "") {
if( tmp < 0 )
tmp = 0;
if( tmp > ALIAS_MASK )
tmp = ALIAS_MASK;
ret += ({ ONE_ARG + tmp });
gumby = 1;
nodollar = 1;
} else {
if( !nodollar )
frog[i] = "$"+frog[i];
nodollar = 0;
space = 0;
if( strlen(frog[i]) && frog[i][<1] == '~') {
if( sizeof(ifargs) ) {
if( strlen(frog[i]) == 1 )
frog[i] = "";
else
frog[i] = frog[i][0..<2];
// Create an offset.
ret += ({ END_IF });
ret[ifargs[<1]] = sizeof(ret) - ifargs[<1];
ifargs = ifargs[0..<2];
nodollar = 1;
space = 1;
}
}
if( sizeof(ret) && stringp(ret[<1]) && space != 2 )
ret[<1] += frog[i];
else
ret += ({ frog[i] });
if( space )
space = 2;
}
}
}
while( sizeof(ifargs) ) {
ret += ({ END_IF });
ret[ifargs[sizeof(ifargs)-1]] = sizeof(ret)-
ifargs[sizeof(ifargs)-1];
ifargs = delete( ifargs, sizeof(ifargs)-1, 1 );
}
if( !gumby ) {
if( sizeof(ret) && !stringp(ret[sizeof(ret)-1]) || space ) {
ret += ({ " ", ALL_ARGS });
} else if( sizeof(ret) ) {
ret[sizeof(ret)-1] += " ";
ret += ({ ALL_ARGS });
}
}
return ret;
} /* compile_alias() */
/**
* This method will print out one or more aliases.
* @param str the aliases to print
*/
int print_some_aliases( string str ) {
if( TP->is_alias(str) ) {
printf("%s: %-=*s\n", str, (int)TP->query_cols() - strlen(str) -2,
alias_string( TP->query_player_alias(str) ) );
return 1;
}
return print_aliases( str, 0 );
} /* print_some_aliases() */
/**
* The main alias control function. Sets up new aliases and prints out
* the values of single aliases or all the aliases.
* @param str the command name
* @return 0 if the alias command failed, 1 if it succeeded
* @see edit_alias()
* @see print_aliases()
*/
protected int alias( string name, string value ) {
#ifdef DISALLOW_COLOUR
if( strsrch( name, "%^") > -1 || strsrch( value, "%^") > -1 )
return notify_fail("You cannot add an alias with a colour escape "
"sequence (% ^).\n");
#endif
if( name == ".plan" || name == ".project" || name == ".signature") {
if( sizeof(value) > MAX_PLAN_LENGTH )
return notify_fail("Sorry, the maximum length of .plan, .project "
"and .signature aliases is "+MAX_PLAN_LENGTH+" characters.\n");
}
if( sizeof(value) > MAX_ALIAS_LENGTH )
return notify_fail("Sorry, the maximum alias length is "+
MAX_ALIAS_LENGTH+" characters.\n");
name = implode( explode( name, " "), "");
write( ( !TP->is_alias(name) ? "Added" : "Changed")+" alias '"+
name+"'.\n");
TP->add_player_alias( name, compile_alias(value) );
return 1;
} /* alias() */
/** @ignore yes */
mixed query_patterns() {
return ({
"", (: print_aliases("", 0) :),
"sorted", (: print_aliases("", 1) :),
"<word'alias'>", (: print_some_aliases($4[0]) :),
"<word'alias'> <string>", (: alias($4[0], $4[1]) :)
});
} /* query_patterns() */