How to create and manipulate Variable
Length Strings (All Platforms)
| |
'Strings' type variables in Synergy DBL are fixed in size. Here is an example of how they
are defined:
| astring ,a20 ;hold
max of 20 character |
Sometimes a 'String' size needs to be defined at runtime or that it needs to change in size during a routines execution. This is where variable
length 'Strings' are useful.
To help me achieve this, I used dynamic memory functions within the language
and then wrote a number of parameterised macros to simplify the usage of these
functions. These can be download from here. Save the file so it can be
included into you routines. (e.g. varstring.def)
Below is the contents of the above downloadable file.
| .ifndef D_VSTR |
|
;data type for variable length string
.define D_VSTR |
D_ADDR |
;create new string
.define VSTR_NEW(size) |
%mem_proc(DM_ALLOC.bor.DM_BLANK, size) |
;access string data
.define VSTR(str_name)
.define VSTR_RANGE(str_name,pos,len) |
^m(vstr_data[1].vstr_char(1:%mem_proc(DM_GETSIZE,
str_name)), str_name)
^m(vstr_data[1].vstr_char(pos:len), str_name) |
;Resize string to given absolute size
.define VSTR_RESIZE_ABS(str_name,newsize) |
%mem_proc(DM_RESIZ.bor.DM_BLANK, newsize, str_name) |
;Resize string by given relative size +ve
or -ve
.define VSTR_RESIZE(str_name, size) |
%mem_proc(DM_RESIZ.bor.DM_BLANK, %mem_proc(DM_GETSIZE,
str_name) + size, str_name) |
;return trimed length of string (same as %trim)
.define VSTR_TRIM(str_name) |
%mem_proc(DM_TRIMSIZE.bor.DM_BLANK, str_name) |
;return size of string (same as ^size)
.define VSTR_SIZE(str_name) |
%mem_proc(DM_GETSIZE, str_name) |
.endc
structure vstr_data
vstr_char ,a1 |
;structure definition for variable strings |
|
Example 1: Here are some simple examples on how to use the
above macros.
.main test1
.include 'varstring.def'
.align
record
string_one ,D_VSTR
size ,i4
len ,i4
chr ,a1
.proc
open(1, o, 'TT:')
string_one = VSTR_NEW(20)
;create variable length string with initial
size of 20 chars.
VSTR(string_one) = "Hello World!"
display(1, %atrim(VSTR(string_one)), 13,
10) ;displays Hello
World!
display(1, VSTR_RANGE(string_one, 7, 5),
13, 10) ;displays World
string_one = VSTR_RESIZ(string_one, 20) ;increases
string length by 20
string_one = VSTR_RESIZ(string_one, -5) ;decreases
string length by 5
size = VSTR_SIZE(string_one) ;set
size to the size of string_one
len = VSTR_TRIM(string_one) ;set
len to the length of string_one without trailing spaces
display(1, "String Size="+%string(size)+"
String Trimed Length="+%string(len), 13, 10)
reads(1, chr)
close 1
.end |
Example 2: Concatenating two strings.
.main test2
.include 'varstring.def'
.align
record
string_one ,D_VSTR
string_two ,D_VSTR
size ,i4
len ,i4
chr ,a1
.proc
open(1, o, 'TT:')
string_one = VSTR_NEW(22)
;create variable length string with initial
size of 22 chars.
string_two = VSTR_NEW(15)
;create variable length string with initial
size of 15 chars.
VSTR(string_one) = "This is an Example of"
VSTR(string_two) = "Hello World!"
string_one = VSTR_RESIZE(string_one, 1+VSTR_TRIM(string_two)) ;extend
string_one to acommodate string_two+space
VSTR(string_one) = VSTR(string_one) + "
" + VSTR(string_two)
display(1, %atrim(VSTR(string_one)), 13,
10) ;displays This
is an Example of Hello World!
reads(1, chr)
close 1
.end |
Example 3: Passing variable strings as arguments.
.main test3
.include 'varstring.def'
.align
record
string_one ,D_VSTR
.proc
open(1, o, 'TT:')
string_one = VSTR_NEW(20)
;create variable length string with initial
size of 20 chars.
VSTR(string_one) = "Hello World!"
;Pass the string two
ways. The first is the address of the string.
;The second is the contents of the string.
Both allow the string to modified by the routine.
xcall mysub(string_one, VSTR(string_one))
reads(1, chr)
close 1
.end
.subroutine mysub
a_string_addr ,n
a_string_data ,a
.include 'varstring.def'
record
temp ,a40
.proc
temp = VSTR(a_string_addr)
temp = a_string_data
xreturn
.end |
Scope of variables: As the macros only create the dynamic
memory as local (i.e. DM_STATIC is not used) the memory is automatically released
when the routine exists. They can be passed to subroutine/functions as arguments
however there is a limitation. The strings can not be resized, as this will
cause the string to become local to the subroutine/function that did the resizing
and therefore will automatically be deleted on exit.
If required DM_STATIC could be added to the macro for creating the strings.
Two addional macros could be created for creating/releasing the memory. This would give
greater control over when the strings are created and deleted. However, every
string created would have to be explicitly deleted. Here is an example of the
macros that could be added.
;create
new static string
.define VSTR_NEW_STATIC(size)
%mem_proc(DM_ALLOC.bor.DM_STATIC.bor.DM_BLANK, size)
;delete/release string
.define VSTR_DEL(str_name)
%mem_proc(DM_FREE, str_name) |
If you have any comments on this code. Please let me know.
Note: Synergy DBL Version 7 or higher required.
|
|
|