?SYMBOLS, INSPECT ?NOCODE, NOICODE, NOMAP, NOLMAP, NOCROSSREF ?PAGE !############################################################################# !# # !# Program : Ksdsdel # !# Author : Mark Dickinson, Environment Technical Support # !# Date : 12th January, 1989 # !# Function : Controlled Deletion Of Records From KSDS Files. # !# # !# # !# This program is designed to delete records from KSDS files. It will # !# delete records based on search text provided by the user and a start # !# offset that is provided by the user. # !# # !# It reads the file sequentially rather than by key, this permits groups # !# of records to be deleted even if the selection criteria is outside of # !# the record keys. # !# # !# All commands must be input interactively, it does not support a batch # !# mode. Verification of delete parameters will be required but no d. # !# verification is propmted for at a record level. # !# # !# An online help function is provided. # !# # !# This program is not supported. # !# # !############################################################################# ?PAGE !############################################################################# !# # !# # !# PROGRAM STRUCTURE # !# =================== # !# # !# # !# Program Entry Point # !# # !# .A............. A^KSDSDEL^V10^890112 Version 1.0 Mainline # !# # !# File Handling Code # !# # !# ..AB........... AB^Initialised^OK Initialisation # !# ..AC........... AC^Get^File^Name File name request code # !# ..AD........... AD^Validate^File File name validation code # !# ..AE........... AE^File^Error File error reporting # !# # !# Command Validation Code # !# # !# .....B......... B^Process^User^Commands Command request code # !# .......BA...... BA^Command^Parse Command determination # !# .......BB...... BB^Parse^Delete^Syntax Delete command parsing # !# # !# Command Execution Code # !# # !# ..........CA... CA^Help Help command responses # !# ..........CB... CB^Swap^Files Swap current active file # !# ..........CC... CC^Delete^Records Delete records from file # !# # !# # !# # !############################################################################# ?PAGE !############################################################################# !# # !# MAINTENANCE LOG # !# # !# Date Person Ver Reason # !# ~~~~~~~~ ~~~~~~~~~~~~~~~~~ ~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # !# 12/01/89 Mark Dickinson 1.0 Initial implementation of product. # !# # !# # !# # !############################################################################# ?PAGE "Global Variables" Literal True = -1, False = 0; Int Error := 0, .Text^Buffer[0:39], .Record^Buffer[0:1023], Transfer^Count, Receive^Name[0:11] := ["$RECEIVE "], Receive^Num := -2, File^Name[0:11] := [" "], File^Num := -2, Term^Name[0:11] := [" "], Term^Num := -2, Record^Key^Offset := 0, Record^Key^Len := 0, Record^Offset := 0, Compare^Len := 0, File^Type := 0; String .Text^Buffer^S := @Text^Buffer '<<' 1, .Record^Buffer^S := @Record^Buffer '<<' 1, .Ptr, .Compare^Buffer[0:49]; ?Page STRUCT .^ci^startup; BEGIN INT msgcode; STRUCT default; BEGIN INT volume[0:3], subvol[0:3]; END; STRUCT infile; BEGIN INT volume[0:3], subvol[0:3], dname [0:3]; END; STRUCT outfile; BEGIN INT volume[0:3], subvol[0:3], dname [0:3]; END; STRING param[0:49]; END; ?PAGE "Defines Used" Define Upshift( A, B ) = Call Shiftstring( A, B, 0 )#; Define Term^Error = Begin Call Fileinfo( Term^Num, Error ); Text^Buffer^S ':=' "Terminal I/O error nnn, data has been lost" -> @Ptr; Call Numout( Text^Buffer^S[19], Error, 10, 3 ); Call Write( Term^Num, Text^Buffer, (@Ptr '-' @Text^Buffer^S) ); If <> Then Call Abend; !Consider two failures in a row non-recoverable End#; Define GetYN = Begin Text^Buffer^S ':=' "X"; While (Text^Buffer^S <> "Y" AND Text^Buffer^S <> "N") DO Begin Text^Buffer^S ':=' "Enter 'Y' or 'N' : " -> @Ptr; Call Writeread( Term^Num, Text^Buffer, (@Ptr '-' @Text^Buffer^S), 80, Transfer^Count ); If <> Then Begin Term^Error; Transfer^Count := 1; Text^Buffer^S ':=' "X"; End; If Transfer^Count = 0 Then Text^Buffer^S ':=' "N"; Upshift( Text^Buffer^S, 1 ); End; End#; Define Msg( A ) = Begin Text^Buffer^S ':=' A -> @Ptr; Call Write( Term^Num, Text^Buffer, (@Ptr '-' @Text^Buffer^S) ); If <> Then Term^Error; End#; ?PAGE "External Procedures Used" !Source $system.system.extdecs( !abend, !close, !control, !fileinfo, !filerecinfo, !fnamecollapse, !fnameexpand, !keyposition, !myterm, !numin, !numout, !open, !read, !shiftstring, !stop, !write, !writeread, !writeupdate) ?Nolist ?Source $system.system.extdecs( ?abend, ?close, ?control, ?fileinfo, ?filerecinfo, ?fnamecollapse, ?fnameexpand, ?keyposition, ?myterm, ?numin, ?numout, ?open, ?read, ?shiftstring, ?stop, ?write, ?writeread, ?writeupdate) ?List ?Page "Forward Declarations Required" Int Proc AB^Initialised^OK; forward; Int Proc AC^Get^File^Name; forward; Int Proc AD^Validate^File; forward; Proc AE^File^Error( ErrVar ) Variable; Int ErrVar; forward; Proc B^Process^User^Commands; forward; Int Proc BA^Command^Parse; forward; Int Proc BB^Parse^Delete^Syntax( All^Text ) Variable; Int All^Text; forward; Proc CA^Help; forward; Int Proc CB^Swap^Files; forward; Proc CC^Delete^Records; forward; Proc CD^Display^Current^File; forward; ?PAGE "A^KSDSDEL^V10^890112" !############################################################################# !# # !# Procedure : A^KSDSDEL # !# # !# This procedure is the mainline of the program. If the initialisation # !# succeeds then it will retrieve record key info for the selected file # !# and go to the user command input processing loop. # !# # !############################################################################# Proc A^KSDSDEL^V10^890112 Main; Begin If AB^Initialised^OK Then Begin Call B^Process^User^Commands; Call Close( File^Num ); Call Close( Term^Num ); End; Call Stop; End; ?PAGE "AB^Initialised^OK" !############################################################################# !# # !# Procedure : AB^Initialised^O.K. # !# # !# This procedure is used to perform the initialisation required by the # !# program. It will open the home terminal and read the startup message # !# on $RECEIVE. It will then ensure that a valid file has been selected # !# for processing. # !# It will return true if the initialisation is O.K. and false if the # !# initialisation has failed (or been terminated by the user from the # !# proc AC^Get^File^Name. # !# # !############################################################################# Int Proc AB^Initialised^OK; Begin Define Open^File = Begin Call Open( File^Name, File^Num,, 1 ); If <> Then Begin Call AE^File^Error; Return False; End Else Return True; End#; Call Myterm( Term^Name ); !Terminal required for user I/O Call Open( Term^Name, Term^Num ); If <> Then Return False; !Note: No way of logging error messages yet Msg( " " ); Msg( "KSDSDEL - Version 1.0 - Mark Dickinson - 12th January 1989" ); Msg( "Generic record deletion facility for Key-sequenced files" ); Msg( " " ); Call Open( Receive^Name, Receive^Num,, 1 ); If <> Then Begin Msg( "Fatal error opening $RECEIVE, unable to continue" ); Return False; End; Call Read( Receive^Num, ^ci^startup, $len( ^ci^startup ) ); If <> Then Begin Msg( "Fatal error reading $RECEIVE, unable to continue" ); Return False; End; Call Close( Receive^Num ); If ^ci^startup.param = 0 Then Begin Msg( "No filename was provided with the run command..." ); Msg( "Expected syntax : ksdsdel " ); Msg( "-- Continuing --" ); If AC^Get^File^Name Then Open^File Else Return False; End Else Begin If AD^Validate^File Then Open^File; End; Return False; End; !Proc AB^Initialised^OK ?PAGE "AC^Get^File^Name" Int Proc AC^Get^File^Name; !############################################################################# !# # !# Procedure : AC^Get^File^Name # !# # !# This procedure is used to obtain from the user the name of a file that # !# is able to be processed by this application. It will loop until a valid # !# existing and accessable ksds file has been entered by the user. # !# This proc will return true if a valid file name is entered or false if # !# the user decides to exit without changing files. # !# # !############################################################################# Begin Int File^Code, File^Type; Error := True; While Error Do Begin Text^Buffer^S ':=' "Enter a ksds filename (or RETURN to exit) : " -> @Ptr; Call Writeread( Term^Num, Text^Buffer, (@Ptr '-' @Text^Buffer^S), 80, Transfer^Count ); If <> Then Term^Error Else Begin If Transfer^Count = 0 Then Return False; ^ci^startup.param ':=' Text^Buffer^S For Transfer^Count & 0; Error := Fnameexpand( ^ci^startup.param, File^Name, ^ci^startup.default.volume ); If Error = 0 Then Begin Msg( "Invalid File Name - Reenter" ); Error := True; End Else Begin Call Fileinfo( , Error, File^Name,,,,,,,,,,,,,,,,,, File^Type ); If Error Then Call AE^File^Error( Error ) Else If ((Error := File^Type.<3:15>) <> 3) Then Begin Msg( "Specified file is not key sequenced, follow instructions please" ); Error := True; End Else Return True; End; End; End; End; !Proc AC^Get^File^Name ?PAGE "AD^Validate^File" !############################################################################# !# # !# Procedure : AD^Validate^File # !# # !# This procedure will be called to validate a file name that has been # !# passed in the run command by a user or passed in the file command. If # !# the file is invalid this proc will call AC^Get^File^Name to obtain a # !# valid file. # !# This procedure will return true when a valid file has been accepted # !# and false if the user decides to terminate out of AC^Get^File^Name. # !# # !############################################################################# Int Proc AD^Validate^File; Begin Error := Fnameexpand( ^ci^startup.param, File^Name, ^ci^startup.default.volume ); If Error = 0 Then Begin Msg( "Invalid File Name , Select A Valid File" ); If AC^Get^File^Name Then Return True Else Return False; End Else Begin Call Fileinfo( , Error, File^Name,,,,,,,,,,,,,,,,,, File^Type ); If Error Then Begin Call AE^File^Error( Error ); If AC^Get^File^Name Then Return True Else Return False; End Else If ((Error := File^Type.<3:15>) <> 3) Then Begin Msg( "File specified is not key sequenced" ); If AC^Get^File^Name Then Return True Else Return False; End Else Return True; End; End; ?PAGE "AE^File^Error" !############################################################################# !# # !# Procedure : AE^File^Error # !# # !# This proc is called if a file error occurs on the current disk file. # !# If no error number is passed the FCB will be queried to determine what # !# the error number was, otherwise the passed error number will be used. # !# The procedure will then display an appropriate message depending on the # !# error number. # !# # !############################################################################# Proc AE^File^Error( ErrVar ) Variable; Int ErrVar; Begin If Not $Param( ErrVar ) Then Begin Call Fileinfo( File^Num, Error ); !Must Be To Error As Value Used Globally ErrVar := Error; End; Case ErrVar Of Begin 1 -> Msg( "End of file" ); 5 -> Msg( "Failure to provide sequential buffering" ); 11 -> Msg( "File does not exist, specify an existing file" ); 12 -> Msg( "File is in use, it cannot be allocated" ); 14 -> Msg( "The device does not exist" ); 48 -> Msg( "Security violation, you cannot access the file" ); 66 -> Msg( "The device you wish to access has been downed by operations staff" ); Otherwise -> Begin Text^Buffer^S ':=' "File Error nnn" -> @Ptr; Call Numout( Ptr[-3], ErrVar, 10, 3 ); Msg( Text^Buffer^S For (@Ptr '-' @Text^Buffer^S) ); End; End; End; !Proc AE^File^Error ?PAGE "B^Process^User^Commands" !############################################################################# !# # !# Procedure : B^Process^User^Commands # !# # !# This procedure will loop retrieving commands from the user at the # !# terminal. It will call BA^Command^Parse to determine what the command # !# and the associated parameters are, and then call the appropriate # !# procedure to handle the command. # !# If any terminal I/O errors occur in this loop any data that may have # !# been entered will be discarded and the user will be re-promted. # !# # !############################################################################# Proc B^Process^User^Commands; Begin Int Exit^Flag := False, Command^Code := 0; While Not Exit^Flag Do Begin Text^Buffer^S ':=' "+"; Call Writeread( Term^Num, Text^Buffer, 1, 80, Transfer^Count ); If <> Then Begin Call Fileinfo( Term^Num, Error ); If Error = 1 Then Exit^Flag := True Else Begin Text^Buffer^S ':=' "Terminal I/O error nnn, data has been lost" -> @Ptr; Call Numout( Text^Buffer^S[19], Error, 10, 3 ); Call Write( Term^Num, Text^Buffer, (@Ptr '-' @Text^Buffer^S) ); If <> Then Call Abend; !Consider two failures in a row non-recoverable End; Transfer^Count := 0; End; If Transfer^Count > 0 Then Begin Command^Code := BA^Command^Parse; Case Command^Code Of Begin !0! Call CA^Help; !1! Call CB^Swap^Files; !2! Call CC^Delete^Records; !3! Exit^Flag := True; !4! ; !Null return, ie:cancelled due to errors !5! Call CD^Display^Current^File; Otherwise Msg( "HELP - Unknown command, use 'help' if necessary" ); End; End; End; End; !Proc B^Process^User^Commands ?PAGE "BA^Command^Parse" !############################################################################# !# # !# Procedure : BA^Command^Parse # !# # !# This procedure is used to determine what command the user has # !# entered, and to ensure that all the parameters that are required by the # !# command are present. # !# If the FILE command is entered without any parameters then the proc # !# AC^Get^File^Name will be called to ensure that a valid file name is # !# provided, also giving the user a chance to cancel out. # !# If the DELETE command is entered the proc BB^Parse^Delete^Syntax will # !# be called to check the parameters and prompt for any that are missing. # !# The BB proc will also set the global variables used for delete selection# !# critera. # !# # !############################################################################# Int Proc BA^Command^Parse; Begin Int Command^Val := 0, Command^Len; String .P; Text^Buffer^S[Transfer^Count] := 0; Scan Text^Buffer^S Until " " -> @P; Command^Len := (@P '-' @Text^Buffer^S); If Command^Len < 1 Then Return 99; !Program error - shouldn't call here Upshift( Text^Buffer^S, Command^Len ); If Text^Buffer^S = "H" Then Command^Val := 0 Else If Text^Buffer^S = "F" Then Command^Val := 1 Else If Text^Buffer^S = "D" Then Command^Val := 2 Else If Text^Buffer^S = "E" Then Command^Val := 3 Else If Text^Buffer^S = "?" Then Return 5 Else Return 99; !Invalid command entered If P <> 0 Then !More text entered Begin Scan P While " " -> @P; Text^Buffer^S ':=' P For (Transfer^Count - (@P '-' @Text^Buffer^S)) + 1; Case Command^Val Of Begin !0! ; !help param needs no more processing !1! Begin ^ci^startup.param ':=' P For (Transfer^Count - (@P '-' @Text^Buffer^S)) + 1; If Not AD^Validate^File Then Command^Val := 3; !Exit from interactive file selection. End; !2! If Not BB^Parse^Delete^Syntax Then Command^Val := 4; !3! ; !exit needs no more processing End; End Else Begin Text^Buffer^S ':=' 0; Case Command^Val Of Begin !0! Text^Buffer^S ':=' "COMMANDS"; !1! If Not AC^Get^File^Name Then Command^Val := 3; !2! If Not BB^Parse^Delete^Syntax( True ) Then Command^Val := 4; !3! ; !exit needs no more processing End; End; Return Command^Val; End; !Proc BA^Command^Parse ?PAGE "BB^Parse^Delete^Syntax" !############################################################################# !# # !# Procedure : BB^Parse^Delete^Syntax # !# # !# This procedure is called from the BA proc when the user has entered a # !# DELETE command. If any parameters have been passed (all^text passed # !# when no data accompanies the command) then all the required data will # !# be prompted for from the terminal. If no parameter is passed then the # !# text^buffer will be parsed to retrieve the command options and only # !# the options that are invalid or missing will be prompted for. # !# # !############################################################################# Int Proc BB^Parse^Delete^Syntax( All^Text ) Variable; Int All^Text; !If passed indicates that all variables are to !entered interactively,otherwise the text buffer !will be scanned for as maby variables as possible. Begin Int Start^Op := 1; String .P1, .P2, .P3, .P4; If Not $Param( All^Text ) Then Begin !The delete command is of the format : DELETE , Scan Text^Buffer^S While " " -> @P1; Scan P1 Until "," -> @P2; If P2 <> "," Then Start^Op := 2 Else Begin Scan P2[1] While " " -> @P3; Scan P3 Until 0 -> @P4; If P3 = 0 Then Start^Op := 2 Else Begin Compare^Len := @P4 '-' @P3; Compare^Buffer ':=' P3 For Compare^Len; Start^Op := 3; End; End; Call Numin( P1, Record^Offset, 10, Error ); While Error Do Begin Msg( " is not numeric, reenter" ); Text^Buffer^S ':=' "D - Enter for select : " -> @Ptr; Call Writeread( Term^Num, Text^Buffer, (@Ptr '-' @Text^Buffer^S), 80, Transfer^Count ); If Transfer^Count > 0 Then Call Numin( Text^Buffer^S, Record^Offset, 10, Error ); End; End; While Start^Op = 1 Do Begin Text^Buffer^S ':=' "D - Enter for select : " -> @Ptr; Call Writeread( Term^Num, Text^Buffer, (@Ptr '-' @Text^Buffer^S), 80, Transfer^Count ); If <> Then Begin Term^Error; Transfer^Count := 0; End; If Transfer^Count > 0 Then Begin Call Numin( Text^Buffer^S, Record^Offset, 10, Error ); If Error Then Msg( " is not numeric, reenter" ) Else Start^Op := 2; End; End; While Start^Op = 2 Do Begin Text^Buffer^S ':=' "D - Enter text string : " -> @Ptr; Call Writeread( Term^Num, Text^Buffer, (@Ptr '-' @Text^Buffer^S), 80, Transfer^Count ); If <> Then Begin Term^Error; Transfer^Count := 0; End; If Transfer^Count > 0 Then Begin Compare^Len := Transfer^Count; Compare^Buffer ':=' Text^Buffer^S For Compare^Len; Start^Op := 3; End; End; Upshift( Compare^Buffer, Compare^Len ); Msg( "D * DELETE ALL RECORDS THAT HAVE THE STRING BELOW (Y/N)" ); Text^Buffer^S ':=' "D * " & Compare^Buffer For Compare^Len & " STARTING AT RECORD OFFSET " -> @Ptr; Call Numout( Ptr, Record^Offset, 10, 4 ); Msg( Text^Buffer^S For (@Ptr '-' @Text^Buffer^S) + 4 ); GetYN; If Text^Buffer^S = "Y" Then Return True Else Return False; End; !Proc BB^Parse^Delete^Syntax ?PAGE "CA^Help" !############################################################################# !# # !# Procedure : CA^Help # !# # !# This procedure is called when the user enters the HELP command. # !# It will display either a list of available commands or explicit help # !# on one subject depending on what parameters the user has passed. # !# If the user entered no parameters then the parsing proc will insert # !# 'commands' for the user. # !# # !############################################################################# Proc CA^Help; Begin String Help^Program = 'P' := ! ....+....1....+....2....+....3....+....4....+....5....+....6....+....7....+ [" ", "KSDSDEL : Version 1.0 ", " ", " This program is designed to delete generically delete records from a ", "key-sequenced file. It will only work on key-sequenced files. ", " ", " Commands may have parameters embedded on the command line, or if ommitted", "the user will be promted for required fields. ", " ", " The deletions are performed by the user supplying a record offset and a ", "text string. Any records that have data matching the supplied text string ", "at the supplied position will be deleted. The text and offset do not have ", "to be a part of the record key. ", " ", " This program is an unsupported Databank product. ", " Supplied by Databank Tandem systems programming group (now defunct). ", " "]; String Help^Commands = 'P' := ! ....+....1....+....2....+....3....+....4....+....5....+....6....+....7....+ [" ", "Supported commands are : ", " ", " DELETE [[,]] ", " EXIT ", " FILE ", " HELP /PROGRAM ", " ? ", " "]; String Help^File = 'P' := ! ....+....1....+....2....+....3....+....4....+....5....+....6....+....7....+ [" ", " FILE ", " ", " This command is used to switch to a new ksds file. A filename is expected", "but if omitted or illegal the user will be prompted for a legal existing ", "ksds file. ", " The file in use before this command is entered will only be dropped if ", "a legal new file has been selected. ", " "]; String Help^Delete = 'P' := ! ....+....1....+....2....+....3....+....4....+....5....+....6....+....7....+ [" ", "DELETE [[,]] ", " ", " This command is used to initiate a delete request. Any records in the ", "current file that have the text starting in the record at ", "byte offset will be deleted. ", " ", " If the parameters are not provided then the user will be prompted to ", "enter them. ", " ", " The parameters entered must be verified by the user prior to command ", "execution, but no verification is made at the individual record level. ", " ", " NOTE: STARTS AT BYTE 0, not byte 1. ", " IS NOT CASE SENSITIVE ", " ", " Example : ", " Records 'This is a Monday ' ", " 'Printed a Month ahead' ", " To delete - delete 10,Mon ", " "]; String Help^Exit = 'P' := ! ....+....1....+....2....+....3....+....4....+....5....+....6....+....7....+ [" ", " The exit command is used to terminate this program. It is only valid from", "the '+' prompt. ", " "]; String Help^Env = 'P' := ! ....+....1....+....2....+....3....+....4....+....5....+....6....+....7....+ [" ", " ? ", " ", " The ? command is used to display the file that is currently open, and in ", "use by the program at this time. ", " "]; Define Display^Text( A, B ) = Begin USE K; For K := 0 To (B -1) Do Msg( " " & A[K*75] For 75 ); DROP K; End#; Upshift( Text^Buffer^S, 1 ); If Text^Buffer^S = "F" Then Display^Text( Help^File, 9 ) Else If Text^Buffer^S = "D" Then Display^Text( Help^Delete, 21 ) Else If Text^Buffer^S = "E" Then Display^Text( Help^Exit, 4 ) Else If Text^Buffer^S = "C" Then Display^Text( Help^Commands, 9 ) Else If Text^Buffer^S = "P" Then Display^Text( Help^Program, 17 ) Else If Text^Buffer^S = "?" Then Display^Text( Help^Env, 6 ) Else Begin Msg( "HELP - Expecting a valid command or 'PROGRAM'" ); Msg( "HELP - If in difficulties try 'help commands'" ); End; End; !Proc CA^Help ?PAGE "CB^Swap^Files" !############################################################################# !# # !# Procedure : CB^Swap^Files # !# # !# This procedure is invoked when the user wishes to select another file # !# to process. It will close the current file and open the newly selected # !# file. By the time this proc is called the filename has been validated. # !# # !############################################################################# Int Proc CB^Swap^Files; Begin Call Close( File^Num ); Call Open( File^Name, File^Num ); If <> Then Begin Call AE^File^Error; Return False; End; Return True; End; !Proc CB^Swap^Files ?PAGE "CC^Delete^Records" !############################################################################# !# # !# Procedure : CC^Delete^Records # !# # !# This procedure is invoked when the user has entered the DELETE command. # !# By the time this procedure is called all the options to be used have # !# been validated. It will reposition to the start of the file and then # !# sequentially read through the file searching for a text match at the # !# start offset. If a match is found the record will be deleted. # !# The records in the file will be read until EOF or an error occur. # !# # !############################################################################# Proc CC^Delete^Records; Begin Int Deleted^Count := 0; Call Keyposition( File^Num, Text^Buffer, 0, 0, 0 ); If <> Then Begin Call AE^File^Error; Return; End; Error := 0; While Not Error Do Begin Call Read( File^Num, Record^Buffer, 2048 ); If <> Then Begin Call AE^File^Error; Text^Buffer^S ':=' "D * nnnn RECORDS WERE DELETED" -> @Ptr; Call Numout( Text^Buffer^S[4], Deleted^Count, 10, 4 ); Msg( Text^Buffer^S For (@Ptr '-' @Text^Buffer^S) ); End Else Begin Upshift( Record^Buffer[Record^Offset], Compare^Len ); If Record^Buffer^S[Record^Offset] = Compare^Buffer For Compare^Len Then Begin Call Writeupdate( File^Num, Record^Buffer, 0 ); If <> Then Call AE^File^Error; Deleted^Count := Deleted^Count + 1; End; End; End; End; !Proc CC^Delete^Records ?PAGE "CD^Display^Current^File" !############################################################################# !# # !# Procedure : CD^Display^Current^File # !# # !# This procedure is called when the user wishes to display information # !# about the current file. # !# # !############################################################################# Proc CD^Display^Current^File; Begin Int F^Name[0:11] := -2; String .P; Call Fileinfo( File^Num, Error, F^Name ); If Error Then Begin Call AE^File^Error( Error ); Msg( "Unable to obtain information required" ); Return; End; Text^Buffer^S ':=' "FILE NAME : " -> @Ptr; Error := Fnamecollapse( F^Name, Ptr ); Ptr[Error] ':=' ", ASSIGNED TO FILE NUMBER n" -> @Ptr; Call Numout( Ptr[-1], File^Num, 10, 1 ); Msg( Text^Buffer^S For (@Ptr '-' @Text^Buffer^S) ); End; !Proc CD^Display^Current^File