[ 前のページ ] [ 次のページ ] [ 目次 ] [ 索引 ] [ DOC Home ]

17 レキシカル関数:情報の取得と処理方法

レキシカル関数は,DCLインタプリタが評価して置換するコマンド言語構造です。DCL インタプリタはレキシカル関数を検出すると,まずこれを評価し置換した後でコマンド文字列を解釈します。 本章では,次のことを説明します。

レキシカル関数についての詳しい説明は,オンライン・ヘルプを参照してください。 本章で説明するコマンドについての詳細は,『OpenVMS DCL Dictionary』を参照してください。

17.1 レキシカル関数について

レキシカル関数を使用すると,次のことに関する情報を入手できます。

多くのレキシカル関数が戻す情報は,DCLコマンドからも得ることができます。

17.1.1 情報の取得

コマンドから情報を得るよりもレキシカル関数から情報を得た方が,コマンド・ プロシージャの中で情報を処理しやすくなります。たとえば, F$ENVIRONMENT関数またはSHOW DEFAULTコマンドのどちらを使用しても, 現在の省略時のディレクトリの名前を得ることができます。ただし,次の点が異なります。

17.2 プロセスについての情報

コマンド・プロシージャを実行している間,プロセス属性を頻繁に変更し, その後で属性を復元します。次のレキシカル関数を使用すれば,プロセスに関する情報を入手できます。

F$DIRECTORY 現在の省略時のディレクトリ文字列を戻す。
F$ENVIRONMENT ユーザ・プロセスのコマンド環境についての情報を戻す。
F$GETJPI ユーザ・ プロセスまたはシステム上の他のプロセスについての会計情報, 状態,識別情報を戻す。
F$MODE プロセスを実行中のモードを示す。
F$PRIVILEGE ユーザ・プロセスに特権が指定されているかどうかを示す。
F$PROCESS プロセスの名前を戻す。
F$SETPRV 指定された特権を設定する。 指定された特権が,F$SETPRV関数を使用する前に使用可能であったかどうかも示す。
F$USER UIC (ユーザ識別コード)を戻す。
F$VERIFY チェック機能のオンまたはオフを示す。

次の表は,コマンド・プロシージャで一般に変更されるプロセス属性を示しています。 また,これらの属性をセーブするレキシカル関数と,元の設定を復元するDCL コマンドも示しています。

属性 操作 コマンドまたは レキシカル関数
制御文字セーブ F$ENVIRONMENT("CONTROL")
復元 SETCONTROL
DCLプロンプトセーブ F$ENVIRONMENT("PROMPT")
復元 SET PROMPT
省略時の保護 セーブ F$ENVIRONMENT("PROTECTION")
復元 SET PROTECTION /DEFAULT
キー状態 セーブ F$ENVIRONMENT("KEY_STATE")
復元 SET KEY
メッセージ形式 セーブ F$ENVIRONMENT("MESSAGE")
復元 SET MESSAGE
特権 セーブ F$PRIVILEGEまたはF$SETPRV
復元 F$SETPRVまたはSET PROCESS/PRIVILEGES
チェック機能 セーブ F$VERIFYまたはF$ENVIRONMENT
復元 F$VERIFYまたはSET VERIFY

プロセス属性をセーブした場合,エラーまたはCtrl/Yによる割り込みによって, 元の属性を復元する前にプロシージャが終了することのないようにしなければなりません。 エラーとCtrl/Yによる割り込みの処理については, 第15章を参照してください。

17.2.1 チェック設定値の変更

F$VERIFYレキシカル関数を使用すると,コマンド・プロシージャが実行されている間だけチェック機能を無効にすることができます。 このとき,ユーザは, プロシージャを実行しながらそのプロシージャの内容を表示することはできません。

チェック機能には,次の2つのタイプがあります。

省略時の設定では,SET [NO]VERIFYコマンドとF$VERIFYレキシカル関数は, 両方のタイプのチェック機能をオン,オフします。通常は,プロシージャの中のプロージャおよびイメージ・ チェック設定値は同じになっています( 両方がオンか,両方がオフになっています)。ただし,設定値を変更する場合には, それぞれのチェック設定値を別々にセーブします。

次の例では,シンボルTEMPを使用して,チェック機能を有効および無効に設定します。

     $ ! Enable verification
     $ !
     $ TEMP = F$VERIFY(1)
     $ LOOP:
     $     INQUIRE FILE "File name"
     $     IF FILE .EQS."" THEN EXIT
     $     PRINT 'FILE'
     $     GOTO LOOP
     $ ! Disable verification
     $ !
     $ TEMP = F$VERIFY(0)
     $ EXIT

次の例では,チェック機能の設定がセーブされます。

     $ ! Save each verification state
     $ ! Turn both states off
     $ SAVE_VERIFY_IMAGE = F$ENVIRONMENT("VERIFY_IMAGE")
     $ SAVE_VERIFY_PROCEDURE = F$VERIFY(0)
        .
        .
        .
     $ ! Restore original verification states
     $ SAVE_VERIFY_IMAGE = F$VERIFY(SAVE_VERIFY_PROCEDURE,-
           SAVE_VERIFY_IMAGE)

上記の例で,F$ENVIRONMENT関数は,現在のイメージ・チェック設定値を戻し, この値をSAVE_VERIFY_IMAGEシンボルに割り当てています。次に, F$VERIFY関数が現在のプロシージャ・チェック設定値を戻し,この値をSAVE_VERIFY_PROCEDURE シンボルに割り当てています。F$VERIFY関数は, イメージ・チェックとプロシージャ・チェックの両方を無効にします。 F$ENVIRONMENT関数を使用すれば,F$VERIFYによってチェック機能を無効にする前にプロシージャ・ チェック設定値を得ることができます。ただし, 上記の例に示すように,F$VERIFYを使用して1つのコマンド行の中で両方のタスクを行った方がプロシージャの長さが短くてすみます。

プロシージャの終わりに,F$VERIFY関数で元の設定値(シンボルSAVE_ VERIFY_PROCEDUREとSAVE_VERIFY_IMAGEによって指定される)を復元しています。


注意
時刻印字を使用する場合, チェック機能が使用可能な場合にだけ適用されることに注意してください。 時刻印字とSET PREFIXコマンドについての詳細は,『OpenVMS DCL Dictionary』またはDCL ヘルプを参照してください。

17.2.2 省略時のファイル保護の変更

コマンド・プロシージャの中で省略時のファイル保護を変更したい場合があります。 次のコマンド・プロシージャは,プロシージャの実行中に作成されたファイルに関連する省略時の保護を変更します。 この場合,終了する前に元の省略時のファイル保護を復元しています。

     $ SAVE_PROT = F$ENVIRONMENT("PROTECTION")
     $ SET PROTECTION = (SYSTEM:RWED, OWNER:RWED, GROUP, WORLD)/DEFAULT
        .
        .
        .
     $ SET PROTECTION=('SAVE_PROT')/DEFAULT
     $ EXIT

この例で,F$ENVIRONMENT関数は,SET PROTECTIONコマンドの構文を使用して省略時の保護コードを戻しています。 このため,SET PROTECTIONコマンドと一緒にSAVE_PORT シンボルを使用して元の省略時のファイル保護を復元できます。

17.3 システムについての情報

システムについての情報を得るには,次のレキシカル関数を使用します。

F$CONTEXT F$PID関数と一緒に使用する場合の選択基準を指定する。F$CONTENT 関数と一緒にF$PID関数を使用すると,OpenVMS Cluster の任意のノードのプロセスについての情報を得ることができる。
F$CSID VMSクラスタ識別番号を戻して,システムのVMSクラスタ・ノード・ リストの中の現在の位置を指すようにコンテキスト・シンボルを更新する。
F$GETQUI システム・ ジョブ・キュー・ファイルに収められたキュー,現在キューの中にあるバッチ・ ジョブと印刷ジョブ,フォーム定義,属性定義についての情報を戻す。
F$GETSYI ローカル・ システムまたはVMSクラスタ内のノード(システムがVMSクラスタの一部である場合) についての情報を戻す。
F$IDENTIFIER 識別子を指定された形式から数値形式に, または数値形式から指定された形式に変換する。
F$MESSAGE 状態コードに関連するメッセージ・ テキストを戻す。
F$PID ユーザがチェックすることが許容されているプロセスのプロセス識別番号(PID) を戻す。
F$TIME 現在の日時を戻す。

17.3.1 OpenVMS Clusterノード名の決定

使用中のシステムがネットワークまたはOpenVMS Clusterの一部で,多数のノードにログインできる場合には, 現在使用中のノードを示すようにDCL プロンプトを設定できます。このためには,ログイン・コマンド・プロシージャの中にF$GETSYI 関数を指定して,ノード名を判別します。次に,SET PROMPT コマンドを使用して,ノード固有のプロンプトを設定します。

プロンプト文字列の中でノード名の一部分だけを使用したい場合には, F$EXTRACT関数を使用して,該当する文字を取り出します。文字の取り出しについては, 第17.6.2項を参照してください。

次の例では,シンボルNODEがFF$GETSYI("NODENAME")として定義され,その後, ノード名がプロンプトとして使用されます。

     $ NODE = F$GETSYI("NODENAME")
     $ SET PROMPT = "''NODE'$ "
        .
        .
        .

17.3.2 キューについての情報

F$GETQUI関数を使用すると,バッチ・キューと印刷キューについての各種の情報を得ることができます。 キューの中のジョブやファイルについての情報を得るには, 該当ジョブに対する読み込みアクセス権か SYSPRVまたはOPER 特権を持っていなくてはなりません。

次の例は,バッチ・キューVAX1_BATCHが終了状態にあるかどうかを判別する方法を示しています。 戻される値は真か偽のいずれかです。キューが終了状態にない場合には, コマンド・プロシージャはジョブをキューに登録します。

     $ QSTOPPED = F$GETQUI("DISPLAY_QUEUE", "QUEUE_STOPPED", "VAX1_BATCH")
     $ IF QSTOPPED THEN GOTO NOBATCH
     $ SUBMIT/QUEUE=VAX1_BATCH TEST.COM
     $ NOBATCH:
        .
        .
        .

17.3.3 プロセスについての情報

F$PID関数を使用すると,チェックすることが許容されているすべてのプロセスのプロセス識別番号(PID) を得ることができます。

PID番号を入手した後,F$GETJPI関数を使用すれば,プロセスに関する特定の情報を入手できます。

次の例は,チェックすることが許容されているプロセスのPIDを得て表示する方法を示しています。

     $ ! Display the time when this procedure
     $ ! begins executing
     $ WRITE SYS$OUTPUT F$TIME()
     $ !
     $ CONTEXT = ""
     $ START:
     $ ! Obtain and display PID numbers until
     $ ! F$PID returns a null string
     $ !
     $ PID = F$PID(CONTEXT)
     $ IF PID .EQS. "" THEN EXIT
     $ WRITE SYS$OUTPUT "Pid --- ''PID'"
     $ GOTO START

システムはCONTEXTシンボルを使用して,ポインタをPIDのシステム・リストに保持しています。 ループを通過するたびに,ポインタを変更して,リストの中の次のPID を指すようにします。すべてのPIDが表示されると,プロシージャは終了します。

次のプロシージャは,PIDとそれぞれのプロセスのUICを表示します。

     $ CONTEXT = ""
     $ START:
     $ ! Obtain and display PID numbers and UICs
     $ !
     $ PID = F$PID(CONTEXT)
     $ IF PID .EQS. "" THEN EXIT
     $ UIC = F$GETJPI(PID,"UIC")
     $ WRITE SYS$OUTPUT "Pid --- ''PID'   Uic--- ''UIC' "
     $ GOTO START

WRITEコマンドの中にF$GETJPI関数を指定すれば,このコマンド・プロシージャを短くできます。

     $ CONTEXT = ""
     $ START:
     $ PID = F$PID(CONTEXT)
     $ IF PID .EQS. "" THEN EXIT
     $ WRITE SYS$OUTPUT "Pid --- ''PID'   Uic --- ''F$GETJPI(PID,"UIC")'"
     $ GOTO START

17.3.4 F$CONTEXTレキシカル関数

OpenVMS Cluster内の任意のノードからプロセスに関する情報を入手するには,F$CONTEXT 関数を使用します。

次の例では,選択基準を設定するためにF$CONTEXTが3回呼び出されています。

     $!Establish an error and Ctrl/Y handler
     $!
     $ ON ERROR THEN GOTO error
     $ ON CONTROL_Y THEN GOTO error
     $!
     $ ctx = ""
     $ temp = F$CONTEXT ("PROCESS", ctx, "NODENAME", "*","EQL") 【1】
     $ temp = F$CONTEXT ("PROCESS", ctx, "USERNAME", "M*,SYSTEM","EQL") 【2】
     $ temp = F$CONTEXT ("PROCESS", ctx, "CURPRIV", "SYSPRV,OPER", "ALL") 【3】
     $!
     $!Loop over all processes that meet the selection criteria.
     $!Print the PID number and the name of the image for each process.
     $!
     $loop: 【4】
     $ pid = F$PID(ctx)
     $ IF pid .EQS. ""
     $ THEN
     $     GOTO endloop
     $ ELSE

     $     image = F$GETJPI(pid,"IMAGNAME") 【5】
     $     SHOW SYMBOL pid
     $     WRITE SYS$OUTPUT image 【6】
     $     GOTO loop
     $ ENDIF
     $!The loop over the processes has ended.

     $!
     $endloop:
     $!
     $ EXIT
     $!
     $!Error handler. Clean up the context's memory with
     $!the CANCEL selection item keyword.
     $!
     $error:
     $ IF F$TYPE(ctx) .eqs. "PROCESS_CONTEXT" THEN - 【7】
     -$ temp = F$CONTEXT ("PROCESS", ctx, "CANCEL") 【8】
     $!
     $ EXIT

例を調べる場合には,次のことに注意してください。

【1】
最初の呼び出しでは,検索がOpenVMS Clusterのすべてのノードで実行されることを要求する。
【2】
2番目の呼び出しでは, ユーザ名がMから始まるプロセス,またはユーザ名がSYSTEMであるプロセスだけを処理することを要求する。
【3】
3番目の呼び出しでは, 現在の特権にSYSPRV (システム特権)と OPER (オペレータ特権)の両方が含まれており, 他の特権も持つことができるプロセスだけを選択する。
【4】
"loop"と"endloop"というラベルの間のコマンド行は,F$PID を継続的に呼び出して,F$CONTEXT呼び出しで設定された条件を満足するプロセスを入手する。
【5】
各PID番号を検索した後,F$GETJPI が呼び出され,プロセスで実行中のイメージの名前が戻される。
【6】
最後に,プロシージャはイメージの名前を表示する。
【7】
エラーが発生したり,Ctrl/Yが押された場合には, 制御はerrorに渡され,必要に応じてコンテキストは閉じられる。
【8】
シンボル・タイプPROCESS_CONTEXTのチェックに注意しなければならない。 シンボルがこのタイプである場合には,F$CONTEXTを呼び出すことにより, 選択条件を取り消さなければならない。シンボルがPROCESS_CONTEXT タイプでない場合には,選択条件がF$CONTEXTでまだ設定されていないか, またはエラーが発生するかプロセス・リストの最後に到達するまで,F$PID に対してシンボルが使用されていた。

17.4 ファイルとデバイスについての情報

ファイルとデバイスについての情報を得るには,次のレキシカル関数を使用します。

F$DEVICE 指定された選択基準を満たすシステム上のすべてのデバイスのデバイス名を戻す。
F$FILE_ATTRIBUTES ファイル属性についての情報を戻す。
F$GETDVI 指定されたデバイスについての情報を戻す。
F$PARSE ファイル指定を解析して,要求された1つまたは複数のフィールドを戻す。
F$SEARCH ディレクトリでファイルを検索する。

17.4.1 デバイスの検索

システム・サービス$GETDVIを使用することによって特定のデバイスについての情報を得るには, デバイス名をサービスに提供しなければなりません。 デバイス名がわからない場合には,F$DEVICEレキシカル関数を使用して検索できます。

F$DEVICE関数を使用すると,デバイス名,デバイス・クラス,またはデバイス・ タイプに基づくワイルドカード検索ができます。デバイス・タイプに基づいて検索を行うには, デバイス・クラスも指定しなければなりません。

コマンド・プロシージャのループの中でF$DEVICE関数を使用すると,指定された選択基準に一致するデバイス名が戻されます。F$DEVICE 関数を実行するたびに, 選択基準に一致する次のデバイスが戻されます。デバイス名が戻される順序は一定でないことに注意してください。 最後のデバイス名が戻されてからF$DEVICE 関数を呼び出すと,空の文字列が戻されます。

次の例のコマンド・プロシージャは,ユニット番号が0のユニット上のすべてのRA60 のデバイス名を表示します。

     $ START:
     $     DEVICE_NAME = F$DEVICE("*0:","DISK","RA60")
     $     IF DEVICE_NAME .EQS. "" THEN EXIT
     $     SHOW SYMBOL DEVICE_NAME
     $     GOTO START

17.4.2 ディレクトリの中でのファイルの検索

ファイルを処理する際には,あらかじめF$SEARCH関数を使用してそのファイルが存在するかどうかを調べなくてはなりません。 たとえば,次のコマンド・ プロシージャは,F$PARSEを使用して,デバイスとディレクトリ文字列をSTATS.DAT ファイルに適用しています。次に,F$SEARCH関数を使用して,DISK3:[JONES.WORK] にSTATS.DATが存在するかどうか判別します。 存在すれば,ファイルを処理し,存在しない場合には,別の入力ファイルを求めるプロンプトを出します。

     $ FILE = F$PARSE("STATS.DAT","DISK3:[JONES.WORK]",,,"SYNTAX_ONLY")
     $ IF F$SEARCH(FILE) .EQS. "" THEN GOTO GET_FILE
     $ PROCESS_FILE:
        .
        .
        .
     $ GET_FILE:
     $   INQUIRE FILE "File name"
     $   GOTO PROCESS_FILE

ファイルの存在を判別した後,F$PARSEまたはF$FILE_ATTRIBUTES関数を使用すれば, ファイルについての補足情報を得ることができます。

     $ IF F$SEARCH("STATS.DAT") .EQS. "" THEN GOTO GET_FILE
     $ PROCESS_FILE:
     $     NAME = F$PARSE("STATS.DAT",, "NAME")
        .
        .
        .
     $ GET_FILE:
     $   INQUIRE FILE "File name"
     $   GOTO PROCESS_FILE

17.4.3 ファイルの古いバージョンの削除

プロシージャの終了後にユーザが必要としないファイルが作成された場合には, プロシージャを終了する前にこれらのファイルを削除またはパージします。 最も新しいバージョンを除くすべてバージョンを削除するには, PURGEコマンドを使用します。ファイルの特定のバージョンを削除するには,DELETE コマンドと一緒にバージョン番号を指定します。ファイルのすべてのバージョンを削除するには,DELETE コマンドのバージョン・フィールドにワイルドカード文字を使用します。

コマンド・プロシージャの中でDELETEコマンドを使用するときに,エラー・ メッセージが出されないようにするには,F$SEARCH関数を使用して, 削除する前にそのファイルが存在するかどうかをチェックします。たとえば, 特定のモジュールが存在する場合にのみTEMP.DATというファイルを作成するコマンド・ プロシージャを作成することができます。次のコマンド行は,TEMP.DAT が存在する場合にだけDELETEコマンドを出します。

     $ IF F$SEARCH("TEMP.DAT") .NES. "" THEN DELETE TEMP.DAT;*

17.5 論理名の変換

論理名を変換するには,次のレキシカル関数を使用します。

F$LOGICAL 論理名の同値文字列を戻す。
F$TRNLNM 論理名の同値文字列または要求された属性を戻す。


注意
F$TRNLNM関数は,OpenVMSオペレーティング・ システムの以前のバージョンで使用されていたF$LOGICAL に代わるものです。コマンド・プロシージャが現在のシステム手法を使用して論理名を処理するようにするには,F$LOGICAL の代わりにF$TRNLNMを使用してください。

場合によっては,コマンド・プロシージャの変数としてシンボルではなく, 論理名を使用するとよいことがあります。プログラムは,DCLシンボルにアクセスするより論理名にアクセスする方が簡単だからです。 したがって, コマンド・プロシージャから実行するプログラムに情報を渡すには, シンボルを使用して情報を得てから,DEFINEまたはASSIGNコマンドを使用して, シンボルの値を論理名に定義します。

また,F$TRNLNM関数を使用して論理名の値を判断してから,その値をシンボルに割り当てることもできます。

次の例は,論理名NAMESが定義されているかどうかをテストします。定義されている場合には, プロシージャはPAYROLL.EXEを実行し,定義されていない場合には,FILE シンボルの値を得て,この値を使用して論理名NAMES を作成します。PAYROLL.EXEは,論理名NAMESを使用して従業員名のファイルを表しています。

     $ ! Make sure that NAMES is defined
     $ IF F$TRNLNM("NAMES") .NES. "" THEN GOTO ALL_SET
     $ INQUIRE FILE "File with employee names"
     $ DEFINE NAMES 'FILE'
     $ !
     $ ! Run PAYROLL, using the file indicated by NAMES
     $ ALL_SET:
     $ RUN PAYROLL
        .
        .
        .

このコマンド・プロシージャは,PAYROLLプログラムで使用される論理名を定義します。

     $ DEFINE NAMES DISK4:[JONES]EMPLOYEE_NAMES.DAT
     $ RUN PAYROLL
        .
        .
        .
     $ WRITE SYS$OUTPUT "Finished processing ",F$TRNLNM("NAMES")

プロシージャの終わりに,ファイルが処理されたことを示すメッセージがWRITE コマンドによって表示されます。

17.6 文字列の処理

文字列を処理するには,次のレキシカル関数を使用します。

F$CVTIME 時刻文字列についての情報を戻す。
F$EDIT 文字列を編集する。
F$ELEMENT 各要素が区切り文字によって分けられている文字列から要素を取り出す。
F$EXTRACT 文字列の一部を取り出す。
F$FAO 出力文字列を書式化する。
F$LENGTH 文字列の長さを決定する。
F$LOCATE 文字列の中の文字または部分文字列を探して, オフセットを戻す。

17.6.1 文字列または文字の有無の判別

文字列を調べる理由の1つに,文字列の中に文字(または部分文字列)が存在するかどうかの判別があります。 このためには,F$LENGTHとF$LOCATE関数を使用します。F$LOCATE 関数が戻す値がF$LENGTH関数が戻す値と等しければ, 探している文字は存在しません。

次のプロシージャは,バージョン番号を含むファイル名を要求しています。 バージョン番号が存在するかどうかを判別するために,ユーザが入力したファイル名の中に, バージョン番号の前に置くセミコロン(;)があるかどうかをテストします。

     $ INQUIRE FILE "Enter file (include version number)"
     $ IF F$LOCATE(";", FILE) .EQ. F$LENGTH(FILE) THEN -
          GOTO NO_VERSION
        .
        .
        .

F$LOCATE関数は,セミコロンのオフセットを戻します。オフセットは0で始まるため, セミコロンが文字列の最初の文字であれば,F$LOCATE関数は整数0 を戻します。文字列の中にセミコロンがなければ,F$LOCATE関数は, 文字列の最後の文字のオフセットより1だけ大きいオフセットを戻します。 この値は,番号1から始まる文字列の長さに相当する F$LENGTHが戻す長さと同じです。

17.6.2 文字列の一部の取り出し

文字列の一部を取り出すには,F$EXTRACT関数またはF$ELEMENT関数のどちらかを使用します。 定義されたオフセットから始まる部分文字列を取り出すにはF$EXTRACT 関数を使用し,2つの区切り文字の間の文字列の一部を取り出すには,F$ELEMENT 関数を使用します。どちらの関数を使用するかを選択するためには, 解析する文字列の一般形式がわかっていなければなりません。

ファイル指定または時刻文字列を解析するには,F$EXTRACTまたはF$ELEMENT を使用する必要はありません。代わりに,F$PARSEまたはF$CVTIME を使用して,ファイル指定または時刻文字列の一部を取り出します。

グループ名を取り出すのと同時に,グループ名の長さを判断することもできます。

文字列にその文字列の異なる部分を区切る区切り文字をが含まれている場合には,F$ELEMENT 関数を使用して,必要な部分を取り出すことができます。F$ELEMENT を使用すると,文字列の中でカンマで区切られた部分を取り出すことにより, 異なるアクセス・タイプを入手できます。システム・ アクセスを判断するには,最初の要素を入手します。オーナ・アクセスを判断するには,2 番目の要素を入手します。以下も同様です。F$ELEMENT関数を使用する場合には, 要素番号は0から始まります。この理由から,4番目の要素を指定するときは, 整数3を使用します。

次のコマンド・プロシージャは,F$EXTRACT関数を使用してUICのグループ部分を取り出します。 このとき,ユーザのUICグループに応じて,異なるコマンド・ セットを実行できます。

     $ UIC = F$USER()
     $ GROUP_LEN = F$LOCATE(",",UIC) - 1
     $ GROUP = F$EXTRACT(1,GROUP_LEN, UIC)
     $ GOTO 'GROUP'_SECTION
        .
        .
        .
     $ WRITERS_SECTION:
        .
        .
        .
     $ MANAGERS_SECTION:
        .
        .
        .

最初に,F$USER関数によってUICを判別します。次に,F$LOCATEを使用してコンマのオフセットを検出して, グループ名の長さを判別します。コンマによってUIC のグループとユーザ部分が区切られているからです。左括弧とコンマの間にあるものがグループ名の部分になります。 たとえば, UIC [WRITERS,SMITH]のグループ名はWRITERSです。

長さを判別した後,プロシージャはF$EXTRACT関数によってグループの名前を取り出します。 名前はオフセット1で始まり,コンマの前の文字で終わります。 最後に,該当するラベルに処理を移します。

次の例では,保護コードの各アクセス・タイプがカンマでどのように区切られるかを示しています。

     $ UIC = F$USER()
     $ GROUP = F$EXTRACT(1, F$LOCATE(",",UIC) - 1, UIC)
     $ GOTO 'GROUP'_SECTION

次の例では,保護コードの各アクセス・タイプがカンマでどのように区切られるかを示しています。

     $ PROT = F$ENVIRONMENT("PROTECTION")
     $ SHOW SYMBOL PROT
     PROT = "SYSTEM=RWED, OWNER=RWED, GROUP=RE, WORLD"

この例のコマンドは,省略時の保護コードからワールド・アクセスの部分(4 番目の要素)を取り出します。

     $ PROT = F$ENVIRONMENT("PROTECTION")
     $ WORLD_PROT = F$ELEMENT(3,",",PROT)
        .
        .
        .

この例では,F$ELEMENT関数は,3番目のコンマと文字列の終わりの間にあるすべてを戻すため, 省略時の保護がワールド・ユーザの読み込みアクセスを許容している場合には, 文字列" WORLD=R"が戻されます。

ワールド・アクセス文字列を得たら,さらにそれを調べる必要があります。 たとえば,次のようにします。

     $ PROT = F$ENVIRONMENT("PROTECTION")
     $ WORLD_PROT = F$ELEMENT(3,",",PROT)
     $ IF F$LOCATE("=", WORLD_PROT) .EQ. F$LENGTH(WORLD_PROT) -
       THEN GOTO NO_WORLD_ACCESS
        .
        .
        .

17.6.3 出力文字列の書式化

WRITEコマンドを使用すると,文字列をレコードに書き込むことができます。 レコード内のカラムをそろえるには,F$FAO関数を使用してレコード・ フィールドを定義し,これらのフィールドにプロセス名とユーザ名を格納します。F$FAO 関数を使用する場合には,制御文字列を使用してレコード内のフィールドを定義します。 その後,これらのフィールドに格納する値を指定します。

レコード内のフィールドを書式化する別の方法として,文字列オーバレイを使用する方法があります。 しかし,F$FAO関数の方が文字列オーバレイより強力です。F$FAO 関数を使用すると,広範囲にわたる出力操作を実行できます。

この例に示したコマンド・プロシージャでは,WRITEコマンドを使用して, システムのプロセスのプロセス名とPID番号を表示します。

     $ ! Initialize context symbol to get PID numbers
     $ CONTEXT = ""
     $ ! Write headings
     $ WRITE SYS$OUTPUT "Process Name     PID"
     $ !
     $ GET_PID:
     $ PID = F$PID(CONTEXT)
     $ IF PID .EQS. "" THEN EXIT
     $ WRITE SYS$OUTPUT F$GETJPI(PID,"PRCNAM"),"     ", F$GETJPI(PID,"PID")
     $ GOTO GET_PID

次に示すように,WRITEコマンドからの出力では,プロセス名とユーザ名の間に5 つのスペースが挿入されますが,桁そろえは行われません。

     Process Name     PID
     MARCHESAND     2CA0049C
     TRACTMEN     2CA0043A
     FALLON     2CA0043C
     ODONNELL     2CA00453
     PERRIN     2CA004DE
     CHAMPIONS     2CA004E3

この例の中では,コマンド・プロシージャは,F$FAO関数を使用して,16 文字フィールドと12文字フィールドを定義しています。F$FAO関数は,最初のフィールドにプロセス名を収めてから, スペースはスキップして,2 番目のフィールドにPIDを収めます。

     $ ! Initialize context symbol to get PID numbers
     $ CONTEXT = ""
     $ ! Write headings
     $ WRITE SYS$OUTPUT "Process Name     PID"
     $ !
     $ GET_PID:
     $ PID = F$PID(CONTEXT)
     $ IF PID .EQS. "" THEN EXIT
     $ LINE = F$FAO("!16AS !12AS", F$GETJPI(PID,"PRCNAM"), F$GETJPI(PID,"PID"))
     $ WRITE SYS$OUTPUT LINE
     $ GOTO GET_PID

ここで,プロシージャを実行すると,桁がそろえられます。

     Process Name     PID
     MARCHESAND       2CA0049C
     TRACTMEN         2CA0043A
     FALLON           2CA0043C
     ODONNELL         2CA00453
     PERRIN           2CA004DE
     CHAMPIONS        2CA004E3

次の例は,オーバレイを使用して,RECORDシンボルの最初の16文字(オフセット0 から始まる)にプロセス名を収め,次の12文字(オフセット17から始まる) にPIDを収めます。

     $ ! Initialize context symbol to get PID numbers
     $ CONTEXT = ""
     $ ! Write headings
     $ WRITE SYS$OUTPUT "Process Name     PID"
     $ !
     $ GET_PID:
     $ PID = F$PID(CONTEXT)
     $ IF PID .EQS. "" THEN EXIT
     $ RECORD[0,16]:= 'F$GETJPI(PID,"PRCNAM")'
     $ RECORD[17,12]:= 'F$GETJPI(PID,"PID")'
     $ WRITE SYS$OUTPUT RECORD
     $ GOTO GET_PID

このプロシージャでは,F$FAO関数で作成したのと同じ書式が生成されます。

     Process Name     PID
     MARCHESAND       2CA0049C
     TRACTMEN         2CA0043A
     FALLON           2CA0043C
     ODONNELL         2CA00453
     PERRIN           2CA004DE
     CHAMPIONS        2CA004E3

17.7 データ・タイプの処理

データを文字列から整数に,整数から文字列に変換するには,次のレキシカル関数を使用します。

F$CVSI 文字列からビット・フィールドを取り出して, 符号付きの値である結果を整数に変換する。
F$CVUI 文字列からビット・フィールドを取り出して, 符号なしの値である結果を整数に変換する。
F$INTEGER 文字列式を整数に変換する。
F$STRING 整数式を文字列に変換する。
F$TYPE シンボルのデータ・タイプを判別する。

17.7.1 データ・タイプの変換

整数と文字列の間で変換を行うには,F$INTEGER関数とF$STRING関数を使用します。 たとえば,次のコマンド・プロシージャはデータ・タイプを変換します。 ユーザが文字列を入力すると整数の同値が表示され,整数を入力すると文字列の同値が表示されます。GOTO 文の中でラベル名を使用するときには,F$TYPE 関数をどのように使用したらよいかに注意してください。F$TYPE は,シンボルのデータ・タイプに応じて,"STRING"または"INTEGER" を戻します。

     $ IF P1 .EQS. "" THEN INQUIRE P1 "Value to be converted"
     $ GOTO CONVERT_'F$TYPE(P1)'
     $
     $ CONVERT_STRING:
     $ WRITE SYS$OUTPUT "The string ''P1' is converted to ''F$INTEGER(P1)'"
     $ EXIT
     $
     $ CONVERT_INTEGER:
     $ WRITE SYS$OUTPUT "The integer ''P1' is converted to ''F$STRING(P1)'"
     $ EXIT

17.7.2 式の評価

INQUIREやREADなどのコマンドは,文字列データしか受け付けません。これらのコマンドを使用して, 整数式として評価したいデータを得るには, F$INTEGER関数を使用してこのデータを変換してから評価します。

EXPシンボルをF$INTEGER関数の引数として使用する場合には,EXPシンボルの前後に一重引用符(') を置かなければなりません。こうすると,シンボル置換の最初のフェーズでEXP の値が置換されます。

次の例では,F$INTEGER関数を使用して,整数式を評価します。

     $ INQUIRE EXP "Enter integer expression"
     $ RES = F$INTEGER('EXP')
     $ WRITE SYS$OUTPUT "Result is",RES

このコマンド・プロシージャからの出力は次のようになります。

     Enter integer expression: 9 + 7
     Result is 16

"9 + 7"の値が置換されます。F$INTEGER関数が引数の"9 + 7"を処理する場合, 式を評価して正しい結果を戻します。

17.7.3 シンボルの有無の判別

シンボルが存在するかどうかを判別するには,F$TYPE関数を使用します。 F$TYPE関数は,シンボルが未定義であると,空の文字列を戻します。

        .
        .
        .
     $ IF F$TYPE(TEMP) .EQS. "" THEN TEMP = "YES"
     $ IF TEMP .EQS. "YES" THEN GOTO TEMP_SEC
        .
        .
        .

このプロシージャは,TEMPシンボルが前に定義されているかどうかをテストします。 定義済みの場合には,TEMPの正しい値が保持され,TEMPが定義されていない場合には,IF 文により"YES"の値がTEMPに割り当てられます。


[ 前のページ ] [ 次のページ ] [ 目次 ] [ 索引 ] [ DOC Home ]