The wasStringContainsDigits
returns 1
in case the supplied string contains digits or 0
otherwise.
/*************************************************************************/ /* Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 */ /*************************************************************************/ wasStringContainsDigits: procedure /* True if string contains digits. */ Parse ARG String Do i=0 To 9 If Pos(i, String) ~= 0 Then Return 1 End Return 0
An example call is the following:
If wasStringContainsDigits("V2.3") ~= 1 Then Do Say "The string does not contain digits..." End
The wasGenerateUUIDv4
function takes as input a seed and generates an UUIDv4:
/*************************************************************************/ /* Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 */ /*************************************************************************/ wasGenerateUUIDv4: procedure /* Generates a version 4 UUID. */ Parse ARG Seed UUID = '' Do i = 0 To 35 Select When i = 8 | i = 13 | i = 18 | i = 23 Then UUID = UUID || '-' When i = 14 Then UUID = UUID || '4' When i = 19 Then UUID = UUID || SubStr('89AB', Random(1, 4, Seed)) Otherwise UUID = UUID || D2X(Random(0, 15, Seed)) End End Return UUID
An example call is the following:
Result = wasGenerateUUIDv4(Time(SECONDS)) Say 'Generated UUID: ' Result
Given two sets of words, where the first set consists of numbers and the second set consists of strings, the wasDualQuicksort
function will sort by the numbers while preserving the relative indices between the first set and the second set.
/*************************************************************************/ /* Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 */ /*************************************************************************/ wasDualQuicksort: procedure /* Sorts by the first argument associatively */ Parse ARG Score,Names Count = Words(Score) If Count <= 1 Then Return Space(Score' 'Names, 1) Mid = Trunc(Count/2) PivotS = SubWord(Score, Mid, 1) PivotN = SubWord(Names, Mid, 1) Score = Space(DelWord(Score, Mid, 1), 1) Names = Space(DelWord(Names, Mid, 1), 1) LessS = '' LessN = '' MoreS = '' MoreN = '' Count = Words(Score) Do i = 1 To Count Select When SubWord(Score, i, 1) > PivotS Then Do LessS = SubWord(Score, i, 1)' 'LessS LessN = SubWord(Names, i, 1)' 'LessN End Otherwise Do MoreS = SubWord(Score, i, 1)' 'MoreS MoreN = SubWord(Names, i, 1)' 'MoreN End End End Return Strip(wasDualQuicksort(LessS, LessN)' 'PivotS' 'PivotN' 'wasDualQuicksort(MoreS, MoreN))
For example, a call such as:
Score = '1.5 8 3 17' Names = 'Gogo Moco Coco Jun' Say wasDualQuicksort(Score, Names)
will produce the output:
17 Jun 8 Moco 3 Coco 1.5 Gogo
When you have a several character to replace in a string, the TRANSLATE built-in function works fine:
Say Translate('hellos/world', ' ', '/')
will output:
hellos world
However, when you want to replace a sequence of characters, then the wasReplaceSubString
does this for you:
/*************************************************************************/ /* Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 */ /*************************************************************************/ wasReplaceSubString: procedure /* Replace a sub-string if found. */ Parse ARG String,Search,Insert If Length(String) = 0 Then Return '' i = Pos(Search,String); If i = 0 Then Return String Less = Left(String, i - 1) More = SubStr(String, i + Length(Search)) Return Less || Insert || wasReplaceSubString(More,Search,Insert)
A series of utility functions used by Wizardry and Steamworks in various functions that emulate arrays based on a token sequence that delimits each element.
wasStringCompare
compares two strings by the ASCII values of each character:
1
-1
0
/*************************************************************************/ /* Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 */ /*************************************************************************/ wasStringCompare: procedure /* Compares two strings by ASCII values. */ Parse ARG One,Two Select When One = '' & Two ~= '' Then Return 1 When One ~= '' & Two = '' Then Return -1 When One = '' & Two = '' Then Return 0 Otherwise Nop End a = Upper(Left(One, 1)); b = Upper(Left(Two, 1)); If C2D(a) < C2D(b) Then Return 1 If C2D(a) > C2D(b) Then Return -1 a = Right(One, Length(One)-1) b = Right(Two, Length(Two)-1) Return wasStringCompare(a, b)
/*************************************************************************/ /* Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 */ /*************************************************************************/ wasStringQuicksort: procedure /* Sorts strings separated by token. */ Parse ARG String,Lambda Count = Words(String) If Count <= 1 Then Return String Middle = Trunc(Count/2) Pivot = SubWord(String,Middle,1) String = DelWord(String,Middle,1) Count = Count - 1 Less = '' More = '' Do i = 1 To Count Word = SubWord(String,i,1) Compare = wasStringCompare(Word, Pivot) Select When Compare = 1 Then Select When Less ~= '' Then Less = Less||' '||Word Otherwise Less = Word End Otherwise Select When More ~= '' Then More = More||' '||Word Otherwise More = Word End End End Interpret Lambda Less = wasStringQuicksort(Less,Lambda) More = wasStringQuicksort(More,Lambda) If Less = '' & More ~= '' Then Return Pivot||' '||More If Less ~= '' & More = '' Then Return Less||' '||Pivot Return Less||' ' ||Pivot||' '||More
/*************************************************************************/ /* Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 */ /*************************************************************************/ wasBinarySearch: procedure /* Finds a string within a string by token. */ Parse ARG String,Search,Lambda Count = Words(String) If Count <= 1 Then Return String Pivot = SubWord(String,Trunc(Count/2),1) Index = Find(String,Pivot) Compare = wasStringCompare(Pivot, Search) Select When Compare < 0 Then Do Less = '' Do i = 1 To Index - 1 Word = SubWord(String,i,1) Select When Less ~= '' Then Less = Less||' ' ||Word Otherwise Less = Word End End String = Less End When Compare > 0 Then Do More = '' Do i = Index + 1 To Count Word = SubWord(String,i,1) Select When More ~= '' Then More = More||' ' ||Word Otherwise More = Word End End String = More End Otherwise Return Pivot End Interpret Lambda Return wasBinarySearch(String,Search,Lambda)
/*************************************************************************/ /* Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 */ /*************************************************************************/ wasSortedSetsIntersect: procedure /* Intersects two sorted sets. */ Parse ARG A,B,Lambda If A = '' | B = '' Then Return '' Parse VAR A AHead ' ' ATail Parse VAR B BHead ' ' BTail Interpret Lambda If AHead ~= BHead Then Do Compare = wasStringCompare(AHead, BHead) If Compare < 0 Then Return wasSortedSetsIntersect(A, BTail, Lambda) If Compare > 0 Then Return wasSortedSetsIntersect(ATail, B, Lambda) End Look = wasSortedSetsIntersect(ATail, BTail, Lambda) If Look ~= '' Then Return AHead||' '||Look Return AHead
Given two sets of space-delimited words:
SetA = '2345 Aweet Bram Clipboards Disk.info ENV FMS Gram Ham Jam kketc sdiierr SSFEerr ssqqq T Zam' SetB = 'Disk.info ENV kketc'
The wasSortedSetsSubtract
function subtracts SetB
from SetA
, resulting in:
2345 Aweet Bram Clipboards FMS Gram Ham Jam sdiierr SSFEerr ssqqq T Zam
/*************************************************************************/ /* Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 */ /*************************************************************************/ wasSortedSetsSubtract: procedure /* Subtract two sorted sets: A \ B */ Parse ARG A,B,Lambda If A = '' Then Return '' Parse VAR A AHead ' ' ATail Parse VAR B BHead ' ' BTail Interpret Lambda Select When AHead ~= BHead Then Nop Otherwise Return wasSortedSetsSubtract(ATail, BTail, Lambda) End Return AHead' 'wasSortedSetsSubtract(ATail, B, Lambda)
Since ARexx does not allow replacing a word in a sequence of words, the following trick should work fine:
Search = 'Clipboards ENV FMS T Disk.info Test Bram Gram Ham Jam Zam Aweet 2345 Pooww SSFEerr sdiierr ssqqq kketc' Index = Find(Search, 'FMS') Search = SubWord(Search, 1, Index - 1)||' '||'NewWord'||' '||SubWord(Search, Index + 1) Say Search
The snippet searches the string of words Search
for the word FMS
and grabs the word index. After that, the Search
string of words is rebuilt as a composition of all words before the word FMS
, the new word to be inserted NewWord
and the rest of the remaining words.
Given a set of words, the wasStringInsertSort
function will sort the words and return the resulting set.
/*************************************************************************/ /* Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 */ /*************************************************************************/ wasStringInsertSort: procedure /* Sorts strings of words. */ Parse ARG String Count = Words(String) Do i = 2 To Count Select = SubWord(String, i, 1) j = i Do While j > 1 Previous = SubWord(String, j - 1, 1) If wasStringCompare(Previous, Select) ~= -1 Then Leave String = SubWord(String, 1, j - 1)||' '||Previous||' '||SubWord(String, j + 1) j = j - 1 End If SubWord(String, 1, j) ~= Select Then Do String = SubWord(String, 1, j - 1)||' '||Select||' '||SubWord(String, j + 1) End End Return String
The wasRandomHexString
function returns a random hexadecimal string of a specified size:
/*************************************************************************/ /* Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 */ /*************************************************************************/ wasRandomHexString: procedure /* Generates a random hexadecimal string. */ Parse ARG Seed,Size If Size = 0 Then Return '' Random = Random(0, 15, Size + Seed) Return D2X(Random)||wasRandomHexString(Random, Size - 1)
For example:
Say wasRandomHexString(TIME(SECONDS), 5)
will output a hexadecimal string of length 5
.
Based on the string comparer we can write a merge-sort algorithm for ARexx:
/*************************************************************************/ /* Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 */ /*************************************************************************/ wasStringMergeSortMerge: procedure /* Compares and merges partitions. */ Parse ARG L,R,Lambda If Words(L) = 0 | Words(R) = 0 Then Return L||' '||R Parse VAR L LHead ' ' LTail Parse VAR R RHead ' ' RTail Interpret Lambda If wasStringCompare(LHead, RHead) < 1 Then Return RHead||' '||wasStringMergeSortMerge(L, RTail, Lambda) Return LHead||' '||wasStringMergeSortMerge(LTail, R, Lambda) /*************************************************************************/ /* Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 */ /*************************************************************************/ wasStringMergeSort: procedure /* Merge sort a set of words. */ Parse ARG String,Lambda Count = Words(String) If Count <= 1 Then Return String Middle = Trunc(Count/2) Interpret Lambda L = wasStringMergeSort(SubWord(String, 1, Middle), Lambda) R = wasStringMergeSort(SubWord(String, Middle+1), Lambda) Return wasStringMergeSortMerge(L, R, Lambda)
Given some input words, we can call wasStringMergeSort
on the set of input words:
Search = 'Clipboards ENV FMS T Disk.info Test Bram Gram Ham Jam Zam Aweet 2345 Pooww SSFEerr sdiierr ssqqq kketc' Say wasStringMergeSort(Search)
which produces the result:
2345 Aweet Bram Clipboards Disk.info ENV FMS Gram Ham Jam kketc Pooww sdiierr SSFEerr ssqqq T Test Zam
Following conversations with Stefan Haubenthal, here are some functions that encode to Base64 strings and decode Base64 strings. Note that these functions do not account for the CR LF
that must be added at the 76th character in order to conform to MIME however once you have the encoded strings it is easy to just split them on the 76th character and insert the CR LF
yourself.
Here is an example call of both functions:
String = 'Good day!' Encoded = wasBase64Encode(String) Say 'Encoded: 'Encoded Decoded = wasBase64Decode(Encoded) Say 'Decoded: 'Decoded
/*************************************************************************/ /* Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 */ /*************************************************************************/ wasBase64Encode: procedure /* Encodes a string into Base64. */ Parse ARG String If Length(String) = 0 Then Return '' Pad = "" Do While Length(String) // 3 ~= 0 String = String||X2C(0) Pad = Pad||'=' End Count = Length(String) BinaryString = '' Do i = 1 To Count BinaryString = BinaryString||C2B(SubStr(String, i, 1)) End b64 =, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' Count = Length(BinaryString) Result = '' Do i = 1 To Count By 6 Result = Result||, SubStr(b64, C2D(B2C("00"SubStr(BinaryString, i, 6))) + 1, 1) End Return SubStr(Result, 1, Length(Result) - Length(Pad))||Pad
/*************************************************************************/ /* Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 */ /*************************************************************************/ wasBase64Decode: procedure /* Decodes a Base64 string. */ Parse ARG String Count = Length(String) If Count = 0 Then Return '' Pad = '' Select When SubStr(String, Count-1, 2) = '==' Then Pad = 'AA' When SubStr(String, Count, 1) = '=' Then Pad = 'A' Otherwise Nop End String = SubStr(String, 1, Length(String) - Length(Pad))||Pad b64 =, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' Count = Length(String) Result = '' Do i = 1 To Count By 4 b1 = Pos(SubStr(String, i, 1), b64) - 1 b2 = Pos(SubStr(String, i+1, 1), b64) - 1 b3 = Pos(SubStr(String, i+2, 1), b64) - 1 b4 = Pos(SubStr(String, i+3, 1), b64) - 1 r1 = b1 * 4 + b2 % 16 r2 = 16 * (b2 // 16) + (b3 % 4) r3 = 64 * (b3 // 4) + b4 Result = Result||D2C(r1)||D2C(r2)||D2C(r3) End Return SubStr(Result, 1, Length(Result) - Length(Pad))
The wasGenerateStringSequence
function generates string sequences starting with a string and provided a number of increments to perform. The starting string can be alpha-numeric.
/*************************************************************************/ /* Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 */ /*************************************************************************/ wasGenerateStringSequence: procedure /* Generate a string sequence. */ Parse ARG First,Count,X If Count = 0 Then Return '' If Length(X) ~= 1 Then Return First||" "||wasGenerateStringSequence(First, Count - 1, 1) Result = '' c = 1 Length = Length(First) Do While Length ~= 0 x = SubStr(First, Length, 1) Select When DataType(x) = 'NUM' Then Do Sum = x + c Select When Sum > 9 Then Do Result = 0||Result c = 1 End Otherwise Do Result = Sum||Result c = 0 End End End Otherwise Do Sum = D2C(C2D(x) + c) Select When Sum > 'z' Then Do Result = 'a'||Result c = 1 End Otherwise Do Result = Sum||Result c = 0 End End End End Length = Length - 1 End If c ~= 0 Then Result = c||Result If Count - 1 = 0 Then Return Result Return Result||" "||wasGenerateStringSequence(Result, Count - 1, 1)
For example, a call such as:
Say wasGenerateStringSequence("0yz8", 3)
Will output the following three sequential words:
0yz8 0yz9 0za0
The generator follows the rules:
z
, then the previous number or letter in the sequence is incremented9
, the the previous number or letter in the sequence is incrementedHere is another example call that demonstrates the extension of the string by one:
Say wasGenerateStringSequence("9z", 30)
that outputs the words:
9z 10a 10b 10c 10d 10e 10f 10g 10h 10i 10j 10k 10l 10m 10n 10o 10p 10q 10r 10s 10t 10u 10v 10w 10x 10y 10z 11a
wasShiftLeft
shifts left c
by n
bits.wasShiftRight
shifts right c
by n
bits./*************************************************************************/ /* Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 */ /*************************************************************************/ wasShiftLeft: procedure /* logical shift left of c by n bits */ Parse ARG c,n Return Right(D2C(C2D(c) * 2 ** n), 1)
/*************************************************************************/ /* Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 */ /*************************************************************************/ wasShiftRight: procedure /* logical shift right of c by n bits */ Parse ARG c,n Return D2C(C2D(c) % 2 ** n)