/**************************************************************************/
/*                                                                        */
/*   ________                                                             */
/*   ()_______)                                                           */
/*    \:::::::\        Make your mark on open source, let people know     */
/*     \:::::::\       what you can do, profit on reputation.             */
/*     @:::::::/                                                          */
/*      ~~~~~~~                                                           */
/* ---------------------------------------------------------------------- */
/*  Scott Auge sauge@amduus.com scott_auge@yahoo.com                      */
/*  Amduus Information Works, Inc.                                        */
/*  www.amduus.com                                                 */
/*                                                                        */
/*  Initial development                                                   */
/*                                                                        */
/* ---------------------------------------------------------------------- */
/*                                                                        */
/**************************************************************************/

/* \$Id: XOR.i 3 2018-24-05 10:01:10Z scott \$ */
/* \$URL: file:///home/scott/svn_rc/repos/trunk/src/demo/XOR.i \$ */

/**************************************************************************/
/* An Exclusive OR routine(s).  When one uses two + n arguments, it XORs  */
/* between all of them that fit in a character.                           */
/* Use must chain with XOR(d,XOR(c,XOR(a,b))) for that to work ie         */
/*  a xor b xor c xor d which is different than xor(a,b,c,d).             */
/* There are examples of use in the unit testing comments at the end of   */
/* the program.                                                           */
/**************************************************************************/

/**************************************************************************/
/* Given a logical using any mnemonic, get it to a value useable by these */
/* tools.                                                                 */
/**************************************************************************/

function LogicalToString returns character (input Truth as logical):

return if Truth then "true" else "false".

end. /* function LogicalToString */

/**************************************************************************/
/* Use this to break apart name-value pairs of the form a=b as character. */
/**************************************************************************/

function NVP returns integer (input NVPair as character,
output TheName as character,
output TheValue as character):

define variable NumberOfEntries as integer no-undo.

assign
NumberOfEntries = num-entries(NVPair, "=")
TheName = ?
TheValue = ?
.

if NumberOfEntries = 2 then
assign
TheName = entry(1, NVPair, "=")
TheValue = entry(2, NVPair, "=")
.

end. /* function NVP () */

/**************************************************************************/
/* Perform an exclusive or operation as defined in                        */
/*   en.wikipedia.org/.../Exclusive_or                           */
/**************************************************************************/

function XOR returns logical (input XORString as character):

define variable NumberOfEntries as integer no-undo.
define variable HasTrue as logical no-undo.
define variable CurrentEntry as integer no-undo.
define variable EntryValue as character no-undo.

assign
NumberOfEntries = num-entries(XORString)
HasTrue = false
.

do CurrentEntry = 1 to NumberOfEntries:

EntryValue = entry(CurrentEntry, XORString).

if EntryValue = "true" and HasTrue then return false.

if EntryValue = "true" then HasTrue = true.

end. /* do CurrentEntry = 1 to NumberOfEntries */

return HasTrue.

end.  /* function XOR () */

/**************************************************************************/
/* Call an XOR with name value pairs seperated by commas.                 */
/**************************************************************************/

function NVPXOR returns logical (input XORString as character):

define variable NumberOfPairs as integer no-undo.
define variable CurrentPair as integer no-undo.
define variable TheName as character no-undo.
define variable TheValue as character no-undo.
define variable ExpressionValue as character no-undo.

NumberOfPairs = num-entries(XORString).

ExpressionValue = "".

do CurrentPair = 1 to NumberOfPairs:

NVP(entry(CurrentPair, XORString), output TheName, output TheValue).

ExpressionValue = if ExpressionValue = "" then TheValue
else ExpressionValue + "," + TheValue.

end. /* do CurrentPair = 1 to NumberOfPairs */

return XOR(ExpressionValue).

end. /* function NVPXOR () */

/******************************************************************

Unit Testing

{XOR.i}

disp LogicalToString(true) LogicalToString(false) LogicalToString(?)
LogicalToString(yes) LogicalToString(no) with frame a.

define variable a as character no-undo.
define variable b as character no-undo.

NVP("name=value", output a, output b).

disp a b with frame b.

disp XOR("true,false,false") XOR("true,false,true") XOR("false,false,false") with frame c.

disp NVPXOR ("t=true,s=false,j=false")
NVPXOR ("t=true,s=false,j=true")
NVPXOR ("t=false,s=false,j=false")
with frame d.

******************************************************************/