OpenVMS
ユーザーズ・マニュアル


前へ 次へ 目次 索引



付録 B
コマンド・プロシージャの例

ここでは,第 13 章第 14 章 ,および 第 15 章 で説明した概念と手法について実際のコマンド・プロシージャを示しながら説明します。1 つの節で 1 つのコマンド・プロシージャを解説します。コマンド・プロシージャごとに次の内容を示します。

B.1 CONVERT.COM コマンド・プロシージャ

このコマンド・プロシージャは,(これ以降の時間の)絶対時刻をデルタ時間に変換し,現在の時刻とユーザが指定した時刻との差を示します。このプロシージャは,F$TIME と F$CVTIME レキシカル関数の使用方法と,割り当て文を使用して算術計算を行ったりシンボル値を連結する方法を示します。

例: CONVERT.COM


 
 
$ ! Procedure to convert an absolute time to a delta time. 
$ ! The delta time is returned as the global symbol WAIT_TIME. 
$ ! P1 is the time to be converted. 
$ ! P2 is an optional parameter - SHOW - that causes the 
$ ! procedure to display WAIT_TIME before exiting 
$ ! 
$ ! Check for inquiry 
$ ! 
$ IF P1 .EQS. "?" .OR. P1 .EQS. "" THEN GOTO TELL          (1)
$ ! 
$ ! Verify the parameter:  hours must be less than 24 
$ !                        minutes must be less than 60 
$ !                        time string must contain only hours 
$ !                        and minutes 
$ ! 
$ ! Change error and message handling to 
$ ! use message at BADTIME 
$ ! 
$ ON WARNING THEN GOTO BADTIME                             (2)
$ SAVE_MESSAGE = F$ENVIRONMENT("MESSAGE")
$ SET MESSAGE/NOFACILITY/NOIDENTIFICATION/NOSEVERITY/NOTEXT 
$ TEMP = F$CVTIME(P1)
$ ! 
$ ! Restore default error handling and message format 
$ ON ERROR THEN EXIT 
$ SET MESSAGE'SAVE_MESSAGE' 
$ ! 
$ IF F$LENGTH(P1).NE. 5 .OR. -                            (3)
        F$LOCATE(":",P1).NE. 2 - 
        THEN GOTO BADTIME 
$ ! 
$ ! Get the current time 
$ ! 
$ TIME = F$TIME()                                         (4)
$ ! 
$ ! Extract the hour and minute fields from both the current time 
$ ! value(TIME)and the future time(P1)
$ ! 
$ MINUTES = F$CVTIME(TIME,"ABSOLUTE","MINUTE")      ! Current minutes (5)
$ HOURS = F$CVTIME(TIME,"ABSOLUTE","HOUR")          ! Current hours 
$ FUTURE_MINUTES = F$CVTIME(P1,"ABSOLUTE","MINUTE") ! Minutes in future time 
$ FUTURE_HOURS = F$CVTIME(P1,"ABSOLUTE","HOUR")     ! Hours in future time 
$ ! 
$ ! 
$ ! Convert both time values to minutes 
$ ! Note the implicit string to integer conversion being performed 
$ ! 
$ CURRENT_TIME = HOURS*60 + MINUTES                        (6)
$ FUTURE_TIME = FUTURE_HOURS*60 + FUTURE_MINUTES 
$ ! 
$ ! Compute difference between the future time and the current time 
$ !(in minutes)
$ ! 
$ ! 
$ MINUTES_TO_WAIT = FUTURE_TIME - CURRENT_TIME             (7)
$ ! 
$ ! If the result is less than 0 the specified time is assumed to be 
$ ! for the next day; more calculation is required. 
$ ! 
$ IF MINUTES_TO_WAIT .LT. 0 THEN -                         (8)
        MINUTES_TO_WAIT = 24*60 + FUTURE_TIME - CURRENT_TIME 
$ ! 
$ ! Start looping to determine the value in hours and minutes from 
$ ! the value expressed all in minutes 
$ ! 
$       HOURS_TO_WAIT = 0 
$ HOURS_TO_WAIT_LOOP:                                      (9)
$       IF MINUTES_TO_WAIT .LT. 60 THEN GOTO FINISH_COMPUTE 
$       MINUTES_TO_WAIT = MINUTES_TO_WAIT - 60 
$       HOURS_TO_WAIT = HOURS_TO_WAIT + 1 
$       GOTO HOURS_TO_WAIT_LOOP 
$ FINISH_COMPUTE: 
$ ! 
$ ! Construct the delta time string in the proper format 
$ ! 
$ WAIT_TIME == F$STRING(HOURS_TO_WAIT)+ ":" + F$STRING(MINUTES_TO_WAIT)- (10)
  + ":00.00" 
$ ! 
$ ! Examine the second parameter 
$ ! 
$ IF P2 .EQS.  "SHOW" THEN SHOW SYMBOL WAIT_TIME           (11)
$ ! 
$ ! Normal exit 
$ ! 
$ EXIT 
$ ! 
$ BADTIME:                                                 (12)
$ ! Exit taken if first parameter is not formatted correctly 
$ ! EXIT command returns but does not display error status 
$ ! 
$ SET MESSAGE'SAVE_MESSAGE' 
$ WRITE SYS$OUTPUT  "Invalid time value: ",P1,", format must be hh:mm" 
$ WRITE SYS$OUTPUT "Hours must be less than 24; minutes must be less than 60" 
$ EXIT %X10000000 
$ ! 
$ ! 
$ TELL:                                                    (13)
$ ! Display message and exit if user enters inquiry or enters 
$ ! an illegal parameter 
$ ! 
$ TYPE SYS$INPUT 
        This procedure converts an absolute time value to 
        a delta time value.  The absolute time must be in 
        the form hh:mm and must indicate a time in the future. 
        On return, the global symbol WAIT_TIME contains the 
        converted time value.  If you enter the keyword SHOW 
        as the second parameter, the procedure displays the 
        resulting value in the output stream. To invoke this 
        procedure, use the following syntax: 
 
                       @CONVERT hh:mm [SHOW] 
$ EXIT 

CONVERT.COM コマンド・プロシージャの説明

  1. パラメータが省略されたのか,またはパラメータとして入力された値が疑問符(?)なのかをチェックする。いずれの場合も,プロシージャは TELL ラベルに分岐する。

  2. F$CVTIME 関数を使用して,時間値が有効な 24 時間形式の時刻を示しているかどうかをチェックする。F$CVTIME は,入力時間が有効でないと警告メッセージを戻す。F$CVTIME 関数がエラーを戻す場合には,省略時の ON アクションを変更して,BADTIME ラベルに制御を渡す。

    プロシージャは,F$ENVIRONMENT 関数を使用して現在のメッセージ設定値をセーブしてから,警告メッセージやエラー・メッセージが表示されないようにメッセージ形式を設定する。時間値をチェックしたら,省略時の ON 状態とメッセージ形式を復元する。

  3. パラメータの形式をチェックする。次の形式の時間値でなければならない。


    hh:mm 
    


    IF コマンドは,(1)入力された値の長さが 5 文字であるかどうか,(2)3 番目の文字(オフセット 2)がコロンであるかどうかをチェックする。IF コマンドには論理 OR 演算子が含まれているため,いずれかの式が真の場合(すなわち,値の長さが 5 文字でないか,3 番目の文字の位置にコロンがない場合)には,プロシージャは BADTIME ラベルに分岐する。

  4. F$TIME レキシカル関数が現在の時間値を TIME シンボルに収める。

  5. F$CVTIME 関数が現在の時間(TIME シンボルにセーブされている)から "minute" と "hour" フィールドを取り出してから,変換したい時間から "minute" と "hour" フィールドを取り出す。

  6. この割り当て文は,現在の時間と将来の時間を分に変換する。割り当て文の中でシンボル MINUTES,HOURS,FUTURE_HOURS,およびFUTURE_MINUTES を使用すると,これらの値は自動的に整数に変換される。

  7. ここで,将来の時間(分)から現在の時間(分)を減算する。

  8. この結果が 0 未満の場合には,将来の時間は翌日になると解釈される。この場合,プロシージャは,これ以降の時間に 24 時間を加算してから現在の時間を減算する。

  9. プロシージャはループに入り,その中で MINUTES_TO_WAIT の値から時間数を計算する。ループを通過するたびに,MINUTES_TO_WAIT が60 より大きいかどうかをチェックする。60 より大きい場合には,MINUTES_TO_WAIT から 60 を減算してから,時間数のアキュムレータ(HOURS_TO_WAIT)に 1 を加算する。

  10. ループを終了すると,プロシージャは時間値と分値を時間文字列に連結する。シンボル HOURS_TO_WAIT と MINUTES_TO_WAIT はそれと同値の文字列に置き換えられ,間にコロンが置かれる。これによって得られた文字列は,これ以降の時間のデルタ時間が収められる WAIT_TIME シンボルに割り当てられる。WAIT_TIME はグローバル・シンボルとして定義されているため,CONVERT.COM プロシージャが終了しても削除されない。

  11. 2 番目のパラメータである SHOW が入力された場合には,結果の時間値を表示し,入力されなかった場合には,プロシージャが終了する。

  12. BADTIME ラベルでは,プロシージャは,間違って入力された値と正しい形式を示すエラー・メッセージを表示する。エラー・メッセージを出した後,CONVERT.COM が終了する。EXITコマンドは,上位桁が 1 に設定されたエラー状態を戻すため,エラー・メッセージは表示されない。

    プロシージャは,EXIT コマンドでエラー状態を明示的に指定するため,ユーザは別のプロシージャの中から CONVERT.COM を実行できる。CONVERT.COM が完了すると,呼び出し側プロシージャは時間が正しく変換されたかどうかを判別できる。

  13. TELL ラベルでは,プロシージャの実行内容を表示する。TYPE コマンドは,入力データ・ストリームの SYS$INPUT にリストされた行を表示する。

CONVERT.COM コマンド・プロシージャの実行結果例


$ SHOW TIME
10-JUN-1999 10:38:26
$ @CONVERT 12:00 SHOW
   WAIT_TIME = "1:22:00.00"

SHOW TIME コマンドは,現在の日時を表示します。CONVERT.COM はパラメータ 12:00 と SHOW を指定して実行されます。プロシージャは,絶対時刻 12:00 をデルタ値に変換して,それをターミナルに表示します。

B.2 REMINDER.COM コマンド・プロシージャ

所定の時間にターミナルに催促メッセージを表示します。このプロシージャは,メッセージを表示したい時間とメッセージのテキストを求めるプロンプトを出し,CONVERT.COM を使用して時間をデルタ時間に変換します。次に,指定された時間まで待ってから催促メッセージを表示するサブプロセスを生成します。F$ENVIRONMENT,F$VERIFY,および F$GETDVI 関数の使用方法を示します。

例: REMINDER.COM


 
 
$ ! Procedure to obtain a reminder message and display this 
$ ! message on your terminal at the time you specify. 
$ ! 
$ ! Save current states for procedure and image verification 
$ ! Turn verification off for duration of procedure 
$ 
$ SAVE_VERIFY_IMAGE = F$ENVIRONMENT("VERIFY_IMAGE")              (1)
$ SAVE_VERIFY_PROC = F$VERIFY(0)
$ ! 
$ ! Places the current process in a wait state until a specified 
$ ! absolute time.  Then, it rings the bell on the terminal and 
$ ! displays a message. 
$ ! 
$ ! Prompt for absolute time 
$ ! 
$ 
$ GET_TIME: 
$ INQUIRE REMINDER_TIME  "Enter time to send reminder(hh:mm)"    (2)
$ INQUIRE MESSAGE_TEXT "Enter message" 
$ ! 
$ ! Call the CONVERT.COM procedure to convert the absolute time 
$ ! to a delta time 
$ ! 
$ @DISK2:[JONES.TOOLS]CONVERT 'REMINDER_TIME'                     (3)
$ IF .NOT. $STATUS THEN GOTO BADTIME 
$ ! 
$ ! 
$ ! Create a command file that will be executed 
$ ! in a subprocess.  The subprocess will wait until 
$ ! the specified time and then display your message 
$ ! at the terminal.  If you are working at a DEC_CRT 
$ ! terminal, the message has double size blinking 
$ ! characters. Otherwise, the message has normal letters. 
$ ! In either case, the terminal bell rings when the 
$ ! message is displayed. 
$ 
$ CREATE WAKEUP.COM                                        (4)
$ DECK                            ! Lines starting with $ are data lines 
$ WAIT 'WAIT_TIME'                                         (5)
$ BELL[0,7] = %X07                ! Create symbol to ring the bell 
$ IF F$GETDVI("SYS$OUTPUT","TT_DECCRT").NES. "TRUE" THEN GOTO OTHER_TERM 
$ ! 
$ DEC_CRT_ONLY: 
$ ! Create symbols to set special graphics(for DEC_CRT terminals only)
$ ! 
$     SET_FLASH = "<ESC>[1;5m"    ! Turn on blinking characters 
$     SET_NOFLASH = "<ESC>[0m"    ! Turn off blinking characters 
$     TOP = "<ESC>#3"             ! Double size characters(top portion)
$     BOT = "<ESC>#4"             ! Double size characters(bottom portion)
$ ! 
$ ! Write double size, blinking message to the terminal and ring the bell 
$ ! 
$     WRITE SYS$OUTPUT BELL, SET_FLASH, TOP, MESSAGE_TEXT 
$     WRITE SYS$OUTPUT BELL, BOT, MESSAGE_TEXT 
$     WRITE SYS$OUTPUT F$TIME(), SET_NOFLASH 
$     GOTO CLEAN_UP 
$ ! 
$ OTHER_TERM: 
$      WRITE SYS$OUTPUT BELL,MESSAGE_TEXT 
$      WRITE SYS$OUTPUT F$TIME()
$ ! 
$ CLEAN_UP: 
$      DELETE WAKEUP.COM;* 
$ EOD 
$ ! 
$ ! Now continue executing commands. 
$ ! 
$ SPAWN/NOWAIT/INPUT=WAKEUP.COM                            (6)
$ END:                                                     (7)
$ !   Restore verification 
$     SAVE_VERIFY_PROC = F$VERIFY(SAVE_VERIFY_PROC, SAVE_VERIFY_IMAGE)
$     EXIT 
$ ! 
$ BADTIME: 
$    WRITE SYS$OUTPUT "Time must be entered as hh:mm" 
$    GOTO GET_TIME 

REMINDER.COM コマンド・プロシージャの説明

  1. F$ENVIRONMENT 関数を使用してイメージ・チェック設定値を SAVE_VERITY_IMAGE シンボルにセーブする。次に,F$VERIFY 関数を使用して,プロシージャ・チェック設定値を SAVE_VERIFY_PROC シンボルにセーブする。F$VERIFY 関数は両方のタイプのチェック設定値をオフにする。

  2. INQUIRE コマンドを使用して,催促メッセージを送信する時間を求めるプロンプトを出す。この値は CONVERT.COM プロシージャへの入力として使用される。メッセージのテキストを求めるプロンプトも出す。

  3. ネストされたプロシージャ CONVERT.COM を実行する。ファイル指定の一部としてディスクとディレクトリを指定するようにする。こうすると,システムは,REMINDER.COM を実行するディレクトリにかかわらず,CONVERT.COM を探すことができる。

    CONVERT.COM は,催促をデルタ時間に変換して,この時間をグローバル・シンボル WAIT_TIME に戻す。このデルタ時間は,現在の時間からメッセージを送信する時間までの時間間隔を示している。CONVERT.COM がエラーを戻す場合は,プロシージャは BADTIME ラベルに分岐する。

  4. CREATE コマンドを使用して新しいプロシージャ WAKEUP.COM を作成する。このプロシージャはサブプロセスの中から実行される。CREATE コマンドでドル記号で始まる行を読み込めるようにするには,DECK と EOD コマンドを CREATE コマンドの入力の前後に置く。このため,DECK と EOD コマンドの間の行はすべて WAKEUP.COM に書き込まれる。

  5. WAKEUP.COM は,次のタスクを実行する。

  6. WAKEUP.COM を作成した後,サブプロセスを生成して,入力コマンド・ファイルとして WAKEUP.COM を使用するようにそのサブプロセスに指示する。/NOWAIT 修飾子があるので,サブプロセスが WAKEUP.COM からコマンドを実行しているときに,ユーザはターミナルで作業を続けることができる。指定された時間に,WAKEUP.COM はターミナルにユーザのメッセージを表示する。

    省略時の設定では,SPAWN コマンドは,グローバル・シンボルとローカル・シンボルを 1 つのサブプロセスに渡す。したがって,ユーザが REMINDER にシンボル WAIT_TIME と MESSAGE_TEXT の値を与えるが,WAKEUP.COM もこの 2 つのシンボルにアクセスできる。

  7. 終了する前に元のチェック設定値を復元する。

REMINDER.COM コマンド・プロシージャの実行結果例


$ @REMINDER
Enter time to send reminder(hh:mm): 12:00
Enter message: TIME FOR LUNCH
%DCL-S-SPAWNED, process BLUTO_1 spawned
$
   .
   .
   .
TIME FOR LUNCH
11-DEC-1999 12:00:56.99

時間値とメッセージを求めるプロンプトを出します。次に,メッセージを表示するサブプロセスを生成します。ユーザがターミナルで作業を継続していても,サブプロセスは,指定された時間になると,ターミナル・ベルを鳴らしたり,ユーザのメッセージを表示したり,時間を表示したりします。

B.3 DIR.COM コマンド・プロシージャ

DCL コマンド・プロシージャ DIRECTORY/SIZE=ALL/DATE を模倣して,指定されたファイルの(使用済みと割り当てられた)ブロック・サイズと作成日を表示します。F$PARSE,F$SEARCH,F$FILE_ATTRIBUTES,および F$FAO レキシカル関数の使用方法を示します。

例: DIR.COM


$ ! 
$ ! Command procedure implementation of DIRECTORY/SIZE=ALL/DATE 
$ ! command 
$ ! 
$ SAVE_VERIFY_IMAGE = F$ENVIRONMENT("VERIFY_IMAGE")
$ SAVE_VERIFY_PROCEDURE = F$VERIFY(0)
$ ! 
$ ! Replace any blank field of the P1 file specification with 
$ ! a wildcard character 
$ ! 
$ P1 = F$PARSE(P1,"*.*;*")                                (1)
$ ! 
$ ! Define initial values for symbols 
$ ! 
$ FIRST_TIME = "TRUE" 
$ FILE_COUNT = 0 
$ TOTAL_ALLOC = 0 
$ TOTAL_USED = 0 
$ 
$ LOOP:                                                    (2)
$       FILESPEC = F$SEARCH(P1)
$ ! Find next file in directory 
$       IF FILESPEC .EQS. "" THEN GOTO DONE 
$ ! If no more files, then done 
$       IF .NOT. FIRST_TIME THEN GOTO SHOW_FILE 
$ ! Print header only once 
$ ! 
$ ! Construct and output the header line 
$ ! 
$       FIRST_TIME =  "FALSE"                              (3)
$       DIRSPEC = F$PARSE(FILESPEC,,, "DEVICE")- 
                +F$PARSE(FILESPEC,,, "DIRECTORY")
$       WRITE SYS$OUTPUT "" 
$       WRITE SYS$OUTPUT  "Directory ",DIRSPEC 
$       WRITE SYS$OUTPUT "" 
$       LASTDIR = DIRSPEC 
$ 
$ ! 
$ ! Put the file name together, get some of the file attributes, and 
$ ! type the information out 
$ ! 
$SHOW_FILE: 
$       FILE_COUNT = FILE_COUNT + 1 
$       FILENAME = F$PARSE(FILESPEC,,, "NAME")-           (4)
                 + F$PARSE(FILESPEC,,, "TYPE")- 
                 + F$PARSE(FILESPEC,,, "VERSION")
$      ALLOC = F$FILE_ATTRIBUTES(FILESPEC, "ALQ")
$      USED = F$FILE_ATTRIBUTES(FILESPEC, "EOF")
$      TOTAL_ALLOC = TOTAL_ALLOC + ALLOC 
$      TOTAL_USED = TOTAL_USED + USED 
$      REVISED = F$FILE_ATTRIBUTES(FILESPEC,"RDT")
$      LINE = F$FAO("!19AS !5UL/!5<!UL!> !17AS",FILENAME,- 
               USED, ALLOC, REVISED)
$      WRITE SYS$OUTPUT LINE 
$      GOTO LOOP 
$ 
$ ! 
$ ! Output summary information, reset verification, and exit 
$ ! 
$ DONE:                                                    (5)
$      WRITE SYS$OUTPUT "" 
$      WRITE SYS$OUTPUT "Total of ''FILE_COUNT' files, " + - 
                        "''TOTAL_USED'/''TOTAL_ALLOC' blocks." 
$      SAVE_VERIFY_PROCEDURE = F$VERIFY(SAVE_VERIFY_PROCEDURE,SAVE_VERIFY_IMAGE)
$      EXIT 

DIR.COM コマンド・プロシージャの説明

  1. F$PARSE 関数を使用して,ユーザが提供するファイル指定である P1 のブランク・フィールドにアスタリスクを置く。DIR.COM を実行するときにユーザがパラメータを指定しないと,F$PARSE 関数は "*.*;*" の値を P1 に割り当てる。この結果,DIR.COM は現在の省略時のディレクトリにあるすべてのファイルを表示する。

  2. F$SEARCH レキシカル関数がこのディレクトリで P1 によって示される 1 つまたは複数のファイルを検索する。P1 にワイルドカード文字(アスタリスク)が指定されている場合,F$SEARCH 関数は一致するすべてのファイル指定を戻す。最後のファイル指定が戻されると,DONE ラベルに分岐する。

  3. 最初のループ実行時に,ディレクトリ表示用のヘッダを書き込む。このヘッダには,デバイスとディレクトリの名前が含まれている。これらの名前を得るために,F$PARSE 関数を使用している。

  4. F$PARSE レキシカル関数を使用して,ディレクトリの中のそれぞれのファイル指定からファイル名を取り出す。このとき,F$FILE_ATTRIBUTES レキシカル関数は,使用済みのブロック数,割り当てられたブロック数,それぞれのファイルについての作成日情報を得る。最後に,F$FAO 関数がディレクトリの中のそれぞれのファイルごとに 1 行ずつフォーマットする。F$FAO 関数はファイル名とファイル属性情報を引数として使用する。

  5. F$SEARCH が空の文字列を戻す場合は,DONE ラベルに分岐して,ファイルの合計数,使用されたブロックの合計数,ディレクトリで割り当てられたブロックの合計数を示す要約情報を表示する。

DIR.COM コマンド・プロシージャの実行結果例


$ @DIR [VERN]*.COM


Directory DISK4:[VERN] 
 
BATCH.COM;1             1/3     11-DEC-1999 11:43 
CALC.COM;3              1/3     11-DEC-1999 11:30 
CONVERT.COM;1           5/6     11-DEC-1999 15:23 
   .
   .
   .
LOGIN.COM;34            2/3     11-DEC-1999 13:17 
PID.COM;7               1/3     11-DEC-1999 09:49 
SCRATCH.COM;6           1/3     11-DEC-1999 11:29)
 
Total of 15 files, 22/48 blocks. 

このプロシージャは,[VERN] ディレクトリのすべての COM ファイルに関する情報を戻します。


前へ 次へ 目次 索引