I need to write FIXED(0) variable content to EMS collector. As WRITEX
API needs buffer in STRING format, I thought of converting FIXED(0) to
STRING before I use WRITEX. Is there any guardian API available?
I know only DNUMIN and DNUMOUT APIs which operates on INT.
Regards,
Bikku.
Minor correction: DNUMIN and DNUMOUT work on INT(32) values, not INT values. NUMIN and NUMOUT work on INTs.
If you are writing tokenized event messages to EMS, you would not have to convert the FIXED value to ascii. A simple token or a structured token can hold FIXED values.
But I imagine you are writing a text string to the collector, in which case you do have to convert binary values to ascii.
In the past, you could do such conversion either by using CODE statements to put the appropriate values onto the stack and execute a CQA instruction, or use the FORMATCONVERT and FORMATDATA procedures. But when pTAL was invented, built-in functions were defined for a lot of often-used CODE sequences, and the same built-in functions were added to TAL so that source code could be compiled either for TNS or native targets.
The built-in function for your problem is $FIXEDTOASCII. It is documented in the pTAL manual in the chapter on Built-In Routines, in the section on type conversion routines. There is even a short code example.
I have never used $FIXEDTOASCII, so I cannot give you any advice about using it from my own experience. One thing I do notice from reading the description in the manual is that it converts the absolute value of the FIXED variable, so your code will have to test whether the value is negative, and if so, put a minus sign into the formatted line before putting the converted FIXED value into the line. There may be other tips on using $FIXEDTOASCII that you ought to know, but if so, I do not know what they are. Maybe someone else knows more about it and will post more about it.
I dealt with that problem years ago and I am using DNUMOUT twice:
FIXED WORKF, WORKF2;
WORKF := <your variable>;
WORKF := WORKF / 1000000000F;
WORKF2 := WORKF2 - (WORKF * 1000000000F);
CALL DNUMOUT(output_string[0], $DBL(WORKF), 10,4);
CALL DNUMOUT(output_string[4], $DBL(WORKF2), 10,9);
For my application 13 digits was ok, if you need more digits, just
change ´the first dnumout.
Oops, just saw there is 1 line missing:
FIXED WORKF, WORKF2;
WORKF := <your variable>;
WORKF2 := WORKF;
There are routines in $system.system.taldecs (or similar) that will
convert binary to ascii and vice-versa. The library file is, I think,
$system.system.tallib.
Take a look at $system.system.tal*
What you are referring is $SYSTEM.SYSTEM.EXTDECS(0), the TACLDECS are
for SQL-programs. But, as Bikku wrote, there is no routine FNUMOUT
available (FNUMIN is not available, either), so it is a bit tricky to
convert a fixed variable into a string and vice versa.
Hi All,
Thanks for your inputs.
I am supposed to compile with pTAL comipler to generate 800 code
object file to run on blade servers.
As keith suggested I achieved this through pTAL inbuilt function
$FIXEDTOASCII.
I will also check "wbreidbach" approach.
Cheers,
Henry Norman
MicroTech Consulting
https://sites.google.com/site/microtechnonstop/
--------------- cut from here ---------------
?SYMBOLS, NOCODE, NOMAP, NOLMAP, NOFMAP, NOGMAP
--
-- TAL: > TAL/ IN <source> / <obj> ; SUPPRESS
-- pTAL: > pTAL/ IN <source> / <obj> ; SUPPRESS
-- TNS/R > nld <obj> -o <obj>
-- TNS/E > eld <obj> -o <obj>
-- All: > RUN <obj>
-- At Inspect prompts, enter D num FOR len
--
?IFNOT pTAL
?SEARCH $SYSTEM.SYSTEM.CRELIB
?NOLIST, SOURCE $SYSTEM.SYSTEM.RTLDECS ( RTL_Int64_to_Decimal_ )
?LIST
?ENDIF pTAL
?NOLIST, SOURCE $SYSTEM.SYSTEM.EXTDECS0 ( DEBUG )
?LIST
INT(32) PROC ZFNUMOUT( out, int64value );
--
-- Enlightened INT(64) conversion, leading zero suppress.
-- Returns next available output address (extended).
--
STRING
.EXT out; -- Output address (not boundary checked!)
INT(64)
int64value; -- Conversion source value
BEGIN
STRING
.s, -- 16-bit string pointer
.EXT xp, -- 32-bit string pointer
work[ 0:20 ]; -- Conversion target array
-- Select builtin or RTL function depending on compiler:
?IF pTAL
$FIXEDTOASCII( int64value, @work, 19 );
?ENDIF pTAL
?IFNOT pTAL
RTL_Int64_to_Decimal_( int64value, work, 19, 2 ); -- No error can
occur...
?ENDIF pTAL
-- Flush leading zeros:
work[ 20 ] := 0; -- SCAN stopper
SCAN work[ 1 ] WHILE "0" -> @s; -- Ignore sign (K.I.S.S.)
IF ( $CARRY ) THEN
@s := @s[ -1 ];
IF ( int64value < 0F ) THEN -- Show negative sign only
out':='"-" -> @out;
@xp := $XADR( s );
out':='xp FOR ( @work[ 19 ]'-'@s ) -> @xp;
xp := 0; -- Null terminator (courtesy to C callers)
RETURN ( @xp );
END; -- INT(32) PROC ZFNUMOUT()
PROC S0000V00_Test MAIN;
BEGIN
INT(64)
val0 := 0F,
val1 := -222F,
val2 := 333333333F;
INT(16)
len;
STRING
.EXT xp,
num[ 0:20 ];
@xp := ZFNUMOUT( num, val0 );
len := $INT( @xp-$XADR( num ) );
DEBUG(); -- Inspect: D num FOR len
@xp := ZFNUMOUT( num, val1 );
len := $INT( @xp-$XADR( num ) );
DEBUG(); -- Inspect: D num FOR len
@xp := ZFNUMOUT( num, val2 );
len := $INT( @xp-$XADR( num ) );
DEBUG(); -- Inspect: D num FOR len
END; -- PROC S0000V00_Test MAIN
--------------- cut to here ---------------
> WRITEX API needs buffer in STRING format, I thought of converting FIXED(0) to
> STRING before I use WRITEX.
WRITEX() expects an "extended" (32 bit) pointer, yes, but this does
NOT mean that everything contained in that buffer needs to be in ASCII
format... You can write whatever you like, as long as the POINTER to
your buffer is a 32-bit address.
In fact WRITEX does not pay any attention to the contents of the
written string so there is no need for ASCII characters only. But one
correction to Henry's comment: There is no need for a 32-bit addressed
string, you can use a 16-bit addressed string as well:
string .mystring[0:127] := [16*[0,1,2,3,4,5,6,7,8]];
int filenum;
call writex (filenum, mystring, 128);
This works fine and mystring does not contain any ASCII character.
Wolfgang
If that is true, why should anyone bother to conditionally compile $FIXEDTOASCII for pTAL and RTL_Int64_to_Decimal_ for TAL? Just use $FIXEDTOASCII whether you are coding TAL or pTAL.
Maybe the RTL_Int64_to_Decimal_ was created before TAL supported $FIXEDTOASCII, and using it now is outmoded? Or is there something I am not aware of that makes it more desirable to use RTL_Int64_to_Decimal_ from TAL code?
This is not correct. I am not referring to EXTDECS(0). I never
mentioned it.
I do not know what the TACLDECS file is.
TALDECS contains RTL_Int64_to_Decimal_ and the object library is
tallib.
TALDECS does contain SQL-related declarations but that does not
preclude the file's use by non-SQL programs.
I made no mention of FNUMOUT or FNUMIN so I do not know why that is
included in your post.
Conversion is not tricky. Have a go yourself.
Sorry for the typo "TACLDECS", of course I meant TALDECS.
By the way: My solution for a conversion (both ways!) is at least 15
years old and not tricky at all.
Just to complete the information: The functions themselves are not in
TALLIB but in CRELIB.
> Maybe the RTL_Int64_to_Decimal_ was created before TAL supported $FIXEDTOASCII
This is correct. I wrote the supplied procedure long ago. And I should
have checked the manual before posting it, but did not. Just remove
all references to the RTL function, and all conditional code, and the
proc should still work just fine (any modern TAL version).
On Jan 18, 5:38 pm, wbreidbach wrote:
> There is no need for a 32-bit addressed string, you can use a 16-bit address
Thanks Wolfgang, for correcting my somewhat misstated WRITEX() buffer
address requirement: I was referring to the function itself, which
requires a 32-bit (.EXT) buffer address (as you point out, TAL
generates code to convert a 16-bit address).
Cheers,
Henry Norman
MicroTech Consulting
sites.google.com/site/microtechnonstop