This is three main scripts that are useful for working with bit-flags until Don blesses use with some bitwise operators.
Included Scripts:
Demo -- demo
Just a small demo of this library's capabilities.
Combine Flags Example -- combineExample
Extract Flags Example -- extractExample
Expand Flags Example -- expandExample
These just show some simple code examples of using the scripts.
Combine Flags -- _combine
Converts a list of global flag/boolean variable names into an OR-ed bitwise value.
Extract Flags -- _extract
Takes an OR-ed bitwise value and a list of global flag/boolean variable names and it will set them appropriately.
Expand Flags -- _expand
Takes an OR-ed bitwise value and sets some generic global flag/boolean variables appropriately.
$G_BIT_COUNT gets the count of flag variables.
$G_BIT_1 through $G_BIT_N are the flag variables.
Code: Select all
/*#############################################################################\
BitFlag.xys
Library for working with bit flags.
[ABOUT]
Author = TheQwerty
Version = 1.0
Date = 2014-10-29 19:30z
Requires = XYplorer v14.50.0000
[]
\#############################################################################*/
/*******************************************************************************
** Demo
** Walks through a small demo of this library's scripts.
*******************************************************************************/
"&Demo||1 : demo"
// Prompt for flag value to expand/extract.
Global $G_FLAGS = Input('OR-ed Bitwise Value', "Enter the value to examine<crlf>This can even be a simple mathematical equation. i.e. '1+2+4'", '1+2+16', 's');
// Accept expressions by evaluating input.
$flagValue = $G_FLAGS;
$G_FLAGS = Eval($G_FLAGS);
// Expand G_FLAGS to G_BIT_# vars.
Sub '_expand';
Global $G_BIT_COUNT;
// Collect G_FLAGS information & expand header.
$result = 'G_FLAGS = ' . $flagValue;
if ($flagValue != $G_FLAGS) {
$result = $result . " = $G_FLAGS";
}
$result = $result . "<crlf 2>Results of Expand Flag:<crlf>G_BIT_COUNT = $G_BIT_COUNT<crlf>";
Unset $flagValue;
// Collect expand results.
$i = 1;
while ($i <= $G_BIT_COUNT) {
$var = '$G_BIT_' . $i;
Global *$var;
$result = $result . $var . ' = ' . (*$var) . "<crlf>";
$i++;
}
Unset $i, $G_BIT_COUNT, $var;
// Prompt for variables to extract to/combine.
Global $G_VARS = Input('Variable Names', "Enter a |-separated list of variable names to store flags in.<crlf>The leading '$' is optional and unwanted flags can be left empty.", '$oneSet|$twoSet|$fourSet||$sweetSet', 's');
// Extract G_FLAGS to G_VARS.
Sub '_extract';
// Collect extract header.
$result = $result . "<crlf 3>Results of Extract Flags:<crlf>G_VARS = " . $G_VARS . "<crlf 2>";
// Collect extract results from specified vars.
foreach ($var, $G_VARS, '|') {
if ($var == '') { continue; }
if ($var UnLikeI '$*') { $var = '$' . $var; }
Global *$var;
$result = $result . $var . ' = ' . (*$var) . "<crlf>";
}
Unset $var;
$G_FLAGS = 0;
// Run combine on G_VARS.
Sub '_combine';
// Collect combine header & results.
$result = $result . "<crlf 3>Results of Combine Flags:<crlf>G_FLAGS = " . $G_FLAGS . "<crlf>Note that if G_VARS does not include all set bits this value will not match the original.";
// Share results.
Text $result;
/******************************************************************* END demo */
"-" //--------------------------------------------------------------------------
/*******************************************************************************
** Combine Flags Example
** Show usage example.
*******************************************************************************/
"&Combine Flags Example : combineExample"
$myPath = Self('file');
if ($myPath != '') {
$myPath = ResolvePath($myPath, <xyscripts>, 1);
} else {
$myPath = 'BitFlag';
}
Text <<<EXAMPLE
The following example demonstrates how to use the Combine Flags script to
convert a list of global binary flag variables into a single OR-ed value.
_combine parameters:
Input: Global $G_VARS
A |-separated list of variable names to combine.
- Each variable must be global and should be set to true (1) or false (0).
- The list starsts with bit-value 1, then 2, 4, 8, 16, etc.
- Omitting variable names (not positions) treats those as false.
- The leading '$' is optional.
- Variable names are trimmed of spaces before use.
- Note that if a variable shares a name with one used locally by _combine
an error will occur.
Output: Global $G_FLAGS
The result of OR-ing each flag variable within $G_VARS.
--------------------------------------------------------------------------------
"Combine Flags Example"
// Use global flag variables.
Global $hasXYplorer = true; // Bit value: 1
Global $hatesXY = false; // Bit value: 2
Global $isAwesome = true; // Bit value: 4
// CALL TO COMBINE:
// Input: List of global variable names to combine.
Global $G_VARS = 'hasXYplorer|hatesXY|isAwesome';
// Make sure to adjust the path to BitFlag if needed.
Load '$myPath', '_combine', 'f';
// Return:
Global $G_FLAGS;
Echo "The OR-ed value is $G_FLAGS - it should be 5.";
EXAMPLE
, /*width*/, /*height*/, 'Example usage of Combine Flags';
/********************************************************* END combineExample */
/*******************************************************************************
** Extract Flags Example
** Show usage example.
*******************************************************************************/
"&Extract Flags Example : extractExample"
$myPath = Self('file');
if ($myPath != '') {
$myPath = ResolvePath($myPath, <xyscripts>, 1);
} else {
$myPath = 'BitFlag';
}
Text <<<EXAMPLE
The following example demonstrates how to use the Extract Flags script to
set a list of global binary flag variables from a single OR-ed value.
_extract parameters:
Input: Global $G_FLAGS
An OR-ed value to extract to the variables specified in G_VARS.
Input: Global $G_VARS
A |-separated list of variable names to set.
- Each variable will be made global and set to true (1) or false (0).
- The list starts with bit-value 1, then 2, 4, 8, 16, etc.
- Omitting variable names (not positions) will skip those bits.
- The leading '$' is optional.
- Variable names are trimmed of spaces before use.
Output:
The variables specified in G_VARS will be made global and set accordingly.
--------------------------------------------------------------------------------
"Extract Flags Example"
// Existing flag value.
$flag = 5;
// CALL TO EXTRACT:
// Input: Flag value.
Global $G_FLAGS = $flag;
// Input: List of global variables to set.
Global $G_VARS = 'hasXYplorer|hatesXY|isAwesome';
// Make sure to adjust the path to BitFlag if needed.
Load '$myPath', '_extract', 'f';
// Returns:
Global $hasXYplorer;
Global $hatesXY;
Global $isAwesome;
Echo <<<MSG
Has XYplorer = $hasXYplorer
Hate It = $hatesXY
Is Awesome = $isAwesome
MSG;
EXAMPLE
, /*width*/, /*height*/, 'Example usage of Extract Flags';
/********************************************************* END extractExample */
/*******************************************************************************
** Expand Flags Example
** Show usage example.
*******************************************************************************/
"E&xpand Flags Example : expandExample"
$myPath = Self('file');
if ($myPath != '') {
$myPath = ResolvePath($myPath, <xyscripts>, 1);
} else {
$myPath = 'BitFlag';
}
$fakeCRLF = '<crlf>';
Text <<<EXAMPLE
The following example demonstrates how to use the Expand Flags script to
expand a single OR-ed value into a set of global variables.
_expand parameters:
Input: Global $G_FLAGS
An OR-ed value to extract into a set of flag variables.
Output: Global $G_BIT_COUNT
The number of global G_BIT_# variables used.
Output: Global $G_BIT_#
For each bit-value there will be a corresponding $G_BIT_# variable.
Example output for G_FLAGS = 1+4
G_BIT_COUNT = 3
G_BIT_1 = 1 // Flag 1
G_BIT_2 = 0 // Flag 2
G_BIT_3 = 1 // Flag 4
--------------------------------------------------------------------------------
"Expand Flags Example"
// Existing flag value.
$flag = 5;
// CALL TO EXPAND:
// Input: Flag value.
Global $G_FLAGS = $flag;
// Make sure to adjust the path to BitFlag if needed.
Load '$myPath', '_expand', 'f';
// Return: Count of global bit variables set.
Global $G_BIT_COUNT;
$i = 1;
$msg = '';
while ($i <= $G_BIT_COUNT) {
// Return: For each bit there is a G_BIT_# global variable.
$varName = '$G_BIT_' . $i;
Global *$varName;
$msg = $msg . 'G_BIT_' . $i . ' = ' . (*$varName) . "$fakeCRLF";
$i++;
}
Echo $msg;
EXAMPLE
, /*width*/, /*height*/, 'Example usage of Expand Flags';
/********************************************************** END expandExample */
"- : _-" //---------------------------------------------------------------------
"- : _-" //---------------------------------------------------------------------
/*******************************************************************************
** Combine Flags
** Converts a set of global flag variables into an OR-ed bitwise value.
*******************************************************************************/
"Combine Flags||4 : _combine"
// -------------------- PARAMETERS -------------------------------------------
// IN: G_VARS
// A |-separated list of variable names to combine.
// - Each variable must be global and should be set to true (1) or false (0).
// - The list starts with bit-value 1, then 2, 4, 8, 16, etc.
// - Omitting variable names (not positions) treats those bits as false.
// - The leading '$' is optional.
// - Variable names are trimmed of spaces before use.
// - Note that if a variable share a name with one used locally by this
// script an error will occur.
// Examples:
// // Combines flags one, two, and four.
// $G_VARS = '$flagOne|$flagTwo|$flagFour';
// // Combines flags two (checkboxes) and eight (genericIcons) only,
// // treats flags one and three as false.
// $G_VARS = '|checkboxes||genericIcons';
Global $G_VARS;
// OUT: G_FLAGS
// The OR-ed bitwise value of the global variables in G_VARS.
Global $G_FLAGS = 0;
// -----------------END PARAMETERS -------------------------------------------
// Parameter validation.
Assert $G_VARS != '', 'G_VARS must contain a |-separated list of variable names.';
$varCount = GetToken($G_VARS, 'Count', '|');
Assert $varCount > 0, 'G_VARS must contain a |-separated list of variable names.';
$flagValue = 0;
$localVars = <<<LOCALVARS
$bitValue
$flagValue
$G_FLAGS
$G_VARS
$i
$localVars
$varCount
$varName
LOCALVARS;
// For each variables in G_VARS.
$i = 1;
while ($i <= $varCount) {
// Get everything that depends on $i done with early.
$bitValue = 2^($i-1);
$varName = GetToken($G_VARS, $i, '|', 't');
$i++;
// Empty names are assumed to be false.
if ($varName == '') { continue; }
// Smartness to add '$' if missing.
if ($varName UnLikeI '$*') { $varName = '$' . $varName; }
//
Assert GetTokenIndex($varName, $localVars, "<crlf>", '') == 0, "Sorry, variable $varName is used locally and cannot be used in G_VARS.";
// NOTE: Non-global variables are assumed false.
Global *$varName;
// Add the bit if it is true.
if (*$varName) {
$flagValue = $flagValue + $bitValue;
}
}
Unset $varCount, $localVars, $i, $bitValue, $varName;
Global $G_FLAGS = $flagValue;
Unset $flagValue;
/*************************************************************** END _combine */
/*******************************************************************************
** Extract Flags
** Sets global flag variables based on an OR-ed bitwise value.
*******************************************************************************/
"Extract Flags||4 : _extract"
// -------------------- PARAMETERS -------------------------------------------
// IN: G_FLAGS
// An OR-ed value to extract to the variables specified in G_VARS.
Global $G_FLAGS;
// IN: G_VARS
// A |-separated list of variable names to set.
// - Each variable will be made global and set to true (1) or false (0).
// - The list starts with bit-value 1, then 2, 4, 8, 16, etc.
// - Omitting variable names (not positions) will skip those bits.
// - The leading '$' is optional.
// - Variable names are trimmed of spaces before use.
// Examples:
// // Retrieves flags one, two, and four.
// $G_VARS = '$flagOne|$flagTwo|$flagFour';
// // Retrieves flags two (checkboxes) and eight (genericIcons) only.
// $G_VARS = '|checkboxes||genericIcons';
Global $G_VARS;
// -----------------END PARAMETERS -------------------------------------------
// Parameter validation.
Assert RegexReplace($G_FLAGS, '^[0-9]+$') == '', 'G_FLAGS must be a non-negative integer.';
Assert $G_VARS != '', 'G_VARS must contain a |-separated list of variable names.';
$varCount = GetToken($G_VARS, 'Count', '|');
Assert $varCount > 0, 'G_VARS must contain a |-separated list of variable names.';
// Leave the global value untouched.
$flagValue = $G_FLAGS;
// Determine how many bits are needed.
$bits = 1;
while (true) {
$max = (2^$bits)-1;
if ($max >= $flagValue) {
break;
}
$bits++;
}
Unset $max;
// Set unneeded variable names to false.
while ($varCount > $bits) {
$varName = GetToken($G_VARS, $varCount, '|', 't');
$varCount--;
// Skip setting empty variables.
// This allows a G_VARS like 'one||four'
if ($varName == '') { continue; }
// Smartness to add '$' if missing.
if ($varName UnLikeI '$*') { $varName = '$' . $varName; }
Global *$varName = false;
}
Unset $varCount, $varName;
// For each bit - in reverse.
while ($bits >= 1) {
$bitValue = 2^($bits-1);
$varName = GetToken($G_VARS, $bits, '|', 't');
// Get this done with so we can 'continue' later.
$bits--;
// Check if bit is set and if so remove it from flags.
$isSet = $flagValue >= $bitValue;
if ($isSet) {
$flagValue = $flagValue - $bitValue;
}
// Skip setting empty variables.
// This allows a G_VARS like 'one||four'
if ($varName == '') { continue; }
// Smartness to add '$' if missing.
if ($varName UnLikeI '$*') { $varName = '$' . $varName; }
Global *$varName = $isSet;
}
Unset $flagValue, $bits, $varName, $bitValue, $isSet;
/*************************************************************** END _extract */
/*******************************************************************************
** Expand Flags
** Expands an OR-ed bitwise value into a set of flag variables.
**
** This will determine how many bits are needed for the specified value and
** save this to the global variable G_BIT_COUNT.
**
** Then for each bit it will save whether or not it is set to a global
** variable G_BIT_# where # is the position of the bit.
**
** Example output for G_FLAGS = 1+4
** G_BIT_COUNT = 3
** G_BIT_1 = 1 // Flag 1
** G_BIT_2 = 0 // Flag 2
** G_BIT_3 = 1 // Flag 4
*******************************************************************************/
"Expand Flags||4 : _expand"
// -------------------- PARAMETERS -------------------------------------------
// IN: G_FLAGS
// An OR-ed value to extract to G_BIT_# variables.
Global $G_FLAGS;
// -----------------END PARAMETERS -------------------------------------------
// Parameter validation.
Assert RegexReplace($G_FLAGS, '^[0-9]+$') == '', 'G_FLAGS must be a non-negative integer.';
// Leave the global value untouched.
$flagValue = $G_FLAGS;
// Determine how many bits are needed.
$bits = 1;
while (true) {
$max = (2^$bits)-1;
if ($max >= $flagValue) {
break;
}
$bits++;
}
Unset $max;
// Share count as G_BIT_COUNT.
$varName = '$G_BIT_COUNT';
Global *$varName = $bits;
// Share the value of each bit as $G_bit#
while ($bits >= 1) {
$varName = '$G_BIT_' . $bits;
$bitValue = 2^($bits-1);
Global *$varName = $flagValue >= $bitValue;
if (*$varName) {
$flagValue = $flagValue - $bitValue;
}
$bits--;
}
Unset $flagValue, $bits, $varName, $bitValue;
/**************************************************************** END _expand */