Note especially the last example, which will trip you up if you use
floating point numbers with dec() and expect it to work like sub().
See also: inc()
+& DECOMPOSE()
+ decompose(<string>)
+
+ decompose() works like escape() with the additional caveat that it inserts
+ parse-able characters to recreate <string> exactly after one parsing. It
+ takes care of multiple spaces, '%r's, and '%t's.
+
+ Someday, perhaps, it will also escape ansi() in a nice way.
+
+ See also: @decompile2
& DECRYPT()
decrypt(<string>, <password>)
extern void look_room(dbref player, dbref loc, enum look_type style);
extern void do_look_around(dbref player);
extern void do_look_at(dbref player, const char *name, int key);
+extern char *decompose_str(char *what);
/* From memcheck.c */
extern void add_check(const char *ref);
#endif
{"CTIME", fun_ctime, 1, 1, FN_REG},
{"DEC", fun_dec, 1, 1, FN_REG},
+ {"DECOMPOSE", fun_decompose, 1, -1, FN_REG},
{"DECRYPT", fun_decrypt, 2, 2, FN_REG},
{"DEFAULT", fun_default, 2, 2, FN_NOPARSE},
{"DELETE", fun_delete, 3, 3, FN_REG},
extern char escaped_chars[UCHAR_MAX + 1];
extern char escaped_chars_s[UCHAR_MAX +1];
+/* ARGSUSED */
+FUNCTION(fun_decompose)
+{
+ /* This function simply returns a decompose'd version of
+ * the included string, such that
+ * s(decompose(str)) == str, down to the last space, tab,
+ * and newline. Except for ansi. */
+ safe_str(decompose_str(args[0]), buff, bp);
+}
+
/* ARGSUSED */
FUNCTION(fun_secure)
{
#include "copyrite.h"
#include <string.h>
+#include <ctype.h>
#include "conf.h"
#include "externs.h"
int skipdef; /**< Skip default flags on attributes if true */
};
+extern char escaped_chars[UCHAR_MAX + 1];
+
+char *
+decompose_str(char *what)
+{
+ static char value[BUFFER_LEN];
+ char *ptr, *s;
+ int len;
+ int dospace;
+
+ len = strlen(what);
+ /* Go through the string, escaping characters and
+ * turning every other space into %b. */
+
+ s = value;
+ ptr = what;
+ /* Put a \ at the beginning if it won't already be put there,
+ * unless it's a space, which would require %b, %r, or %t anyway */
+ if (!escaped_chars[(unsigned int) *what] && !isspace(*what)) {
+ safe_chr('\\', value, &s);
+ }
+ dospace = 1;
+ for (; *ptr; ptr++) {
+ switch (*ptr) {
+ case ' ':
+ if (dospace) {
+ safe_str("%b", value, &s);
+ } else {
+ safe_chr(' ', value, &s);
+ }
+ dospace = !dospace;
+ break;
+ case '\n':
+ dospace = 0;
+ safe_str("%r", value, &s);
+ break;
+ case '\t':
+ dospace = 0;
+ safe_str("%t", value, &s);
+ break;
+ default:
+ if (escaped_chars[(unsigned int) *ptr]) {
+ safe_chr('\\', value, &s);
+ }
+ safe_chr(*ptr, value, &s);
+ dospace = 0;
+ }
+ }
+ /* Now check the last space. */
+ if (*(s - 1) == ' ') {
+ s -= 1;
+ safe_str("%b", value, &s);
+ }
+ *s = '\0';
+ return value;
+}
+
static int
decompile_helper(dbref player, dbref thing __attribute__ ((__unused__)),
dbref parent __attribute__ ((__unused__)),
FUNCTION_PROTO(fun_cwho);
FUNCTION_PROTO(fun_dbwalker);
FUNCTION_PROTO(fun_dec);
+FUNCTION_PROTO(fun_decompose);
FUNCTION_PROTO(fun_decrypt);
FUNCTION_PROTO(fun_default);
FUNCTION_PROTO(fun_delete);