Languages and Scripting
Showing results for 
Search instead for 
Do you mean 

Creating a new "OpenVMS function"

SOLVED
Go to Solution
Occasional Advisor

Creating a new "OpenVMS function"

Hi all,

 

I have looked a lot of documentation but I am not able to find what I am looking for, probably 'cause I don't know how to call it. What I want to do is a new function like if it were a lexical. I need to use within a DCL a new function that returns a value. I mean, something like:

 

$ out :== write sys$output

$ calamar = f$my_new_function("potato")

$ out "calamar value is ''calamar'"

 

Is it possible. If so, how can I do it.

 

Thanks in advance,

 

Salva.

1 ACCEPTED SOLUTIONS
Honored Contributor Honored Contributor

Re: Creating a new "OpenVMS function"

User written lexical functions have been on the wishlist for a long time, but they're unlikely to ever happen.

 

You can get close with syntax like this

 

$ YOURFUNCTION symbol = parameter [parameter...] [/qualifier...] 

 

where "YOURFUNCTION" activates a program which uses the CLI routines to parse parameters and qualifiers, and LIB$SET_SYMBOL to return the result. It happens that the CLI parser will tack the "=" sign(s) to the end of the first parameter, regardless of spaces. That means you can define a local symbol if there is one, or global if two (or more). I have a few examples of such programs. Here is the CLI/documentation for one

 

MODULE FINDFILE_CLD
DEFINE VERB FINDFILE
ROUTINE DOFINDFILE
!
! Program to search for files given multiple filespecs, defaults and related filespecs
! Optionally parses resultant file into multiple fields
!
! Syntax:
!
!   FINDFILE <sym> [= ]  <filespec>[,...] [<defaultspec>[,...] [<relatedspec>[,...]]]
!                  [== ]
!     = is optional syntax single = is local, == implies global
!
!   Parameters
!
PARAMETER P1, LABEL=SYM,      VALUE(REQUIRED,NOCONCATENATE)
!     <sym> is a symbol to be defined with the resuling filename
!
PARAMETER P2, LABEL=FILE   , VALUE(LIST,NOCONCATENATE,TYPE=$FILE,REQUIRED)
!     primary filespec(s)in precendence order    F1,F2,...Fn
!
PARAMETER P3, LABEL=DEFAULT, VALUE(LIST,NOCONCATENATE,TYPE=$FILE)
!     default filespec(s)in precendence order    D1,D2,...Dn
!
PARAMETER P4, LABEL=RELATED, VALUE(LIST,NOCONCATENATE,TYPE=$FILE)
!     related filespec(s)in precendence order    R1,R2,...Rn
!
! Searches until a file is found. Sequence as follows:
!
!     F1,D1,R1
!     F1,D1,R2
!     ...
!     F1,D1,Rn
!     F1,D2,R1
!     F1,D2,R2
!     ...
!     F1,D2,Rn
!     F2,D1,R1
!     F2,D1,R2
!     ...
!     F2,D1,Rn
!     F2,D2,R1
!     F2,D2,R2
!     ...
!     F1,D2,Rn
!     F2,D1,R1
!     F2,D1,R2
!     ...
!     Fn,Dn,Rn
!
QUALIFIER LOCAL
QUALIFIER GLOBAL
DISALLOW ANY2 (LOCAL,GLOBAL)
!     /LOCAL  (D)
!     /GLOBAL
!       Specifies the symbol table
!
QUALIFIER IFERROR VALUE(REQUIRED)
!     /IFERROR=message (to be written if not found)
!
QUALIFIER QUIET   DEFAULT
!     /NOQUIET to output error messages
!
QUALIFIER DEBUG
!    Displays debug information while executing
!
QUALIFIER SEARCH  DEFAULT
!    Use /NOSEARCH to parse filespec only (first valid filespec will be returned)
!
QUALIFIER NORMALISE,       DEFAULT
!     /NORMALISE changes any <> brackets into []. Use /NONORMALISE to preserve <> in filespecs
!
QUALIFIER CONCEAL,       DEFAULT
!     /CONCEAL retains concealed logical names. Use /NOCONCEAL to translate concealed logical names
!
QUALIFIER SHOW,             VALUE
!     /SHOW[="string"]            - display name and resulting value with string
!
QUALIFIER PARSE   VALUE(TYPE=FILE_FIELDS,LIST)
!     /PARSE=(field list)
!
QUALIFIER OUTPUT VALUE(REQUIRED)
!     /[NO]OUTPUT=file
!
!       Select file specification fields to include in the output. By default all are included
!       If any fields are specified, only those are include. Use NOfield to omit fields.
!
!    For example
!       /PARSE=(DEVICE,DIR,NAME) => dev:[dir]name
!       /PARSE=NOVER             => dev:[dir]name.typ
!       /PARSE=(NAME,TYPE)       => name.typ
!       /PARSE=NODEV             => [dir]name.typ;ver
!       /PARSE=VER               => ;ver
!
!    Note that NODE will only be non-null if it was explicitly included in the input file specification
DEFINE TYPE FILE_FIELDS
  KEYWORD NODE,      NEGATABLE
  KEYWORD DEVICE,    NEGATABLE
  KEYWORD DIRECTORY, NEGATABLE
  KEYWORD NAME,      NEGATABLE
  KEYWORD TYPE,      NEGATABLE
  KEYWORD VERSION,   NEGATABLE
!

 

 

A crucible of informative mistakes
5 REPLIES
Regular Advisor

Re: Creating a new "OpenVMS function"

Do not know about the lexical, but is it not possible to use subroutines

i.e.

 

$ out :== write sys$output
$ call sub1 "potato"
$ calamar = "''ppp'"
$ out "calamar value is ''calamar'"
$ exit
$ sub1 : subroutine
$ ppp :== "''p1'"
$ exit

 

                       Regards

                               Jouk

Esteemed Contributor Esteemed Contributor

Re: Creating a new "OpenVMS function"

What kind of problem do you want to solve?

 

You can write a program to set a symbol by calling  lib$set_symbol. On VMS, programs are usually running in the current DCL context so a program is able to set a symbol for the current process. On recent versions of VMS, some utilities create and set symbols. Analyze/image with /select is an example.

Trusted Contributor Trusted Contributor

Re: Creating a new "OpenVMS function"

It's not possible to define a new lexical function.  It's also not possible to call a user-written function in DCL and have it directly return a value (e.g.  A = B(C)).

 

Depending on the complexity of what you want to do (and perhaps what already exists elsewhere) your choices are

 

(a) call a DCL subroutine, returning a value in a global symbol (see $ HELP CALL for details)

 

(b) execute a piped command and return a job logical (see $ HELP PIPE)

 

(c) call a separate command procedure and return a global symbol

 

(d) run an executable image that sets a global symbol (see $ HELP RTL LIB$ LIB$SET_SYMBOL) or sets a process logical (see $ HELP RTL LIB LIB$SET_LOGICAL)

 

 

Honored Contributor Honored Contributor

Re: Creating a new "OpenVMS function"

User written lexical functions have been on the wishlist for a long time, but they're unlikely to ever happen.

 

You can get close with syntax like this

 

$ YOURFUNCTION symbol = parameter [parameter...] [/qualifier...] 

 

where "YOURFUNCTION" activates a program which uses the CLI routines to parse parameters and qualifiers, and LIB$SET_SYMBOL to return the result. It happens that the CLI parser will tack the "=" sign(s) to the end of the first parameter, regardless of spaces. That means you can define a local symbol if there is one, or global if two (or more). I have a few examples of such programs. Here is the CLI/documentation for one

 

MODULE FINDFILE_CLD
DEFINE VERB FINDFILE
ROUTINE DOFINDFILE
!
! Program to search for files given multiple filespecs, defaults and related filespecs
! Optionally parses resultant file into multiple fields
!
! Syntax:
!
!   FINDFILE <sym> [= ]  <filespec>[,...] [<defaultspec>[,...] [<relatedspec>[,...]]]
!                  [== ]
!     = is optional syntax single = is local, == implies global
!
!   Parameters
!
PARAMETER P1, LABEL=SYM,      VALUE(REQUIRED,NOCONCATENATE)
!     <sym> is a symbol to be defined with the resuling filename
!
PARAMETER P2, LABEL=FILE   , VALUE(LIST,NOCONCATENATE,TYPE=$FILE,REQUIRED)
!     primary filespec(s)in precendence order    F1,F2,...Fn
!
PARAMETER P3, LABEL=DEFAULT, VALUE(LIST,NOCONCATENATE,TYPE=$FILE)
!     default filespec(s)in precendence order    D1,D2,...Dn
!
PARAMETER P4, LABEL=RELATED, VALUE(LIST,NOCONCATENATE,TYPE=$FILE)
!     related filespec(s)in precendence order    R1,R2,...Rn
!
! Searches until a file is found. Sequence as follows:
!
!     F1,D1,R1
!     F1,D1,R2
!     ...
!     F1,D1,Rn
!     F1,D2,R1
!     F1,D2,R2
!     ...
!     F1,D2,Rn
!     F2,D1,R1
!     F2,D1,R2
!     ...
!     F2,D1,Rn
!     F2,D2,R1
!     F2,D2,R2
!     ...
!     F1,D2,Rn
!     F2,D1,R1
!     F2,D1,R2
!     ...
!     Fn,Dn,Rn
!
QUALIFIER LOCAL
QUALIFIER GLOBAL
DISALLOW ANY2 (LOCAL,GLOBAL)
!     /LOCAL  (D)
!     /GLOBAL
!       Specifies the symbol table
!
QUALIFIER IFERROR VALUE(REQUIRED)
!     /IFERROR=message (to be written if not found)
!
QUALIFIER QUIET   DEFAULT
!     /NOQUIET to output error messages
!
QUALIFIER DEBUG
!    Displays debug information while executing
!
QUALIFIER SEARCH  DEFAULT
!    Use /NOSEARCH to parse filespec only (first valid filespec will be returned)
!
QUALIFIER NORMALISE,       DEFAULT
!     /NORMALISE changes any <> brackets into []. Use /NONORMALISE to preserve <> in filespecs
!
QUALIFIER CONCEAL,       DEFAULT
!     /CONCEAL retains concealed logical names. Use /NOCONCEAL to translate concealed logical names
!
QUALIFIER SHOW,             VALUE
!     /SHOW[="string"]            - display name and resulting value with string
!
QUALIFIER PARSE   VALUE(TYPE=FILE_FIELDS,LIST)
!     /PARSE=(field list)
!
QUALIFIER OUTPUT VALUE(REQUIRED)
!     /[NO]OUTPUT=file
!
!       Select file specification fields to include in the output. By default all are included
!       If any fields are specified, only those are include. Use NOfield to omit fields.
!
!    For example
!       /PARSE=(DEVICE,DIR,NAME) => dev:[dir]name
!       /PARSE=NOVER             => dev:[dir]name.typ
!       /PARSE=(NAME,TYPE)       => name.typ
!       /PARSE=NODEV             => [dir]name.typ;ver
!       /PARSE=VER               => ;ver
!
!    Note that NODE will only be non-null if it was explicitly included in the input file specification
DEFINE TYPE FILE_FIELDS
  KEYWORD NODE,      NEGATABLE
  KEYWORD DEVICE,    NEGATABLE
  KEYWORD DIRECTORY, NEGATABLE
  KEYWORD NAME,      NEGATABLE
  KEYWORD TYPE,      NEGATABLE
  KEYWORD VERSION,   NEGATABLE
!

 

 

A crucible of informative mistakes
Occasional Advisor

Re: Creating a new "OpenVMS function"

 

Many thanks to all you.

 

I will manage to solve my problem somehow using your ideas.