Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

STR$lowercase ?

15 views
Skip to first unread message

Rick Dyson

unread,
Jan 28, 2002, 12:32:49 PM1/28/02
to
There is a STR$UPCASE system service in the STR$ system, but I have a user that
would like to force lowercase in his Fortran program and I can't quickly find
an answer to his question. Is there such a pre-existing VMS service or function
that can be easily called from a Fortran program?

This is currently on an Alpha/OpenVMS v7.1 with FORTRAN v7.4-xxx.

Thanks for any help!

Rick Dyson

Jan-Erik Söderholm

unread,
Jan 28, 2002, 1:06:29 PM1/28/02
to
I'v not checked, but the F$FAO lexical have a "LOWERCASE" argument.
Maybe the sys$fao service also can do that ?

Jan-Erik Söderholm.

Steve Lionel

unread,
Jan 28, 2002, 2:17:02 PM1/28/02
to
On Mon, 28 Jan 2002 17:32:49 GMT, Rick Dyson <Rick-...@UIowa.EDU>
wrote:

>There is a STR$UPCASE system service in the STR$ system, but I have a user that
>would like to force lowercase in his Fortran program and I can't quickly find
>an answer to his question. Is there such a pre-existing VMS service or function
>that can be easily called from a Fortran program?

One can call LIB$MOVTC with LIB$AB_LOWERCASE as the translation table.
The catch is that you have to hand-craft a descriptor for this, but
it's easy to do. Here's an example:

character* 10 old,new
external lib$ab_lowercase
integer*4 tabledesc(2)
old = 'ABCDEFGHIJ'
tabledesc(1) = 256
tabledesc(2) = loc(lib$ab_lowercase)
istat = LIB$MOVTC (old,' ',tabledesc,new)
write (*,*) new
end

Steve Lionel
Compaq Fortran Engineering
Intel Corporation
Nashua, NH

Compaq Fortran - http://www.compaq.com/fortran
Intel Fortran - http://developer.intel.com/software/products/compilers/f50/

Kenneth H. Fairfield

unread,
Jan 28, 2002, 3:02:12 PM1/28/02
to
Rick Dyson wrote:

> There is a STR$UPCASE system service in the STR$ system, but I have a user that
> would like to force lowercase in his Fortran program and I can't quickly find
> an answer to his question. Is there such a pre-existing VMS service or function
> that can be easily called from a Fortran program?

In the past I've used calls to BAS$EDIT, IIRC. There was an old
INFO-VAX post that gave the calling arguments, but I seem to have lost
in during my job move. :-( ISTR that BAS$EDIT gives you everything
that F$EDIT gives, plus perhaps one or two others. Perhaps someone
else can dig up that old post (or provide a new one)?

--
I don't speak for Intel, Intel doesn't speak for me...

Ken Fairfield
F20 Automation VMS System Support
kenneth.h.fairfield#intel.com


Rick Dyson

unread,
Jan 28, 2002, 3:25:57 PM1/28/02
to
"Kenneth H. Fairfield" wrote:
>
> Rick Dyson wrote:
>
> > There is a STR$UPCASE system service in the STR$ system, but I have a user that
> > would like to force lowercase in his Fortran program and I can't quickly find
> > an answer to his question. Is there such a pre-existing VMS service or function
> > that can be easily called from a Fortran program?
>
> In the past I've used calls to BAS$EDIT, IIRC. There was an old
> INFO-VAX post that gave the calling arguments, but I seem to have lost
> in during my job move. :-( ISTR that BAS$EDIT gives you everything
> that F$EDIT gives, plus perhaps one or two others. Perhaps someone
> else can dig up that old post (or provide a new one)?

Is there a way I can call F$Edit (String, "lowercase") from within a FORTRAN
program easily? I think that command will do what I want but it is a DCL
Lexical...

Rick

Rick Dyson

unread,
Jan 28, 2002, 5:16:12 PM1/28/02
to Steve Lionel
Steve Lionel wrote:
>
> On Mon, 28 Jan 2002 17:32:49 GMT, Rick Dyson <Rick-...@UIowa.EDU>
> wrote:
>
> >There is a STR$UPCASE system service in the STR$ system, but I have a user that
> >would like to force lowercase in his Fortran program and I can't quickly find
> >an answer to his question. Is there such a pre-existing VMS service or function
> >that can be easily called from a Fortran program?
>
> One can call LIB$MOVTC with LIB$AB_LOWERCASE as the translation table.
> The catch is that you have to hand-craft a descriptor for this, but
> it's easy to do. Here's an example:
>
> character* 10 old,new
> external lib$ab_lowercase
> integer*4 tabledesc(2)
> old = 'ABCDEFGHIJ'
> tabledesc(1) = 256
> tabledesc(2) = loc(lib$ab_lowercase)
> istat = LIB$MOVTC (old,' ',tabledesc,new)
> write (*,*) new
> end

Excellent Suggestion Steve! I was unaware of that Library service.

With your help, I have written this which appears to work. Does
anyone see any problems with it? It is not documented nor tested for
robustness,
but it appears to work with a simple test program I through together...

Integer Function Str$LowerCase (Input, Output)

Character*(*) Input, Output
Integer TableDesc (2)
External Lib$AB_LowerCase

Str$LowerCase = -1
TableDesc (1) = 256
TableDesc (2) = Loc (Lib$AB_LowerCase)
Str$LowerCase = Lib$MovTC (Input, ' ', TableDesc, Output)

Return
End

THANKS AGAIN! That was pretty fast too!

Rick

Kenneth H. Fairfield

unread,
Jan 28, 2002, 5:27:39 PM1/28/02
to
Small addendum:

To call BAS$EDIT from Fortran, pass the two character variables
in the "usual" way, but the "edit mask" bits by value, e.g.,

INTEGER BAS$M_UPCASE
PARAMETER (BAS$M_UPCASE = 32)
...
CALL BAS$EDIT (NEW_STRING, OLD_STRING, %VAL(BAS$M_UPCASE))

to convert to upper case.

Kenneth H. Fairfield

unread,
Jan 28, 2002, 5:20:32 PM1/28/02
to
Rick Dyson wrote:

> Is there a way I can call F$Edit (String, "lowercase") from within

> a FORTRAN
> program easily? I think that command will do what I want but it is a DCL
> Lexical...

Short answer, "no". Longer answer, if you were willing to play games
with logical names and spawned subprocesses, yes, but that seems like an
awfully large hammer to use for tightening the "temple" screws on your
eyeglasses... 8^O :-)

If I were to consider such a thing, I'd at least avoid the subprocess
by using callable TPU with a small (custom) section file and a single
procedure that used TPU's TRANSLATE function. At that point, Steve
Lionel's suggestion to use LIB$MOVTC would be even easier.

FWIW, I pulled my personal archive of saved c.o.v articles from
BACKUP and found the BAS$EDIT post. I include it below in its entirety
(note that the most useful information comes from Bart Z. Lederman who
is still active in this news group). The bad news is, I don't see an
item code for LOWERCASE! :-( OTOH, there are still more unused bits
that could be defined...whether or not BAS$EDIT will _do_ anything
with them... (Alas, the answer it "nothing".)

Ken


--
I don't speak for Intel, Intel doesn't speak for me...

Ken Fairfield
F20 Automation VMS System Support
kenneth.h.fairfield#intel.com

=============================================================================
From: web...@itwol.bhp.com.au (Ken Bosward)
Newsgroups: comp.os.vms
Subject: Summary: Callable F$EDIT
Message-ID: <1993Jun22....@iwsd01.itwol.bhp.com.au>
Date: 22 Jun 93 08:47:52 +1000
Organization: BHP Information Technology
Lines: 76

Thanks to all those who responded re a "callable F$EDIT" routine. Most
people drew my attention to the BASIC built-in EDIT. Thanks to:

fri...@zams.kapsch.co.at (Martin Frischherz)
BRE...@CCHS.SU.EDU.AU (Luke Brennan)
"B. Z. Lederman" <LEDE...@Eisner.DECUS.Org>
GV...@ISUVAX.IASTATE.EDU (rod eldridge)
simons/G=Colin/S=Sewell/O=H.A.Simons.Ltd/OU=PAC...@mhs.attmail.com

I have enclosed mail from Bart Lederman for your information.

--------------------------------------------------------------------------
I have only read-only access to NEWS, so you may want to post
this as a followup for everyone.

While there is no STR$ routine to do what you want, there is,
fortunately, such a routine built in to the BASIC Run Time
Library. Since this is part of the VMS operating system,
everyone has it. It does everything that F$EDIT does, plus more.
I've published instructions on how to use it in the (now defunct)
DECUS Newsletter, and it's also on various DECUS Library tapes.


But it's fairly easy to use. The following is the header file
I wrote to define the function for C programs, which I call
BAS$EDIT.H

#ifndef __BAS$EDIT_LOADED
#define __BAS$EDIT_LOADED 1
#endif

/*
Define a prototype and values for the VAX/BASIC EDIT$ function.

The EDIT$ function performs one or more string editing functions,
depending on the value of its integer argument.

Example (in BASIC)

New_string$ = EDIT$(Old_string$, 48%)

Example (in C)

(void) BAS$EDIT (&New_String, &Old_String, Edit-Exp);

New_String and Old_String are string descriptors passed by address
(reference).

Edit-Exp is an integer value specifying one or more edit actions
from the set listed below, which can be ANDed together.

There does not appear to be a return status to check.

All of the definitions here are my own and NOT Digital's.

Bart Z. Lederman 15-Jun-1992
*/

void BAS$EDIT ();

/* Values Effect */

#define BAS$M_NOPARITY 1 /* Trim parity bits */
#define BAS$M_COLLAPSE 2 /* Discard all spaces and tabs */
#define BAS$M_DISFORM 4 /* Discard characters: CR, LF, FF, ESC, */
/* RUBOUT, and NULL */
#define BAS$M_DISLEAD 8 /* Discard leading spaces and tabs */
#define BAS$M_COMPRESS 16 /* Reduce spaces and tabs to one space */
#define BAS$M_UPCASE 32 /* Convert lowercase to uppercase */
#define BAS$M_BRACKET 64 /* Convert [ to ( and ] to ) */
#define BAS$M_DISTRAIL 128 /* Discard trailing spaces and tabs */
#define BAS$M_KEEPQUOTE 256 /* Do not alter characters inside */
/* quotes */
--------------------------------------------------------------------------

Ken Bosward, BHP Information Technology, Wollongong. Australia.
E-mail: web...@itwol.bhp.com.au


Kenneth H. Fairfield

unread,
Jan 28, 2002, 5:34:35 PM1/28/02
to
> With your help, I have written this which appears to work. Does
> anyone see any problems with it? It is not documented nor tested for
> robustness,
> but it appears to work with a simple test program I through together...
>
> Integer Function Str$LowerCase (Input, Output)
>
> Character*(*) Input, Output
> Integer TableDesc (2)
> External Lib$AB_LowerCase
>
> Str$LowerCase = -1
> TableDesc (1) = 256
> TableDesc (2) = Loc (Lib$AB_LowerCase)
> Str$LowerCase = Lib$MovTC (Input, ' ', TableDesc, Output)
>
> Return
> End

I'd just note that "-1" is not the default return status value
I'd choose since that value tests TRUE in Fortran (in fact, setting
IVAL = .TRUE. sets the integer value to -1 (as opposed to the logical
value). Better to initialize to .FALSE. or "0", unless the caller is
expected to test for specific return values. This would at least be
consistent with the VMS condition value returned by LIB$MOVCT...

da...@pebble.org

unread,
Jan 28, 2002, 7:47:19 PM1/28/02
to
In article <3C55B3D5...@UIowa.EDU>, Rick Dyson wrote:

>> In the past I've used calls to BAS$EDIT, IIRC. There was an old


Umm, but BAS$EDIT doesn't have "uppercase to lowercase" functionality,
does it? I don't see it in any case. :-)


EDIT$

Syntax


str-var = EDIT$(str-exp, int-exp)

Values Effect

1% Trim parity bits
2% Discard all spaces and tabs
4% Discard characters: CR, LF,FF, ESC, RUBOUT, and NULL
8% Discard leading spaces and tabs
16% Reduce spaces and tabs to one space
32% Convert lowercase to uppercase
64% Convert [ to ( and ] to )
128% Discard trailing spaces and tabs
256% Do not alter characters inside quotes

- Dan

Steve Lionel

unread,
Jan 29, 2002, 9:44:22 AM1/29/02
to
On Mon, 28 Jan 2002 22:16:12 GMT, Rick Dyson <Rick-...@UIowa.EDU>
wrote:

> Excellent Suggestion Steve! I was unaware of that Library service.

There are a bunch of LIB$ routines like this. If memory serves, I
wrote the VAX version of LIB$MOVTC and constructed the various
translate tables WAAAAAY back when (1979-1980) Of course, the Alpha
version is different code entirely.

> With your help, I have written this which appears to work. Does
>anyone see any problems with it? It is not documented nor tested for
>robustness,
>but it appears to work with a simple test program I through together...

I agree with Ken Fairfield's comment that initializing the return
value to -1 seems irregular. Actually, there's no need to initialize
it at all because it will always get set by LIB$MOVTC. I do recommend
adding:

Include '($LIB$ROUTINES)'

to properly declare LIB$MOVTC.

Please send Visual Fortran support requests to vf-su...@compaq.com

Arne Vajhøj

unread,
Jan 30, 2002, 10:03:00 AM1/30/02
to Rick Dyson
Rick Dyson wrote:
> With your help, I have written this which appears to work. Does
> anyone see any problems with it? It is not documented nor tested for
> robustness,
> but it appears to work with a simple test program I through together...

Both LIB$MOVTC and the LIB$AB_ tables has been documented for >10 years
!

Arne

Carl Perkins

unread,
Jan 30, 2002, 2:36:00 PM1/30/02
to
Arne =?iso-8859-1?Q?Vajh=F8j?= <arne.v...@gtech.com> writes...

It also works with STR$Translate (which may be a more obvious
thing to try that the somewhat inobviously, if you don't know
VAX macro, named LIB$MOVTC):

u(1) = 256
u(2) = %loc(LIB$AB_Upcase)
l(1) = 256
l(2) = %loc(LIB$AB_Lowercase)
i= STR$Translate(out,in,l,u)

This also works fine to translate from uppercase to lowercase.

--- Carl

Steve Wright

unread,
Jan 30, 2002, 6:21:19 PM1/30/02
to
In message <slrna5bs8l...@pebble.org>, da...@pebble.org writes

I don't know the name of the library routine, but when we wanted to do
something similar in DEC-BASIC, we used the XLATE function.

From the on-line VMS manual

================== START OF CUT & PASTE ===============================

XLATE$

The XLATE$ function translates one string to another by referencing a
table string you supply.

-----------------------------------------------------------------------

Format

Str-result = xlate (Str-exp1, Str-exp2)
------------------------------------------------------------------------

-----------------------------------------------------------------------

Syntax Rules
Str-exp1 is the input string.
Str-exp2 is the table string.

-----------------------------------------------------------------------

Remarks
Str-exp2 can contain up to 256 ASCII characters, numbered from 0 to 255;
the position of each character in the string corresponds to an ASCII
value. Because 0 is a valid ASCII value (null), the first position in
the table string is position zero.
XLATE$ scans str-exp1 character by character, from left to right. It
finds the ASCII value n of the first character in str-exp1 and extracts
the character it finds at position n in str-exp2. XLATE$ then appends
the character from str-exp2 to str-var. XLATE$ continues this process,
character by character, until the end of str-exp1 is reached.
The output string may be smaller than the input string for the following
reasons:
XLATE$ does not translate nulls. If the character at position n in
str-exp2 is a null, XLATE$ does not append that character to str-var.
If the ASCII value of the input character is outside the range of
positions in str-exp2, XLATE$ does not append any character to str-var.


------------------------------------------------------------------------

Example


DECLARE STRING A, table, source
A = "abcdefghijklmnopqrstuvwxyz"
table = STRING$(65, 0) + A
LINPUT " Type a string of uppercase letters"; source
PRINT XLATE$(source, table)


Output

Type a string of uppercase letters? ABCDEFG
abcdefg

================== END OF CUT & PASTE ==================================


Well look at that... the example in the manual shows how to convert
uppercase to lowercase, although it does strip any non uppercase
characters :-(

Better to do something like

TABLE = ""
FOR I = 0% TO ASCII ("A") - 1%
TABLE = TABLE + CHR$ (I)
NEXT I
TABLE = TABLE + "abcdefghijklmnopqrstuvwxyz"
FOR I = ASCII ("Z") + 1% TO 255%
TABLE = TABLE + CHR$ (I)
NEXT I

to set up the table. That way, any non uppercase characters are
preserved.


--
Steve Wright

0 new messages