setq()/setr() parallel register setting
authorAri Johnson <ari@cobramush.org>
Tue, 20 Feb 2007 21:50:18 +0000 (21:50 +0000)
committerAri Johnson <ari@cobramush.org>
Tue, 20 Feb 2007 21:50:18 +0000 (21:50 +0000)
game/txt/hlp/cobra_func.hlp
src/function.c
src/funmisc.c

index e1656c4269046d81c8d68082f726b627a5c0afa4..40f8bec2d6a4f46459ab50e99db7191f424b3f39 100644 (file)
@@ -3063,59 +3063,59 @@ for an object named "Test", preferring a thing over other types.
 
 & SETQ()
 & SETR()
-  setq(<register>,<string>)
-  setr(<register>,<string>)
+  setq(<register>,<string>[,<reg2>,<string2>,...])
+  setr(<register>,<string>[,<reg2>,<string2>,...])
   
   The setq() and setr() functions are used to copy strings into local
   registers.  setq() returns a null string; it is a purely "side effect"
-  function.  setr() returns the value stored.
-  
-  There are thirty-six local registers, numbered 0 through 9 and A through Z.
-  They are cleared at the start of each new queue cycle (i.e. whenever
-  a new command is evaluated). They are most useful for storing
-  complex function evaluations which are used repeatedly within a
-  single command.
+  function.  setr() returns the value stored. Multiple registers can be
+  assigned with a single setq() or setr(), with additional pairs of
+  registers and values in the function's arguments. In this case,
+  setr() returns the value stored in the first register listed.
+
+  There are thirty-six local registers, numbered 0 through 9 and A
+  through Z.  They are cleared at the start of each new queue cycle
+  (i.e. whenever a new command is evaluated). They are most useful for
+  storing complex function evaluations which are used repeatedly within
+  a single command.
+
   Registers set via setq() or setr() can be accessed via the r() function, 
   or via the %qN percent-substitution.
-  
+
   See "help SETQ2" for examples of its use.
-  
+
 & SETQ2
-  
+
   The setq() function is probably best used at the start of the string
   being manipulated, such as in the following example:
-  
-    &TEST object=[strlen(%0)]
-    &CMD object=$test *:"[setq(0,u(TEST,%0))]Test. %0 has length [r(0)].
-    test Foo
-    > Object says, "Test. Foo has length 3."
-  
-  In this case, it is a waste to use setq(), since we only use the function
-  result once, but if TEST was a complex function being used multiple times
-  within the same command, it would be much more efficient to use the local
-  register, since TEST would then only be evaluated once.
-  
-  setq() can thus be used to improve the readability of MUSH code, as well
-  as to cut down the amount of time needed to do complex evaluations.
+
+    &TEST object=[strlen(%0)] &CMD object=$test
+    *:"[setq(0,u(TEST,%0))]Test. %0 has length [r(0)].  test Foo >
+    Object says, "Test. Foo has length 3."
+
+  In this case, it is a waste to use setq(), since we only use the
+  function result once, but if TEST was a complex function being used
+  multiple times within the same command, it would be much more efficient
+  to use the local register, since TEST would then only be evaluated once.
+
+  setq() can thus be used to improve the readability of MUSH code, as
+  well as to cut down the amount of time needed to do complex evaluations.
+
   See "help SETQ3" for scoping rules of setq().
-  
+
 & SETQ3
   The registers set by setq() can be used in later commands in the same
   thread.  That is, the registers are set to null on all $-commands,
-  ^-commands, A-attribute triggers, etc., but are then retained from
-  that point forward through the execution of all your code.  Code
-  branches like @wait and @switch retain the register values from the
-  time of the branch, so the code:
-    
+  ^-commands, A-attribute triggers, etc., but are then retained from that
+  point forward through the execution of all your code.  Code branches
+  like @wait and @switch retain the register values from the time of
+  the branch, so the code:
+
   say setr(a,foo); @wait 0=say %qa; say setr(a,bar)
-    
+
   produces the following when executed by an object:
-  
-  Object says "foo"
-  Object says "bar"
-  Object says "foo"
+
+  Object says "foo" Object says "bar" Object says "foo"
 
 & SETUNION()
   setunion(<list1>, <list2>[, <delimiter>][, <sort type>][, <osep>])
index d7a6319a373a79906588a60cbbd5033d86466ab2..3eef453f2ca94e232450c121b17ec0860afd10d3 100644 (file)
@@ -586,8 +586,8 @@ FUNTAB flist[] = {
   {"SECURE", fun_secure, 1, -1, FN_REG},
   {"SENT", fun_sent, 1, 1, FN_REG},
   {"SET", fun_set, 2, 2, FN_REG},
-  {"SETQ", fun_setq, 2, 2, FN_REG},
-  {"SETR", fun_setq, 2, 2, FN_REG},
+  {"SETQ", fun_setq, 2, INT_MAX, FN_REG},
+  {"SETR", fun_setq, 2, INT_MAX, FN_REG},
   {"SETDIFF", fun_setdiff, 2, 5, FN_REG},
   {"SETINTER", fun_setinter, 2, 5, FN_REG},
   {"SETUNION", fun_setunion, 2, 5, FN_REG},
index 738699d7aeb181648769eeafa9b0b80e6a591000..df20f506b87d52a22a268db0a648de0386da5cf5 100644 (file)
@@ -159,15 +159,23 @@ FUNCTION(fun_setq)
 {
   /* sets a variable into a local register */
   int qindex;
+  int n;
 
-  if (*args[0] && (*(args[0] + 1) == '\0') &&
-      ((qindex = qreg_indexes[(unsigned char) args[0][0]]) != -1)
-      && global_eval_context.renv[qindex]) {
-    strcpy(global_eval_context.renv[qindex], args[1]);
-    if (!strcmp(called_as, "SETR"))
-      safe_strl(args[1], arglens[1], buff, bp);
-  } else
-    safe_str(T("#-1 REGISTER OUT OF RANGE"), buff, bp);
+  if ((nargs % 2) != 0) {
+    safe_str(T("#-1 FUNCTION EXPECTS AN EVEN NUMBER OF ARGUMENTS"), buff, bp);
+    return;
+  }
+
+  for (n = 0; n < nargs; n += 2) {
+    if (*args[n] && (*(args[n] + 1) == '\0') &&
+       ((qindex = qreg_indexes[(unsigned char) args[n][0]]) != -1)
+       && global_eval_context.renv[qindex]) {
+      strcpy(global_eval_context.renv[qindex], args[n + 1]);
+      if (n == 0 && !strcmp(called_as, "SETR"))
+       safe_strl(args[n + 1], arglens[n + 1], buff, bp);
+    } else
+      safe_str(T("#-1 REGISTER OUT OF RANGE"), buff, bp);
+  }
 }
 
 /* ARGSUSED */