/*
* apply.c -- the function apply_definition
*
* PMF -- Padrone's MudFrontend, a frontend for (maybe mostly LP-)mud
* Thomas Padron-McCarthy (Email: padrone@lysator.liu.se), 1990, 1991
* Share and enjoy, but be nice: don't steal my program! Hugo is watching!
* This file latest updated: Sept 21, 1991
*
*/
#include <stdio.h>
#include <strings.h>
#include <ctype.h>
#include "safe_malloc.h"
#include "config.h"
#include "pmf.h"
#include "globals.h"
/*---------------------------------------------------------------------------*/
/* This function is called with a string containing a macro definition
* (for example an alias definition), an integer containing the number
* of arguments, an a pointer to an array, containing those arguments.
* Note that argument 0 is the command itself, and normally not used.
* A malloced string is returned, containg the evaluated form.
* In the pattern, these substitutions are performed:
* $N, where N is a number, is changed to argument N
* $* is changed to the list of all arguments (except argument 0)
* $LN, as $N but lower-cased argument
* $L*, as $* but lower-cased arguments
* $$ is changed to $
* $anything-else (including $n) is not replaced
* If append_if_none_inserted is true, and no arguments were inserted,
* all arguments (except argument 0) are appended to the resulting string.
*/
char *apply_definition(definition, nr_arguments, arguments, append_if_none_inserted)
char *definition, **arguments;
int nr_arguments;
int append_if_none_inserted;
{
register char *result, *defcp, *rescp;
int argnr;
int arg_was_inserted;
int lower_flag; /* Also used to remember if 'L' or 'l' */
USER_DEBUG(("apply_definition(\"%s\", %d, ...)", definition, nr_arguments));
result = safe_malloc(10 * MAX_LINE_LENGTH + 1);
rescp = result;
defcp = definition;
arg_was_inserted = 0;
while (*defcp) {
if (*defcp == '$') {
++defcp;
if ((*defcp == 'L' || *defcp == 'l') && (defcp[1] == '*' || isdigit(defcp[1]))) {
/* $Lsomething or $lsomething */
lower_flag = *defcp;
++defcp;
}
else
lower_flag = 0;
if (*defcp == '$')
/* $$ */
*rescp++ = *defcp++;
else if (*defcp == '*') {
/* $* */
for (argnr = 1; argnr < nr_arguments; ++argnr) {
if (argnr > 1)
*rescp++ = ' ';
strcpy(rescp, arguments[argnr]);
if (lower_flag)
lower_string(rescp);
rescp += strlen(arguments[argnr]);
arg_was_inserted = 1;
}
defcp++;
}
else if (isdigit(*defcp)) {
/* $number */
argnr = atoi(defcp);
if (argnr >= 0 && argnr < nr_arguments) {
strcpy(rescp, arguments[argnr]);
if (lower_flag)
lower_string(rescp);
rescp += strlen(arguments[argnr]);
arg_was_inserted = 1;
}
else
error("Bad argument reference ($%d) when applying definition \"%s\".",
argnr, definition);
while (isdigit(*defcp))
++defcp;
}
else {
/* $something-else */
*rescp++ = '$';
if (lower_flag)
*rescp++ = lower_flag;
}
}
else {
*rescp++ = *defcp++;
}
} /* while not end of definition string */
/* If no arguments were inserted with the $N or $* syntax, just append them. */
if (append_if_none_inserted && !arg_was_inserted) {
for (argnr = 1; argnr < nr_arguments; ++argnr) {
*rescp++ = ' ';
strcpy(rescp, arguments[argnr]);
rescp += strlen(arguments[argnr]);
}
}
*rescp++ = '\0';
return safe_realloc(result, strlen(result) + 1);
} /* apply_definition */
syntax highlighted by Code2HTML, v. 0.9.1