PHF Logo

PHF Consultancy


Development | Consultancy | Training

www Search this site
Powered by
Google
Home

Email

BookMark
Home Contact Us Products Services Technology How To... Partners Other Links

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.

 

Valid HTML 4.01! Privacy Policy

Copyright © 1999-2007 PHF Consultancy
Banner images are trademarks of the companies represented