Version 7.4 of the Sirius Mods was released in February, 2009.
This was an interim release only available to the Beta testers of Model 204 V7R1.
It is no longer available and its features will be documented as part of the
Sirius Mods Version 7.5.
Sirius Mods Version 7.3
Version 7.3 of the Sirius Mods was released in October, 2008.
Please refer to the
Notes for Sirius Mods Version 7.3 for more detailed information.
Supported Model 204 Versions
Sirius Mods version 7.3 supports only Model 204 V6R1.
Documentation
The
Sirius Mods Command and Parameter Reference Manual
is now available; it describes all Model 204 commands and parameters
and Model 204 Editor commands which are implemented as part of the Sirius Mods.
The Janus Network Security Reference Manual and the
HTML pages of the SSL certificate management application are copyedited as well as updated to include
information about client certificates and intermediate server certificates.
The FloatNamedArray class that has been available since the earliest releases of
the Janus SOAP ULI is now documented in the
Janus SOAP Reference Manual.
All or Multiple Products
Several Janus SOAP classes available to all
A number of Janus SOAP classes are now available to any Sirius Mods version 7.3 customer.
The following classes are not restricted to those with a Janus SOAP license:
String, Float, and Unicode intrinsic
StringList
CharacterMap
StringTokenizer
New Model 204 parameters
Two new parameters that affect Model 204 retrieve key processing
are added.
RETRVBUF
This User 0 parameter specifies the size of the buffer
for the 3270 terminal PF key that retrieves previously input command lines.
The larger the retrieve buffer, the more commands you can save for retrieval.
The minimum and default setting of RETRVBUF is 288 bytes, and its maximum is 32767.
The parameter setting is always rounded
down to the nearest 8-byte multiple, so the largest buffer allowed is
actually 32760 bytes.
RETRVOPT
This user parameter is a bitmask parameter that controls some characteristics of the
Model 204 retrieve key.
The RETRVOPT bits are:
X'01'
The PF key that is 1 higher than the RETRVKEY setting is mapped
to a forward retrieval operation, which
returns the command in the retrieve buffer that follows the one that is currently
displayed.
For example, if this X'01' bit is set, and RETRVKEY is set to 6,
PF7 will be a forward retrieve key.
X'02'
The forward and backward retrieve keys will not wrap.
With this bit set,
if you retrieve all the commands stored in the retrieve buffer,
your next retrieval is a blank (instead of wrapping to the beginning of the
retrieval ring, as was the behavior prior to the availability of the RETRVOPT
parameter).
X'04'
Do not add to the retrieve buffer any text typed in response to a screen-full
prompt.
For example,
if you issue a VIEW, then type C or K to
stop the output, the C or K
is added to the retrieve buffer — unless RETRVOPT X'04' is set.
RETRVOPT X'04' also prevents N, NP,
or NEW commands
(which clear the screen) from being added to the retrieve buffer.
X'10'
If the X'01' bit is also set, RETRVOPT X'10' maps the
forward retrieve key to the PF key that is 12 greater than the current
retrieve key (setting of RETRVKEY).
This will be the shifted version of the current retrieve key if that current
key is less than PF13, and it will be the non-shifted version if that key is
greater than PF12.
For example, if RETRVOPT is set to X'17' and RETRVKEY is 12,
the forward retrieve key is PF24.
And if RETRVOPT is set to X'17' and
RETRVKEY is 21 (Shift+PF9), the forward retrieve key is PF9.
New bit settings for the FUNCOPTS system parameter
Two new FUNCOPTS bit settings
allow a site to ease or eliminate the restrictions on who can use
the $PRIORTY function to change another user's priority:
The X'40' bit means that any user can issue the
$PRIORTY function.
The X'20' bit means that a procedure invoked via the
NEWSESCMD facility can use $PRIORTY function.
If neither of these bits
is set, then only a System Manager or System Administrator can use the
$PRIORTY function.
New default for the SCRNSTBL user parameter
The default value of SCRNSTBL is increased from 4096 to 6144.
Enhancement to Sirius regex
The following feature is added to the Sirius regular expression support (the regex methods
in the StringList and String intrinsic class, and the $RegexMatch and $RegexReplace $functions).
The regex support is summarized in the “Regex Processing” chapters
in the Janus SOAP Reference Manual and the
Sirius Functions Reference Manual.
Support is added for the \b and \B multi-character escape
sequences.
They operate as they do under the Perl language.
Janus SOAP ULI
The following sections describe changes in the Janus SOAP ULI
in this release.
New system classes
Three “smaller,” unrelated, system classes have been added.
These are all documented in the Janus SOAP Reference Manual.
RandomNumberGenerator class
As its name suggests, the RandomNumberGenerator class
is designed to generate random numbers.
It is patterned after the Sirius functions $Random and $Random_Seed, described
in the Sirius Functions Reference Manual.
The methods in the class include a New constructor to instantiate an object,
a Value method for printing as well as constraining the random number value
range, and an UpdateSeed method to reset the value of an object.
As an example, the methods in this request create a reproducible sequence of ten numbers
between 0 and 99:
b
%rand is object randomNumberGenerator
%i is float
%rand = new(seed='abcd')
for %i from 1 to 10
printtext {~} = {%rand:value(0, 99)}
end for
end
CharacterMap class
A CharacterMap class object contains a mapping of characters to characters.
Each character in an In string
(the “input table”) is associated with, or mapped to, an individual character
from an Out string (the “output table”).
The output table may be supplemented with instances of a pad character
to ensure a one-to-one mapping with the input table characters.
CharacterMap includes a constructor, copy methods, and an update method
for modifying the map.
Most of these methods are shown in the following example,
which features the Translate method for longstrings (Translate function).
In the example, a new CharacterMap is the argument for the Translate method;
then that map is copied and modified, and the modified map is used in a
second Translate call:
begin
%map is object characterMap
%map2 is object characterMap
%ls is longstring
%map = new(in='x-', out='!c')
%ls = 'xu--exx'
printtext {~} = '{%ls:translate(%map)}'
%map2 = %map:copy
%map2:update(in='x',out='s')
printtext {~} = '{%ls:translate(%map2)}'
end
Intended for performance work, the UserStatistics class
is designed to replace $STAT and similar tools that return the
values for selected Model 204 User statistics.
The UserStatistics constructor takes a snapshot of the user stat block at the
time the constructor is invoked.
You then use the UserStatistics methods to extract
the statistical data from the instantiated object.
The object holds two types of user statistics:
Login and Request.
Login statistics (also called “Final”) are those that keep
data per user since the user's most recent login.
The statistics available to the Model 204 $STAT function,
as well as the OBJSWAP statistic for Janus SOAP objects, are valid.
Request statistics are a combination of:
Statistics that keep the
current high-water marks for some work tables per user.
Model 204 documentation includes these with “since last” statistics.
Since last statistics, which keep data per user comprising
only the user's most recent work unit (like compilation or evaluation);
they are not accumulated.
Login and Request statistics are not mutually exclusive.
Both Login and Request data are kept for some activities, so many
statistics appear in lists of both types and are valid in all methods
that are restricted to one type or the other.
The Model 204 System Manager's Guide
and the SirMon User's Guide are good sources of information
about the available statistics, although not all statistics shown in the
SirMon User's Guide are included in a UserStatistics object.
Where they occasionally differ in spelling the name of a statistic, the
Model 204 System Manager's Guide
is more likely to have the spelling required by the UserStatistics methods.
You can also view all the individual statistics contained in a UserStatistics
object by applying the ToString method to it, as follows:
%statobject:ToString(Zeros=true)
The longstring output from this ToString method invocation displays all
the Login statistics followed by all the Request statistics.
Note:
The ToString method shown above can be applied implicitly:
simply print or audit an object variable, and
the ToString method is automatically applied to the object.
Print %statobject is equivalent to Print %statobject:ToString.
The following is a simple example that
shows how much CPU a request uses and how many DKRDs it did:
b
%statStart is object userStatistics
%statEnd is object userStatistics
%statStart = new
%statEnd = new
printText CPU: {%statEnd:difference(%statStart, 'CPU')}
printText DKRDs: {%statEnd:difference(%statStart, 'DKRD')}
end
Specifying a statistic that is not a User statistic, or that is not the type of statistic
(Login or Request) that a method calls for, triggers an UnknownStatistic exception.
The StringTokenizer class
The StringTokenizer class is used to divide an input string (method object) into
substrings (tokens).
The tokens are separated by either of two types of delimiters:
Delimiters that are not tokens themselves
(analogs of whitespace and quotation-mark characters in the English language)
Delimiters that are also tokens themselves
(token-characters, that may be of interest or significance, like a character escape, for example)
A token is thus a sequence of
consecutive characters that are not delimiters, or it is
a single token-delimiter character.
The delimiters are user definable, are
specified per StringTokenizer object at creation time, and can be modified thereafter.
StringTokenizer operations maintain two positions within the
method object string:
The location of the most recent token's first
character (the “current token position”)
The location from which to begin parsing for the next token
(the “tokenizing position”)
You can also explicitly modify these positions individually.
To navigate the simplest path through the given string, you
“walk” forward (left to right) from the beginning of the string using token-sized
steps (that is, from whole token to next whole token to next whole token, and so on).
The following is a simple example of this in which three tokens are separated
by blank, non-token delimiters:
%tok = new
%tok:string = 'a tokenization example'
%tok:nextToken
%tok:nextToken
%tok:nextToken
Each of the NextToken method calls above returns a token:
respectively, “a”, “tokenization”,
and “example”.
The StringTokenizer class also has methods that let you take character-sized steps
forward in the string, as well as methods that let you modify the position markers
and thereby select tokens or sub-tokens in the order you require.
You can also locate specified tokens, and you can return substrings that are
the characters in the entire string that precede a position or that follow a position.
The StringTokenizer class methods include:
AtEnd function
This method returns a Boolean value that indicates whether
the present tokenizing position is immediately after the last token.
The value is True if the position at after the last token;
otherwise it is False.
CurrentQuoted function
This method returns a Boolean value that indicates whether
the current token is a quoted token.
A quoted token contains all the characters between a pair of identical
quotation characters.
The CurrentQuoted value is True if the current token is quoted;
otherwise it is False.
CurrentToken function
This method returns the string value of the current token.
The current token is typically the most recent token
returned by the NextToken or FindToken function. n
CurrentToken is invalid and cancels the request until one of these calls has been made.
You can also update the current token by explicitly setting the CurrentTokenPosition value.
CurrentTokenPosition property
This readWrite property returns or sets the position of the first character in
the current token.
If you change the current token (by invoking NextToken or FindToken),
CurrentTokenPosition is updated with a new value.
If you explicitly set CurrentTokenPosition, the current token value is adjusted accordingly.
FindToken function
This callable method returns a Boolean value that indicates whether
it finds a specified token.
The value is True if the token is found; otherwise it is False.
The search starts from the tokenizing position, the value of which is returned by NextPosition.
If the token is found, the position in the string is advanced past the found token, and CurrentToken
will return the found token.
Otherwise, AtEnd is set to True, and CurrentToken is set to the last token at the end of the string.
The delimiters that are involved in determining the tokens
are set initially by the New method that instantiates the StringTokenizer object.
The delimiters can be modified by the Spaces, Quotes, and and TokenChars methods.
New constructor
This method returns a new instance of a StringTokenizer object.
It has three optional arguments that let you specify the delimiter characters
that determine the tokens in the string that is being tokenized.
NextChar function
This method returns the value of the character that is at the tokenizing position,
and it advances the tokenizing position past that character to the next character.
The tokenizing position is the value returned by the NextPosition property.
NextPosition property
This readWrite property returns or sets the tokenizing position, the position of the character
from which the parsing of the next token begins.
Unless you explicitly set it otherwise, the tokenizing position is the position that follows the
(last) character in the value returned by the most recent call of NextToken, FindToken or NextChar.
NextToken function
This method returns the string value of the next token forward in the current tokenizer string.
The next token parsing begins from the tokenizing position, which is the value returned by NextPosition.
When the next token is determined, NextToken advances the tokenizing position
to the position following that token, then returns the token value.
The delimiters that are involved in determining the tokens
are set initially by the New method that instantiates the StringTokenizer object.
The delimiters can be modified by the Spaces, Quotes, and TokenChars methods.
NotAtEnd function
This method returns a Boolean value that indicates whether or not
the present tokenizing position is after the last token in the tokenizer string.
The value is True if the position is not after the
last token; otherwise it is False.
The tokenizing position is given by NextPosition.
PeekChar function
This method returns the value of the character that is at the tokenizing position.
The tokenizing position is the value returned by NextPosition.
After returning the character value, PeekChar does not advance the tokenizing position,
which remains what it was when PeekChar was called.
PeekToken function
This method returns the string value of the next token forward in the current tokenizer string.
The next token parsing begins from the tokenizing position, which is the value returned by NextPosition.
When the next token is determined, PeekToken does not advance the tokenizing position,
which remains what it was when PeekToken was called.
The delimiters that are involved in determining the tokens are set initially by the New method
that instantiates the StringTokenizer object.
The delimiters can be modified by the Spaces, Quotes, and TokenChars methods.
Quotes property
This readWrite property returns or sets the characters that are recognized as quotation characters.
The text between each disjoint pair of identical quotation characters (a “quoted region”)
is treated as a single token, and any delimiter characters (Quote, Space, or TokenChar)
within a quoted region are treated as non-delimiters.
RemoveQuotes property
This readWrite property returns or sets the Boolean value that indicates
whether to remove the quote characters from the returned values of quoted tokens.
The default value for a new tokenizer is True.
RestOfString function
This method returns the current non-tokenized substring of the tokenizer string.
This substring starts from the position after the next token,
and it includes the remaining characters going forward to the end of the string.
Spaces property
This readWrite property returns or sets the characters that are recognized as
“whitespace”characters, that is, as characters that separate tokens.
Such a character is also called a “non-token delimiter,”
because it is a delimiter that is not itself a token.
You can specify “token delimiters,” which are delimiters that are also tokens,
using the TokenChars method or the New constructor TokenChars parameter.
One or multiple consecutive whitespace characters mark the end or beginning
of a token, except when these spaces are part of a quoted region.
In that case, the spaces become non-delimiters.
StartOfString function
This method returns the substring of the tokenizer string
that precedes the first character of the current token.
String property
This readWrite property returns or sets the string to be tokenized.
StringLength function
This method returns the length of the current tokenizing string.
This string is the value of the String method.
SubString function
This function returns a substring that is a specified length and starts at a specific
position in the tokenizing string.
The substring may be padded on the right.
TokenChars property
This readWrite property returns or sets the characters that are recognized as
token-delimiter characters, that is, as single-character delimiters that are
also tokens themselves.
As a delimiter, a token-delimiter character is a non-included boundary at the
end or beginning of a token, unless the character is part of a quoted region
(in which case it is treated as a non-delimiter character).
TokensToLower property
This readWrite property returns or sets the Boolean value that indicates
whether to convert returned, non-quoted, tokens to all-lowercase characters.
The default value for a new tokenizer is False.
TokensToUpper property
This readWrite property returns or sets the Boolean value that indicates
whether to convert returned, non-quoted, tokens to all-uppercase characters.
The default value for a new tokenizer is False.
New system exception class: UnknownStatistic
The UnknownStatistic exception class describes an exception associated with
finding a string identifier that is not a valid or not an appropriate
Model 204 statistic name.
To produce an UnknownStatistic exception, you typically use a User Language
Throw statement with an UnknownStatistic constructor (New).
For example, the following statement throws an UnknownStatistic exception
for the value ABCD:
throw %(unknownStatistic):new(Name='abcd')
In addition to the New constructor that creates an object instance,
the class includes a Name property that returns the invalid statistic name.
Constant methods
Constant methods are methods that belong to system classes but are unique
because they are evaluated at compilation time.
These methods require constant inputs and may have no parameters,
but they have no run-time overhead.
For example, the following Constant method sets %x to a string with hex value x'0678':
%x = '0678':x
The hex conversion is done at compilation time.
The method in this example (named X)
is a compile-time-only equivalent of the String intrinsic class HexToString method.
As other intrinsic methods,
the term “method object” is used for the constant value to which a Constant method is
applied, even though the value is not really an object.
Unlike other intrinsic methods, Constant methods may be invoked only against constants.
A variable as method object is not allowed:
%x = %y:x
Also, a statement like %x = 1234:x is not allowed, because a Constant method
requires the constant to have the correct datatype (in this case, String).
Once a Constant method is evaluated, the expression compilation is
replaced by the constant result of the evaluation, and all intermediate
work quads/variables are deleted.
Thus, '0d25':x is basically a hex constant.
The X function and the Unicode U constant function are
the only Constant methods as of Sirius Mods version 7.3.
%out = string:X
Float intrinsic methods
Multiple new methods are added, as described in the following subsections.
Many of the examples use the PrintText statement, which was introduced
in Sirius Mods version 7.2 and is described in the
Janus SOAP Reference Manual.
Absolute function
This function returns a number that is the absolute value of the method object.
%value = number:absolute
AntiLog function
This function returns a number that is the natural anti-logarithm (or exponential)
of the method object value.
The result is the natural logarithmic base (e) raised to the power of the method object value.
AntiLogE is a synonym for AntiLog.
The AntiLog function is an object-oriented version of the $EXP function, which is described in the
Sirius Functions Reference Manual.
%value = number:antiLog
AntiLog10 function
This function returns a number that is the base-10 anti-logarithm (or 10's exponent)
of the method object value.
The result is (10), the base-10 logarithmic base, raised to the power of the method object value.
The AntiLog10 function is an object-oriented version of the $EXP10 function, which is described in the
Sirius Functions Reference Manual.
%value = number:antiLog10
AntiLog2 function
This function returns a number that is the base-2 anti-logarithm (or 2's exponent) of the method object value.
The result is (2), the base-2 logarithmic base, raised to the power of the method object value.
The AntiLog2 function is an object-oriented version of the $EXP2 function, which is described in the
Sirius Functions Reference Manual.
%value = number:antiLog2
Div function
This function returns the integer part of the result of dividing the method object by the method argument.
The numbers to be divided are first rounded to the nearest integer, including zero.
Any remainder from the division is ignored.
%quo = number:Div(num)
IntegerToBinary function
This function converts an integer to its binary string representation.
Only integers that convert to a string no longer than four characters are allowed.
%str = number:IntegerToBinary(num, [Signed=bool])
IsPrime function
This function returns a boolean value that indicates whether
the method object value, rounded to an integer, is prime.
%bool = number:IsPrime
Log function
This function returns a number that is the natural logarithm
(the logarithm base-e) of the method object value.
LogE is a synonym for Log.
The Log function is an object-oriented version of the $Log function, which is described in the
Sirius Functions Reference Manual.
%value = number:log
If number is not greater than zero, the request is cancelled.
Log10 function
This function returns a number that is the logarithm base-10 of the method object value.
The Log10 function is an object-oriented version of the $Log10 function, which is described in the
Sirius Functions Reference Manual.
%value = number:log10
If number is not greater than zero, the request is cancelled.
Log2 function
This function returns a number that is the logarithm base-2 of the method object value.
The Log2 function is an object-oriented version of the $Log2 function, which is described in the
Sirius Functions Reference Manual.
%value = number:log2
If number is not greater than zero, the request is cancelled.
Modulus function
This function returns the remainder from the division of the method object by the method argument.
The numbers to be divided are first rounded to an integer, including zero,
so the remainder is always an integer or zero.
Mod is a synonym for Modulus.
%mod = number:Mod[ulus](num)
NextPrime function
This function returns the next prime number after the method object value.
%value = number:NextPrime
The method object value is initially rounded to the nearest integer before the next prime is determined.
PreviousPrime function
This function returns the prime number that immediately precedes the method object value.
%value = number:PreviousPrime
The method object value is initially rounded to the nearest integer before the preceding prime is determined.
ToFloatPower function
This function returns a number that is the method object value
raised to the float power specified by the method argument.
The ToFloatPower function is an object-oriented version of the $RXPR function, which is described in the
Sirius Functions Reference Manual.
%value = number:toFloatPower(exponent)
ToFloatPower uses good-fit techniques that sometimes produce slightly different results from
ToIntegerPower with the same inputs.
For example:
Consequently, you should generally use ToIntegerPower unless you are working with Float powers.
ToIntegerPower function
This function returns a number that is the method object value
raised to the power specified by the method argument.
The argument value is initially rounded to the nearest integral value.
ToPower is a synonym for ToIntegerPower.
The ToIntegerPower function is an object-oriented version of the $RXPI function, which is described in the
Sirius Functions Reference Manual.
%value = number:toIntegerPower(exponent)
If number is 0 and exponent is less than or equal to 0, the request is cancelled.
String intrinsic methods
Multiple new methods are added, as described in the following subsections.
Many of the examples use the PrintText statement, which was introduced in Sirius Mods version 7.2
and is described in the Janus SOAP Reference Manual.
BinaryToInteger function
This function treats a string as if it were binary and converts it to an integer.
The string may contain no more than four characters.
%num = string:BinaryToInteger([Signed=bool])
Center function
The Center function is introduced.
For a given input string and suitable specified length, this function
returns a string of the requested length that has the original string
embedded in the center.
If the requested length is larger than the length of the input string,
pad characters are added to the input string to produce the returned string.
If the requested length is shorter, the input string's front and end are cropped
to produce the returned string.
Centre is a synonym for the Center function.
%out = string:Center(length, [Pad=char,] [OffsetLeft=bool])
Note: This method is much like the $Center function except
in cases where an uneven number of characters is to be padded or cropped.
$Center puts the extra character on the right when padding
and on the left when cropping.
The Center method by default puts the extra character on the right in both cases,
and it provides an optional parameter if you want to use the left side instead
for the extra character.
Char function
The Char function returns one byte of the method object string, at the
position requested by its argument.
outStr = string:Char(position)
If the position exceeds the length of method object string, the request is cancelled;
otherwise, Char is the same as the Substring function with the given position
argument and with the length argument set to 1.
IsOneOf function
This function returns a Boolean value that indicates whether the method object
string is matched by one of the strings in an input list of strings.
The input list of strings is concatenated in a single delimited longstring
argument to the method.
A returned value of True signals a successful match.
%bool = stringoneof:(stringSet)
MD5digest function
Available to Janus SOAP or Janus Network Security users,
this function returns the 16-byte (always) binary string that is the
MD5 digest (hash) of the method object string.
MD5 (Message-Digest algorithm 5) is a well-known cryptographic hashing function
which is used in the Janus Network Security product for digital signatures.
A complete explanation of MD5 hashing can be found at Wikipedia
http://en.wikipedia.org/wiki/MD5.
%outStr = string:MD5digest
The 16-byte MD5 hash of a string is typically expressed as a 32-digit hex value.
In the following example, the output string from the MD5digest method is converted to hex using the
stringToHex intrinsic method:
printText {'this is a test':md5digest:stringtohex}
RC4encrypt function
This function returns a binary string that is the method object string encrypted or
decrypted with the specified RC4 encryption key.
The length of the returned string is the same as that of the object string.
RC4 is the default stream cipher (algorithm) used in Janus Network Security, and it may be used
by customers who license Janus Network Security or Janus SOAP.
RC4decrypt is a synonym for RC4encrypt; you can use the RC4decrypt synonym to
“document” that you are decrypting rather than encrypting in a call.
RC4 is a two-way, or symmetric, cipher, so encrypting a string with a key and then
encrypting the result of that encryption with the same key produces the original string.
That is, the following assertion should always hold:
The Replace method replaces one or multiple occurrences of a substring of an
input string (the method object) with a substitute string, and it returns the
modified version of the input string.
The Remove method removes one or multiple occurrences of a specified substring
from an input string, and it returns the modified version of the input string.
The Reverse function returns the characters in the method object string in right-to-left order.
outStr = string:Reverse
SHAdigest function
Available to Janus SOAP or Janus Network Security users, this function returns
the 20-byte (always) binary string that is the SHA digest of the method object string.
SHA (Secure Hash Algorithm) is a set of cryptographic hashing functions.
SHAdigest provides SHA-1, the most commonly used function as descibed in
http://en.wikipedia.org/wiki/SHA_hash_functions.
%outStr = string:SHAdigest
The 20-byte SHA hash of a string is typically expressed as a 40-digit hex value.
ToUpper and ToLower functions
The ToUpper and ToLower functions return the alphabetic characters in the
method object string as all-uppercase or all-lowercase characters, respectively.
Non-alphabetic characters are returned as is, and the input string undergoes no other change.
outStr = string:ToUpper
outStr = string:ToLower
Translate function
The Translate method for longstrings is a method that is roughly
equivalent to $lstr_translate.
The Translate method takes a CharacterMap object as input.
A CharacterMap object maps In (“input table”) characters to Out (“output table”) characters.
%outStr = string:translate(charMap)
In the following request, a's are translated to B's,
and c's are translated to d's, as dictated by the character mapping in %map:
Begin
%map is object characterMap
%ls is longstring
%map = new(in='ac',out='Bd')
%ls = 'aaaccc'
printtext {~} = '{%ls:translate(%map)}'
End
The result is:
%ls:translate(%map) = 'BBBddd'
Unspace function
This function removes the whitespace characters from the method object string and it
returns the resulting string.
Options are available to:
Define which character or characters are to be interpreted as whitespace
Remove leading whitespace, trailing whitespace, both or neither
Collapse to a single whitespace character any sequences of non-leading,
non-trailing whitespace
New with this release, Collections may be members of Collections.
The members of a collection of any type (ArrayList, NamedArrayList,
FloatNamedArrayList) may themselves be collections of any single type.
To declare a collection of a collection, you name the container collection,
then as its type you fully identify the member collections.
For example:
%value is NamedArrayList of NamedArrayList of longstring
As this declaration suggests, the collection members must all be the same
type of collection and item datatype.
Collections of collections are otherwise not different from other collections,
although referencing them is more complicated.
To operate on an item in a member collection, you might need to identify which
item it is in its array, as well as which item the array is in the containing array.
For example, to update the items in %scores, an Arraylist of Float,
you might use:
for %i from 1 to %scores:count
%scores(%i) = %scores(%i) + 10
end for
To perform a similar operation for the items in %AllScores, an Arraylist
of Arraylist of Float, you require an additional loop:
for %i from 1 to %AllScores:count
for %j from 1 to %AllScores:item(%i):count
%AllScores(%i)(%j) = %AllScores(%i)(%j) + 10
end for
end for
And for collection %x, a NamedArrayList of NamedArrayList of Float,
you might specify the following
to print the value of the bar item of the namedArraylist
whose item name in %x is foo:
print %x('foo')('bar')
If you use the syntax of the New function that explicitly indicates the class for
a collection of collections, both the collection and item datatypes must be
specified just as on the collection variable declaration:
%nal is collection namedArrayList of arraylist of longstring
%nal = %(namedArrayList of arraylist of longstring):new
Daemon class UserStatistics method
This method returns the Model 204 User statistics for the thread associated with the daemon object.
It is useful for metering a daemon or for determining table usage by a compilation done on the daemon thread.
The daemon cannot be running asynchronously when this method is invoked.
The method takes no arguments and returns a UserStatistics object.
%ustat = %daem:UserStatistics
Record class ToXmlDoc method
This method returns in a Janus SOAP XmlDoc object the fields and values of
the method Record object.
The method has options that let you:
Display field names in uppercase or lowercase
Output the field names as XML element names or as values of a name attribute
of the field XML element
Output the field values as XML attributes or as XML text
of the field XML element
The default is to display the field names as uppercase XML element names,
with field values as XML text; for example:
COMM.
If a field value contains non-displayable characters, the ToXmlDoc output
data is automatically base64 encoded, and an attribute called encoding
is added to the field's XML element with a value of base64.
The ToXmlDoc method will add BLOB values to the output
XmlDoc, no matter how large they are.
A BLOB field will have
a reserved attribute added to the field element if more bytes were reserved
in the BLOB than are in the actual value.
The ToXmlDoc method insists that the record object be locked at least in
share mode, therefore it gets no locks while it operates.
No locks are required for a sorted record or in single-user mode.
Examples
The display of field data below is produced
by the following request
OPENC FILE CCASYS
b
%r is object record in file ccasys
%r = new(1)
%r:toXmlDoc:print
%r:toXmlDoc(namesToLower=true):print
%r:toXmlDoc(attributeValues=true):print
%r:toXmlDoc(attributeValues=true, attributeNames=true, -
namestoLower=true):print
end
The default value of the SCRNSTBL user parameter is changed from 4096 to 6144.
SCRNSTBL specifies the maximum amount of STBL space available to an application
that uses a Screen object.
Implicit ToString calls for printing enumeration values
Prior to this release, the ToString method was the only way to return a string
representation of the value of a Janus SOAP ULI enumeration.
As of Sirius Mods 7.3, however, you no longer need to explicitly specify
ToString to print the value of a system or user-defined enumeration.
You can now simply print (or audit) the value of an enumeration,
as shown in the following example:
b
enumeration color
public
value red
value white
value blue
value green
end public
end enumeration
%x is boolean initial(true)
%z is enumeration color initial(blue)
%daem is object daemon
%daem = new
print %x with ' ' %z
printText {~} = {%x}, {~} = {%z}
print %daem:haveDaemon
printText {~} = {%daem:haveDaemon}
end
The Print and PrintText statements above produce these results:
True blue
%x = True, %z = blue
True
%daem:haveDaemon = True
In addition, the implicit ToString feature extends beyond enumerations:
upon any attempt to print or audit any object value, Janus SOAP ULI will try to apply a
ToString method to the object.
If the object is an enumeration (as shown above) or is an instance of a class that has a
ToString method (say, a user-defined class) a ToString is implicitly
applied and the result is a successful print or audit of the object value.
For example, the user-defined class in the following request includes a
ToString method:
b
class mumble
public
variable a is float
variable b is float
constructor new(%a is float nameRequired, %b is float)
function tostring is longstring
end public
constructor new(%a is float nameRequired, %b is float)
%this:a = %a
%this:b = %b
end constructor
function tostring is longstring
return 'a=' with %a with ', b=' with %b
end function
end class
%x is object mumble
%x = new(a=11, b=22)
printText {~} = {%x}
end
When this request is run it produces the following output:
%x = a=11, b=22
If the object you try to print or audit directly is not an enumeration or is
an instance of a class (system or user) for which no ToString method is written,
you receive a compilation error.
For example, if %sl is a StringList object, no user ToString method exists,
and your request contains a Print %sl statement,
you get a message like the following:
*** 1 MSIR.0733: Member TOSTRING not found in class STRINGLIST
print %sl
(FILE = JALWORK, PROCEDURE = FOO, LINE = 28)
*** M204.1042: COMPILATION ERRORS
Janus SOAP Xml API
The following sections describe changes in the Janus SOAP Xml API
in this release.
ASCII subset of Unicode
A pervasive change to XML processing in Janus SOAP is related to support of
the full 8-bit ASCII (ISO-8859-1) character set, that is, all Unicode code points with
a value less than U+0256 (see Unicode).
The changes to XML processing for full 8-bit ASCII character set support
are described in this section.
Some of these changes can cause compatibility issues, please refer to the
Notes for Sirius Mods Version 7.3
for more detailed information.
XPathOrder property removed
Previously, the XPathOrder property was available (with a default value
of Unicode) to allow EBCDIC ordered string comparisons in XPath.
This has now been removed, and it is a compatibility issue.
InvalidChar property deprecated; null and untranslatable characters not allowed
Previously, setting the InvalidChar property of an XmlDoc to Allow
let you store any EBCDIC character in the value of an Attribute
or Text node (using any “storing” method, such as Value or AddElement).
This toleration of any character did not apply to deserialization.
Version 1.1 of the XML standard has a different approach than XML 1.0 regarding
valid characters.
For deserialization, it allows a character reference to any character, in particular including control
characters (for example, ) — except not for the null character (x'00').
Therefore, in view of this loosening of the validity standard, the InvalidChar property
has no effect in version 7.3 of the Sirius Mods, and it is now deprecated.
That is, Sirius recommends that InvalidChar not be used, and at
some future date it may be removed from the Janus SOAP XML API.
In all cases in version 7.3, Janus SOAP deserialization allows references
to all non-null characters,
except those Unicode/ASCII characters that do not translate to an EBCDIC character.
(With the default Unicode-to-EBCDIC table, the only characters
that do not translate to an EBCDIC character were also disallowed —
as “control characters” — in previous versions of Janus SOAP.)
Any “storing” method in version 7.3 allows the storing of any non-null
EBCDIC character that translates to Unicode.
Note:
This change in character validity is a compatibility issue.
Previously, if the InvalidChar property is set to Allow, you were able to store any EBCDIC
character, including the null character and including a character that does not translate to Unicode.
Reference used to serialize control characters
Since the design of XML is to be human-readable, the serialization of
all control characters (for example, U+0008, the Backspace character)
now uses a character reference (in this example, ).
This is a compatibility issue.
Previously, when a control character (other than tab, carriage return, or linefeed)
occurs in an XmlDoc (which could only happen if it were added using a “store”
method while the XmlDoc InvalidChar property is set to Allow), it
is serialized “directly”, using the octet containing the control character.
Corrected translations
When translating between EBCDIC and ASCII/Unicode,
the Janus SOAP XML API now correctly does the following:
Translates to and from EBCDIC for the ASCII/Unicode code points X'85'
and X'A0' through and including X'FF'.
Identifies the other code points in the range X'80' through and including X'9F' as not
being translatable to EBCDIC.
Previously, all translations in this ASCII range (X'80' – X'FF') except
X'A2' were incorrect (Unicode U+0080 - U+00FF: 8 bit ASCII mentions some of the
types of characters in this range).
For translation from EBCDIC, many code points now translate to a character in the range
X'85' – X'FF'; previously these EBCDIC code points
did not translate to an ASCII/Unicode character.
Note that the above comments about translations apply for most of the
codepages, with no additional customization.
Both the codepage to use and any additional customization can be specified
during Model 204 initialization with the UNICODE command
(see UNICODE command).
AllowXmlElement to deserialize "xml.." element names
When this XmlDoc property is
set to True, you can deserialize an XML document into the XmlDoc even
if the document contains elements whose names use the reserved character
sequence xml (in any case) as the start of the element name.
Elements whose name begins with “xml” were restricted due to
the following excerpt from the XML standard:
Names beginning with the string "xml", or any string which would match
(('X'|'x') ('M'|'m') ('L'|'l')), are reserved for standardization in this
or future versions of this specification.
Therefore you should use care with element names: using
an element name such as XML makes you vulnerable to a change in the
standards that would leave your document incompatible with them.
Note:
This property does not allow the AddElement method to add an element
with a name that starts with “xml”.
However, it is easy to use the LoadXml method to accomplish this:
%doc:AllowXmlElement = True
%node:LoadXml('')
ToXpathString and ToXpathStringList methods
Two new methods are added to the XmlDoc and XmlNode classes: ToXpathString
and ToXpathStringList.
ToXpathStringList is simply a synonym for the existing XpathNodeID method.
ToXpathString performs the same function as XpathNodeid (returns
an absolute XPath expression), but
instead of returning a StringList like ToXPathStringList, it returns a string.
If the Stringlist returned from ToXpathStringList would contain multiple items,
the string returned from ToXpathString in the same context would
contain blank-delimited substrings.
The ToXpathString syntax, where %str is a string or longstring variable
and nr is an XmlDoc or XmlNode object, is:
%str = nr:ToXpathString([selection_XPath])
Note:
The impetus for creating the ToXpathString method is to allow SirFact, Janus Debugger,
and Sirius Debugger users to extract XPath information when needed.
The XPathNodeID method does not work in those environments because of its
object (StringList) output.
OmitNullElement in serialization methods
The new OmitNullElement option of the Xml serialization methods
(Print, Serial, WebSend, Xml) has the following restrictions and effect:
The OmitNullElement option may not be specified if ExclCanonical is specified.
When OmitNullElement is specified, an Element node that has no children and
no Attributes is not serialized, unless it is the top level Element in
the subtree being serialized.
Whether or not the serialization of an Element would contain
Namespace declarations in its start tag has no effect on the suppression
of the serialization of the Element.
OmitNullElement is not “transitive”; that is to say, if a
(parent) Element node has no Attributes, and has only Element children (and it
has one or more) and all of its children are Attribute-free and child-free,
then that parent Element is serialized, even though its content in the
serialization is empty.
If, in the previous case, an Element is serialized with empty content,
it is serialized with a start tag and an end tag (and, if the serialization
method inserts them, a line separator).
For example, given the following User Language fragment:
%d Object XmlDoc Auto New
%l Object Stringlist Auto New
Text To %l
End Text
%d:LoadXml(%l)
Print 'Entire XmlDoc:'
%d:Print(, 'OmitNullElement')
Print 'Empty Element as top of subtree:'
%d:Print('*/*/*', 'OmitNullElement')
The resulting output is:
Entire XmlDoc:
Empty Element as top of subtree:
Unicode
Traditional representation of characters has relied on 8-bit character codes,
but an 8-bit character code only allows representation of at most 256 characters.
With the need to represent
many special-purpose characters
and
characters of many languages, 8-bit character sets have
become strained to represent all necessary characters.
This has led to the use of multiple 8-bit code sets: in EBCDIC, using multiple
code pages, and in ASCII, a variety of ISO-8859-x character sets.
It has also led to the use of escape sequences where it is absolutely necessary
(for example, with Kanji characters) to use more than 8 bits to represent a
single character.
The Unicode standard (or ISO-10646) establishes a new character encoding scheme,
and various representations for character codes, to allow for over 1 million
characters.
The first Unicode standard was published in 1990 (Unicode 1.0) and has evolved
since then.
The list of Unicode versions is available on the Internet at:
http://www.unicode.org/versions/enumeratedversions.html
Unicode is becoming ubiquitous; it is used as the encoding scheme on most non-mainframe
applications, and over time, more and more Model 204 applications will need to accept
Unicode data.
Unicode also provides an important reference point.
For example, you can discuss the square
bracket character codes, U+005B and U+005D, without concern about the code page
being used.
Version 7.3 of the Sirius Mods introduces support for Unicode, consisting of:
A UNICODE command to allow:
Customization, during Model 204 initialization, of Unicode tables (which specify
translations between EBCDIC and Unicode/ASCII) and of
replacement of Unicode characters.
Display of these customizations.
A new intrinsic data type: Unicode
A string of type Unicode can contain any of the characters in Unicode's
Basic Multilingual Plane, consisting of the code points U+0000 through
and including U+FFFD, which cover most languages and characters.
A set of functions that operate on Unicode strings,
return Unicode results, or are based on the Unicode tables.
Automatic conversion between Unicode strings and other User Language
intrinsic types (String, Longstring, Float, Fixed).
An exception class for cases in which a conversion fails, for example when an
attempt is made to translate
a character from one code set to another that does not have a corresponding
character.
Use of the Unicode tables to control XmlDoc serialization and deserialization,
as well as XPath processing.
Using the UNICODE command for some common problems
Before the complete discussion of Unicode and its support in version 7.3 of the
Sirius Mods, some applications of the UNICODE command are presented.
For the full syntax of the UNICODE command, see UNICODE command.
A number of incorrect translations involving XML in earlier versions of the Sirius Mods
have been corrected in version 7.3.
These changes are intended to improve the quality of data that is handled by the Janus SOAP
processing of XML documents, but there are some cases
in which the changes can cause problems for customer applications.
A discussion of some common problems and possible workarounds follows.
Invertible translations
An invertible translation occurs when a code point in one code set translates to a
code point in another code set, and the translation of that other code point
is the original code point.
It is strongly desirable that all translations being used are invertible.
This helps enforce data quality, simplicity of application programming,
understandability of the Unicode translation tables, and consistent
“round-tripping” of XML documents.
All translations in the supported codepages are invertible.
Note:
Standardizing on a single code page and correcting all User Language code to use that
code page will ensure invertible translations and is the long term direction that
Sirius recommends.
However, because the correct translation of “special characters” has only
recently become important, it is quite possible that a variety of translation issues
have crept into User Language applications.
The following discussions of workarounds show how non-invertible translations can be
used to temporarily bypass common translation issues.
It is important that you recognize these as temporary workarounds and that the d
best long term solution is to achieve fully invertible translations using a standard
codepage.
In the UNICODE command, an invertible translation, or a two-way translation
or mapping, is specified with the Map form of the UNICODE updating command.
(Note, however, that specifying a Map subcommand can cause an existing
mapping to become uninvertible; see Vertical bar vs. broken bar.)
When a translation is uninvertible, unusual results can occur, and there
can be cases of this in ealier versions of Janus SOAP.
For example, if you employ the dual square bracket workaround described below and
your base codepage is 1047, then the following request fragment shows how
a character value can change merely by being serialized and then deserialized:
%d Object XmlDoc Auto New
%s Longstring
* Value is "secondary" left square bracket:
%d:AddElement('x', 'BA':X)
Print 'Before round trip, hex value:' And %d:Value:StringToHex
%s = %d:Serial
%d = New
%d:LoadXml(%s)
Print 'After round trip, hex value:' And %d:Value:StringToHex
The result of the above fragment is:
Before round trip, hex value: BA
After round trip, hex value: AD
If you are receiving MSIR messages indicating
“error processing XPath expression,” especially if that message
is preceded by a message indicating “Invalid name character,”
you may be using a different set of EBCDIC square brackets than those
used by default in XML processing in version 7.3 of Janus SOAP.
Probably the best way to determine this is to run the following ad hoc request:
Begin
Print $C2X('[]')
End
The result should be either BABB or ADBD.
If the result is BABB, then your terminal is probably
using codepage 0037 (or, in the United Kingdom, codepage 0285).
You can change the Sirius Mods Unicode processing to use that codepage
by inserting the appropriate following command as part of Model 204 initialization:
UNICODE Table Standard Base Codepage 0037
or, in the UK:
UNICODE Table Standard Base Codepage 0285
If this resolves your XPath problems, all applications are likely to be
consistently using square brackets from codepage 0037 or 0285.
If there are still some XPath errors, then the applications may
be inconsistent, with some using the 0037/0285 brackets, and some
using the 1047 brackets.
If the result is ADBD, then your terminal is probably
using codepage 1047, the same as the Sirius Mods Unicode default.
This is probably a good indication that your applications may
be inconsistent, with some using the 0037/0285 brackets, and some
using the 1047 brackets.
XPath predicate errors even after setting proper codepage
If either of the following is true, you may benefit from temporarily using
both common sets of square brackets in the Unicode tables:
You have determined the proper codepage to use as described above,
and you are still getting the XPath errors indicative of codepage mismatch.
You have a mixture of codepages used by User Language programmers.
In the longer term, you should attempt to standardize the codepages used
by User Language programmers and correct the square brackets in User Language applications
so that you can remove this workaround.
If your base codepage is 1047
If your base codepage is 1047,
you can use the following commands to add the alternate square brackets:
* Support codepage 0037 square brackets when 1047 is base
* codepage - used until setting consistent square brackets:
UNICODE Table Standard Trans E=BA To U=005B
UNICODE Table Standard Trans E=BB To U=005D
* Since codepage 1047 usually maps E=BA/BB to U=DD/A8, make
* those Unicode points invalid, rather than have yet more
* uninvertible translations:
UNICODE Table Standard Trans U=00DD Invalid
UNICODE Table Standard Trans U=00A8 Invalid
If your base codepage is 0037
If your base codepage is 0037,
you can use the following commands to add the alternate square brackets:
* Support codepage 1047 square brackets when 0037 is base
* codepage - used until setting consistent square brackets:
UNICODE Table Standard Trans E=AD To U=005B
UNICODE Table Standard Trans E=BD To U=005D
* Since codepage 0037 usually maps E=AD/BD to U=DD/A8, make
* those Unicode points invalid, rather than have yet more
* uninvertible translations:
UNICODE Table Standard Trans U=00DD Invalid
UNICODE Table Standard Trans U=00A8 Invalid
If your base codepage is 0285
It is somewhat unusual to have mixed codepages among User Language programmers
when the base codepage is 0285, but since the square bracket mappings for 0285 are the
same as 0037, you can use the same approach as shown above for 0037.
For the sake of consistency, you should change “0037” in the comment
to “0285”.
Vertical bar vs. broken bar
The common translations for the vertical bar character (|)
and for the broken bar character
(¦)
are shown in the following
excerpt of the output of the UNICODE Display Codepage xxxx command
(where xxxx is any of the common codepages: 1047, 0037, or 0285):
* .. Map E=4F Is U=007C Vertical bar
* .. Map E=6A Is U=00A6 Broken bar
For these common codepages, the above translations are used in
version 7.3 of Janus SOAP for XML processing.
However, in earlier versions the translations are not correct:
EBCDIC vertical bar (X'4F') is correctly translated to ASCII X'7C'.
ASCII vertical bar (X'7C') is incorrectly translated to EBCDIC X'6A',
the broken bar.
EBCDIC broken bar (X'6A') is incorrectly translated to ASCII X'7C',
the vertical bar.
ASCII broken bar (X'A6') is incorrectly translated to EBCDIC X'50',
the ampersand.
Note: This is but one example of the fact that in prior versions of the Sirius Mods,
almost all translations of ASCII code points greater than X'7F' are incorrect.
The concern is that you may have applications that depend on these incorrect translations.
In the following discussion, the term “solid bar” is used for the
vertical bar character, to help contrast it with the broken bar character.
Search your applications for instances of broken bars:
If the broken bar is being used, for example, as a delimiter of items of a value in an XmlDoc
received in ASCII, UTF-8, or UTF-16 (say, with the XmlDoc WebReceive method or the HttpResponse
ParseXml method), then the document was probably sent with an ASCII solid bar, which
was incorrectly translated to EBCDIC broken bar by Janus SOAP.
If the broken bar is being used, for example, to populate an XmlDoc that will be sent in
UTF-8 (say, with the XmlDoc WebSend method, or the HttpRequest AddXml method), then with prior
versions of Janus SOAP the document would have been sent with an ASCII solid bar.
The proper long-term fix to your application is probably to use
solid bar rather than broken bar in the above two cases.
The next two subsections discuss the technique for searching your applications for broken bars,
and a workaround to use if you are not able to fix your applications at the time that you install
version 7.3 of the Sirius Mods.
Searching for broken bar
Run the following ad hoc request:
Begin
Print $C2X('6A')
End
“Copy” the result character to your clipboard, for example, by highlighting
it and pressing ctl-C.
Go to a procedure search facility, such as SirPro, and “paste”
the character as the search string.
Note: Probably due to odd behavior in some tn3270 packages, you should place the cursor
after the broken bar in the search string and delete the blank.
After you have a list of procedures containing the broken bar, edit them and paste the broken bar
after a slash (/) in the editor command line to locate the specific lines where they occur.
Perpetuate bad vertical/broken bar translations
If you have applications with broken bars that need to be fixed when using version 7.3 of
Janus SOAP, but you are unable to make those changes at that time, you can use the
UNICODE command as follows to modify the Unicode tables to mimic some of the translations
used by earlier versions.
Place the following lines in your Model 204 initialization stream:
* EBCDIC broken bar goes to Unicode vertical bar, and
* vice-versa (used until setting consistent vertical/
* broken bars) - note that EBCDIC vertical bar
* translates to Unicode vertical bar in the base table:
UNICODE Table Standard Map E=6A Is U=007C
Note: The above Map subcommand causes uninvertible translations in the Unicode tables: neither
the translation from EBCDIC X'4F' to Unicode U+007C, nor the translation from Unicode U+00A6 to
EBCDIC X'6A' is invertible.
These translations should be viewed as temporary workarounds until the characters can be fixed
up in the User Language programs.
Code points, character set mappings
A code point is simply one of the numeric values in the range of a character set
encoding scheme.
In EBCDIC, an 8-bit character set, code points vary from X'00'
through and including X'FF'.
As an example, the character “A” is mapped to the
EBCDIC code point X'C1'.
In ASCII, also an 8-bit character set, code points also vary from X'00'
through and including X'FF'.
As an example, the character “A” is mapped to the
ASCII code point X'41'.
The first 128 code points (X'00' through X'7F') have well-defined mappings;
for code points X'80' through X'FF', the mappings depend on the “flavor”
of ASCII being employed (ISO-8859-1 through ISO-8859-9).
In Unicode, the customary way to represent a code point is U+hhhhhh,
where hhhhhh is the hexadecimal representation of the value of the
code point.
As an example, the “trademark” character is mapped to the
code point U+2122.
Note that the first 256 code points in Unicode have the same mappings as the
code points in ISO-8859-1; for this reason, we may use the U+hh notation to
refer to ASCII code points.
Some characters are simple to deal with; here are some
common EBCDIC and corresponding ASCII mappings (note that these ASCII code points
are all less than X'80'):
In previous versions of the Sirius Mods, all translation between EBCDIC and ASCII
(other than the customization available with the JANUS LOADXT command)
was based on tables that ignored all but one ASCII code point greater than X'7F'
(the code point for the “cent sign”).
Please refer to the section titled “Corrected translations between ASCII/Unicode and
EBCDIC” in the Notes for Sirius Mods Version 7.3
for information about various translations that have been corrected.
As of 7.3 of the Sirius Mods, parsing an XML document and
non-EBCDIC serialization of an XmlDoc is
performed using the corrected translation tables.
The actual translations used can be controlled with the UNICODE command
during Model 204 initialization, chiefly by selecting the codepage to use.
The common codepages are:
0037
For the USA, Australia, Canada, ...
0285
For the UK
1047
Latin/1 Open Systems for USA, Australia, Canada, ...
EBCDIC column 5 of that yellow card corresponds to codepage 1047.
Here are some examples of Unicode characters in the range U+80 through U+FF:
U+A2: cents sign
U+A3: pound (sterling) sign
U+A5: Chinese Yuan or Japanese Yen
(See ISO 4217 for actual currency designations such
as USD for “US Dollars,” JPY for “Japanese Yen,”
CNY for “Chinese Yuan,” and so on.)
U+A9: copyright symbol
U+BC: small fraction 1/4
U+C1: acute capital A
Unicode: a new User Language type
Version 7.3 of the Sirius Mods introduces a new intrinsic data type, Unicode.
A string of type Unicode can contain any of the characters in Unicode's Basic Multilingual
Plane (any of the code points U+0000 through and including U+FFFD) which covers most languages and characters.
Each character in a Unicode string occupies 2 bytes.
Values X'D800' through X'DFFF' are used in Unicode
for surrogate pairs (not supported in version 7.3 of the Sirius Mods).
Values X'FFFE' and X'FFFF' are not characters.
So the valid code points of a character in a Unicode string are as follows:
U+0000 through U+D7FF
U+E000 through U+FFFD
UTF-8 and UTF-16
Any Unicode character can be represented using UTF-8 or UTF-16.
As their names imply, these representations use items of 8 or 16 bits in length, respectively.
When using one of the User Language intrinsic functions (Unicode intrinsic functions)
to convert between a Unicode string and a UTF-8 or UTF-16 stream, UTF-8 or UTF-16 is stored as
a byte stream, in a User Language String or Longstring value.
For conversion from a Unicode string to UTF-8, each character of the UTF-8 representation
uses from 1 to 3 bytes per character.
This is the most common encoding of Unicode sent over
the Internet and usually results in the most compact byte stream.
For conversion from a Unicode string to UTF-16, each character
of the UTF-16 representation uses 2 bytes per character.
For most commonly used characters, this representation is longer
than a UTF-8 representation.
ASCII conversion
User Language programs and Janus Web Server operations have employed translation between
ASCII and EBCDIC for many years.
Unfortunately, these translations have historically been incorrect for many seldom-used code points.
Version 7.3 of the Sirius Mods corrects the translations for XmlDocs, and it also provides two
String intrinsic functions to perform correct translation:
EbcdicToAsciiAsciiToEbcdic.
Since they are both 8-bit code sets, in principle there need not be untranslatable characters
between ASCII and EBCDIC.
In fact, however, there are about 30 code points in each which represent characters that do not
have representations in the other character set.
For example, the EBCDIC code point X'FF' is the EO (“Eight Ones”) control character; there is no
ASCII EO control character (ASCII X'FF' is the small letter “y with diaeresis”
which corresponds to EBCDIC X'DF').
Besides providing correct translations when they exist, the EbcdicToAscii and AsciiToEbcdic
functions throw an exception
(CharacterTranslationException exception class)
when a character cannot be translated.
AsciiToEbcdic alternatively allows encoding of untranslatable
characters using the XML “character reference” mechanism.
UnicodeToEbcdic also allows this.
The character references can be converted back to ASCII or Unicode
by, respectively, EbcdicToAscii or EbcdicToUnicode.
Unicode and Unicode-related intrinsic methods
Janus SOAP support for the Unicode data type includes intrinsic functions that operate
on Unicode strings, return Unicode results, or are based on the Unicode tables.
These functions are described in the sections below.
Unicode intrinsic functions
These methods treat their method object as a string of type Unicode.
UnicodeReplace
This function gets the Unicode string resulting from applying the
Unicode replacement table to the input Unicode string.
%unicode = unicode:UnicodeReplace
Where:
The intrinsic method object input is a Unicode string.
The result is the input Unicode string, with those characters
specified in the Unicode replacement table
replaced by their corresponding Unicode strings.
By default (that is, when there is no Unicode replacement table),
this function merely copies its input.
Example:
UNICODE Table Standard Rep U=2122 '(TM)'
Begin
%u Unicode Initial('Cool™':U)
Print %u:UnicodeReplace
End
The result is:
Cool(TM)
Note that an updating UNICODE command is shown here “in-line”
with a User Language request, to make the example concrete.
In actual usage, updating UNICODE commands should only be issued
from your Model 204 initialization stream.
UnicodeToEbcdic
This function converts a Unicode string to EBCDIC.
The intrinsic method object input is a Unicode string.
The optional (name required) CharacterEncode argument is a Boolean:
If False, the default, an exception is thrown if the
input contains any Unicode character not translatable to EBCDIC.
If True, any Unicode character not translatable to EBCDIC
is replaced with the hexadecimal character reference of the character,
and the ampersand character is replaced with &.
For example, the eight characters “
“left double-quotation mark.”
The result is the input string translated to EBCDIC — with
untranslatable characters represented with character references,
if CharacterEncode=True.
Note: Unless the CharacterEncode argument is used, or you want to Catch a
CharacterTranslationException, this function is generally not needed, because a Unicode
string is implicitly converted to EBCDIC when used in an EBCDIC context.
Example:
%u Unicode Initial('1':U)
* Note: "Print %u" gives the same result as the following:
Print %u:UnicodeToEbcdic
%u = '12':U
Print %u:UnicodeToEbcdic(CharacterEncode=True)
* Note: "Print %u" cancels the request as well:
Print %u:UnicodeToEbcdic
The result of the above fragment is:
1
12
CANCELLING REQUEST: MSIR.0751: Class STRING, function
UNICODETOEBCDIC: CHARACTER TRANSLATIONEXCEPTION
exception: Unicode character U+0080 without valid
translation to EBCDIC at byte position 5 ...
UnicodeToUtf16
This function converts a Unicode string to a UTF-16 Longstring byte stream.
The intrinsic method object input is a Unicode string.
The optional (name required) InsertBOM argument is a Boolean.
If its value is True, the “Byte Order
Mark” (U+FEFF) is inserted at the start of the output
stream.
If False, the default, no Byte Order Mark is inserted.
The result is the input Unicode string transformed to a
UTF-16 Big-Endian byte stream
(that is, any Unicode point U+wxyz results in the pair of bytes
X'wx' and X'yz', in that order).
Example:
%u Unicode Initial('1':U)
Print %u:UnicodeToUtf16:StringToHex
The result of the above fragment is:
0031
UnicodeToUtf8
This function converts a Unicode string to a UTF-8 Longstring byte stream.
The intrinsic method object input is a Unicode string.
The optional (name required) InsertBOM argument is a Boolean.
If its value is True, the “Byte Order Mark”
(U+FEFF, encoded as X'EFBBBF') is inserted at the start of the output stream.
If False, the default, no Byte Order Mark is inserted.
The result is the input Unicode string transformed to a UTF-8 byte stream.
The intrinsic method object input is a Longstring, presumed to
contain an EBCDIC character string.
The optional (name required) CharacterDecode argument is a Boolean.
If its value is True, an ampersand (&) is allowed in the input EBCDIC
string only in two ways:
As the substring &.
This substring is converted to '&'.
At the start of a hexadecimal character reference (for example, the eight characters
'“' for the Unicode “Left double quotation mark”).
The character reference is converted to the referenced character.
The default is False.
The result is the input string translated to Unicode — with character
references and & references converted to the represented Unicode
character, if CharacterDecode=True.
00310032
003121220032
CANCELLING REQUEST: MSIR.0751: Class STRING, function
EBCDICTOUNICODE: CHARACTER TRANSLATIONEXCEPTION
exception: EBCDIC character X'FF' without valid
translation to Unicode at byte position 2 ...
U constant function
Similar to the hexadecimal constant function X,
U is a constant function that allows you to specify a Unicode constant.
%unicode = stringWithRefs:U
Where:
The constant character string method object of the U function can contain character references.
An ampersand (&) is allowed in the following cases:
As the substring &.
This substring is converted to '&'.
At the start of a hexadecimal character reference (for example, the eight characters
'“' for the Unicode “Left double quotation mark”).
The character reference is converted to the referenced character.
Example:
* Constant for trademark symbol:
%tm Unicode Initial('™':U)
Print %tm:UnicodeToUtf16:StringToHex
The result of the above fragment is:
2122
Utf16ToUnicode
This function converts a UTF-16 Longstring byte stream to Unicode.
%unicode = utf16Stream:Utf16ToUnicode
Where:
The intrinsic method object input is a Longstring, presumed to contain a UTF-16 byte stream.
The result is the input UTF-16 byte stream converted to Unicode.
This function may throw a CharacterTranslationException exception.
Note:
The input UTF-16 stream may contain a Byte Order Mark (U+FEFF).
If one is present, that controls the conversion from UTF-16 to
Unicode.
If a Byte Order Mark is not present, the input stream is considered
to be a Big Endian stream, that is, it is the same as if the stream
were preceded by the two bytes X'FE' and X'FF', in that order.
For example:
%u Unicode
%u = '0032':X:Utf16ToUnicode
Print %u
The result of the above fragment is:
2
Utf8ToUnicode
This function converts a UTF-8 Longstring byte stream to Unicode.
%unicode = utf8Stream:Utf8ToUnicode
Where:
The intrinsic method object input is a Longstring, presumed to
contain a UTF-8 byte stream.
The result is the input UTF-8 byte stream converted to Unicode.
This method may throw a CharacterTranslationException.
Example:
%u Unicode
%u = '32':X:Utf8ToUnicode
Print %u
The result of the above fragment is:
2
Other Unicode-related intrinsic functions
These intrinsic String methods rely on the Unicode translation tables as optionally modified by the
UNICODE command.
AsciiToEbcdic
This function converts an ASCII (ISO-8859-1) string to EBCDIC.
The intrinsic method object input is a Longstring, presumed to
contain an ASCII string.
The optional (name required) CharacterEncode argument is a Boolean:
If its value is False, the default, an exception is thrown if
the input contains any ASCII character not translatable to EBCDIC.
If its value is True, any ASCII character not translatable
to EBCDIC is replaced with the hexadecimal character reference of the
character, and the ampersand character is replaced with &.
For example, the six characters '„' replace the ASCII
“INDEX” control character.
The result is the input string translated to EBCDIC — with
untranslatable characters represented with character references,
if CharacterEncode=True.
%a String Len 20
%a = '31':X
Print %a:AsciiToEbcdic
%a = '318032':X
Print %a:AsciiToEbcdic(CharacterEncode=True)
Print %a:AsciiToEbcdic
The result of the above fragment is:
1
12
CANCELLING REQUEST: MSIR.0751: Class STRING, function
ASCIITOEBCDIC: CHARACTER TRANSLATIONEXCEPTION
exception: ASCII character X'80' without valid
translation to EBCDIC at byte position 1 ...
EbcdicToAscii
This function converts an EBCDIC string to ASCII (ISO 8859-1).
The intrinsic method object input is a Longstring, presumed to
contain an EBCDIC character string.
The optional (name required) CharacterDecode argument is a Boolean:
If its value is True, an ampersand (&) is allowed in the input EBCDIC
string only in two ways:
As the substring &.
This substring is converted to '&'.
At the start of a hexadecimal character reference (for example, the six characters
'„' for the ASCII “INDEX” control character).
The character reference is converted to the referenced character.
The default is False.
The result is the input string translated to ASCII — with character
references and & references converted to the represented ASCII
character, if CharacterDecode=True.
This function may throw a CharacterTranslationException exception.
3132
310A32
CANCELLING REQUEST: MSIR.0751: Class STRING, function
EBCDICTOASCII: CHARACTER TRANSLATIONEXCEPTION
exception: EBCDIC character X'FF' without valid
translation to ASCII at byte position 2 ...
EbcdicRemoveNonUnicode
This function removes the bytes from the EBCDIC input string
that do not translate to Unicode.
%string = string:EbcdicRemoveNonUnicode
Where:
The intrinsic method object input is a Longstring, presumed to
contain an EBCDIC character string.
The result is the input string with the bytes removed that are
not translatable to Unicode.
This function is useful because there is no way to convert
to Unicode an EBCDIC string that contains untranslatable characters.
Example:
%e String Len 20
%e = 'C1FFC2':X
Print %e:EbcdicRemoveNonUnicode
The result of the above fragment is:
AB
EbcdicTranslateNonUnicode
This function replaces any bytes from the EBCDIC input string
that do not translate to Unicode.
Non-translatable bytes are replaced with the character specified as the
function argument.
%string = string:EbcdicTranslateNonUnicode(char)
Where:
The argument is a one-character EBCDIC string, which is
used to replace untranslatable input characters.
The result is a copy of the input string, but with each input byte that is not
translatable to Unicode replaced by an occurrence of the specified argument character.
This function throws a CharacterTranslationException if the
argument character is not translatable to Unicode.
EbcdicTranslateNonUnicode is useful because there is no way to convert
to Unicode an EBCDIC string that contains untranslatable characters.
Example:
%e String Len 20
%e = 'C1FFC2':X
Print %e:EbcdicTranslateNonUnicode('?')
The result of the above fragment is:
A?B
CharacterTranslationException exception class
Various methods throw a CharacterTranslationException exception
when they encounter character translation problems.
To avert request cancellation, you can catch such an exception,
optionally catching to an object of this class.
This class has the following read-only properties:
Reason
A TranslationExceptionReason enumeration instance.
BytePosition
A number that indicates the postion (starting with 1) of the byte at which the exception was thrown.
CharacterPosition
A number that indicates the position (starting with 1) of the character at which the exception was thrown.
The number of bytes that constitute a character depends on the type of string
that causes the exception:
If EBCDIC, one byte corresponds to one character.
If Unicode, two bytes correspond to one character.
If UTF-16, two bytes correspond to one character.
If UTF-8, the relationship between bytes and characters is variable, depending on the code points.
HexValue
A string that contains the hexadecimal representation of the bytes that caused the exception to be thrown.
Description
A string that contains a brief description of the exception.
This class has the following constructor:
New
This constructor's syntax follows.
The arguments set the values of the properties of the class that have the corresponding names.
The values of this class are returned by the Reason function
of the CharacterTranslationException exception class.
The enumeration values in this class are as follows:
InvalidEncoding
An example of invalid encoding is UTF-16 string input to Utf16ToUnicode that contains bytes
whose hexadecimal value is D800 (that is, in the surrogates range).
InvalidCharacterReference
For example, EbcdicToUnicode is called specifying CharacterDecode=True, and the input
contains an ampersand (&) followed by a space.
UntranslatableCharacter
As examples (with the translation tables
as delivered by Sirius):
The EBCDIC input to the EbcdicToUnicode method
contains a byte whose hexadecimal value is X'FF.
The Unicode input to UnicodeToEbcdic contains one of the many
Unicode characters that is not translated to an EBCDIC character
(for example, U+20AC, the Euro currency symbol).
As do all enumeration classes, this class also contains
the ToString method, which converts an enumeration value to a
character string whose value is the name of the enumeration value.
UNICODE command
The UNICODE command is used to manage the Unicode tables, effecting the following:
Translation between Unicode and EBCDIC and between ASCII and EBCDIC.
Replacement of Unicode characters by designated character strings.
In the descriptions of the UNICODE command that follow:
h2 is two hexadecimal digits.
hex4 is four hexadecimal digits, excluding FFFE, FFFF,
and the surrogate areas (D800 through and including DFFF).
As a Model 204 command, the term “UNICODE” that starts the
UNICODE command must be entered entirely in uppercase letters.
The other keywords of the UNICODE command may be entered in any mixture
of uppercase or lowercase letters.
The command descriptions below use an initial capital letter to indicate
a keyword, and they use all-lowercase letters to indicate a term that is
substituted for a particular value in the command.
The various forms of the UNICODE command are:
UNICODE List Codepages
This form of the command obtains a list of all codepages.
UNICODE Difference Codepages name1 And name2 [Range E=h2 To E=h2]
This form of the command obtains a list of the differences
between two codepages
for the EBCDIC range specified (which defaults to the 00 to FF range).
UNICODE Difference Xtab name1 And Codepage name2 [Range E=h2 To E=h2]
This form of the command obtains a list of the differences
between a JANUS XTAB table and a codepage
for the EBCDIC range specified (which defaults to the 00 to FF range).
UNICODE Display Codepage name
This form of the command obtains, in commented form, the
Maps of the specified codepage.
UNICODE Display Table Standard
This form of the command obtains, in command form, a display of
current replacements and current Maps and/or translations
(see Trans subcommands, below) that differ from the base.
UNICODE Table Standard subcommand
The updating forms of the UNICODE command begin with the
keyword Table; they are described below.
For the updating subcommands:
The user must be a System Administrator (or user 0).
These commands should only be invoked during Model 204 initialization,
because other users running at the same time as the change may
obtain inconsistent results, including the results
of UNICODE Display.
You may test UNICODE command changes as part of a “private” test
Online (that is, one which only you access), so no other users
are running while you issue updating forms of the UNICODE command.
Changing the base codepage and changing translation
or mapping points should be done before entering any replacement
strings, because a replacement string is translated from EBCDIC
to Unicode when the Rep subcommand is processed.
The various subcommand values of the updating forms of the
UNICODE command are:
Base Codepage name
Replace the current translation tables with those derived from the
named codepage.
Trans E=h2 To U=hex4
Specify one-way translation from EBCDIC point h2 to
Unicode point hex4.
Trans E=h2 Invalid
Specify that the given EBCDIC point is not translatable to Unicode.
Trans E=h2 Base
Remove any customized translation or
mapping specified for the given EBCDIC point.
Trans U=hex4 To E=h2
Specify one-way translation from Unicode point hex4
to EBCDIC point h2.
Trans U=hex4 Invalid
Specify that the given Unicode point is not translatable to EBCDIC.
Trans U=hex4 Base
Remove any customized translation or
mapping specified for the given Unicode point.
Trans All Base
Remove any customized translation or mapping specified from all
Unicode and EBCDIC points.
Map E=h2 Is U=hex4
Specify mapping from EBCDIC point h2 to Unicode point
hex4, and from Unicode point hex4 to EBCDIC point h2.
Map U=hex4 Is E=h2
Same as Map E=h2 Is U=hex4.
Rep U=hex4 'str'
Specify replacement for Unicode point hex4 by the Unicode
string str.
str may be a series of the following:
Non-ampersand EBCDIC characters (which must be translatable to Unicode).
& (for an ampersand).
A character reference of the form &#xhhhh;
The length of the resulting Unicode replacement string is limited to
127 characters.
No character in the replacement string
may be the U=hex4 value in any Rep subcommand.
Norep U=hex4
Specify that there is no replacement string for Unicode point hex4.
Norep All
Specify that there is no replacement string for any Unicode point.
Please refer to the
Notes for Sirius Mods Version 7.3 for a discussion of any compatibility
issues with prior versions of the Sirius Mods and any bugs which have
been fixed in this version, but had not, as of the date of this release, been fixed
in the immediately prior version.
Version 7.2 of the Sirius Mods was released in February, 2008.
Please refer to the
Notes for Sirius Mods Version 7.2 for more detailed information.
Supported Model 204 Versions
Version 7.2 of the Sirius Mods supports only Model 204 version V6R1.
All or Multiple Products
Html/Text statement enhancements
The User Language Html and Text statements, alternatives to a series of PRINT statements,
are enhanced as described in the following subsections.
To Audit, To Print, and To Trace options
These three new Html/Text statement To options let you direct
the contents of an Html/Text block or line to the destinations
associated with the User Language statements Audit, Print, or Trace.
Respectively these destinations are
the journal/audit trail, the current print output device, or the
trace destination (which may be the audit trail, print device,
or CCATEMP trace table, or a combination of them).
Audit, Print, and Trace keywords
These new keywords act like the Data keyword:
they denote that the HTML block consists of only the text that follows
the keyword on the logical line.
Further, they identify the output destination of the line's text,
implying To Audit, To Print, and To Trace, respectively.
AuditText, PrintText, and TraceText options
These options are simply shortened forms of Text Audit, Text Print,
and Text Trace, respectively, that place the action first.
These are likely to be
the common way of auditing, printing, or tracing text when no additional Text
statement options need to be specified.
LiteralsToTemp keyword
When this keyword is specified in a Text statement, the literal data in the
statement is stored in CCATEMP rather than STBL, avoiding excessive demands
on STBL space.
Designed for a Text statement with an unusually large amount of literal data,
this is an alternative to setting the X'01' bit of the SIRCOMP user parameter
(which performs the same function).
{~} directive
In a Text/Html statement block,
content enclosed in expression start and end characters is evaluated
as if it were the right-hand side of a User Language
assignment, and the resulting value
takes the place of the expression (and expression start and end characters)
in the HTML block.
For example, printText {$date} produces 08-02-29.
The special expression {~}, however, directs the compiler to replace
this expression with
the literal chartacter content of the next expression appearing on the same line.
So printText {~} {$date} produces $date 08-02-29.
The evaluation of the expression following {~} is carried out as usual.
Longstrings in images
The Longstring datatype is not supported inside images.
However, Sirius Mods version 7.2 introduces support for image items with
length greater than 255.
The following is an example of a declaration of a 300-byte image item:
image foo
bar is string len 300
end image
While such image items can't have arbitrary lengths up to 2**31-1
like other longstring variables, they exhibit the same behavior as
other longstring variables in:
Request cancellation in the case of truncation
Upgrading With operations to longstring With operations
Report writer parameters
Report writers
can use a lot of virtual storage which can adversely effect other users in an Online.
The new CURREP31, CURREP64, HGHREP31, and HGHREP64
system parameters indicate the current and greatest amounts of
31-bit and 64-bit virtual storage used in the Model 204 run by report writers.
The MAXREP31 and MAXREP64 parameters indicate the maximum amount allowed.
The only existing report writer is invoked by the SirTuneReport method of
the Dataset class.
That method is called by the SirTune product, and it can also be called directly.
Only the parameters that specify the maximum amount of storage (MAXREP31 and MAXREP64)
are resettable.
Janus stream logging
The JANUS TCPLOG subcommand lets you capture all input
and output streams for a particular Janus port.
The captured streams are written to a sequential file.
One suggested use for a file of captured streams is to provide “playback”
for customer-written applications that simulate real workloads during testing
of new system or application code.
Details of the format of the log file are available in the
Janus TCP/IP Base Reference Manual.
SirScan accepts large datasets
SirScan now supports the use of z/OS large datasets for CCAJRNL.
Janus Debugger and Sirius Debugger
The Janus Debugger is a tool designed for software developers who create and maintain
Janus Web Server applications.
The Sirius Debugger is designed to debug classical screen-based 3270 applications as well as
BATCH2 applications.
Though the two debuggers use different thread types on the host, they can run
concurrently, and they both use the same Windows-based GUI client.
For more information about the debuggers, see the
Janus/Sirius Debugger User's Guide.
Features available only with Sirius Mods 7.2
Jump to arbitrary statement
The Jump feature lets you alter the normal flow of program execution in the Debugger
by invoking an immediate transfer of control to a specified statement
and then executing that statement.
The target statement may be earlier or later in the request than the current statement.
You invoke a jump by right-clicking a line in the Client's Source Code
window or by using commands in a macro or mapped button or hot
key.
The commands offer additional functionality: jumps to a line
number, jumps that are a number of lines relative to the
current line, and jumps to lines that contain specified strings.
Audit Trail display for procedures excluded by White List processing
When white listing is on, the Debugger filters procedures
automatically, stopping to interactively debug only the
requests that are on the white list.
A non-listed procedure executes normally, but it is not
interactively debugged, and the Debugger Client's Audit Trail displays
are immediately refreshed (as of Sirius Mods 7.2) to specify
that such a procedure has been “skipped.”
Interrupting White List or Run Until processing
Once the Debugger's White List processing is invoked, it continues in effect
unless you explicitly turn it off or until you exit the Debugger
Client.
It is manually interruptable, however, as of version 7.2 of
the Sirius Mods: the mappable Client command breakOnNextProc
lets you override the White List to interactively debug the
next procedure.
New features for Sirius Mods 6.9 through 7.2
These features were added by update builds of the Client
subsequent to the release of Sirius Mods 7.1.
Enhanced support for macros
User-created macros were made available for the Debugger in Sirius Mods version 7.1.
The following subsections describe enhancements to macro support
added in Sirius Mods 7.2.
New macro-only commands
These macro-only commands are added:
set
Lets you create and initialize macro variables.
assert
Performs an equality comparison between a) the value of
program data or a macro variable and b) a constant or the
value of a macro variable or macro function.
For example:
assert %i=666
assert failure messages are displayed in the macro
console, if it is open.
Otherwise, they are displayed in a Windows message box.
vardump
Displays the values of all current macro variables.
The message is normally displayed in a standard Windows
informational box (entitled varDump for Macro).
If the macro console is open, however, the message is sent to
the console instead.
echo
The macro-only command echo lets you display a user-specified message.
The message is normally displayed in a standard Windows informational box
(entitled Macro message).
If the macro console is open, however, the message is sent to the console instead.
Passing a command argument to a macro
This feature lets you
pass an argument to a macro command at the time the macro runs.
You can use either a standard macro variable or a standard macro
function:
The &argstring
is, in effect, a placeholder for a macro command argument.
You specify &argstring
the command argument.
Then, depending how you invoke the macro,
the Debugger substitutes an explicit value for &argstring
when the macro runs.
The client obtains the substitute value from the Variable or Field
text area, from the Macro Command Line tool, or from a mapped macro
command line.
The &&prompt
is used to prompt for a macro command argument.
The function format is:
&&prompt("promptString")
where promptString is a double-quoted character string.
When a macro command that contains a &&prompt
place of the command argument is executed, the Client
displays a dialog box which uses promptString
to solicit the value to substitute for the command argument.
A console for macro information
The Macro Console is an independent window that logs
informational messages about the Debugger macros you run.
It is invoked from its option in the Client's Macros menu.
When a macro is called, the Macro Console
displays information about the macro, including its starting
and stopping, as well as any error messages.
Macro command line
The Macro Command Line menu option opens
the Macro Command Line dialog box, which provides a command line
interface for running macros.
This dialog box
stays available unless explicitly closed, so it is a
step-saver for macro testing.
Macro-running indicator
A ... macro running indicator is now displayed on the Client's
title bar while a macro is running or waiting.
Watching mixed-case global variables
Prior to this feature, you add a global variable to the Client's
Watch Window by specifying the variable name (in any case) preceded by
“G.” or “g”.
Then the Debugger searched for (only) the variable with the
all-uppercase form of the variable's name.
As of Sirius Mods 7.2, if you enclose the variable name in single quotation
marks, however, the Debugger will search for exactly the case of
the characters that you specify.
Keyboard-invoked consecutive searches
These two changes to the Search feature enable
keyboard-invoked consecutive searches:
The default response to pressing the Enter key while the
Search text box has focus is changed from "search from the
top" to "search from current line."
This lets you press Enter
repeatedly to find subsequent occurrences of a search string.
Formerly, pressing Enter again
found the same occurrence as the first time, because it repeated the search
from the top.
Note:This introduces a small upward incompatibility.
The new focusToSearchBox command gives the input focus to the
Search string text area.
The Ctrl+F key combination is changed to perform the same function by default.
New mappable commands
These mappable commands are added:
addWatchOnCurrentLine
Adds to the Client Watch Window any variables found in the current
Source Code line.
It is the same as right-clicking a line and selecting Add Watch from
the context menu.
The new Data Display menu item Add Watch on Current Line has the same
effect as this command.
toggleBreakpointOnCurrentLine
Sets (or removes) a breakpoint for the current Source Code
line if the line is or starts an executable statement.
It is the same as double-clicking a line or right-clicking a
line and selecting Toggle Breakpoint from the context menu.
The new Breakpoints menu item Toggle Breakpoint on Current Line
has the same effect as this command.
reloadWhiteList
Updates the existing White List with the current contents of
the whitelist.txt file, so you can dynamically update your White List.
Same as clicking the Reload White List button on
the Proc Selection page.
The new Execution menu item Reload White List
has the same effect as this command.
turnOnWhiteList, turnOffWhiteList
Activates or deactivates White List filtering (like clicking the Turn
On White List button or the Turn Off White List button
on the Proc Selection page).
The new Execution menu items Turn On White List and
Turn Off White List have the same effect as these commands.
runUntil
Runs program code without interruption until it reaches a
specific procedure, then displays that procedure for
debugging.
Its required argument is the name of, or a character pattern for, the
target procedure.
Having the same effect as the Run Until Procedure button.,
this command was formerly a macro-only command.
The new Execution menu item Run Until Proc
has the same effect as this command.
ON UNIT code debugging
An exception to ordinary request-cancellation handling is added
for the purpose of ON UNIT code debugging.
Instead of stopping you from stepping through a request when the request
has a canceling error, the Client lets you continue in the exceptional
case of the following error only
(which occurs within a User Language ON UNIT):
M204.1982: ILLEGAL JUMP ATTEMPTED OUT OF COMPLEX SUBROUTINE ON UNIT
Reporting for DEBUGGERSERVER and DEBUGGERCLIENT Janus ports
The DEBUGGERSERVER and DEBUGGERCLIENT Janus ports defined for the Debuggers
are now reported as DEBUGSRV and DEBUGCLI ports, respectively, in the
output from JANUS STATUS and JANUS DISPLAY commands.
Formerly, they were reported as SRVSOCK and CLSOCK types.
Janus SOAP ULI
The following sections describe changes in the
Janus SOAP ULI in this release.
The Dataset class
The Dataset classes provide an object-oriented interface to sequential datasets.
This interface is more flexible than the traditional image-oriented
interface used in User Language.
In addition, they provide User Language access to Model 204 streams —
datastreams composed of one or more sequential datasets via the Model 204
DEFINE STREAM command (see the
Model 204 Command Reference Manual.
The Dataset class operates on datasets or streams defined by any of the
following:
An MVS DD card.
A VSE DLBL card.
A CMS FILEDEF command.
A Model 204 ALLOCATE command.
A Model 204 DEFINE STREAM command.
The Dataset class uses two class-specific enumerations: the RecordFormat
enumeration, and the DatasetState enumeration.
RecordFormat Enumeration
The RecordFormat enumeration indicates the format of the blocks in the sequential
dataset.
While, strictly speaking, the RecordFormat enumeration actually describes block
formats or maybe file formats, it corresponds to the RECFM value used in DD cards,
ALLOCATE statements, etc., so the term RecordFormat was used.
The DatasetState Enumeration
The DatasetState enumeration describes the current state of a Dataset object.
A newly created Dataset object starts in the Closed state and then changes state
as certain methods are performed on it.
Certain methods are restricted to Dataset objects in a particular subset of
states.
Dataset methods
The following dataset methods are available:
Blocksize property
Indicates the blocksize for the underlying dataset.
Close subroutine
Closes an open dataset.
Discard subroutine
Discards a dataset object.
New constructor
Creates a new dataset object, associating it with a sequential dataset
or stream.
NumberOfBuffers property
Indicates the number of virtual storage buffers to be used, or being used,
to read or write blocks of data.
Output property
Indicates whether or not the dataset is to be used for, or is being
used for, output (written to).
ReadBlock function
Reads a block of data from the dataset.
ReadRecord function
Reads a record from the dataset.
RecordFormat property
Indicates the record and block format for the underlying dataset.
RecordLength property
Indicates the record length for the underlying dataset.
SirtuneReport function
Reads a SirTune sample dataset and produces a report (in XML format)
summarizing the data in that sample dataset.
This function is only available to sites authorized for SirTune.
WriteBlock subroutine
Writes a block of data to the dataset.
WriteRecord subroutine
Writes a record to the dataset.
Intrinsic classes
User Language is a legacy programming language for which object-oriented capabilities are a
relatively recent addition.
So, one might expect that strings and numbers are not maintained internally
as objects, since their existence pre-dates objects.
This is in fact the case, though as has been shown, this is largely
irrelevant from a User Language programmer's perspective,
And even if object-oriented capabilities were present in User Language from its inception,
strings and numbers might have been special-cased for efficiency anyway.
However, beyond the internal representation of strings and numbers,
a distinction between User Language and pure object-oriented languages was that
the object:method syntax was not used to manipulate strings and numbers;
instead, strings and numbers were manipulated via $functions.
In Sirius Mods 7.2, this has been changed to allow the
object:method syntax against string and numeric variables and constants.
The following code fragment illustrates how the same operation can be accomplished
via traditional $functions and via object-oriented syntax:
%name is string len 32
print $len(%name)
print %name:length
While this might not seem very significant, it provides considerable value:
It allows User Language to be used as a “pure” object-oriented language.
This might be especially appealing to programmers who were trained in
a pure object-oriented language.
It provides the benefit that expressions can generally be read in the
natural left-to-right manner rather than the inside-to-outside manner required
to understand an expression coded with $functions.
It provides capabilities to methods that operate on strings or numbers
that are not available with $functions.
These include support for named parameters and the ability to take objects
as input parameters and to produce objects as results.
While it would have been possible to extend $functions to have this same
functionality (much as Sirius Mods provided callable $function support),
it makes more sense to provide it using true object-oriented syntax.
Given that this has now been done, it is unlikely that these capabilities
will ever be added to $functions.
Intrinsic method objects
The term “method object” (or “intrinsic method object”) is used for
the value or variable to which an intrinsic method is applied,
even though the value or variable isn't really an object.
This is justified because, strings and numbers can be considered
immutable objects, regardless of their history or internal representation.
For example, in the following case,
%str is the intrinsic method object for the Length method:
%str is string len 32
print %str:Length
Intrinsic methods can be applied to constants, in addition to variables.
For example, the following assigns the length of the string literal
“Whatever” to %x:
%x = 'Whatever':length
Intrinsic methods can, of course, take the output from another method,
intrinsic or not, as its input:
For example, the following uses the Right method (which gets the
rightmost characters of a string) against the output of a Stringlist
Item method:
%list is object stringlist
%value = %list:item(%i):right(8)
Of course, since it is unnecessary to specify the Item method for
a Stringlist, the above can also be written as:
%list is object stringlist
%value = %list(%i):right(8)
Intrinsic methods can also be applied to image and screen items:
image michigan
romulus is string len 32
end image
%value = %michigan:romulus:right(8)
Intrinsic methods can also be applied to the output from a $function:
%seconds = $time:right(2)
Intrinsic methods can even be applied to the results of expressions:
%value = (%tweedledum with %tweedledee):right(8)
As with other methods, the colon that separates the method object from
the method name can be optionally preceded or followed by spaces.
This could be done to enhance readability, or even to split a long line.
The following four statements are all equivalent:
As with most other uses of intrinsic variables or values, if the method
object is of a different type than the data type on which the method
operates, the input value is automatically converted into the target
datatype.
For example, the expression 7/3 clearly produces a numeric
value, but the Left method operates on strings.
So, in the statement:
%i = (7/3):left(4)
the result of the division is converted into a string and then passed
to Left, which produces 2.33 as its result.
Because of this automatic conversion, the specific class (String or Float) of
an intrinsic method cannot be determined from the datatype of its method
object.
This means that the class must be determined only from the name
of the method, which means that method names must be unique among all
intrinsic classes (that is, among String, Float, and Fixed).
For example, there may not be a Length method in both the String and
Float intrinsic classes.
In the case of Length, the method is an intrinsic String method.
Intrinsic Float methods
The individual intrinsic Float methods are described in the following sections.
Float intrinsic methods treat their method object as a Float value.
Any value that is not a Float value is automatically converted before it is
acted on by the method.
SquareRoot function
This function returns a number that is the square root of the method object.
An attempt to get the square root of a negative number results in request
cancellation.
%value = number:squareRoot
Intrinsic String methods
The individual intrinsic String methods are described in the following sections.
Intrinsic String methods treat their method object as a Longstring value.
Any value that is not a String value is automatically converted before it is
acted on by the method.
Base64toString function
Base-64 encoding is useful for encoding strings that might contain
binary or other characters that could cause problems in certain contexts.
This function returns the unencoded value of a base-64 encoded string.
%out = string:base64toString
HexToString function
This function returns the unencoded value of a hex encoded string.
Hex (short for hexadecimal) encoding is usually used for debugging
when there is a concern that non-displayable characters (including
trailing blanks) might be present in a string.
By hex encoding such a string, all non-displayable bytes are converted
to displayable hexadecimal equivalents.
%out = string:hexToString
Left function
This function returns the left-most characters of the method object string,
possibly padding it on the right.
%out = string:left(length, [Pad=char])
Length function
This function returns the length in bytes of the method object string.
%len = string:length
PositionIn and PositionOf functions
These functions return the numeric position of the first occurrence of one string
inside another.
The difference between the two methods is that for PositionIn, the method
object string is located in the first argument string, whereas for
PositionOf, the first argument string is located in the method object string.
Which is more convenient to use will be application dependent.
This function determines whether a given pattern (regular expression,
or “regex”) matches within a given string according to the “rules” of
regular expression matching.
%pos = string:regexMatch(regex [,Options=opts])
RegexReplace function
This function searches a given string for matches of a regular expression, and it
replaces matches with, or according to, a specified replacement string.
The function stops after the first match and replace, or
it can continue searching and replacing until no more matches are found.
Matches are obtained according to the “rules” of regular
expression matching.
This method repeatedly applies a regular expression,
or “regex,” to the method object string until it has tested the entire string.
This splits the string into the substrings that are matched by the regex
(the "separators") and the substrings that are not matched.
By default, the method saves each unmatched substring as a separate
item in the StringList result object.
The leftmost unmatched substring is the first item in the StringList, the next leftmost
is the second item, and so on.
A simple application of the method is to extract only the data
items from a string of comma-separated data items.
If the specified regex is a comma, each of the resulting StringList
items will contain one of the data items.
RegexSplit uses the rules of regular expression matching.
To diagnose or correct or reduce the damage from run-time errors
that occur in places in a program where the use of a request
cancellation, return-value processing, or output-parameter processing
are insufficient, the Janus SOAP ULI introduces exception handling.
Exception handling consists of three parts:
The ability to define classes of exceptions and the information available
for these classes.
Unsurprisingly, classes of exceptions are defined in almost the same way as other
classes.
The ability to indicate an unusual or exception situation.
This is referred to as throwing an exception.
The ability to detect a thrown exception and to perform special processing
for the exception.
This is known as catching an exception.
Although the Janus SOAP ULI exception handling support is very similar to many other
object-oriented programming languages, such as Java or VB.Net,
each language's implementation of exception handling has
subtle or not so subtle differences from the others.
As a significant example,
while many object-oriented languages make all (or almost all) errors exceptions,
Janus SOAP ULI does not.
This is partially because many object-oriented languages are not, strictly speaking,
application languages — in addition
to writing applications in some other object-oriented languages,
one might write programming environments or even operating systems.
As such, a programming environment or operating system must be able to
intercept all errors and try to deal with them, so the object-oriented languages
facilitate this by making all errors catchable.
User Language is an application development language.
While it is theoretically possible to build a program environment in User Language,
or even an operating system, this is not really the focus of User Language and it is
not likely anyone would ever do this.
The User Language programming environment (Model 204, which is not, itself, written in User Language)
is responsible both for the ultimate catching of errors and the providing of
information about the nature of the errors so that they can be corrected.
The kinds of errors that Janus SOAP ULI does not turn into exceptions,
and thus are not trappable, fall into two broad categories:
Pernicious environmental errors from which it would generally be
almost impossible to recover gracefully on an application level.
For example, if CCATEMP fills up, it is exceedingly unlikely that a
request could recover gracefully.
Since CCATEMP is used for so many different things (including record
sets for finds, stringlists, collections, internal storage of objects
swapped out of a server, transaction backout logs, and so on), it would
be very difficult for an application to anticipate all the places that
CCATEMP could fill.
And even if it could anticipate the places, it would be very difficult to avoid
doing anything that might also require CCATEMP.
Errors that are indicative of logic errors in a program.
For example, a class member reference via a null object variable is usually
indicative of a programming error.
Similarly, a reference to an invalid collection item number is also generally
indicative of a programming error.
While there might be error-causing cases of “sloppy” references to
object variables or collection items that you would want to simply catch
when they happen:
Most of these are handled well by existing facilities such as Auto New
and also UseDefault processing for collections.
In the odd cases where such sloppy references are useful, it is trivial
and efficient to check for the sloppy references (null object variable,
invalid collection item number), so an exception-handling paradigm
adds little value.
Exception class definitions
The collection of data describing an error situation might be used
immediately after the error is detected, or it might be examined elsewhere.
As such, this error data should be able to persist indefinitely.
Given this requirement, it is clear that the logical place to
hold error information is inside an object.
And the description of the data associated with a particular error would be a class.
Classes that describe trappable error situations are called exception classes.
To a large degree, exception classes are no different from any other class:
They can have Public, Private, and Shared blocks; they
can have variables, methods, and the same Allow and Disallow rules
as any other class.
There can be system exception classes,
which are maintained by the Janus SOAP ULI environment, and there can be User Language
exception classes, which are defined and maintained by User Language code.
Exception classes can be used wherever non-exception classes are used,
although the reverse is not true.
That is, there are certain statements that require an exception class or
an object of an exception class.
This is largely to prevent accidental misuse of a non-exception class
in an exception class context.
User Language exception classes are denoted by using the Exception
keyword in the class header:
class tackyColor exception
One can think of the Exception keyword on the Class declaration
as indicating that the class extends some hidden base class.
You can put the Exception keyword on almost all class declarations;
specifying it removes no capabilities from the class.
Doing so, however, is misleading, since most classes are likely never to be used
to indicate error situations.
In this regard, you can view the Exception keyword on a class declaration as
documentation that a class can be used as an exception class.
While the compiler cannot ensure that a class with an Exception
declaration will be used as an exception, it does ensure that a
class not declared as Exception is not used in exception contexts.
The one case where the Exception keyword is not allowed on class declarations
is in declarations that extend non-exception classes — exception classes
can only extend other exception classes.
Throwing exceptions
When an error situation occurs, the code that detects the situation can do
one of two things:
It can cancel the request.
In User Language this is done with an Assert statement.
In system code, this is done by some equivalent of the Assert statement.
This is the correct response to an error if the error is clearly indicative
of a programming error or a severe environmental constraint that is likely
to make request continuation unproductive.
It can throw an exception.
In User Language this is done with a Throw statement.
In system code, this is done by some equivalent of the Throw statement.
This is the correct response to an error if the error might occur in the
normal course of processing and the code that called the method might be
able to recover from the error.
Note:
In the Janus SOAP ULI implementation of exceptions, exceptions can only
be thrown by methods.
In both system and User Language methods, a thrown exception can only be handled
(caught) by the code that called the method, as opposed to
inside the same method that threw the exception.
The exceptions that might be thrown by a method
must be documented in the method header.
Specifying a Throws clause
The exceptions thrown by a method are indicated by the Throws
clause in the method declaration and definition header.
For example, if the method Paint might throw a TackyColor and InvalidHexData
exception, it should be declared and defined as:
subroutine paint(%hexColor is string len 6) -
throws tackyColor and invalidHexData
The keyword and is used to separate the exceptions
that might be thrown by a method.
The method can only ever throw one exception
at a time, and in most cases, it will not throw an exception at all.
The list of exceptions after a Throws keyword is the list of exception
class names.
These class names could be User Language exception class names, or they could be system
exception class names.
If the class is a system class name, it could be fully qualified with the
System: namespace indicator.
For instance, the previous example could be written as
subroutine paint(%hexColor is string len 6) -
throws tackyColor and -
system:invalidHexData
As with most method descriptions, the Throws clause on a method declaration
and definition must match exactly.
Methods that implement an overridable method cannot throw any
exceptions not thrown by the implemented method; however, they do not
necessarily have to throw all the exceptions thrown by the implemented
method.
Using the Throw statement
Once a method declaration indicates the exceptions it might throw,
that method could then throw the exception with the Throw statement.
The Throw statement must be followed by an instance of the exception
class being thrown.
For example, if the method header contains
subroutine paint(%color is string len 6) -
throws tackyColor
and there is a variable declaration in the method
%tacky is object tackyColor
the method could do
throw %tacky
An attempt to throw an exception object whose class does not match one
of the classes listed in the method declaration's Throws clause results
in a compilation error.
Exception classes extending other exception classes
Exception classes can extend other exception classes.
As such, the class of an object specified in a Throw statement does not
have to match any class in the method's Throws list exactly —
it can be of an extension class of one of the Throws list classes.
Because an extension class can, itself, be extended, and because of
multiple inheritance, this means that a Thrown exception object might
match multiple classes in a method's Throws list.
The thrown (and so catchable) class is the first class in the Throws
list that matches the object in the Throw.
That is, the first class in the Throws list that exactly matches the thrown
object's class or that is a base class of the thrown object is used as the thrown
class for the method caller.
Try and Catch
Without any action on a method caller's part, a thrown exception is,
for all intents and purposes, a request cancelling error.
To prevent the request cancellation, an exception must be “caught.”
This is achieved by the use of a Try/Catch block.
A Try/Catch block consists of two parts.
The first, the Try section contains one or more User Language statements that
might result in an exception.
The Try section is then followed by one or more Catch sections, each
one of them handling (catching) a particular class of exception.
The following fragment illustrates the use of a Try/Catch block to trap
an exception caused by invalid hexadecimal data:
The end of the statements whose exceptions are being caught is indicated
by the first Catch block.
The class of exceptions being caught follows the Catch statement.
A catch block is terminated by another Catch statement or an End Try.
One can catch multiple exception types, each within its own Catch block.
There is no validation that the type of exception being caught might
actually be thrown inside the Try block.
What gets thrown with an exception is an exception object that contains
information about the nature of the exception.
To reference the thrown exception object, you must specify a
To clause, followed by an object variable of the exception class being caught.
For example, if %daemon is a Daemon object and %daemonLost
is an object of the DaemonLost exception class, the following block
catches the exception thrown if the daemon thread was logged
off for some reason, and it displays the output of the last command
up to the point where it logged off:
try %daemon:run('INCLUDE NASTY')
catch daemonLost to %daemonLost
printText Daemon died! Its last words were:
%daemonLost:daemonOutput:print
end try
Some differences with other languages
The following are some differences between the Janus SOAP ULI implementation
of Try/Catch and implementations in other languages.
Outside of these differences, Try/Catch
support in Janus SOAP ULI is very similar to that in other languages.
Unlike Java, it is not necessary to provide a Catch for all exceptions
that a method might throw.
Unlike many other languages, uncaught exceptions are not automatically
propagated to higher level callers.
Partially, this is because the User Language environment is not written in User Language, so
there is no need to propagate exceptions to some outer User Language environment
which, presumably, would clean up the failing request and possibly provide
diagnostics about the error.
Instead, clean-up and diagnostics are provided by the assembler environment.
The absence of automatic exception propagation eliminates the utility of a
Finally clause
(to “ensure” that the method
doesn't leave things in a half-done state),
so no Finally clause is available in Try/Catch blocks in User Language.
Catches cannot catch locally thrown exceptions.
That is, a Throw statement always results in immediate exit from the current
method, regardless of whether or not the Throw is inside of a Try block and
whether or not there are Catches that correspond to the thrown exception.
Nesting Try/Catch blocks
Like in other languages, Try/Catch blocks can be nested.
That is, a Try/Catch block can be inside the try or catch clause of another
Try/Catch block.
OnThrow and OnUncaught
An exception class might want to perform special processing at the time an
exception is thrown:
It might want to make sure the exception object has valid data.
It might want to record diagnostic information, perhaps to the audit
trail or perhaps to some Model 204 file.
It might want to derive some variable values that might not necessarily
have been derivable in the constructor.
To provide this capability, Janus SOAP ULI special-cases two method names in a
User Language exception class: OnThrow and OnUncaught.
Both of these methods must be subroutines (as opposed to Functions or
Properties) and cannot have parameters.
The OnUncaught subroutine is automatically called whenever an exception
of the containing class is thrown, and the exception will not be caught.
The OnThrow subroutine is automatically called whenever an exception
of the containing class is thrown, and either the exception will not be
caught and there is no OnUncaught method in the class, or the exception
will be caught.
These two method names have no meaning in non-exception classes.
These methods can be called explicitly, and they can be either Private
or Public (though whether they are Public or Private is irrelevant for
implicit calls when an exception is thrown).
The following illustrates an OnThrow subroutine that makes sure the
exception data is valid at the time an exception is thrown:
class pratfall exception
public
variable sound is string len 32
subroutine onThrow
end public
subroutine onThrow
assert %this:sound eq 'splat' or -
%this:sound eq 'boing'
end subroutine
end class
The following illustrates an OnUncaught subroutine that logs information
from the exception to the audit trail before allowing the request to be cancelled:
class pratfall exception
public
variable sound is string len 32
subroutine onUncaught
end public
subroutine OnUncaught
auditText Taking a pratfall -- {%this:sound}
end subroutine
end class
If SirFact is available and capturing dumps for requesting cancelling
errors, all the information one would need is likely to be in the dump,
so there is probably little need to collect extra data in an OnUncaught
subroutine.
There is no way for an OnUncaught or OnThrow subroutine to undo the
effect of the exception, that is, to prevent a request cancellation
if the exception is uncaught.
Both routines, however, can force a request cancellation,
perhaps by using an Assert statement, even if the exception would
have been caught.
If a request cancellation occurs inside on OnThrow subroutine for
an exception that's about to be caught, the catching statements
are not executed, because the request is cancelled before the
OnThrow subroutine returns.
The Throws clause is invalid on an exception class's OnThrow and
OnUncaught subroutines, so these subroutines cannot, themselves,
throw an exception.
System Exception classes
As already described, classes that describe trappable error situations are called exception classes.
System exception classes are maintained by the Janus SOAP ULI
environment, while User Language exception classes are
defined and maintained by User Language code.
The system exception classes added in Sirius Mods 7.2 are described in the
following sections.
DaemonLost class
The DaemonLost exception class indicates that a daemon thread associated
with a daemon object was lost, most probably because of a user restart.
InvalidBase64Data class
The InvalidBase64Data exception class describes an exception associated with
finding non-base64-encoded data where base64-encoded data was expected,
usually when decoding base64-encoded data.
InvalidHexData class
The InvalidHexData exception class describes an exception associated with finding
non-hexadecimal data where hexadecimal data was expected, usually
when translating the hexadecimal data to something else.
InvalidRegex class
The InvalidRegex exception class describes an exception associated with an
invalid regular expression being passed to a method that takes a regular expression
argument.
NoFreeDaemons class
The NoFreeDaemons exception class indicates that the Daemon class constructor
was invoked, but there were no daemon threads available to service the object.
Enhancement methods
When using a class, it is not uncommon to want to perform operations
on objects of the class that are not one of the standard methods
provided by the class.
Before Sirius Mods version 7.2, there were three ways of addressing this:
Add a new method to the class.
Create an extension of the class that contains the new method.
Create a shared method in another class that takes objects of
the first class as input parameters.
Sirius Mods version 7.2 introduced a new type of shared method called an
enhancement method to provide a better way of invoking a
method on an object of another class.
Because enhancement methods do not operate on objects of the containing
class, they are considered shared methods of that class, so they are declared
inside the Public Shared or Private Shared blocks of the class.
An enhancement method declaration has the following syntax:
(): []
Where:
<method>
The method type — Subroutine, Function, or Property.
An enhancement method cannot be a constructor.
<class>
The class of the objects to which the method applies.
It cannot be the containing class nor an extension class of the
containing class.
<name>
The name of the enhancement method.
The name can be the same name as that of other methods in the class,
shared or non-shared, as long as it is not the same name as an enhancement
method on the same class.
<otherMethodDesc>
Method parameters, method type (for Functions and Properties), and
other method qualifiers (like AllowNullObject).
Any descriptors available to other methods are available to enhancement methods.
An enhancement method invocation has the following syntax:
Where:
<object>
An object variable of the class against which the enhancement method
operates.
<+containerClass>
The name of the class that contains the enhancement method definition.
Note that the class name must be preceded by a plus sign (+) to
indicate an enhancement method invocation.
The plus sign distinguishes an enhancement method container class name
from other uses of class names inside parentheses that might appear in
the same context.
<name>
The name of the enhancement method.
<parameters>
Any arguments the enhancement method might take as input.
Optional, default, and named parameters work exactly the same way with
enhancement methods as with any other methods.
For example, to declare and define an enhancement method version of
an “EveryOther” method, one would do something like the following:
class utility
public shared
function (stringlist):everyOther -
is object stringlist
end public shared
function (stringlist):everyOther -
is object stringlist
%i is float
%outList is object stringlist
%outlist = new
for %i from 1 to %this:count by 2
%outlist:add(%this(%i))
end for
return %outlist
end function
end class
As can be seen in this example, an enhancement method has an
implicitly declared object variable called %this.
As with unshared methods, the %this variable is a reference
to the method object.
Unlike unshared methods, the %this variable is not an object of
the containing class, but is, instead, an instance of the class
to which the enhancement method applies.
This enhancement method could then be invoked as follows:
%mylist:(+utility)everyOther:print
As this example illustrates, the syntax for invoking an
enhancement method is more natural from an object-oriented perspective than
invoking a shared method that does the same thing.
Using an enhancement method in a chain of methods makes this point
even clearer:
%mylist:sortNew('1,20,A'):(+utility)everyOther:print
This chain of methods can be read from left to right rather than from the inside out.
Enhancement methods and inheritance
Enhancement methods are never automatically inherited by extension
classes of the methods to which they apply, regardless of whether
the Inherit keyword is specified on the class declaration for the
extension class.
For example, the EveryOther method
in the preceding section cannot be directly applied
to %mylist if %mylist is actually an object of class Funnylist,
where FunnyList is an extension of class Stringlist.
However, the method can be applied by explicitly specifying
the name of the class to which the method applies:
%mylist:(stringlist)(+utility)everyOther:print
In some languages this is referred to as casting,
that is, casting a variable as one of its base classes.
You can also explicitly indicate that an extension class is to
inherit a base class's enhancement method with a special form
of the Inherit statement in the Public or Private Shared blocks:
public shared
function (stringlist):everyOther -
is object stringlist
inherit (funnylist):everyOther from stringlist
end public shared
If this were specified, the EveryOther enhancement method could
be applied to objects of class Funnylist without any extra qualification.
Note: Because an enhancement method is not defined in the class
to which the method applies, it cannot reference private variables in that class.
However, it can reference private members of instances
of objects of the containing class.
In fact, one typical application for enhancement methods is to
provide a method for creating a new instance of the containing
class from an instance of the method object class.
These are a special kind of factory method.
Such a method might not need to access private members of the
method object class, but it might need to access private members of
the containing class, so an enhancement factory method is
perfectly suitable.
Intrinsic Enhancement methods
In addition to Enhancement methods, Sirius Mods 7.2 introduces
Intrinsic methods and classes (Intrinsic classes).
And, just as you can create enhancement methods for other system
classes, you can create enhancement methods for intrinsic classes,
specifically for the Float and String classes.
For example, the following definition creates an enhancement method that
calculates the length of the hypotenuse of a triangle given the
length of one side as the method object and the other side as a parameter:
class calc
public shared
function (float):hypotenuse(%otherSide is float) -
is float
end public shared
function (float):hypotenuse(%otherSide is float) -
is float
return ((%this * %this) + -
(%otherSide * %otherSide)):squareRoot
end function
end class
You can invoke the above method as follows:
%hyp = 3:(+calc)hypotenuse(4)
The preceding statement sets %hyp to 5.
As can be seen in this example, for a Float enhancement method, the
implicitly defined %this variable has a Float datatype.
The following is an example of a String enhancement method that returns
the number of vowels in a string:
class myString
public shared
function (string):vowels is float
end public shared
function (string):vowels is float
%i is float
%vowels is float
for %i from 1 to %this:length
if %this:substring(%i, 1): -
positionIn('aeiouAEIOU') then
%vowels = %vowels + 1
end if
end for
return %vowels
end function
end class
You can invoke the above method as follows:
%nvowels = 'Canberra':(+myString)vowels
The preceding statement sets %nvowels to 3.
For a String enhancement method, the implicitly defined %this variable
has a Longstring datatype.
Enhancement methods for Collections
Enhancement methods can be added to any class, including
Collection classes (Arraylists, NamedArraylists, and so on).
Given this capability, it is quite common for a class to have
a need to create an enhancement method on a collection of that class.
For example, you might have an Order class that describes an order for widgets.
You might want to provide an enhancement method on Arraylist of
Order objects that creates a new Arraylist of objects that contains
items that need to be back-ordered (there are insufficient widgets
in stock to satisfy the order).
The method might look something like:
class order
public shared
function (arraylist of object order):backorderlist -
is collection arraylist of object order
end public shared
function (arraylist of object order):backorderlist -
is collection arraylist of object order
%i is float
%warehouse is object warehouse global
%newlist is collection arraylist of object order
%newlist = new
for %i from 1 to %this:count
if %this(%i):number gt -
%warehouse:instock(%this(%i):widgetId)
%newlist:add(%this)
end if
end for
return %newlist
end function
end class
To invoke this enhancement method, one might do something like:
%backOrders = %orders:(+order)backOrderlist
However, because a class has a special relationship to collections of objects of that
class, it is not necessary to indicate the class of the enhancement method.
That is, you can also write the above method invocation as:
%backOrders = %orders:backOrderlist
It is possible to create enhancement methods with the same name as
standard collection methods.
For example, it is possible to create an Add method.
If you create such a method, the collection class method is completely hidden.
That is, there is no way to invoke the collection class method of the same
name, even from inside the enhancement method.
For this reason, it is generally not a good idea to create an enhancement
method for a collection class with the same name as a collection class
method.
The ability to hide collection class methods is available mainly to preserve
backward compatibility when a new collection class method is introduced.
If there were already enhancement methods of the same name, those methods
would continue to be invoked.
ReadOnly and Protected variables
In Sirius Mods 7.2 and later, it is possible to to declare a class variable
as ReadOnly or Protected.
A ReadOnly variable can be examined by code outside the class, but it can only
be updated inside the class.
A Protected variable can be examined by code outside the class, but it can only
be updated inside the class or by code inside an extension class.
Since a ReadOnly or Protected variable must be accessible outside the class,
it would make no sense for such a variable to be in a Private section, so this
is not allowed.
ReadOnly and Protected variables are useful for providing an efficient means of
accessing relatively static information about objects in a class.
Unlike a property, retrieving ReadOnly or Protected variables requires no code
to be run in the class.
The term Protected is something of a misnomer.
In a very real sense, Protected variables aren't protected, at all.
After all, they can be updated by extension classes.
Their real purpose is to act as a sort of overridable variable, that is, a
value that can be overridden by an extension class.
For example, suppose a class has a ReadOnly variable called PartNumber.
Perhaps PartNumber is set by the class's constructor, and then it is never set
again (for a particular object instance).
Now, suppose this class wants to allow extension classes to set a different
PartNumber, probably in their constructors.
One approach would be to make PartNumber an Overridable ReadOnly property.
But this is a somewhat heavyweight approach, as it requires a bit of code
(the property Get method) for each extension class, and this code has to be
run every time PartNumber is retrieved.
Instead, PartNumber could be made a Protected variable, and an extension class's
constructor could simply set it after calling the base class constructor.
This allows the extension classes to override the base class's PartNumber
using little extra code and using a very efficient access path for the value.
Protected variables differ from Overridable ReadOnly properties,
however, in that an Overridable ReadOnly property always guarantees that the
extension class's code is run, so it overrides the base class's properties.
With a Protected variable, it would be possible for an extension class to
set it, and for the base class to then set it to something else, undoing
the extension class action.
Because they can be updated by both base and extension classes,
Protected variables are probably most useful for very
static values, like values that are only set by the constructors.
Use of Protected variables that can be set throughout the life of objects
of a class is likely to be error-prone, as it requires careful coordination
of updates between the base and extension classes.
New System class methods
These new methods are added to the System class:
Arguments, CallStack, CallStackDepth, and CallStackCaller.
The Arguments method
The Arguments method allows evaluation-time examination of INCLUDE arguments.
This shared function returns the arguments passed in the INCLUDE command for the
procedure that contained the Begin for the current request.
%args = %(system):Arguments
For example, if procedure FOO contained the following:
b
printText {~} = '{%(system):arguments}'
end
The following requests (preceded by >) would produce the following outputs:
> I FOO This is a test
%(system):arguments = ' This is a test'
Note that everything after the INCLUDEd procedure name is returned by the
Arguments method, including any blanks or commas after the procedure name.
The CallStack method
This shared function returns a Stringlist containing information about the current
call stack: information about the caller of the current method or subroutine,
the caller of that caller, and so on.
%callList = %(system):CallStack
The CallStack method returns the name of the procedure and the line within
the procedure that made the calls of the current method or subroutine.
Generally, each returned StringList item has the name of the file containing
the calling procedure at positions one through eight, followed by a blank,
followed by the name of the calling procedure, followed by a blank, followed
by the line number within the calling procedure.
The CallStackCaller method
This shared function returns a string containing information about the caller
of the current method or subroutine.
The information can extend back to a specific number of call levels.
%callString = %(system):CallStackCaller(%depth)
The CallStackCaller method returns the name of the procedure and the line within
the procedure that made the calls of the current method or subroutine.
Generally, the returned string has the
name of the file containing the calling procedure at positions one through eight, followed
by a blank, followed by the name of the calling procedure, followed by a blank, followed
by the line number within the calling procedure.
The CallStackDepth method
This shared function returns a number indicating the depth of the call stack.
%depth = %(system):CallStackDepth
At level-0 (immediately inside a Begin/End), CallStackDepth always returns 0.
For a method or subroutine called directly from level-0 code, CallStackDepth
would return 1.
For a method called from a method called from level-0, CallStackDepth would
return 2; and so on.
Janus SOAP Xml API
The following sections describe changes in the Janus SOAP Xml API
in this release.
Multiple XPath predicates
XPath expressions may now contain multiple predicates in a single step.
Previous versions of Janus SOAP supported some, but not all,
cases of multiple predicates.
The primary purpose of the new multiple predicate support is to let you
use the position() function to filter based
on the position of nodes from the preceding predicate, rather than
from the step's nodetest.
For example, the following expression
selects the second chapter child of the book,
if its author is Alex:
/book/chapter[author="Alex" and 2]
While the following expression
selects the second chapter child that is authored by Alex:
/book/chapter[author="Alex"] [2]
not() function in XPath predicates
The not() function is now supported in XPath predicates.
The argument is a Boolean expression, and the result is true
if the value of the argument is false, and false
otherwise.
Note: The result of the not() function applied to a comparison
expression is different than the same expression with the complementary comparison.
For example, this statement selects children that have the value of the status
attribute equal to "pending":
%lis = %nod:SelectNodes('*[@status="pending"]')
The following statement selects children that have the value of the status
attribute equal to something other than "pending":
%lis = %nod:SelectNodes('*[@status!="pending"]')
And the following statement selects children that have the value of the status
attribute equal to something other than "pending", or that have no status attribute:
An XPath expression is now allowed to have a predicate that contains a location path which
itself contains a predicate; that is, predicates may be nested.
For example, this selects Chapters whose first Section has a Racy attribute:
%lis = %bk:SelectNodes('Chapter[Section[1 and @Racy]]')
Boolean parentheses in XPath predicates
In an XPath expression that has a predicate that contains a Boolean expression,
parentheses are now allowed for grouping in the Boolean operands.
For example, the following predicate is supported by Janus SOAP
in Sirius Mods 7.2 and later:
chapter[@type="methods" and
(@class="Stringlist" or @class="Daemon")]"
URI now allows hexadecimal escape (%hh)
The various places in Janus SOAP that process a URI (for example, the third
argument of the AddElement method, or the string input to the LoadXml method)
now allow a URI to contain a “hexadecimal escape,” that is, a percent
sign (%) followed by two hexadecimal digits (which may be either uppercase
or lowercase when the letters A-F are used).
Note that there is no replacement of the hexadecimal values when URI
processing is performed.
For example, even though the ASCII code for the number “4” is
hexadecimal 34, the following two URIs are different and distinct:
http://my.URI.number4
http://my.URI.number%34
Thus, for instance, the following fragment:
%n = %d:AddElement('x', , 'http://my.URI.number4')
%n:AddElement('x', , 'http://my.URI.number%34')
%d:Print
%d:SelectionPrefix('f') = 'http://my.URI.number4'
Print %d:SelectCount('//f:x') And 'matching node(s)'
Will have the following result:
1 matching node(s)
Janus Sockets
The following features are new or changed in Janus Sockets:
HTTPRequest class Send method
Prior to the addition of the Send method, the
HTTPRequest class had methods only for HTTP GETs and POSTs.
The new Send method is a way to carry out HTTP methods in addition to GET or POST.
The Send function sends an HTTP request to an HTTP server
using a parameter value to identify which of any of the HTTP method types
(GET, POST, PUT, and so on) you want the function to perform.
Any HTTP method type is valid as long as its name is 16 characters or less.
The HTTP method type is specified with the Method (name required) parameter.
If you set the Method value to GET or POST,
the Send method invocation becomes equivalent to the existing Get method
or Post method, respectively, of the HTTPRequest class.
The following features are new or changed in Janus Web Server:
Support for additional HTTP method types
Janus Web Server now accepts any HTTP method in a request as long as the method
name is 16 bytes or shorter.
This feature is provided by:
Adding support for specifying additional HTTP method types
in Janus Web rules.
The new OTHER option in the method parameter in the
JANUS WEB command refers to all methods other than PUT, GET, POST, and HEAD.
A method whose name exceeds 16 characters is not allowed.
Examples of rules that use OTHER follow:
JANUS WEB WEBPORT ALLOW OTHER * USER *
JANUS WEB WEBPORT ON OTHER /WEBDAV/* OPEN FILE WEBDAV CMD 'I *'
The ANY option of the method parameter
now means any HTTP method whose name is 16 bytes or shorter.
Prior to Sirius Mods version 7.2, ANY referred only to PUT, GET,
POST, or HEAD.
Note:
This is a slight backward incompatibility: if a web rule specifies ANY,
URLs indicating methods other than GET, POST, PUT, or HEAD may now trigger
unexpected Web Server actions.
You can detect the method type in an application by a $web_hdr_parm('METHOD') query.
Sirius Functions
The following are new or changed features in the Sirius Functions:
NOURGMSG option of $Wakeup
Prior to Sirius Mods 7.2, the waiting time that remains for a user
paused by a $Wakeup call
is cancelled if a BROADCAST URGENT message is sent to the user.
As of Sirius Mods 7.2, the $Wakeup function accepts an optional argument so that
BROADCAST URGENT does not cause the $Wakeup function time to complete.
The string NOURGMSG (or any upper/lower case variant) is the
optional argument for $Wakeup that prevents a paused user from being immediately
wakened by BROADCAST URGENT.
$Lstr_Word return word longer than 255 bytes
The $Lstr_Word function now may return a Longstring, whose length exceeds 255 bytes.
Previously, attempting to return such a result either caused request cancellation,
or caused truncation to 255 bytes of the returned string.
Compatibility/Bug fixes
Please refer to the
Notes for Sirius Mods Version 7.2 for a discussion of any compatibility
issues with prior versions of the Sirius Mods and any bugs which have
been fixed in this version, but had not, as of the date of this release, been fixed
in the immediately prior version.
Fast/Unload Version 4.4 was released in September, 2007.
The major enhancements are summarized below.
Please refer to the
Fast/Unload Release Notes Version 4.4 for more detailed information.
New Features
The principal purpose of the release of version 4.4 of Fast/Unload is
to support the FILEORG X'80' feature introduced in Model 204 V7R1.
In addition, the OPEN command in a “batch” Fast/Unload job (that is, not
using the Fast/Unload User Language Interface) now allows specification of multiple filenames,
allowing the unload of an ad-hoc group of files.
OPEN statement for ad-hoc groups
Your FUEL program now may specify a group in the OPEN statement.
There are two alternatives to the OPEN statement:
OPEN FILE filename
This form indicates that a single file is to be opened, with the given name.
OPEN filename1 [, filename2] ...
This form, if there is more than one filename in the comma-separated
list, indicates that a group of files is to be opened, with DD names
filename1, filename2, etc.
With this new capability, you are no longer required to use the Fast/Unload User Language Interface
to unload a group.
#FILENAME special variable
The #FILENAME special variable is now available.
It obtains the name of the file currently being unloaded.