Document revision date: 19 July 1999 | |
Previous | Contents | Index |
To perform a given string manipulation operation, you can often choose one of several routines from the Run-Time Library. The LIB$, OTS$, and STR$ facilities all contain string copying and dynamic string allocation routines. Furthermore, a MACRO or BLISS program can call several of these routines using either a JSB or CALL entry point.
You should consider the factors discussed in the following sections
when choosing a routine to perform the desired operation.
2.3.1 Efficiency
One of the major considerations in choosing among several routines is the efficiency of the various options.
In general, LIB$ and STR$ routines execute more efficiently than the corresponding OTS$ routines. OTS$ routines usually invoke the LIB$ entry point to perform an operation.
JSB entry points usually execute more efficiently than CALL entry points. However, a high-level language cannot explicitly access a JSB entry point. Further, a JSB entry point does not establish a stack frame and executes entirely in the environment of the calling program. This means, for instance, that the called routine cannot establish its own condition handler, so it cannot regain control if an exception occurs during execution. Also, some of the efficiency gained by using the JSB entry point may be lost because the calling routine must explicitly save all of the registers that the called routine uses.
Some routines perform a specific operation that is a subset of a more
general capability. These more specialized routines are usually more
efficient. For example, if you want to join two strings together,
STR$APPEND and STR$PREFIX are more specific, and more efficient, than
STR$CONCAT. Similarly, STR$LEFT and STR$RIGHT are subsets of the
capabilities of STR$POS_EXTR.
2.3.2 Argument Passing
The mechanism by which a routine passes or receives arguments may also help you to decide among several routines that perform basically the same function.
Routines in the LIB$ and STR$ facilities pass scalar input arguments by reference to CALL entry points and by immediate value to JSB entry points. OTS$ routines pass scalar input arguments by immediate value to all entry points. For most high-level languages, the default passing mechanism is by reference. Thus, if you call a LIB$ or STR$ routine from one of these languages, you do not need to specify the passing mechanism for input scalar arguments.
Some routines require you to set up and pass more arguments than
others. For example, some use a single string descriptor, while others
require separate arguments for the length and the address of the
string. Which routine you choose then depends on the form of the
information already available in your program.
2.3.3 Error Handling
Routines from the LIB$, OTS$, and STR$ facilities handle errors in string copying differently:
Table 2-4 indicates the errors and the corresponding message that each facility considers severe.
Error | LIB$_ | OTS$_ | STR$_ |
---|---|---|---|
Fatal internal error | FATERRLIB | FATINTERR | FATINTERR |
Illegal string class | INVSTRDES | INVSTRDES | ILLSTRCLA |
Insufficient virtual memory | INSVIRMEM | INSVIRMEM | INSVIRMEM |
Some Run-Time Library routines require you to specify the length of a string or the position of a character within a string. When you refer to character positions in a string, the first position is 1. Given a string with length L, containing a substring specified by character positions M to N, the following evaluation rules apply:
When specifying a substring of length L, the following applies:
If any of these evaluation rules applies, the range error status
(qualified success) is returned. STR$POSITION represents the exception
to this convention. This routine returns a function value giving the
character position of a substring within a string. If the function
value is 0, the substring was not found.
2.4 Allocating Resources for Dynamic Strings
This section tells how to use the Run-Time Library string resource allocation routines. These routines allocate virtual memory for a dynamic string and place the address of the allocated memory in a descriptor.
Dynamic strings may be the most convenient type to write, since you need not specify constant length, maximum length, or position for them. However, there are some restrictions on dynamic strings.
In most cases, when you call a Run-Time Library routine to manipulate dynamic strings, the Run-Time Library routine itself allocates the required memory for the string. Your program needs to allocate only the descriptors.
For example, if you are copying a source string into a dynamic destination string, simply use one of the library's string-copying routines. Copy the input string into a dynamic string whose length and address are initialized to zero. The string-copying routine then allocates the space that the calling program needs.
However, if your program must explicitly construct or modify a dynamic string descriptor, it must use the Run-Time Library allocation and deallocation routines. This technique may be necessary, for instance, if you are constructing a string out of components that are not themselves in string form. Further, you can use one of the deallocation routines to free the dynamic string after the string resources are no longer needed, in order to optimize the program's use of resources.
The Run-Time Library provides eight entry points for string resource allocation and deallocation, all with slightly different input arguments, calling techniques, or methods of indicating errors. The following tables summarize these routines and their functions.
The following routines allocate a specified number of bytes of dynamic virtual memory to a specified string descriptor.
Routine | JSB Entry Point |
---|---|
LIB$SGET1_DD | LIB$SGET1_DD_R6 |
LIB$SGET1_DD_64 | LIB$SGET1_DD_R6 |
OTS$SGET1_DD | OTS$SGET1_DD_R6 |
STR$GET1_DX | STR$GET1_DX_R4 |
STR$GET1_DX_64 | STR$GET1_DX_R4 |
The following routines return one dynamic string area to free storage, and set the descriptor POINTER and LENGTH fields to zero.
Routine | JSB Entry Point |
---|---|
LIB$SFREE1_DD | LIB$SFREE1_DD6 |
OTS$SFREE1_DD | OTS$SFREE1_DD6 |
STR$FREE1_DX | STR$FREE1_DX_R4 |
The following routines return one or more dynamic string areas to free storage, and set the descriptor POINTER and LENGTH fields to zero.
Routine | JSB Entry Point |
---|---|
LIB$SFREEN_DD | LIB$SFREEN_DD6 |
OTS$SFREEN_DD | OTS$SFREEN_DD6 |
When you call the dynamic string allocation routines, consider the following factors:
You can call the string resource allocation routines only from user mode, at asynchronous system trap (AST) or non-AST level. However, be extremely careful if you manipulate dynamic strings at AST level. The string manipulation routines in the Run-Time Library do not prevent the strings that they are manipulating at non-AST level from being modified at AST level.
For example, consider the case in which a string manipulation routine has calculated the lengths and addresses involved in a concatenation operation. This string manipulation routine may be interrupted by an AST. The user, at AST level, may write to the same string, changing its length and address. It is then possible to resume execution of the routine with addresses that are no longer allocated or string lengths that are no longer valid. For this reason, if you use dynamic strings at AST level, you should allocate, use, and deallocate them within the AST code.
The dynamic string manipulation routines are intended for use at user
mode only. To manipulate dynamic strings at another access mode, you
should allocate and deallocate storage for each string at that access
mode to avoid side effects. Link each segment of your program that runs
at a different access mode with the /NOSYSSHR qualifier. In this way,
you establish a separate copy of the string database for each access
mode.
2.4.1 String Zone
All virtual memory for dynamic strings is allocated from a Run-Time Library zone called the string zone.
The string zone has the following benefits:
Table 2-5 shows attribute values for 32-bit and 64-bit string zones. VAX systems have a 32-bit string zone; Alpha systems have both a 32-bit and a 64-bit string zone.
Attribute | 32-bit String Zone | 64-bit String Zone |
---|---|---|
Algorithm | Quick fit | Quick fit |
Number of lookaside lists | 17 (short strings from 8 to 136 bytes) | 17 (short strings from 8 to 272 bytes) |
Area of initial size | 4 pages | 4 pages |
Area of extension size | 32 pages | 32 pages |
Block size | 8 bytes | 16 bytes |
Alignment | Longword boundary | Quadword boundary |
Smallest block size | 16 bytes (includes boundary tags) | 32 bytes (includes boundary tags) |
Boundary tags | Boundary tags are used for long strings | Boundary tags are used for long strings |
Page limit | No page limit | No page limit |
Fill on allocate | No fill on allocate | No fill on allocate |
Fill on free | No fill on free | No fill on free |
The Add Two Decimal Strings routine adds two decimal strings of digits.
STR$ADD asign ,aexp ,adigits ,bsign ,bexp ,bdigits ,csign ,cexp ,cdigits
OpenVMS usage: cond_value type: longword (unsigned) access: write only mechanism: by value
asign
OpenVMS usage: longword_unsigned type: longword (unsigned) access: read only mechanism: by reference
Sign of the first operand. The asign argument is the address of an unsigned longword containing this sign. A value of 0 is considered positive; a value of 1 is considered negative.aexp
OpenVMS usage: longword_signed type: longword (signed) access: read only mechanism: by reference
Power of 10 by which adigits is multiplied to get the absolute value of the first operand. The aexp argument is the address of a signed longword containing this exponent.adigits
OpenVMS usage: char_string type: character string access: read only mechanism: by descriptor
Text string of unsigned digits representing the absolute value of the first operand before aexp is applied. The adigits argument is the address of a descriptor pointing to this string. This string must be an unsigned decimal number.bsign
OpenVMS usage: longword_unsigned type: longword (unsigned) access: read only mechanism: by reference
Sign of the second operand. The bsign argument is the address of an unsigned longword containing the second operand's sign. A value of 0 is considered positive; a value of 1 is considered negative.bexp
OpenVMS usage: longword_signed type: longword (signed) access: read only mechanism: by reference
Power of 10 by which bdigits is multiplied to get the absolute value of the second operand. The bexp argument is the address of a signed longword containing the second operand's exponent.bdigits
OpenVMS usage: char_string type: character string access: read only mechanism: by descriptor
Text string of unsigned digits representing the absolute value of the second operand before bexp is applied. The bdigits argument is the address of a descriptor pointing to this string. This string must be an unsigned decimal number.csign
OpenVMS usage: longword_unsigned type: longword (unsigned) access: write only mechanism: by reference
Sign of the result. The csign argument is the address of an unsigned longword containing the result's sign. A value of 0 is considered positive; a value of 1 is considered negative.cexp
OpenVMS usage: longword_signed type: longword (signed) access: write only mechanism: by reference
Power of 10 by which cdigits is multiplied to get the absolute value of the result. The cexp argument is the address of a signed longword containing this exponent.cdigits
OpenVMS usage: char_string type: character string access: write only mechanism: by descriptor
Text string of unsigned digits representing the absolute value of the result before cexp is applied. The cdigits argument is the address of a descriptor pointing to this string. This string is an unsigned decimal number.
STR$ADD adds two strings of decimal numbers (a and b). Each number to be added is passed to STR$ADD in three arguments:
- xdigits-the string portion of the number
- xexp-the power of ten needed to obtain the absolute value of the number
- xsign-the sign of the number
The value of the number x is derived by multiplying xdigits by 10xexp and applying xsign. Therefore, if xdigits is equal to '2' and xexp is equal to 3 and xsign is equal to 1, then the number represented in the x arguments is 2 * 103 plus the sign, or -2000.
The result of the addition c is also returned in those three parts.
SS$_NORMAL Routine successfully completed. STR$_TRU String truncation warning. The destination string could not contain all the characters in the result string.
LIB$_INVARG Invalid argument. STR$_FATINTERR Fatal internal error. An internal consistency check has failed. This usually indicates an internal error in the Run-Time Library and should be reported to your Digital support representative. STR$_ILLSTRCLA Illegal string class. The class code found in the class field of a descriptor is not a string class code allowed by the OpenVMS calling standard. STR$_INSVIRMEM Insufficient virtual memory. STR$ADD could not allocate heap storage for a dynamic or temporary string. STR$_WRONUMARG Wrong number of arguments.
100 !+ ! This is a sample arithmetic program ! showing the use of STR$ADD to add ! two decimal strings. !- ASIGN% = 1% AEXP% = 3% ADIGITS$ = '1' BSIGN% = 0% BEXP% = -4% BDIGITS$ = '2' CSIGN% = 0% CEXP% = 0% CDIGITS$ = '0' PRINT "A = "; ASIGN%; AEXP%; ADIGITS$ PRINT "B = "; BSIGN%; BEXP%; BDIGITS$ CALL STR$ADD (ASIGN%, AEXP%, ADIGITS$, & BSIGN%, BEXP%, BDIGITS$, & CSIGN%, CEXP%, CDIGITS$) PRINT "C = "; CSIGN%; CEXP%; CDIGITS$ 999 END |
This BASIC example uses STR$ADD to add two decimal strings, where the following values apply:
- A = -1000 (ASIGN = 1, AEXP = 3, ADIGITS = '1')
- B = .0002 (BSIGN = 0, BEXP = -4, BDIGITS = '2')
The output generated by this program is listed below; note that the decimal value of C equals -999.9998 (CSIGN = 1, CEXP = -4, CDIGITS = '9999998').
A = 1 3 1 B = 0 -4 2 C = 1 -4 9999998
Previous | Next | Contents | Index |
privacy and legal statement | ||
5936PRO_002.HTML |