Operating System - OpenVMS
1753861 Members
7296 Online
108809 Solutions
New Discussion юеВ

Re: User of F$FAO() in replce a char with another

 
George Tjionas
Occasional Contributor

User of F$FAO() in replce a char with another

Is there a quick way of using mostly the F$FAO() lexical to find and replace a char with another?

I am trying to avoid using loops and extracts and ifs an dlooking for an elegant way of having f$fao() to do the job or most of the job. In a way I see it as a chalenge too.

Also similarly - two more cases!

How can I use F$FAO() to left or right justify (shift and align) a string within a certain field size? I assume spaces are used to pad the rest of the space (right or left).

Thanks.
8 REPLIES 8
George Tjionas
Occasional Contributor

Re: User of F$FAO() in replce a char with another

To clarify.

For the REPLACE I meant

replace any ascii character in the string with another ascii character.

Hoff
Honored Contributor

Re: User of F$FAO() in replce a char with another

Why avoid loops? While certainly a bit ugly, loops are expected of typical DCL coding and can and do work. Or are you seeking to avoid the looping here for performance reasons? (And if performance is an issue here, then a DCL solution can be viewed as a liability.)

The f$fao lexical doesn't have a substitution mechanism for use in an existing string; it's a way to generate formatted output based on a control string and on some number of parameters.

f$fao is not a regular expression tool. (Nor does OpenVMS have a regular expression tool built in.)

The usual approach here involves string addition and string subtraction (particularly if you have an anchor in the string you can aim for), and/or the f$locate lexical, or a loop using f$extract. What works best here depends highly on what string you start with and particularly its structure, and what string you want to end up with.

Other potential approaches here involve using text editors (or pieces, such as TPU), or using perl or php, or other similar languages. gnv and bash, potentially. This is a heavy-weight approach, but can be applicable when dealing with volumes of text. And you get regexp and other goodies.

If you can find a copy of it, the Writing Real Programs in DCL book, 2nd ed., Anagnostopoulos and Hoffman, goes into gonzo details on DCL and DCL programming.

Stephen Hoffman
HoffmanLabs LLC
Hein van den Heuvel
Honored Contributor

Re: User of F$FAO() in replce a char with another

Hello George,

Welcome to the HP ITRC Forum for OpenVMS

F$FAO does not 'search'. F$LOCATE does.
F$FAO does not 'replace'. This does: var[offset,len] := text

So a solution for your first question might be:


$ x="test"
$ x[f$loc("s",x),1] := X
$ show symb x
X = "teXt"

If the character might not be fe found then you need a test:

$ x="test"
$ y=f$loc("s",x)
$ if y.ne.f$len(x) then x[y,1] := X
$ show symb x
X = "teXt"


note: F$LOC does a simple first match. So it would be tricky to replace the second "t" in "test".

F$FAO is supports field widths, but does not really do allignments. It just looks likes a left align. The field width is a number between the ! and the directive. For example:

$ write sys$output f$fao("=!10AS=", x)
=teXt =

That number can be a variable, when indicated with a #:

$ write sys$output f$fao("=!#AS=", 10, x)
=teXt =

You can fake a right align by combining that with the repeat character directive !n*c

$ write sys$output f$fao("=!#* !AS=", 10-f$len(x),x)
= teXt=


Also check out the double !x< and !> directive to group F$FAO output into a specific width.


Finally, if there are more question then kindly provide a consice example of input and output. What more complete problem are you trying to solve?

Personally I would probably use 'printf' in GAWK or PERL for tasks involving those steps.

Hope this helps some,
Hein.


Ian Miller.
Honored Contributor

Re: User of F$FAO() in replce a char with another

you may also want to look at F$EDIT
____________________
Purely Personal Opinion
George Tjionas
Occasional Contributor

Re: User of F$FAO() in replce a char with another

Thanks,

Ref: Stephen Hoff. I was looking into the power of F$FAO() in handling things (as I've seen undocumented ways of using it) and I though I had a couple of interesting situations to put that function to excersise and to use. It's not a question of performance at all. I am inclined to short length code.

George
Hoff
Honored Contributor

Re: User of F$FAO() in replce a char with another

>>>I was looking into the power of F$FAO() in handling things (as I've seen undocumented ways of using it)<<<

Look at the underlying sys$fao system service for details of how this and other similar DCL lexical functions work. The undocumented mechanisms here are little more than a pass-through of the mechanisms and capabilities of the underlying system service; these typically involving pointers and indirection. Pointers don't work all that well in DCL, but you can use them to poke around inside process address space.

>>> and I though I had a couple of interesting situations to put that function to excersise and to use.<<<

Could you elaborate? You're leaving me and others here to to try to read your intentions. Unmentioned and undocumented features of f$fao and regexp-like capabilities don't usually map into the same thought, from what I know of DCL.

>>> It's not a question of performance at all. I am inclined to short length code.<<<

Some philosophy and opinion follow: Raw code length doesn't equate with better or worse, any more than when length is applied to a term paper in school. I can code some seriously terse DCL (and have done so), and it can easily be entirely cryptic to anyone not versed in various of the "DCL magicks". Structured and commented and consistent DCL is typically more maintainable, and is what is preferred in production. You'll see this philosophy throughout the DCL book.

re: gawk and awk, et all. Forgot that approach. Another good choice.


Hein van den Heuvel
Honored Contributor

Re: User of F$FAO() in replce a char with another

George wrote:

>>> (as I've seen undocumented ways of using it)

The only really useful undocumented usage that I am aware of is in using !AD to trick a pointer to a 64 bit binary date value onto the argument list. Sample usage for example in:

http://h71000.www7.hp.com/wizard/wiz_7154.html

If you are aware of other usages, then by all means please share instead of letting us speculate.


Hein.
George Tjionas
Occasional Contributor

Re: User of F$FAO() in replce a char with another

Thanks guys. I will stay in itrc. It's a good way to learn from all of you. I am not trying to engineer anything with DCL, just some primitive scanning and parsing of parameters passed and for input read from file for validity vs. expected strings.

"Also check out the double !x< and !> directive to group F$FAO output
into a specific width."

This is what made me post as the description was not clear.

I was looking at the !n<...!> directive of f$fao() and DCL help isn't good in giving some examples.

From the online help of f$fao() directives:
----------------
!n<...!> None

Left-justifies and blank-fills all data represented by the instructions . . . in fields n characters wide.
----------------

When I saw the reference to Left Justify it arose my curiosity to find out how to use it for Right Justify needs which can also be handy.

By a simple plug in I have this
$ ws f$fao("!20") + "]"
abc def ]

Now the following does not give me left justified string (notice spaces before abc).

$ ws f$fao("!20< abc def!>") + "]"
abc def ]

I thought this would be left justified but I was wrong (maybe I missinterpreted the deescription about the directive). I was expecting this to come out left justified thinking that this directive was to do it for me.

Was my expectation OK according to the description of this directive?

I then had to trim the leading spaces with the f$edit()

$ ws f$fao("!#", 20, f$edit(" abc def","TRIM")) + "]"
abc def ]

Thanks Hein for the "Right Justify" tip
Thanks to all.

George