Operating System - OpenVMS
1753781 Members
7622 Online
108799 Solutions
New Discussion юеВ

Using Varying String Descriptors in HP Basic

 
harold teter_1
New Member

Using Varying String Descriptors in HP Basic

I'm in the process of migrating some old 4GL code to HP Basic. This old code supports string fields with a max length. There doesn't appear to be any direct way of creating a string of this type in HP basic but HP Basic appears to recognize and support a varying string descriptor once set. I've done this by modifying the descriptor after declaring a dynamic string and assigning a value to the string. If I want to create a varying string with a max of 10 I do the following:

Declare a string variable
DECLARE STRING VARS
Assign a value to the string variable making the the length of the string my max length plus 2 - the first 2 bytes carry the current length of the string in a varying string and the descriptor carries the max length. Assuming i want a string with a max length of 10 i'd assign 12 characters to the string:

VARS = STRING$(12%, ASCII(CHR$(0%)))

I then call a routine to modify the string descriptor to be a varying string and a max length of 10.

Will this cause any problem with memory management - specifically, the way HP Basic manages memory for dynamic strings ?
4 REPLIES 4
Ian McKerracher_1
Trusted Contributor

Re: Using Varying String Descriptors in HP Basic

Hello Harold,

HP Basic supports both fixed-length and varying-length (or dynamic) strings. A string field is classed as fixed-length if it is defined in a MAP, COMMON or RECORD statement. For general use I prefer to use the MAP statement, as in the following example.

MAP (my_variables) STRING vars = 10

This statement defines a string variable called 'vars' which will always have a fixed length of 10 characters. If you attempt to assign a string which is greater than 10, the new string is simply truncated.


Regards,

Ian

harold teter_1
New Member

Re: Using Varying String Descriptors in HP Basic

Thanks for the response Ian.

I understand that HP Basic supports both the varying (dynamic) string and fixed string as you describe them. what i need is a varying string with a max length which is what a varying string descriptor gives me. without getting into all the details I need to be able to treat the string as a dynamic string without exceeding the predefined maximum length. i realize i could do this by writing or generating code but that complicates the overall process.

modifying the descriptor to be a varying string gives me exactly what i need. i'm just not sure what kind of impact ( if any ? ) this will have on the memory allocation basic does for dynamic variables. my guess is none but i wanted to find out what others thought.
John Gillings
Honored Contributor

Re: Using Varying String Descriptors in HP Basic

harold,

I'd strongly recommend against messing with the descriptors created by Basic. If you want to use varying strings, write yourself a little management package that constructs a descriptor, allocates the memory, adjusts the length field, and any other operations you require.

Apart from protecting you from violating assumptions made by the compiler, this will also give you a layer of abstraction to hide the implementation details from your application logic.

An alternative would be to change to a language which supports the data types you require (Pascal springs to mind).
A crucible of informative mistakes
Hein van den Heuvel
Honored Contributor

Re: Using Varying String Descriptors in HP Basic


I am a little surprised and concerned that your topic does not mention the 'technical terms'

Are we talking about string descriptor type: DSC$K_DTYPE_VT ?
Are you talking about zapping an existing descriptor from class CLASS_D to CLASS_VS?
It sounds like you are aleady accounting for the 2 length bytes outside the body.

I don't think that'll work. Basic creates Class_D dynamic strings. For local dynamic strings, on subroutine return it will deallocate them. That will fail signalling:
%STR-F-ILLSTRCLA, illegal string class
See sample C program below.

Basic will be a happy user of those varying string descriptor as it strictly uses STR$xxx functions to do the work, but it can not longer dispose of them properly. So you woudl also have the clear them. And you have to go through the hassle of pre-allocating them. In all you are better of just rolling your own all the way.

I suppose you could try declaring your string variables intended to be variable as static in a map (or common), such that basic will not deallocate them. Have the map set up the size, and use your function to zap the descriptor.

Using class=D and type=VT should not work either me thinks.

In the end you have to ask yourself when and where those string lengths are used and whether a converting to fully using simple dynamic strings is not more suitable.


The warning in the "HP OpenVMS Calling Standard" chapter 7.8 "Varying String Descriptor (CLASS_VS)" is rather stern:

"A class VS descriptor is used for varying string data types (see Section 6.5).

As an input parameter, this format is not interchangeable with class 1 (CLASS_S) or with class 2 (CLASS_D). When a called procedure modifies a varying string passed by reference or by descriptor, it writes the new length, n, into CURLEN and can modify all bytes of BODY. Figure 7-8 shows the format of a varying string descriptor. Table 7-10 describes the fields of the descriptor."

http://h71000.www7.hp.com/doc/82final/5973/5973PRO.HTML


sample program for experiments:
#include
#include
main()
{
int str$free1_dx(), str$get1_dx(), stat;

struct dsc$descriptor desc;

desc.dsc$w_length = 0;
desc.dsc$a_pointer = NULL;
desc.dsc$b_class = DSC$K_CLASS_D;
desc.dsc$b_dtype = DSC$K_DTYPE_T;

stat = str$get1_dx( &123, &desc );
printf ("GET1 %08X %04X %d\n", desc.dsc$a_pointer, desc.dsc$w_length, stat);
stat = str$free1_dx( &desc );
printf ("FREE %08X %04X %d\n", desc.dsc$a_pointer, desc.dsc$w_length, stat);


stat = str$get1_dx( &123, &desc );
printf ("GET1 %08X %04X %d\n", desc.dsc$a_pointer, desc.dsc$w_length, stat);
desc.dsc$b_class = DSC$K_CLASS_VS;
desc.dsc$b_dtype = DSC$K_DTYPE_VT;
stat = str$free1_dx( &desc );
printf ("FREE %08X %04X %d\n", desc.dsc$a_pointer, desc.dsc$w_length, stat);
return stat;
}

Sample output:

GET1 0004482C 007B 1
FREE 00000000 0000 1
GET1 0004482C 007B 1
%STR-F-ILLSTRCLA, illegal string class
%TRACE-F-TRACEBACK, symbolic stack dump follows

Hope this helps some,
Hein.