TinyMUSH 3.3
TinyMUSH Server
Loading...
Searching...
No Matches
Functions
funiter.c File Reference

Functions for user-defined iterations over lists. More...

#include "config.h"
#include "constants.h"
#include "typedefs.h"
#include "macros.h"
#include "externs.h"
#include "prototypes.h"
#include <stdbool.h>
#include <string.h>
Include dependency graph for funiter.c:

Functions

void perform_loop (char *buff, char **bufc, dbref player, dbref caller, dbref cause, char *fargs[], int nfargs, char *cargs[], int ncargs)
 backwards-compatible looping constructs: LOOP, PARSE More...
 
void perform_iter (char *buff, char **bufc, dbref player, dbref caller, dbref cause, char *fargs[], int nfargs, char *cargs[], int ncargs)
 Looping constructs. More...
 
void fun_ilev (char *buff, char **bufc, dbref player __attribute__((unused)), dbref caller __attribute__((unused)), dbref cause __attribute__((unused)), char *fargs[] __attribute__((unused)), int nfargs __attribute__((unused)), char *cargs[] __attribute__((unused)), int ncargs __attribute__((unused)))
 Obtain nested iter tokens (#!) More...
 
void fun_inum (char *buff, char **bufc, dbref player __attribute__((unused)), dbref caller __attribute__((unused)), dbref cause __attribute__((unused)), char *fargs[], int nfargs __attribute__((unused)), char *cargs[] __attribute__((unused)), int ncargs __attribute__((unused)))
 Obtain nested iter tokens (#@) More...
 
void fun_itext (char *buff, char **bufc, dbref player __attribute__((unused)), dbref caller __attribute__((unused)), dbref cause __attribute__((unused)), char *fargs[], int nfargs __attribute__((unused)), char *cargs[] __attribute__((unused)), int ncargs __attribute__((unused)))
 Obtain nested iter tokens (##) More...
 
void fun_itext2 (char *buff, char **bufc, dbref player __attribute__((unused)), dbref caller __attribute__((unused)), dbref cause __attribute__((unused)), char *fargs[], int nfargs __attribute__((unused)), char *cargs[] __attribute__((unused)), int ncargs __attribute__((unused)))
 Two-list version of iter. More...
 
void fun_ibreak (char *buff __attribute__((unused)), char **bufc __attribute__((unused)), dbref player __attribute__((unused)), dbref caller __attribute__((unused)), dbref cause __attribute__((unused)), char *fargs[], int nfargs __attribute__((unused)), char *cargs[] __attribute__((unused)), int ncargs __attribute__((unused)))
 Break out of an iter. More...
 
void fun_fold (char *buff, char **bufc, dbref player, dbref caller, dbref cause, char *fargs[], int nfargs, char *cargs[], int ncargs)
 iteratively eval an attrib with a list of arguments and an optional base case. With no base case, the first list element is passed as %0 and the second is %1. The attrib is then evaluated with these args, the result is then used as %0 and the next arg is %1 and so it goes as there are elements left in the list. The optinal base case gives the user a nice starting point. More...
 
void handle_filter (char *buff, char **bufc, dbref player, dbref caller, dbref cause, char *fargs[], int nfargs, char *cargs[], int ncargs)
 iteratively perform a function with a list of arguments and return the arg, if the function evaluates to TRUE using the arg. More...
 
void fun_map (char *buff, char **bufc, dbref player, dbref caller, dbref cause, char *fargs[], int nfargs, char *cargs[], int ncargs)
 Iteratively evaluate an attribute with a list of arguments. More...
 
void fun_mix (char *buff, char **bufc, dbref player, dbref caller, dbref cause, char *fargs[], int nfargs, char *cargs[], int ncargs)
 Like map, but operates on two lists or more lists simultaneously, passing the elements as %0, %1, %2, etc. More...
 
void fun_step (char *buff, char **bufc, dbref player, dbref caller, dbref cause, char *fargs[], int nfargs, char *cargs[], int ncargs)
 A little like a fusion of iter() and mix(), it takes elements of a list X at a time and passes them into a single function as %0, %1, etc. step(<attribute>,<list>,<step size>,<delim>,<outdelim>) More...
 
void fun_foreach (char *buff, char **bufc, dbref player, dbref caller, dbref cause, char *fargs[], int nfargs, char *cargs[] __attribute__((unused)), int ncargs __attribute__((unused)))
 Like map(), but it operates on a string, rather than on a list, calling a user-defined function for each character in the string. No delimiter is inserted between the results. More...
 
void fun_munge (char *buff, char **bufc, dbref player, dbref caller, dbref cause, char *fargs[], int nfargs, char *cargs[], int ncargs)
 Combines two lists in an arbitrary manner. More...
 
void fun_while (char *buff, char **bufc, dbref player, dbref caller, dbref cause, char *fargs[], int nfargs, char *cargs[], int ncargs)
 Evaluate a list until a termination condition is met: while(EVAL_FN,CONDITION_FN,foo|flibble|baz|meep,1,|,-) where EVAL_FN is "[strlen(%0)]" and CONDITION_FN is "[strmatch(%0,baz)]" would result in '3-7-3' being returned. The termination condition is an EXACT not wild match. More...
 

Detailed Description

Functions for user-defined iterations over lists.

Author
TinyMUSH development team (https://github.com/TinyMUSH)
Version
3.3
Date
2021-01-04

Function Documentation

◆ fun_fold()

void fun_fold ( char *  buff,
char **  bufc,
dbref  player,
dbref  caller,
dbref  cause,
char *  fargs[],
int  nfargs,
char *  cargs[],
int  ncargs 
)

iteratively eval an attrib with a list of arguments and an optional base case. With no base case, the first list element is passed as %0 and the second is %1. The attrib is then evaluated with these args, the result is then used as %0 and the next arg is %1 and so it goes as there are elements left in the list. The optinal base case gives the user a nice starting point.

‍&REP_NUM object=[%0][repeat(%1,%1)] say fold(OBJECT/REP_NUM,1 2 3 4 5,->) You say "->122333444455555"

Note
To use added list separator, you must use base case!
Parameters
buffOutput buffer
bufcOutput buffer tracker
playerDBref of player
callerDBref of caller
causeDBref of cause
fargsFunction arguments
nfargsNumber of function arguments
cargsCommand arguments
ncargsNumber of command arguments

We need two to four arguments only

Two possibilities for the first arg: <obj>/<attr> and <attr>.

Evaluate it using the rest of the passed function args

may as well handle first case now

◆ fun_foreach()

void fun_foreach ( char *  buff,
char **  bufc,
dbref  player,
dbref  caller,
dbref  cause,
char *  fargs[],
int  nfargs,
char *cargs[]  __attribute__(unused),
int ncargs   __attribute__(unused) 
)

Like map(), but it operates on a string, rather than on a list, calling a user-defined function for each character in the string. No delimiter is inserted between the results.

Parameters
buffOutput buffer
bufcOutput buffer tracker
playerDBref of player
callerDBref of caller
causeDBref of cause
fargsFunction arguments
nfargsNumber of function arguments
cargsNot used
ncargsNot used

first letter in string is 0, not 1

Look for a start token.

Skip to the next character. Don't copy the start token.

We've found an end token. Skip over it. Note that it's possible to have a start and end token next to one another.

◆ fun_ibreak()

void fun_ibreak ( char *buff   __attribute__(unused),
char **bufc   __attribute__(unused),
dbref player   __attribute__(unused),
dbref caller   __attribute__(unused),
dbref cause   __attribute__(unused),
char *  fargs[],
int nfargs   __attribute__(unused),
char *cargs[]  __attribute__(unused),
int ncargs   __attribute__(unused) 
)

Break out of an iter.

Parameters
buffNot used
bufcNot used
playerNot used
callerNot used
causeNot used
fargsFunction arguments
nfargsNot used
cargsNot used
ncargsNot used

◆ fun_ilev()

void fun_ilev ( char *  buff,
char **  bufc,
dbref player   __attribute__(unused),
dbref caller   __attribute__(unused),
dbref cause   __attribute__(unused),
char *fargs[]  __attribute__(unused),
int nfargs   __attribute__(unused),
char *cargs[]  __attribute__(unused),
int ncargs   __attribute__(unused) 
)

Obtain nested iter tokens (#!)

Parameters
buffOutput buffer
bufcOutput buffer tracker
playerNot used
callerNot used
causeNot used
fargsNot used
nfargsNot used
cargsNot used
ncargsNot used

◆ fun_inum()

void fun_inum ( char *  buff,
char **  bufc,
dbref player   __attribute__(unused),
dbref caller   __attribute__(unused),
dbref cause   __attribute__(unused),
char *  fargs[],
int nfargs   __attribute__(unused),
char *cargs[]  __attribute__(unused),
int ncargs   __attribute__(unused) 
)

Obtain nested iter tokens (#@)

Parameters
buffOutput buffer
bufcOutput buffer tracker
playerNot used
callerNot used
causeNot used
fargsFunction arguments
nfargsNot used
cargsNot used
ncargsNot used

◆ fun_itext()

void fun_itext ( char *  buff,
char **  bufc,
dbref player   __attribute__(unused),
dbref caller   __attribute__(unused),
dbref cause   __attribute__(unused),
char *  fargs[],
int nfargs   __attribute__(unused),
char *cargs[]  __attribute__(unused),
int ncargs   __attribute__(unused) 
)

Obtain nested iter tokens (##)

Parameters
buffOutput buffer
bufcOutput buffer tracker
playerNot used
callerNot used
causeNot used
fargsFunction arguments
nfargsNot used
cargsNot used
ncargsNot used

◆ fun_itext2()

void fun_itext2 ( char *  buff,
char **  bufc,
dbref player   __attribute__(unused),
dbref caller   __attribute__(unused),
dbref cause   __attribute__(unused),
char *  fargs[],
int nfargs   __attribute__(unused),
char *cargs[]  __attribute__(unused),
int ncargs   __attribute__(unused) 
)

Two-list version of iter.

Parameters
buffOutput buffer
bufcOutput buffer tracker
playerNot used
callerNot used
causeNot used
fargsFunction arguments
nfargsNot used
cargsNot used
ncargsNot used

◆ fun_map()

void fun_map ( char *  buff,
char **  bufc,
dbref  player,
dbref  caller,
dbref  cause,
char *  fargs[],
int  nfargs,
char *  cargs[],
int  ncargs 
)

Iteratively evaluate an attribute with a list of arguments.

‍&DIV_TWO object=fdiv(%0,2) say map(1 2 3 4 5,object/div_two) You say "0.5 1 1.5 2 2.5" say map(object/div_two,1-2-3-4-5,-) You say "0.5-1-1.5-2-2.5"

Parameters
buffOutput buffer
bufcOutput buffer tracker
playerDBref of player
callerDBref of caller
causeDBref of cause
fargsFunction arguments
nfargsNumber of function arguments
cargsCommand arguments
ncargsNumber of command arguments

If we don't have anything for a second arg, don't bother.

Two possibilities for the second arg: <obj>/<attr> and <attr>.

now process the list one element at a time

◆ fun_mix()

void fun_mix ( char *  buff,
char **  bufc,
dbref  player,
dbref  caller,
dbref  cause,
char *  fargs[],
int  nfargs,
char *  cargs[],
int  ncargs 
)

Like map, but operates on two lists or more lists simultaneously, passing the elements as %0, %1, %2, etc.

Parameters
buffOutput buffer
bufcOutput buffer tracker
playerDBref of player
callerDBref of caller
causeDBref of cause
fargsFunction arguments
nfargsNumber of function arguments
cargsCommand arguments
ncargsNumber of command arguments

Check to see if we have an appropriate number of arguments. If there are more than three arguments, the last argument is ALWAYS assumed to be a delimiter.

Get the attribute, check the permissions.

process the lists, one element at a time.

◆ fun_munge()

void fun_munge ( char *  buff,
char **  bufc,
dbref  player,
dbref  caller,
dbref  cause,
char *  fargs[],
int  nfargs,
char *  cargs[],
int  ncargs 
)

Combines two lists in an arbitrary manner.

Parameters
buffOutput buffer
bufcOutput buffer tracker
playerDBref of player
callerDBref of caller
causeDBref of cause
fargsFunction arguments
nfargsNumber of function arguments
cargsNot used
ncargsNot used

Find our object and attribute

Copy our lists and chop them up.

Call the u-function with the first list as %0. Pass the input separator as %1, which makes sorting, etc. easier.

Now that we have our result, put it back into array form. Search through list1 until we find the element position, then copy the corresponding element from list2.

◆ fun_step()

void fun_step ( char *  buff,
char **  bufc,
dbref  player,
dbref  caller,
dbref  cause,
char *  fargs[],
int  nfargs,
char *  cargs[],
int  ncargs 
)

A little like a fusion of iter() and mix(), it takes elements of a list X at a time and passes them into a single function as %0, %1, etc. step(<attribute>,<list>,<step size>,<delim>,<outdelim>)

Parameters
buffOutput buffer
bufcOutput buffer tracker
playerDBref of player
callerDBref of caller
causeDBref of cause
fargsFunction arguments
nfargsNumber of function arguments
cargsCommand arguments
ncargsNumber of command arguments

Get attribute. Check permissions.

◆ fun_while()

void fun_while ( char *  buff,
char **  bufc,
dbref  player,
dbref  caller,
dbref  cause,
char *  fargs[],
int  nfargs,
char *  cargs[],
int  ncargs 
)

Evaluate a list until a termination condition is met: while(EVAL_FN,CONDITION_FN,foo|flibble|baz|meep,1,|,-) where EVAL_FN is "[strlen(%0)]" and CONDITION_FN is "[strmatch(%0,baz)]" would result in '3-7-3' being returned. The termination condition is an EXACT not wild match.

Parameters
buffOutput buffer
bufcOutput buffer tracker
playerDBref of player
callerDBref of caller
causeDBref of cause
fargsFunction arguments
nfargsNumber of function arguments
cargsNot used
ncargsNot used

If our third arg is null (empty list), don't bother.

Our first and second args can be <obj>/<attr> or just <attr>. Use them if we can access them, otherwise return an empty string.

Note that for user-defined attributes, atr_str() returns a pointer to a static, and that therefore we have to be careful about what we're doing.

If our evaluation and condition are the same, we can save ourselves some time later. There are two possibilities: we have the exact same obj/attr pair, or the attributes contain identical text.

Process the list one element at a time.

◆ handle_filter()

void handle_filter ( char *  buff,
char **  bufc,
dbref  player,
dbref  caller,
dbref  cause,
char *  fargs[],
int  nfargs,
char *  cargs[],
int  ncargs 
)

iteratively perform a function with a list of arguments and return the arg, if the function evaluates to TRUE using the arg.

‍&IS_ODD object=mod(%0,2) say filter(object/is_odd,1 2 3 4 5) You say "1 3 5" say filter(object/is_odd,1-2-3-4-5,-) You say "1-3-5"

Note
If you specify a separator it is used to delimit returned list
Parameters
buffOutput buffer
bufcOutput buffer tracker
playerDBref of player
callerDBref of caller
causeDBref of cause
fargsFunction arguments
nfargsNumber of function arguments
cargsCommand arguments
ncargsNumber of command arguments

< 0 is filter(), 1 is filterbool()

Two possibilities for the first arg: <obj>/<attr> and <attr>.

Now iteratively eval the attrib with the argument list

◆ perform_iter()

void perform_iter ( char *  buff,
char **  bufc,
dbref  player,
dbref  caller,
dbref  cause,
char *  fargs[],
int  nfargs,
char *  cargs[],
int  ncargs 
)

Looping constructs.

Note
iter() and list() parse an expression, substitute elements of a list, one at a time, using the '##' replacement token. Uses of these functions can be nested. In older versions of MUSH, these functions could not be nested. parse() and loop() exist for reasons of backwards compatibility, since the peculiarities of the way substitutions were done in the string replacements make it necessary to provide some way of doing backwards compatibility, in order to avoid breaking a lot of code that relies upon particular patterns of necessary escaping.

whentrue() and whenfalse() work similarly to iter(). whentrue() loops as long as the expression evaluates to true. whenfalse() loops as long as the expression evaluates to false.

istrue() and isfalse() are inline filterbool() equivalents returning the elements of the list which are true or false, respectively.

iter2(), list2(), etc. are two-list versions of all of the above.

Parameters
buffOutput buffer
bufcOutput buffer tracker
playerDBref of player
callerDBref of caller
causeDBref of cause
fargsFunction arguments
nfargsNumber of function arguments
cargsCommand arguments
ncargsNumber of command arguments

< 0 is iter(), 1 is list()

Enforce maximum nesting level.

Figure out what functionality we're getting.

The list argument is unevaluated. Go evaluate it.

Same thing for the second list arg, if we have it

If both lists are empty, we're done

we might nibble this

◆ perform_loop()

void perform_loop ( char *  buff,
char **  bufc,
dbref  player,
dbref  caller,
dbref  cause,
char *  fargs[],
int  nfargs,
char *  cargs[],
int  ncargs 
)

backwards-compatible looping constructs: LOOP, PARSE

Note
See notes on perform_iter for the explanation.
Parameters
buffOutput buffer
bufcOutput buffer tracker
playerDBref of player
callerDBref of caller
causeDBref of cause
fargsFunction arguments
nfargsNumber of function arguments
cargsCommand arguments
ncargsNumber of command arguments

< 0 is parse(), 1 is loop()