1
0
mirror of https://github.com/PDP-10/its.git synced 2026-04-03 04:37:53 +00:00
Files
PDP-10.its/src/_batch/nbatch.usg140
Eric Swenson 6429d80e4e Added/fixed support for DM daemons (GUNNER, ZONE, BATCHN).
Also added creation of HUDINI directory, required by GUNNER daemon.
2023-03-10 09:20:46 -08:00

1563 lines
54 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<PACKAGE "NBATCH">
;"NEW BATCH INTERFACE (MUDCAL) by S. W. Galley (SWG) and Jerry Morrison (JHM)
-- TALKS DIRECTLY TO DISK QUEUE, BY WRITING OUT SPECS AND MODS FILES IN .BATCH
DIRECTORY, AND IPC'S THE DEMON OR MODIFIES ITS SCHEDULED AWAKENING TIME."
<ENTRY SIGNAL-BATCH-DEMON>
;<USE-DEFER "HOSTS" ;"to prevent BATCHQ from loading it">
<FLOAD "DSK:.BATCH;BATCHQ NBIN">
<FLOAD "DSK:.BATCH;TEMPLT >">
<USE "BATCHQ" ;"TASK-ID-NUMBER etc."
"CALCOM" ;"ADDTABLE"
"CALRDR" ;"READER READARGS"
"CALSYM" ;"MAKEMST MAKESST SYMBOL"
"CALUTL" ;"FSP-PARSE"
"COMMAND" ;"CALICO-COMMAND"
"DEMCLS" ;"READ-DEMON-STATUS SET-DEMON-STATUS"
"DIRHAK" ;"DIR-DIFF"
"DOW" ;"DOW"
"FP" ;"FPRINT"
"MUDCAL" ;"DUMPCAL"
"QPUT" ;"READ-PUTAWAY UNPUTAWAY-WRITE FALSE-PRIME"
"STR" ;"STRTOX UPPERCASE"
"TEMPLT" ;"TASK-TEMPLATE TASK-FIELDNAMES MOD-TEMPLATE MOD-FIELDNAMES"
"TIMFCN" ;"DATE-DOW DTNORM DTNOW DTADD TIMEST SPDATE PTIME REL-TIMEST">
<MANIFEST SPECS-NAME MODS-NAME>
<GDECL (DEFAULT-ID)
FIX
(QUEUE Q-HANDLE PURELIST)
LIST
(BATCHQ-OBL)
<LIST [REST OBLIST]>
(CTL-R-MSG FORMAT)
STRING
(BATCH-COMMANDS
MAIN-TASK-ELEMENTS
TASK-CREATION-COMMANDS
TASK-IDS
TASK-IDS-NULL
TASK-MOD.TION-COMMANDS
YES-NO
SWITCH-SETTINGS
TASK-STATES
TASK-TYPES)
SYMTABLE
(TASK-BUILD MODS-BUILD CC-ARGS)
VECTOR
(SPECS-HEADINGS
MODS-HEADINGS
DEFAULT-INPUT-FILE
DEFAULT-FILE-TO-RUN
DEFAULT-OUTPUT-FILE)
<VECTOR [REST STRING]>
(SPECS-PRINTERS)
<UVECTOR ATOM>
(R-ARGS)
<UVECTOR VECTOR>
(DISK-DIR NEW-DIR TASK-MODS CONFRIM-V)
<UVECTOR [REST FIX]>>
<SETG PURELIST () ;"LIST of objects that can be purified">
<PROG () ;"PROG just to make comments colinear"
<SETG TASK-BUILD <EVAL ,TASK-TEMPLATE>> ;"sample description"
<SETG MODS-BUILD <EVAL ,MOD-TEMPLATE>> ;"sample modification"
<SETG BATCHQ-OBL (<MOBLIST BATCHQ!-PACKAGE> <ROOT>)>
;"for un/parsing field names and values"
<SETG SPECS-NAME <STRTOX "SPECS ">>
;"for finding SPECS files in disk directory"
<SETG MODS-NAME <STRTOX "MODS ">> ;"ditto for MODS files"
<SETG QUEUE ()> ;"internal queue of task specs"
<SETG Q-HANDLE ([])> ;"for splicing new specs into QUEUE"
<SETG DISK-DIR <IUVECTOR 1024 0>> ;"stores old disk dir in image mode"
<SETG NEW-DIR <IUVECTOR 1024 0>> ;"ditto new disk dir"
<SETG TASK-MODS <IUVECTOR 99 0>> ;"maps MODS numbers to SPECS numbers"
<SETG CONFRIM-V <IUVECTOR
<MAX ,INPUT-STREAM ,OUTPUT-FILE ,FILE-TO-RUN ,WORKING-DIRECTORY>
0>> ;"records whether those field values confirmed"
<SETG DEFAULT-ID 0> ;"for defaulting task identification"
<SETG CTL-R-MSG
"
(1) To abort field/value specification, use the ABORT... command, and
(2) to modify a previously-typed value, just name the field again
-- next time you are asked for a field name."> ;"msg when user types ^R">
<ADDTABLE <SETG BATCH-COMMANDS ;"top-level commands in Batch command table"
<1 <SETG PURELIST
(<MAKESST "Batch commands"
'["create.task"
<CREATE-TASK>
"short.create.task"
<AND <INITZ ,TASK-BUILD T>
<PRINC <SHORT-CREATE-TASK>>>
"long.create.task"
<PRINC <LONG-CREATE-TASK>>
"copy.task"
<COPY-TASK>
"modify.nascent.task"
<PRINC <SHORT-CREATE-TASK>>
"modify.task"
<AND <INITZ ,MODS-BUILD>
<PRINC <MODIFY-TASK>>>
;"modify.existing.task"
;<PRINC " This command is now named MODIFY.TASK.">
"modify.similarly"
<PRINC <MODIFY-TASK>>
;"modify.existing.similarly"
;<PRINC " This command is now named MODIFY.SIMILARLY.">
"abort.task"
<ABORT-TASK>
"print.task.description"
<PRINT-TASK-DESCRIPTION>
"print.task.status"
<PRINT-TASK-STATUS>
"print.queue.status"
<PRINT-QUEUE-STATUS>
"signal.daemon"
<SIGNAL-BATCH-DEMON>
"revise.task.identification.symbols"
<AND <MAKE-TASK-IDS> ,NULL>
"remove.task.identification.symbols"
<AND <SETG TASK-IDS ,TASK-IDS-NULL>
,NULL>]>
!,PURELIST)>>>>
<SETG MAIN-TASK-ELEMENTS
;"fields that a user can specify
(the FORM returns a FALSE in order to continue the specification loop)"
<1 <SETG PURELIST
(<MAKESST "main.task.elements"
'["originated-by"
<AND <RDR %,ORIGINATOR> <>>
"name"
<AND <RDR %,TASK-NAME> <>>
"state"
<AND <RDR %,TASK-STATE> <>>
"to-run-at"
<AND <RDR %,TIME-OF-NEXT-RUN> <>>
"night-run-switch"
<AND <RDR %,NIGHT-RUN-SWITCH> <>>
"type"
<AND <RDR %,TASK-TYPE> <>>
"scheduler"
<AND <RDR %,SCHEDULER> <>>
"reschedule-info"
<AND <RDR %,RESCHEDULE-INFO> <>>
"stop-running-after"
<AND <RDR %,WHEN-TO-STOP-RESCHEDULING> <>>
"maximum-times-to-run"
<AND <RDR %,MAXIMUM-NUMBER-OF-RUNS> <>>
"file-to-run"
<AND <RDR %,FILE-TO-RUN> <>>
"input-stream"
<AND <RDR %,INPUT-STREAM> <>>
"output-file"
<AND <RDR %,OUTPUT-FILE> <>>
"job-control-line"
<AND <RDR %,JCL-LINE> <>>
"delimiter-string"
<AND <RDR %,DELIMITER-STRING> <>>
"working-directory"
<AND <RDR %,WORKING-DIRECTORY> <>>
"cpu-time-limit"
<AND <RDR %,TIME-LIMIT> <>>
"acknowledgement-info"
<AND <RDR %,ACKNOWLEDGEMENT-INFO> <>>
"run-test"
<AND <RDR %,RUN-TEST> <>>
"run-test-info"
<AND <RDR %,RUN-TEST-INFO> <>>
"hang-time-limit"
<AND <RDR %,HANG-LIMIT> <>>
"restart-switch"
<AND <RDR %,RESTART-SWITCH> <>>
"batch-queue-check-switch"
<AND <RDR %,BATCH-QUEUE-CHECK-SWITCH> <>>]>
!,PURELIST)>>>
<SETG TASK-CREATION-COMMANDS
;"field-name symbol table while creating a task, including meta-names
for controlling specification loop"
<1 <SETG PURELIST
(<MAKEMST "creation.commands"
[<MAKESST "extra.creation.specs"
'["print.specifications"
<PRINT-SPECS .BUILD>
"end.specifications"
END-SPECS
"quit.specifications"
END-SPECS
"abort.specifications"
T]>
,MAIN-TASK-ELEMENTS]>
!,PURELIST)>>>
<SETG TASK-MOD.TION-COMMANDS ;"ditto for modifying a task"
<1 <SETG PURELIST
(<MAKEMST "modification.commands"
[<MAKESST "extra.modification.specs"
'["print.modifications"
<PRINT-SPECS .BUILD <>>
"end.modifications"
END-SPECS
"quit.modifications"
END-SPECS
"abort.modifications"
T]>
,MAIN-TASK-ELEMENTS]>
!,PURELIST)>>>
<SETG TASK-STATES
<1 <SETG PURELIST
(<MAKESST "task.states"
'["runnable"
"RUNNABLE"
"unrunnable"
"UNRUNNABLE"
"aborted.while.running"
"ABORTED"
"removed.permanently.from.queue"
"REMOVED"]>
!,PURELIST)>>>
<SETG TASK-TYPES
<1 <SETG PURELIST
(<MAKESST "task.types" '["short" "SHORT" "long" "LONG"]>
!,PURELIST)>>>
<SETG YES-NO ;"symbol table for answering questions"
<1 <SETG PURELIST
(<MAKESST "yes/no"
'["y"
T
"yes"
T
"true"
T
"n"
#FALSE ()
"no"
#FALSE ()
"false"
#FALSE ()]>
!,PURELIST)>>>
<SETG SWITCH-SETTINGS
;"symbol table for setting switch-type fields
(FALSE-PRIME means 'turn it off' but FALSE means 'no change' or 'default it')"
<1 <SETG PURELIST
(<MAKESST "switch.settings"
'["y"
T
"yes"
T
"true"
T
"n"
<CHTYPE () FALSE-PRIME>
"no"
<CHTYPE () FALSE-PRIME>
"false"
<CHTYPE () FALSE-PRIME>]>
!,PURELIST)>>>
<SETG TASK-IDS-NULL
;"empty symtab for task ID's, used if tasks not identified by name"
<1 <SETG PURELIST (<MAKESST "Task identifications" '[]> !,PURELIST)>>>
<DEFINE UN-SYM (ITM) ;"fcn to get value from symbol"
#DECL ((ITM) ANY) <COND (<TYPE? .ITM SYMBOL> <2 .ITM>) (T .ITM)>>
\
<DEFINE CREATE-TASK ;"Perform CREATE.TASK command"
("AUX" (BUILD <INITZ ,TASK-BUILD T>) HUM)
#DECL ((BUILD) <SPECIAL VECTOR>)
<COND (<AND <SET HUM <RDR %,TASK-NAME>> <N=? .HUM "">>
;"First get viable name,"
<MAPF <>
,RDR ;"then some 'important' fields,"
'![%,FILE-TO-RUN
%,INPUT-STREAM
%,OUTPUT-FILE
%,TASK-TYPE
%,TIME-OF-NEXT-RUN
%,RESCHEDULE-INFO!]>
<PRINC <SHORT-CREATE-TASK>>)> ;"then enter field/value loop.">
<DEFINE SHORT-CREATE-TASK ;"do field-name/value loop for sample descr'n"
("AUX" OLD F (BUILD ,TASK-BUILD) BLAH)
#DECL ((VALUE) STRING (OLD) <OR FALSE STRING> (BUILD) <SPECIAL VECTOR>
(F) <OR FALSE STRING VECTOR>)
<PROG ()
<OR <SET OLD <TASK-NAME .BUILD>>
;"OLD = is there a real task already (M.N.T cmd)?"
<COND (<OR <NOT <SET BLAH <RDR %,TASK-NAME>>> <=? .BLAH "">>
<RETURN ,NULL>)>> ;"get name for new task"
<PUT .BUILD ,WHEN-ORIGINATED <DTNOW>> ;"put in current time"
<AND <TYPE? <SET F <FILE-TO-RUN .BUILD>> VECTOR>
<SETG DEFAULT-FILE-TO-RUN .F>> ;"establish defaults"
<AND <TYPE? <SET F <INPUT-STREAM .BUILD>> VECTOR>
<SETG DEFAULT-INPUT-STREAM .F>>
<AND <TYPE? <SET F <OUTPUT-FILE .BUILD>> STRING>
<SET F <UPPERCASE .F>>
<OR <MEMBER "MSG:" .F>
<SETG DEFAULT-OUTPUT-FILE <FSP-PARSE .F>>>>
<COND (<==? END-SPECS
<SPECLOOP ,TASK-CREATION-COMMANDS
<COND (.OLD
'["Type '?' for more help."
"ARC:.BATCH;INFO CREATO"])
('["Type '?' for more help."
"ARC:.BATCH;INFO CREATE"])>>>
<OUTPUT-TASK>)
("
Task creation was aborted.")>>>
<DEFINE LONG-CREATE-TASK ;"Perform LONG.CREATE.TASK command"
("AUX" (BUILD <INITZ ,TASK-BUILD T>) TNAME)
#DECL ((VALUE) STRING (BUILD) <SPECIAL VECTOR>)
<COND
(<OR <NOT <SET TNAME <RDR %,TASK-NAME>>> <=? .TNAME "">> "")
;"Get viable task name."
(<PROG ()
<SETG DEFAULT-FILE-TO-RUN ["SYS" <SNAME> "TS" .TNAME]>
<SETG DEFAULT-INPUT-FILE ["DSK" <SNAME> .TNAME "INPUT"]>
<SETG DEFAULT-OUTPUT-FILE ["DSK" <SNAME> .TNAME "OUTPUT"]>
<NOT <CALICO-COMMAND ,PUT-TASK-BUILD ,CC-ARGS>>>
;"^R typed at first field"
"")
(T
<COND (<UN-SYM <READER ,YES-NO
"Print task description?"
'[
"You now have the option of looking at the task description you have
just created, before adding the new task to the queue."
""]
'["SYM"]>>
<PRINT-SPECS .BUILD>)>
<COND
(<UN-SYM <READER ,YES-NO
"Put task in queue?"
'[
"Last chance to abort submission of the task! If you don't like the
current description, say No now and use the MODIFY.NASCENT.TASK command
to fix it."
""]
'["SYM"]>>
<OUTPUT-TASK>)
("Task creation was aborted. If you wish, use the MODIFY.NASCENT.TASK
command to fix the task description.")>)>>
<DEFINE PUT-TASK-BUILD ;"mungs tuple of field values for LONG-CREATE-TASK"
("TUPLE" CC-RESULT "AUX" FTR (T ,TASK-BUILD) OUTF)
#DECL ((CC-RESULT) TUPLE (FTR T) VECTOR (OUTF) STRING)
;"Move CC results (from TONR to BQCS) into sample description,
compensating for no WHEN-ORIGINATED args but double INPUT-STREAM args:"
<SUBSTRUC .CC-RESULT
0
<- ,WHEN-ORIGINATED ,TIME-OF-NEXT-RUN> ;3
<REST .T <- ,TIME-OF-NEXT-RUN 1>>> ;4
<PUT .T ,WHEN-ORIGINATED <DTNOW>>
<SUBSTRUC .CC-RESULT
<- ,WHEN-ORIGINATED ,TIME-OF-NEXT-RUN> ;3
<- ,INPUT-STREAM ,WHEN-ORIGINATED 1> ;5
<REST .T ,WHEN-ORIGINATED>> ;8
<SUBSTRUC .CC-RESULT
<- ,INPUT-STREAM ,TIME-OF-NEXT-RUN> ;9
<- ,BATCH-QUEUE-CHECK-SWITCH ,INPUT-STREAM -1> ;12
<REST .T <- ,INPUT-STREAM 1>>> ;13
;"Here on is equivalent to RDR actions:"
<MAPF <>
#FUNCTION ((F) #DECL ((F) FIX)
<PUT .T .F <UN-SYM <NTH .T .F>>>)
'![%,TASK-STATE %,TASK-TYPE!]>
<MAPF <>
#FUNCTION ((F) #DECL ((F) FIX)
<PUT .T .F <EVAL <UN-SYM <NTH .T .F>>>>)
'![%,RESTART-SWITCH %,NIGHT-RUN-SWITCH %,BATCH-QUEUE-CHECK-SWITCH!]>
<PUT .T ,RESCHEDULE-INFO <EVAL <RESCHEDULE-INFO .T>>>
<COND (<=? "LONG" <TASK-TYPE .T>> <PUT .T ,NIGHT-RUN-SWITCH T>)>
<PUT .T ,FILE-TO-RUN <SET FTR <FSP-PARSE <FILE-TO-RUN .T>>>>
'<AND <DECL? .FTR '<VECTOR [4 LOSE]>>
<PUT .T
,FILE-TO-RUN
<SET FTR ["SYS" <ORIGINATOR .T> "TS" <TASK-NAME .T>]>>>
<SETG DEFAULT-FILE-TO-RUN .FTR>
<COND (.FILE?
<PUT .T
,INPUT-STREAM
<SETG DEFAULT-INPUT-FILE <FSP-PARSE <INPUT-STREAM .T>>>>)>
<UNASSIGN FILE?>
<OR <MEMBER "MSG:" <UPPERCASE <SET OUTF <OUTPUT-FILE .T>>>>
<SETG DEFAULT-OUTPUT-FILE <FSP-PARSE .OUTF>>>>
<DEFINE INITZ ;"wipes clean the sample description or modification"
(V "OPTIONAL" (T? <>)) ;"T? = is V a description?"
#DECL ((VALUE V) VECTOR (T?) <OR 'T FALSE>)
<MAPR <> #FUNCTION ((VV) #DECL ((VV) VECTOR) <PUT .VV 1 <>>) .V>
;<REPEAT ((VV .V)) #DECL ((VV) VECTOR)
<COND (<EMPTY? .VV> <RETURN>)
(T <PUT .VV 1 <>> <SET VV <REST .VV>>)>>
;"compiler likes this better"
<PUT .V <COND (.T? ,ORIGINATOR) (,BY-WHOM-MODIFIED)> <XUNAME>>
<COND (.T?
<SETG DEFAULT-FILE-TO-RUN ["SYS" <XUNAME> "TS" "MDL"]>
<SETG DEFAULT-OUTPUT-FILE ["DSK" <XUNAME> "MDL" "OUTPUT"]>)>
<MAPF <>
#FUNCTION ((F) #DECL ((F) FIX) <PUT ,CONFRIM-V .F 0>)
'![%,OUTPUT-FILE %,FILE-TO-RUN %,INPUT-STREAM %,WORKING-DIRECTORY!]>
;"remember none of these confirmed"
.V>
<DEFINE CONFRIM (F) ;"Confirm or get new field F. (not CONFIRM!-COMMAND)"
#DECL ((F) FIX (VALUE) <OR FALSE ANY>)
<COND (<1? <NTH ,CONFRIM-V .F>>) ;"Already confirmed."
(<=? <>
<UN-SYM <READER ,YES-NO
"Are you sure?"
'["" ""]
'["SYM"]>>>
<RDR .F>
<>) ;"No => get another and check it too."
(T <PUT ,CONFRIM-V .F 1>)>
;"anything else => OK, note already confirmed.">
<DEFINE FSP-FIXUP (INP "AUX" FSPV);"borrowed and modified from CALRDR package"
#DECL ((INP VALUE) STRING (FSPV) VECTOR)
<SET FSPV <FSP-PARSE .INP>>
<MAPR ,STRING
<FUNCTION (A B C)
#DECL ((A B) VECTOR (C) STRING)
<AND <TYPE? <1 .A> STRING> <PUT .B 1 <1 .A>>>
<MAPRET <1 .B> <1 .C>>>
.FSPV
,DEFAULT-OUTPUT-FILE
":; ">>
<DEFINE RDR ;"gets a field value from terminal into sample = .BUILD"
(FIELD "AUX" E V (RDR-ARGS <NTH ,R-ARGS .FIELD>) (OBLIST ,BATCHQ-OBL)
(BUILD .BUILD) (OUTCHAN .OUTCHAN))
#DECL ((VALUE E) ANY (FIELD) FIX (V RDR-ARGS) VECTOR
(OBLIST) <SPECIAL LIST> (BUILD) VECTOR)
<COND
(<MEMQ .FIELD '![%,FILE-TO-RUN %,INPUT-STREAM %,OUTPUT-FILE!]>
;"LVALs in args needed for these fields."
<COND (<SET E <READARGS !.RDR-ARGS>>
<COND (<==? .FIELD %,INPUT-STREAM>
<SET V .E> ;"for compiler"
<COND (.FILE?
<SET E <FSP-PARSE <2 .V>>>
<SETG DEFAULT-INPUT-FILE .E>)
(T <SET E <2 .V>>)>
;"Get filename Vector or text String."
<UNASSIGN FILE?>)
(<AND <TYPE? .E VECTOR> <SET E <1 .E>> <>>)
(<==? .FIELD %,OUTPUT-FILE>
<OR <MEMBER "MSG:" <UPPERCASE .E>>
<SET E <FSP-FIXUP .E>>>)
(<==? .FIELD %,FILE-TO-RUN>
<SETG DEFAULT-FILE-TO-RUN <SET E <FSP-PARSE .E>>>)>
<PUT .BUILD .FIELD .E>
<PUT ,CONFRIM-V .FIELD 0> ;"not confirmed by user"
.E)
(T <PRINC ,CTL-R-MSG> <>)>)
(T
<COND (<OR <SET E <READER !.RDR-ARGS>>
<EMPTY? .E>
<TYPE? <1 .E> STRING>> ;"anything typed but ^R"
<COND (<==? .FIELD %,TASK-NAME>
<SETG DEFAULT-FILE-TO-RUN ["SYS" <SNAME> "TS" .E]>
<SETG DEFAULT-INPUT-FILE ["DSK" <SNAME> .E "INPUT"]>
<SETG DEFAULT-OUTPUT-FILE
["DSK" <SNAME> .E "OUTPUT"]>) ;"Fix defaults."
(<==? .FIELD %,TASK-STATE> <SET E <UN-SYM .E>>)
;"remove nasty symbol"
(<==? .FIELD %,TASK-TYPE>
<SET E <UN-SYM .E>> ;"remove nasty symbol"
<AND <=? "LONG" .E> <PUT .BUILD ,NIGHT-RUN-SWITCH T>>)
;"Don't bug prime-time users."
(<==? .FIELD %,TIME-OF-NEXT-RUN>
<PUT .BUILD ,TASK-STATE "RUNNABLE">)
;"handy if modifying"
(<MEMQ .FIELD
'![%,RESTART-SWITCH
%,NIGHT-RUN-SWITCH
%,BATCH-QUEUE-CHECK-SWITCH!]>
<SET E <EVAL <UN-SYM .E>>>) ;"remove nasty symbols"
(<==? .FIELD %,RESCHEDULE-INFO> ;"ALLOW TIMFCN CALLS"
<SET E <EVAL .E>>)
(<==? .FIELD %,WORKING-DIRECTORY>
<PUT ,DEFAULT-FILE-TO-RUN 2 .E>
<PUT ,DEFAULT-INPUT-FILE 2 .E>
<PUT ,DEFAULT-OUTPUT-FILE 2 .E> ;"Fix defaults."
<PUT ,CONFRIM-V .FIELD 0>) ;"not confirmed by user">
<PUT .BUILD .FIELD .E> ;"Put field into sample."
.E)
(T <PRINC ,CTL-R-MSG> <>) ;"^R typed.">)>>
\
<SETG R-ARGS
;"contains vectors of READER/READARGS arguments, one for each field"
<1 <SETG PURELIST
(<IUVECTOR ,BATCH-QUEUE-CHECK-SWITCH '[]> !,PURELIST)>>>
"<PUT ,R-ARGS ,TASK-ID-NUMBER <>>"
;"JUST TO TABULATE ALL FIELDS IN PROPER ORDER"
<PUT ,R-ARGS
,ORIGINATOR
'[[]
""
["the user ID of the person to be responsible for this task" ""]
["LINE"]]>
<PUT ,R-ARGS
,TASK-NAME
'[[]
"named"
["Type '?' for more help." "ARC:.BATCH;INFO T-NAME"]
["LINE"]]>
<PUT ,R-ARGS
,TASK-STATE
[,TASK-STATES "" '["the desired state for the task" ""] '["SYM"]]>
<PUT ,R-ARGS
,TIME-OF-NEXT-RUN
'[[]
"run at"
["When should this task be run for the first (or only) time?
Please type either a date/time in standard MDL format, or an atom: N for
now, T for tonight. [More info follows.]"
"ARC:.BATCH;INFO DAYTIM"]
["LIST" "ATOM"]]>
<PUT ,R-ARGS
,NIGHT-RUN-SWITCH
[,SWITCH-SETTINGS
"Run only at night?"
'["Type '?' for more help." "ARC:.BATCH;INFO NIGHT"]
'["SYM"]]>
<PUT ,R-ARGS
,TASK-TYPE
[,TASK-TYPES
"type"
'["In which Batch queue should this task be? Type '?' for more help."
"ARC:.BATCH;INFO T-TYPE"]
'["SYM"]]>
"<PUT ,R-ARGS ,WHEN-ORIGINATED <>>"
;"PUT-TASK-BUILD RELIES ON THIS FIELD NOT BEING REQUESTED DURING LONG-CREATE-TASK."
<PUT ,R-ARGS
,SCHEDULER
'[[]
"scheduler"
["A scheduler can compute arbitrarily the time-of-next-run after
each run of the task. Almost all tasks will use the standard scheduler,
which can step thru a sequence of times or increment by a constant each
time (see the Reschedule-info field, next).
[More info follows.]"
"ARC:.BATCH;INFO USRFRM"]
["OBJECT"]]>
<PUT ,R-ARGS
,RESCHEDULE-INFO
'[[]
"rescheduling interval or sequence"
["Type '?' for more help." "ARC:.BATCH;INFO RESCHE"]
["LIST" "VECTOR" "OBJECT"]]>
<PUT ,R-ARGS
,WHEN-TO-STOP-RESCHEDULING
'[[]
"stop rescheduling after"
[
"A date/time in standard MDL format, after which the task will be removed
from the queue (if rescheduled). By default (on creation of a task)
the task can run at any future time.
[More help follows.]"
"ARC:.BATCH;INFO DAYTIM"]
["LIST"]]>
<PUT ,R-ARGS
,MAXIMUM-NUMBER-OF-RUNS
'[[]
"number of runs (IF it needs a limit)"
[
"By default (on creation of a task) there is no limit, that is,
the task can run an unlimited number of times."
""]
["FIX"]]>
<SETG DEFAULT-FILE-TO-RUN '["SYS" "SYS" "TS" "MDL"]>
<PUT ,R-ARGS
,FILE-TO-RUN
'[,DEFAULT-FILE-TO-RUN
"system program"
["Type the name of the program file to run, for example, TS MDL.
('SYS:' will work for any 'SYSn;' directory.)"
""]
["FILE"]]>
<SETG DEFAULT-INPUT-FILE ["DSK" <SNAME> "BATCH" "INPUT"]>
<PUT ,R-ARGS
,INPUT-STREAM
'[FILE?
,YES-NO
"terminal input from a file?"
["Type '?' for more help." "ARC:.BATCH;INFO INPUT"]
["SYM"]
<COND (<SET FILE? <UN-SYM .FILE?>> ,DEFAULT-INPUT-FILE) (T '[])>
<COND (.FILE? "which file? (without \"s)") (T "terminal input")>
<COND (.FILE?
'["Type the name of a file that will contain simulated terminal input."
""])
(T
'["Type the characters that will be used for simulated terminal input."
""])>
<COND (.FILE? '["FILE"]) (T '["TEXT"])>]>
<SETG DEFAULT-OUTPUT-FILE ["DSK" <SNAME> "BATCH" "OUTPUT"]>
<PUT ,R-ARGS
,OUTPUT-FILE
'[[]
"terminal output to file named (without \"s)"
["Type '?' for more help." "ARC:.BATCH;INFO OUTPUT"]
["LINE"]]>
<PUT ,R-ARGS
,JCL-LINE
'[[] "jcl" ["Type '?' for more help." "ARC:.BATCH;INFO JCL"] ["LINE"]]>
<PUT ,R-ARGS
,DELIMITER-STRING
'[[]
"break input after"
["Type '?' for more help." "ARC:.BATCH;INFO DELIM"]
["STRING"]]>
<PUT ,R-ARGS
,WORKING-DIRECTORY
'[[]
"working directory"
[
"Please type the initial SNAME (disk file directory, without a ';') for
the task to use. By default (on creation of a task) it is your directory."
""]
["LINE"]]>
<PUT ,R-ARGS
,TIME-LIMIT
'[[]
"cpu time limit"
["Type '?' for more help." "ARC:.BATCH;INFO CPUTIM"]
["FLOAT"]]>
<PUT ,R-ARGS
,ACKNOWLEDGEMENT-INFO
'[[]
"acknowledgements?"
["Type '?' for more help." "ARC:.BATCH;INFO ACKNOW"]
["OBJECT"]]>
<PUT ,R-ARGS
,RUN-TEST
'[[]
"run test"
["Something to EVALuate before running the task. By default
(on creation of a task) the task will run unconditionally.
[More help follows.]"
"ARC:.BATCH;INFO USRFRM"]
["OBJECT"]]>
<PUT ,R-ARGS
,RUN-TEST-INFO
'[[]
"run test info"
["information for the run test [More help follows.]"
"ARC:.BATCH;INFO USRFRM"]
["OBJECT"]]>
<PUT ,R-ARGS
,HANG-LIMIT
'[[]
"maximum hang time"
["Type '?' for more help." "ARC:.BATCH;INFO HANG"]
["FIX"]]>
<PUT ,R-ARGS
,RESTART-SWITCH
[,SWITCH-SETTINGS
"Restart on crash?"
'["Type '?' for more help." "ARC:.BATCH;INFO RESTAR"]
'["SYM"]]>
<PUT ,R-ARGS
,BATCH-QUEUE-CHECK-SWITCH
[,SWITCH-SETTINGS
"Check queue afterwards?"
'["Type '?' for more help." "ARC:.BATCH;INFO BQCS"]
'["SYM"]]>
<SETG CC-ARGS ;"a vector of all args for CALICO-COMMAND in LONG-CREATE-TASK"
<1 <SETG PURELIST
(<MAPF ,VECTOR
#FUNCTION ((V) <MAPRET !.V>)
<REST ,R-ARGS <- ,TIME-OF-NEXT-RUN 1>>>
;"only TIME-OF-NEXT-RUN and later"
!,PURELIST)>>>
\
<DEFINE SPECLOOP (CMDS HELP "AUX" BLAH (FIRST T) (OUTCHAN .OUTCHAN))
#DECL ((VALUE) ATOM (CMDS) SYMTABLE (HELP) VECTOR
(BLAH) <OR FALSE SYMBOL ATOM> (FIRST) <OR 'T FALSE>
(OUTCHAN) CHANNEL)
<REPEAT ()
<COND (<=? <SET BLAH
<READER .CMDS "field name" .HELP '["SYM"]>>
#FALSE (#FALSE ())> ;"^R typed"
<COND (.FIRST <RETURN ,NULL>)> ;"If first ^R, quit."
<PRINC ,CTL-R-MSG>) ;"Else type helpful msg."
(<NOT .BLAH> ;"null line typed"
<PRINC
"To stop specification, either ABORT the loop or QUIT or END specifying.">)
(<SET BLAH <EVAL <UN-SYM .BLAH>>> <RETURN .BLAH>)>
;"get field value: True => quit looping"
<SET FIRST <>>>>
<DEFINE OUTPUT-TASK ;"file new task on disk"
("AUX" CHNL (OUTCHAN .OUTCHAN) (BUILD .BUILD))
#DECL ((VALUE) STRING (CHNL) <OR FALSE CHANNEL> (OUTCHAN) CHANNEL)
<COND (<NOT <SET CHNL <OPEN "PRINT" "DSK:.BATCH;SPECS >">>>
<TERPRI> ;"can't do it"
<PRINC "The new task could not be filed because: ">
<PRINC <1 .CHNL>>
<TERPRI>
"Use MODIFY.NASCENT.TASK to try again.")
;"CALICO prints value."
(T
<UNPUTAWAY-WRITE ,TASK-FIELDNAMES
<TASK-CHECK .BUILD>
.CHNL
,ERROR
,BATCHQ-OBL> ;"put out"
<CLOSE .CHNL>
<SIGNAL-BATCH-DEMON <> .BUILD>
<SETG DEFAULT-ID <PARSE <8 .CHNL>>>
<STRING "
The new task ID number is " <8 .CHNL> !\.>)>>
\
<DEFINE SIGNAL-BATCH-DEMON ("OPTIONAL" (MODS <>) (SPECS <>)
"AUX" STATUS TSTAT)
#DECL ((VALUE) ANY (MODS SPECS) <OR FALSE VECTOR>
(STATUS) <OR <VECTOR [4 FIX]> FALSE> (TSTAT) ANY)
<COND (<SEND ".BATCH" "BATCHN" "">) ;"IPC SEND IF POSSIBLE"
(<NOT <SET STATUS <READ-DEMON-STATUS "BATCHN">>>
;"ASSUME DEMON IS NOT UP"
<DEMSIG "BATCHN">) ;"NOT IN DEMON TABLE -- SO DEMSIG IT"
(.MODS ;"FOR A MODS FILE ..."
<COND (<=? <SET TSTAT <TASK-STATE .MODS>> "RUNNABLE">
<COME-UP-BY <T-MINUS .MODS> <4 .STATUS>>)
(.TSTAT) ;"NO LONGER RUNNABLE ==> NO DEMSIG"
(<OR <TIME-OF-NEXT-RUN .MODS> <NIGHT-RUN-SWITCH .MODS>>
<COME-UP-BY <T-MINUS .MODS> <4 .STATUS>>)>)
(.SPECS <COME-UP-BY <T-MINUS .SPECS> <4 .STATUS>>)
;"FOR A SPECS FILE ..."
(<DEMSIG "BATCHN">)>>
<DEFINE T-MINUS (SPECS-OR-MODS ;"COULD EVEN GO READ THAT TASK DESCRIPTOR"
"AUX" (R-TIME <TIME-OF-NEXT-RUN .SPECS-OR-MODS>)
(N-SWITCH <NIGHT-RUN-SWITCH .SPECS-OR-MODS>))
#DECL ((VALUE) FLOAT ;"COMPUTES MINUTES UNTIL DEMON NEED BE SIGNALLED"
(SPECS-OR-MODS) VECTOR (R-TIME) <OR LIST FALSE> (N-SWITCH) ANY)
<COND (<TYPE? .N-SWITCH FALSE-PRIME> ;"NO LONGER A NIGHT-RUN TASK"
<COND (.R-TIME <MAX <DTDIFF .R-TIME> 0>) (0)>)
(.N-SWITCH <TILL-NEXT-NIGHT>) ;"IS NOW A NIGHT-RUN TASK"
(.R-TIME <MAX <DTDIFF .R-TIME> 0>) ;"SOME 'FUTURE' DATE"
(<TILL-NEXT-NIGHT>)> ;"ELSE AT NIGHT...">
<DEFINE COME-UP-BY (NEW-MINS OLD-MINS)
#DECL ((VALUE) ANY (NEW-MINS) FLOAT ;<OR FALSE FIX FLOAT> (OLD-MINS) FIX)
<COND ;(<NOT .NEW-MINS>)
(<L=? .NEW-MINS 3> <DEMSIG "BATCHN">)
(<L? .NEW-MINS .OLD-MINS>
<SET-DEMON-STATUS "BATCHN"
<FIX .NEW-MINS>
0
<FIX .NEW-MINS>>)>>
<DEFINE TILL-NEXT-NIGHT ("AUX" (DAY <DOW>))
;"returns the time of the next NIGHT?"
#DECL ((VALUE) FLOAT (DAY) FIX)
<COND (<NIGHT?> 0)
(<OR <==? .DAY 6> <==? .DAY 0> <HOLIDAY?>>
;"i.e. 0:00 on sundays and mondays and days after holidays"
<DTDIFF <DTNORM '(() (24))>>)
(T <DTDIFF <DTNORM '(() (25))>>)> ;"else at 1:00 tomorrow">
<DEFINE NIGHT? ("OPTIONAL" (DATE-TIME <DTNOW>)
"AUX" (HOUR <1 <2 .DATE-TIME>>)
(DAY <DATE-DOW <1 .DATE-TIME>>))
#DECL ((VALUE) ANY (DATE-TIME) <LIST LIST LIST STRING> (HOUR DAY) FIX)
<OR <AND <L? .HOUR 8> <G=? .HOUR 1>>
;"Night is: between 1 am and 8 am"
<==? .DAY 0> ;"and Sundays"
<AND <==? .DAY 1> <L? .HOUR 8>> ;"and Mondays before 8 am"
<AND <HOLIDAY? <1 .DATE-TIME>> <G=? .HOUR 1>> ;"and MIT holidays"
<AND <HOLIDAY? <1 <DTADD .DATE-TIME '((1) ())>>> <L? .HOUR 8>>>
;"and before 8, days after holidays">
<DEFINE MODIFY-TASK ;"do field-name/value loop for sample mod'n"
("AUX" N L (BUILD ,MODS-BUILD))
#DECL ((BUILD) <SPECIAL VECTOR> (N) <OR FALSE <VECTOR LIST>>
(L) <OR FIX LIST>)
<SET N
<READARGS <GET-TASK-IDS>
"ID(s)"
'[
"Please type the identification(s) of the task(s) you want to modify."
""]
'["MULT" "SYM" "FIX"]>>
<PROG ()
<COND (<TYPE? .N FALSE> ;<=? .N #FALSE (#FALSE ())>
<RETURN ,NULL>)> ;"^R typed"
<SET L <MAPF ,LIST ,UN-SYM <1 .N>>>
<COND (<EMPTY? .L> <RETURN ,NULL>) ;"no IDs typed"
(<1? <LENGTH .L>> <SETG DEFAULT-ID <SET L <1 .L>>>)>
;"one ID typed"
<PUT .BUILD ,TASK-ID-NUMBER .L>
<PUT .BUILD ,WHEN-MODIFIED <DTNOW>>
<COND (<==? END-SPECS
<SPECLOOP ,TASK-MOD.TION-COMMANDS
'["Type '?' for more help."
"ARC:.BATCH;INFO MODIFY"]>>
<TASK-CHECK .BUILD T>
<COND (<STRUCTURED? .L> ;"If modifying more than one,"
<AND <MAPF ,OR? ,OUTPUT-MODS .L>
<SIGNAL-BATCH-DEMON .BUILD>>
;"signal if any output."
<PUT .BUILD ,TASK-ID-NUMBER .L>)
;"Replace LIST that OUTPUT-MODS munged."
(<OUTPUT-MODS .L> <SIGNAL-BATCH-DEMON .BUILD>)>
,NULL)
("
Task modification was aborted.")>>>
<DEFINE GET-TASK-IDS ;"fcn to supply task-ID symtab a la USE-DATUM"
()
#DECL ((VALUE) SYMTABLE)
<COND (<GASSIGNED? TASK-IDS> ,TASK-IDS) (T <MAKE-TASK-IDS>)>>
<DEFINE MAKE-TASK-IDS
;"fcn to construct task-ID symtab from abbreviated disk queue"
("AUX" V (U <XUNAME>) (C <OPEN "READ" ".BATCH;BATCH QUEUE">))
#DECL ((V) VECTOR (VALUE) SYMTABLE (U) STRING (C) <OR FALSE CHANNEL>)
<COND (.C <SET V <READ .C>> <CLOSE .C> ;"V = entire contents of disk file")
(T <SET V '[]>)>
<SET V
<MAPF ,VECTOR
<FUNCTION (L)
#DECL ((L) LIST) ;"L = short or long queue from disk file"
<MAPF ,VECTOR
<FUNCTION (V)
#DECL ((V) VECTOR) ;"V = line from abb'd disk queue"
<COND (<=? .U <2 .V>>
<MAPRET <STRING <3 .V> !\. <UNPARSE <1 .V>>>
<1 .V>> ;"Return user's name.numbers.")
(T <MAPRET>)>>
<REST .L> ;"REST .L to remove name of queue">>
.V>>
<SET V <MAPF ,VECTOR ;"Make one vector out of 2 returned above."
<FUNCTION (V) #DECL ((V) VECTOR) <MAPRET !.V>> .V>>
<SETG TASK-IDS
<COND (<EMPTY? .V> ,TASK-IDS-NULL)
;"If file OPEN fails or all queues empty, use empty symtab."
(T <MAKESST "Task identifications" .V>)
;"Make symtab out of vector.">>>
<DEFINE OUTPUT-MODS ;"file modification on disk"
(ID "AUX" CHNL (OUTCHAN .OUTCHAN))
#DECL ((ID) FIX (CHNL) <OR FALSE CHANNEL> (BUILD) <SPECIAL VECTOR>
(OUTCHAN) CHANNEL)
<COND (<NOT <SET CHNL <OPEN "PRINT" ".BATCH;MODS >">>>
<TERPRI>
<PRINC "The modification to task ">
<PRINC .ID>
<PRINC " could not be filed because: ">
<PRINC <1 .CHNL>>
<TERPRI>
<PRINC "Use MODIFY.SIMILARLY to try again.">
<>)
(T
<UNPUTAWAY-WRITE ,MOD-FIELDNAMES
<PUT .BUILD ,TASK-ID-NUMBER .ID>
;"maybe LIST in .BUILD"
.CHNL
,ERROR
,BATCHQ-OBL>
<CLOSE .CHNL>
<TERPRI>
<PRINC "The modification to task ">
<PRINC .ID>
<PRINC " has been filed.">
T)>>
<DEFINE TASK-CHECK
;"Bless task descr'n or mod'n: MOD? = is this a mod'n? Generally acceptable:
False = default/no change; canonical value from last CHECK."
(TASK "OPTIONAL" (MOD? <>) "AUX" F ICH FLT (OUTCHAN .OUTCHAN))
;"F=field ICH=test channel"
#DECL ((TASK VALUE) VECTOR (MOD?) <OR 'T FALSE> (F) ANY (FLT) FLOAT
(ICH) <OR CHANNEL FALSE> (OUTCHAN) CHANNEL)
<COND ;"TASK-NAME"
(<OR <NOT <TYPE? <SET F <TASK-NAME .TASK>> STRING>> <EMPTY? .F>>
;"not usable string"
<COND (.MOD? <AND .F <PUT .TASK ,TASK-NAME <>>>)
(<FILE-TO-RUN .TASK> <PUT .TASK ,TASK-NAME "nameless">)
(<PUT .TASK ,TASK-NAME "NULL">
<PUT .TASK ,TASK-STATE "REMOVED">)>)>
;"no file-to-run either"
<COND ;"TASK-STATE"
(<NOT <SET F <TASK-STATE .TASK>>> ;"false"
<COND (<NOT .MOD?> <PUT .TASK ,TASK-STATE "RUNNABLE">)>)
(<NOT <TYPE? .F STRING>> ;"not string either"
<COND (.MOD? <PUT .TASK ,TASK-STATE <>>)
(T <PUT .TASK ,TASK-STATE "UNRUNNABLE">)>)>
<COND ;"ORIGINATOR"
(<AND .MOD?
<TYPE? <SET F <ORIGINATOR .TASK>> STRING>
<EMPTY? .F>> ;"not usable string"
<PUT .TASK ,ORIGINATOR <>>)>
<PROG (TO)
#DECL ((TO) <OR FALSE STRING>)
<COND ;"OUTPUT-FILE"
(<TYPE? <SET F <OUTPUT-FILE .TASK>> STRING>
<SET F <UPPERCASE .F>>
<COND (<=? .F "">) ;"no output wanted"
(<=? .F "NUL:"> <PUT .TASK ,OUTPUT-FILE "">)
;"ditto"
(<=? <1 <FSP-PARSE .F>> "NUL">
<PUT .TASK ,OUTPUT-FILE "">) ;"ditto"
(<SET ICH <OR <OPEN "READ" .F> <OPEN "PRINT" .F>>>
<CLOSE .ICH>) ;"viable file"
(<SET TO <MEMBER "MSG:" .F>>
<PUT .TASK ,OUTPUT-FILE .TO>)
(T
<CRLF>
<PRINC "*** WARNING: the file ">
<PRINC .F>
<PRINC " given as OUTPUT-FILE cannot be opened now.">
<CRLF>
<OR <CONFRIM %,OUTPUT-FILE> <AGAIN>>)>)
(.F <PUT .TASK ,OUTPUT-FILE <>>)>>
<COND ;"TIME-OF-NEXT-RUN"
(<TYPE? <SET F <TIME-OF-NEXT-RUN .TASK>> LIST> ;"canonical"
<PUT .TASK ,TIME-OF-NEXT-RUN <DTNORM .F>>)
(<AND <TYPE? .F ATOM> <MEMQ <1 <SPNAME .F>> '![!\N !\n!]>>
;"now!"
<PUT .TASK ,TIME-OF-NEXT-RUN <DTNOW>>)
(<OR <TYPE? .F ATOM> <NOT .MOD?>>
<PUT .TASK ,TIME-OF-NEXT-RUN <DTNORM '(() (25))>>)>
;"else tonite"
<COND ;"TASK-TYPE & TIME-LIMIT"
(<TYPE? <SET F <TIME-LIMIT .TASK>> FLOAT>) ;"canonical"
(<TYPE? .F FIX> <PUT .TASK ,TIME-LIMIT <FLOAT .F>>) ;"fix"
(<AND .F <PUT .TASK ,TIME-LIMIT <>>>)> ;"default"
<COND (<NOT <SET F <TASK-TYPE .TASK>>> ;"default"
<OR .MOD? <PUT .TASK ,TASK-TYPE "SHORT">>)
(<AND <N=? .F "LONG"> <N=? .F "SHORT">> ;"not canonical either"
<PUT .TASK ,TASK-TYPE "LONG">)>
<COND (<NOT <SET F <TIME-LIMIT .TASK>>> ;"not default"
<OR .MOD? ;"Let daemon handle MODS."
<PUT .TASK
,TIME-LIMIT ;"canonical"
<COND (<=? <TASK-TYPE .TASK> "SHORT"> 5.0) (30.0)>>>)
(<G? <SET FLT .F> 5.0>
<PUT .TASK ,TASK-TYPE "LONG">)> ;"constraint"
<COND ;"HANG-LIMIT"
(<NOT <SET F <HANG-LIMIT .TASK>>>) ;"default"
(<TYPE? .F FLOAT> <PUT .TASK ,HANG-LIMIT <SET F <FIX .F>>>)
;"float"
(<NOT <TYPE? .F FIX>> <PUT .TASK ,HANG-LIMIT <SET F <>>>)>
;"random"
<AND .F <G? .F 5> <PUT .TASK ,TASK-TYPE "LONG">> ;"constraint"
<AND .F <G? .F 25> <PUT .TASK ,HANG-LIMIT 25>> ;"constraint"
<COND ;"RESCHEDULE-INFO"
(<NOT <SCHEDULER .TASK>> ;"Ignore if there's a scheduler."
<COND (<TYPE? <SET F <RESCHEDULE-INFO .TASK>> LIST> ;"interval"
<PUT .TASK ,RESCHEDULE-INFO <DTADD-2NORM .F>>)
;"canonicalize"
(<TYPE? .F VECTOR> ;"sequence"
<PUT .TASK ,RESCHEDULE-INFO <MAPF ,VECTOR ,DTNORM .F>>)
;"canonicalize"
(.F <PUT .TASK ,RESCHEDULE-INFO <>>)>)>
;"Else must be null."
<COND ;"WHEN-TO-STOP-RESCHEDULING"
(<TYPE? <SET F <WHEN-TO-STOP-RESCHEDULING .TASK>> LIST>
;"date/time"
<PUT .TASK ,WHEN-TO-STOP-RESCHEDULING <DTNORM .F>>)
;"canonicalize"
(.F <PUT .TASK ,WHEN-TO-STOP-RESCHEDULING <>>)>
;"else must be null"
<COND ;"MAXIMUM-NUMBER-OF-RUNS"
(<NOT <TYPE? <MAXIMUM-NUMBER-OF-RUNS .TASK> FIX>>
;"Only FIX allowed."
<AND .F <PUT .TASK ,MAXIMUM-NUMBER-OF-RUNS <>>>)>
<PROG ()
<COND ;"FILE-TO-RUN"
(<TYPE? <SET F <FILE-TO-RUN .TASK>> STRING>
<PUT .TASK ,FILE-TO-RUN <SET F <FSP-PARSE .F>>>)
;"string -> vector"
(<AND .MOD? <NOT .F>>) ;"no change"
(<NOT <TYPE? .F VECTOR>> ;"default"
<PUT .TASK
,FILE-TO-RUN
["SYS"
<OR <ORIGINATOR .TASK> <XUNAME>>
"TS"
<OR <TASK-NAME .TASK> "MDL">]>)>
<AND <TYPE? <SET F <FILE-TO-RUN .TASK>> VECTOR>
;"EXISTENCE CHECK"
<COND (<OR <SET ICH
<OPEN "READB" <3 .F> <4 .F> <1 .F> <2 .F>>>
;"literal"
<AND
<=? <1 .F> "SYS"> ;"or any SYSn dir"
<OR
<SET ICH
<OPEN "READB" <3 .F> <4 .F> "DSK" "SYS1">>
<SET ICH
<OPEN "READB" <3 .F> <4 .F> "DSK" "SYS2">>>>>
<CLOSE .ICH>)
(T ;"not there anywhere"
<CRLF>
<PRINC "*** WARNING: the file ">
<FNV-PRINT .F>
<PRINC " given as FILE-TO-RUN does not exist now.">
<CRLF>
<OR <CONFRIM %,FILE-TO-RUN> <AGAIN>>)>>>
<PROG ()
<COND ;"INPUT-STREAM"
(<DECL? <INPUT-STREAM .TASK> '<VECTOR [4 LOSE]>>
;"from FSP-PARSE"
<PUT .TASK
,INPUT-STREAM
["DSK"
<OR <ORIGINATOR .TASK> <XUNAME>>
<OR <TASK-NAME .TASK> "MDL">
"INPUT"]>)>
<AND <TYPE? <SET F <INPUT-STREAM .TASK>> VECTOR>
;"EXISTENCE CHECK"
<COND (<SET ICH <OPEN "READ" <3 .F> <4 .F> <1 .F> <2 .F>>>
<CLOSE .ICH>)
(T
<CRLF>
<PRINC "*** WARNING: the file ">
<FNV-PRINT .F>
<PRINC " given as INPUT-STREAM does not exist now.">
<CRLF>
<OR <CONFRIM %,INPUT-STREAM> <AGAIN>>)>>>
<COND ;"JCL-LINE"
(<OR <NOT <TYPE? <SET F <JCL-LINE .TASK>> STRING>> <EMPTY? .F>>
;"either usable string or false"
<AND .F <PUT .TASK ,JCL-LINE <>>>)>
<PROG ()
<COND ;"WORKING-DIRECTORY"
(<OR <NOT <TYPE? <SET F <WORKING-DIRECTORY .TASK>>
STRING>>
<EMPTY? .F>> ;"either usable string or false"
<AND .F <PUT .TASK ,WORKING-DIRECTORY <>>>)
(<MEMQ !\; .F>
<PUT .TASK
,WORKING-DIRECTORY
<MAPF ,STRING
<FUNCTION (C)
#DECL ((C) CHARACTER)
<COND (<==? !\; .C> <MAPRET>) (T .C)>>
.F>>)> ;"Remove unwanted ';'."
<AND <TYPE? <SET F <WORKING-DIRECTORY .TASK>> STRING>
;"EXISTENCE CHECK"
<COND (<SET ICH <OPEN "READ" ".FILE." "(DIR)" "DSK" .F>>
<CLOSE .ICH>)
(T
<TERPRI>
<PRINC "*** WARNING: the disk directory ">
<PRINC .F>
<PRINC " given as WORKING-DIRECTORY does not exist now.">
<TERPRI>
<OR <CONFRIM %,WORKING-DIRECTORY> <AGAIN>>)>>>
<COND ;"SWITCHES"
(<NOT .MOD?> ;"On new task,"
<MAPF <>
#FUNCTION ((SW "AUX" (E <NTH .TASK .SW>))
#DECL ((SW) FIX (E) ANY)
<COND (<TYPE? .E FALSE-PRIME>
<PUT .TASK .SW <>>)>) ;"user said no."
'![%,RESTART-SWITCH
%,NIGHT-RUN-SWITCH
%,BATCH-QUEUE-CHECK-SWITCH!]>)>
<COND ;"DELIMITER-STRING"
(<TYPE? <DELIMITER-STRING .TASK> STRING>) ;"any string OK"
(<AND <SET F <FILE-TO-RUN .TASK>>
<TYPE? .F VECTOR>
<=? <1 .F> "SYS">
<=? <3 .F> "TS">
<MEMBER <4 .F> '["TECO" "NTECO" "T" "NT"]>>
;"LOOKS LIKE TECO"
<PUT .TASK ,DELIMITER-STRING "">) ;"AN ALTMODE FOR TECO"
(<PUT .TASK ,DELIMITER-STRING <>>)> ;"let daemon decide"
<COND ;"ACKNOWLEDGEMENT-INFO"
(<DECL? <SET F <ACKNOWLEDGEMENT-INFO .TASK>>
'<VECTOR [REST
<OR ATOM <VECTOR [REST <OR FIX STRING>]>>]>>)
(.F <PUT .TASK ,ACKNOWLEDGEMENT-INFO <>>)> ;"default"
.TASK>
<DEFINE ABORT-TASK ;"Performs ABORT.TASK command quickly."
("AUX" T-NUM CHNL (SYM? <GASSIGNED? TASK-IDS>))
#DECL ((T-NUM) <OR FALSE FIX> (CHNL) <OR FALSE CHANNEL>
(SYM?) <OR FALSE 'T>)
<PROG ()
<SET T-NUM ;"get ID without building symtab"
<UN-SYM <READER <COND (.SYM? ,TASK-IDS) (T '[])>
"ID"
'[
"Please type the identification of the task you want aborted immediately.
The task will remain in the queue in the 'ABORTED' state."
""]
<COND (.SYM? '["SYM" "FIX"])
(T '["FIX"])>>>>
<COND (<AND .T-NUM <N==? .T-NUM 0>> <SETG DEFAULT-ID .T-NUM>)
;"actual ID"
(<=? .T-NUM #FALSE (#FALSE ())> <RETURN <>>) ;"^R typed"
(<N==? <SET T-NUM ,DEFAULT-ID> 0>) ;"use default if any"
(<RETURN <>>)> ;"done -- return false for debugging"
<COND (<SEND ".BATCH" "BATCHN" ![.T-NUM!] 2>)
;"DIRECT IPC MSG TO ABORT"
(T
<SET CHNL <OPEN "PRINT" ".BATCH;MODS >">> ;"DEMON NOT UP"
<PRINC [TASK-ID-NUMBER ;"SO JUST WRITE OUT THE MODS"
.T-NUM
BY-WHOM-MODIFIED
<STRING !\" <XUNAME> !\">
TASK-STATE
"\"ABORTED\""]
.CHNL>
<CLOSE .CHNL>)>>>
<DEFINE COPY-TASK ;"Gets task from disk into sample description"
("AUX" BT)
#DECL ((BT) <OR FALSE VECTOR>)
<COND (<NOT <SET BT <PRINT-TASK-STATUS>>>)
(<SETG TASK-BUILD .BT>
<PRINC "
This task was copied into core.">)>>
\
<SETG FORMAT ;"FPRINT format for PRINT.QUEUE.STATUS"
<1 <SETG PURELIST
(<STRING "(/I6 2X A8 A15 PPRINC, 43G 'at ' P"
<PROG ((OBLIST ()))
<UNPARSE DTP>> ;"could be local but for this"
", X A13)">
!,PURELIST)>>>
<DEFINE PRINT-QUEUE-STATUS ;"Performs PRINT.QUEUE.STATUS"
("AUX" V (C <OPEN "READ" ".BATCH;BATCH QUEUE">) (OUTCHAN .OUTCHAN))
#DECL ((V) VECTOR (C) <OR FALSE CHANNEL> (OUTCHAN) CHANNEL)
<TERPRI>
<TERPRI>
<COND (.C ;"either (1) from daemon's abbreviated queue"
<PRINC " ID # ORIG'R NAME STATE">
<MAPF <>
<FUNCTION (L) ;"L = a queue"
#DECL ((L) LIST)
<PRINT <1 .L>>
<MAPF <>
<FUNCTION (V) ;"V = abb'd task descr'n"
#DECL ((V) VECTOR)
<COND (<6 .V>
<PUT .V 6 "only at night">)
(T
<PUT .V 6 " ">)>
<FPRINT ,FORMAT .OUTCHAN .V>>
<REST .L>>>
<SET V <READ .C>>> ;"V = whole file"
<CLOSE .C>)
(T ;"or (2) from in-core queue"
<PRINC " ID # TYPE NAME ORIG'R STATE">
<TERPRI>
<UPDATE-QUEUE>
<MAPF <> ,TASK-STATUS ,QUEUE>)>>
<DEFINE PRINT-TASK-STATUS ;"Performs PRINT.TASK.STATUS"
("OPTIONAL" N "AUX" TMPL)
#DECL ((N) FIX (TMPL VALUE) <OR FALSE VECTOR>)
<COND (<COND (<ASSIGNED? N> <SET TMPL <GET-ID-FROM-USER .N>>)
(T <SET TMPL <GET-ID-FROM-USER>>)>
<TASK-STATUS .TMPL>)>>
<DEFINE TASK-STATUS ;"prints one-line status from in-core descriptor"
(TMPL
"AUX" DT (S <TASK-STATE .TMPL>) (OUTCHAN .OUTCHAN)
(TUP
<TUPLE <TASK-ID-NUMBER .TMPL>
<TASK-TYPE .TMPL>
<TASK-NAME .TMPL>
<ORIGINATOR .TMPL>
.S>))
#DECL ((VALUE TMPL) VECTOR (S) <OR FALSE STRING> (TUP) TUPLE
(DT) <OR FALSE <LIST <LIST [3 FIX]>>> (OUTCHAN) CHANNEL)
<FPRINT "(/I6 2X PPRINC, T A11 X A8 PPRINC, X)" .OUTCHAN .TUP>
;"ID type name originator state"
<COND (<=? .S "RUNNABLE"> ;"line up columns and get time"
<PRINC " ">
<SET DT <TIME-OF-NEXT-RUN .TMPL>>)
(<=? .S "RUNNING">
<PRINC " ">
<SET DT <LAST-STARTING-TIME .TMPL>>)
(<SET DT <LAST-COMPLETION-TIME .TMPL>>
<AND <MEMBER .S '["ABORTED" "REMOVED"]> <PRINC " ">>)>
<COND (.DT <PRINC "AT "> <DTP .DT>)> ;"print time"
.TMPL>
<DEFINE PRINT-TASK-DESCRIPTION ;"Performs PRINT.TASK.DESCRIPTION"
("AUX" TMPL (OUTCHAN .OUTCHAN))
#DECL ((TMPL) <OR FALSE VECTOR> (OUTCHAN) CHANNEL)
<COND (<SET TMPL <GET-ID-FROM-USER>>
<TERPRI>
<PRINT-SPECS .TMPL T <>>)>
<TERPRI>>
<DEFINE GET-ID-FROM-USER ("OPTIONAL" T-NUM "AUX" TMPL (OUTCHAN .OUTCHAN))
#DECL ((T-NUM) <OR FALSE FIX> (TMPL VALUE) <OR FALSE VECTOR>
(OUTCHAN) CHANNEL)
<OR <ASSIGNED? T-NUM>
<SET T-NUM
<UN-SYM <READER <GET-TASK-IDS>
"ID"
'[
"Please type the identification of the task you want to inspect."
""]
'["SYM" "FIX"]>>>>
<COND (<=? .T-NUM #FALSE (#FALSE ())> <>) ;"^R typed"
(<==? <OR .T-NUM <SET T-NUM ,DEFAULT-ID>> 0> <>)
;"number defaulted"
(<SET TMPL <GET-TASK .T-NUM>> <SETG DEFAULT-ID .T-NUM> .TMPL)
(T <TERPRI> <PRINC <1 .TMPL>> <>)> ;"GET-TASK failed">
<DEFINE GET-TASK (N)
#DECL ((VALUE) <OR FALSE VECTOR> (N) FIX)
<UPDATE-QUEUE .N>
<OR <FIND-TASK .N>
<CHTYPE (<STRING "Task "
<UNPARSE .N>
" is not in the Batch queue.">)
FALSE>>>
<DEFINE FIND-TASK ;"Finds task in in-core queue"
(N)
#DECL ((VALUE) <OR FALSE VECTOR> (N) FIX)
<MAPF <>
#FUNCTION ((BT)
#DECL ((BT) VECTOR)
<AND <==? .N <TASK-ID-NUMBER .BT>>
<TASK-NAME .BT> ;"ensure task is real"
<MAPLEAVE .BT>>
<> ;"make compiler happy")
,QUEUE>>
<DEFINE UPDATE-QUEUE
;"Updates in-core specs (for task N or all) from disk
(I know there are possible timing errors if daemon is up, but I'm not picky.)"
("OPTIONAL" N "AUX" C DIFF (TEMP 'T) (OBLIST ,BATCHQ-OBL))
#DECL ((C) <OR FALSE CHANNEL> (DIFF) <UVECTOR LIST LIST> (TEMP) ANY (N) FIX
(OBLIST) <SPECIAL LIST>)
<COND (<NOT <SET C <OPEN "READB" "DSK:.BATCH;.FILE. (DIR)">>>)
;"can't open directory"
(<AND <READB ,NEW-DIR .C> <CLOSE .C> <=? ,NEW-DIR ,DISK-DIR>>)
;"no change in directory"
(T
<SET DIFF <DIR-DIFF ,SPECS-NAME ,DISK-DIR ,NEW-DIR>>
;"compare new&old SPECS no.s"
<COND (<NOT <ASSIGNED? N>> ;"update all tasks"
<MAPF <> ,INSERT-SPECS <1 .DIFF>> ;"new SPECS numbers"
<MAPF <> ,REMOVE-SPECS <2 .DIFF>>) ;"gone SPECS numbers"
(<MEMQ .N <1 .DIFF>>
<INSERT-SPECS .N> ;"get new task"
<COND (<OR <NOT <LENGTH? <1 .DIFF> 1>>
<NOT <EMPTY? <2 .DIFF>>>>
<SET TEMP <>>)>)
;"don't remember dir if other changes"
(<MEMQ .N <2 .DIFF>>
<REMOVE-SPECS .N> ;"remove gone task"
<COND (<OR <NOT <LENGTH? <2 .DIFF> 1>>
<NOT <EMPTY? <1 .DIFF>>>>
<SET TEMP <>>)>)
;"don't remember dir if other changes"
(<NOT <FIND-TASK .N>> <SET TEMP <>>)>
;"CHECK FOR BOGUS NO."
<SET DIFF <DIR-DIFF ,MODS-NAME ,DISK-DIR ,NEW-DIR>>
;"compare new&old MODS no.s"
<MAPF <> ,UPDATE-SPECS <1 .DIFF>>
;"Update specs for all new MODS."
<MAPF <> ;"Read daemon-modified specs for all gone MODS."
#FUNCTION ((M)
#DECL ((M) FIX)
<INSERT-SPECS <NTH ,TASK-MODS .M>>
<PUT ,TASK-MODS .M 0>)
;"Forget modified-task number."
<2 .DIFF>>
<COND (.TEMP ;"If in-core queue is really up-to-date,"
<SET TEMP ,DISK-DIR>
<SETG DISK-DIR ,NEW-DIR> ;"remember how dir looks now."
<SETG NEW-DIR .TEMP>)>)>>
<DEFINE INSERT-SPECS ;"insert or update in-core specs for task N"
(N "AUX" TMPL (C <OPEN "READ" "SPECS" <UNPARSE .N> "DSK" ".BATCH">))
#DECL ((N) FIX (TMPL) VECTOR (C) <OR FALSE CHANNEL>)
<COND
(.C
<COND (<TASK-NAME <PUT <SET TMPL <READ-PUTAWAY ,TASK-TEMPLATE .C>>
,TASK-ID-NUMBER ;"Make vector."
.N>> ;"If it's real, i.e. has a name,"
<REPEAT ((I 0) (Q ,QUEUE) HOLD ID) ;"put it in in-core queue."
#DECL ((I ID) FIX (Q HOLD) <LIST VECTOR>)
<COND (<OR <EMPTY? .Q>
<G? .N <SET ID <TASK-ID-NUMBER <1 .Q>>>>>
<PUTREST ,Q-HANDLE ,QUEUE>
<SET HOLD <REST ,Q-HANDLE .I>>
<PUTREST .HOLD <PUTREST <LIST .TMPL> <REST .HOLD>>>
<SETG QUEUE <REST ,Q-HANDLE>> ;"splice a la EDIT"
<RETURN>)
(<==? .N <TASK-ID-NUMBER <1 .Q>>>
<PUT .Q 1 .TMPL> ;"replace previous"
<RETURN>)
(<SET Q <REST .Q>> <SET I <+ .I 1>>)>>)>
<CLOSE .C>)>>
<DEFINE REMOVE-SPECS ;"Remove in-core specs for task N"
(N "AUX" (I 0))
#DECL ((N I) FIX)
<MAPR <>
#FUNCTION ((Q)
#DECL ((Q) <LIST VECTOR>)
<COND (<==? .N <TASK-ID-NUMBER <1 .Q>>>
<PUTREST ,Q-HANDLE ,QUEUE>
<PUTREST <REST ,Q-HANDLE .I> <REST .Q>>
<SETG QUEUE <REST ,Q-HANDLE>>
;"unsplice a la EDIT"
<MAPLEAVE>)
(T <SET I <+ .I 1>>)>)
,QUEUE>>
<DEFINE UPDATE-SPECS (M ;"M = new MODS number"
"AUX" N MODS TASK X
(C <OPEN "READ" "MODS" <UNPARSE .M> "DSK" ".BATCH">))
#DECL ((VALUE X) ANY (M N) FIX (MODS) VECTOR (TASK) <OR FALSE VECTOR>
(C) <OR FALSE CHANNEL>)
<AND .C
<PROG ((OBLIST ,BATCHQ-OBL))
#DECL ((OBLIST) <SPECIAL LIST>)
<SET MODS <READ .C>>>
;"read MODS myself (makes smaller garbage vector)"
<CLOSE .C>
<SET X <MEMQ TASK-ID-NUMBER .MODS>>
;"Find task number to modify."
<G=? <LENGTH .X> 2>
<PUT ,TASK-MODS .M <SET N <2 .X>>> ;"remember it"
<SET TASK <FIND-TASK .N>> ;"Find task in core."
<REPEAT (N) #DECL ((N) FIX) ;"Update in-core specs."
<COND (<LENGTH? .MODS 1> <RETURN>)
(<MEMQ <1 .MODS> ,TASK-FIELDNAMES>
<PUT .TASK <SET N ,<1 .MODS>> <2 .MODS>>)>
<SET MODS <REST .MODS 2>>>>>
\
<DEFINE PRINT-SPECS ;"print descr'n or mod'n in pretty format"
(TMPL "OPTIONAL" (T? T) (CHK? T)
"AUX" (OBLIST ,BATCHQ-OBL) (OUTCHAN .OUTCHAN))
#DECL ((VALUE) FALSE (T? CHK?) <OR 'T FALSE> (TMPL) <SPECIAL VECTOR>
(OBLIST) <SPECIAL LIST> (OUTCHAN) CHANNEL)
<TERPRI>
<MAPF <>
#FUNCTION ((HDG FCN FLD)
#DECL ((HDG) STRING (FCN) ATOM (FLD) ANY)
<COND (.FLD
<PRINC .HDG>
<APPLY ,.FCN .FLD>
<TERPRI>)>)
<COND (.T? ,SPECS-HEADINGS) (T ,MODS-HEADINGS)>
,SPECS-PRINTERS
<COND (.CHK? <TASK-CHECK .TMPL <NOT .T?>>) (T .TMPL)>>>
<DEFINE DTP (DT "OPTIONAL" (OUTCHAN .OUTCHAN)) ;"date/time print"
#DECL ((DT) <OR FALSE STRING <LIST <LIST [3 FIX]>>> (OUTCHAN) CHANNEL)
<COND (<TYPE? .DT STRING> <PRIN1 .DT>)
(<TYPE? .DT LIST>
<PTIME <2 .DT>>
<PRINC " on ">
<PRINC <NTH '![SUN MON TUE WED THU FRI SAT!]
<+ 1 <DATE-DOW <1 .DT>>>>>
<PRINC !\ >
<COND (<G? 10 <3 <1 .DT>>> <PRINC !\ >)>
<SPDATE <1 .DT>>)
(T <PRINC "[never]">)>>
<DEFINE RESCHEDULE-PRINT (FLD "AUX" (OUTCHAN .OUTCHAN))
#DECL ((VALUE) ANY (FLD) <OR LIST VECTOR ANY> (OUTCHAN) CHANNEL
(TMPL) VECTOR)
<COND (<SCHEDULER .TMPL> <EPRINT .FLD>)
(<TYPE? .FLD LIST>
<PRINC "intervals of ">
<PRINC <REL-TIMEST .FLD>>)
(<TYPE? .FLD VECTOR>
<MAPF <>
#FUNCTION ((DT) #DECL ((DT) <OR STRING LIST>)
<DTP .DT> <TERPRI>
<PRINC " ">)
.FLD>)
(T <EPRINT .FLD> ;"PPRINT to right of current column.")>>
<DEFINE FNV-PRINT (FLD "AUX" (OUTCHAN .OUTCHAN)) ;"filename-vector print"
#DECL ((FLD) VECTOR (OUTCHAN) CHANNEL)
<PRINC <1 .FLD>>
<PRINC !\:>
<PRINC <2 .FLD>>
<PRINC !\;>
<PRINC <3 .FLD>>
<PRINC !\ >
<PRINC <4 .FLD>>>
<DEFINE INPUT-PRINT (FLD "AUX" (OUTCHAN .OUTCHAN))
#DECL ((FLD) ANY ;<OR STRING VECTOR> (OUTCHAN) CHANNEL)
<COND (<TYPE? .FLD VECTOR> <PRINC "the file "> <FNV-PRINT .FLD>)
(<=? .FLD ""> <PRINC "-- none --">)
(<TYPE? .FLD STRING> <PRINC .FLD>)
(T <PRINC "-- none --">)>>
<DEFINE DELIM-PRINT ("TUPLE" FLD)
#DECL ((FLD) <TUPLE STRING>)
<FPRINT "(RA41)" .OUTCHAN .FLD>>
<DEFINE F3-PRINT ("TUPLE" FLD "AUX" (OUTCHAN .OUTCHAN))
;"floating 3-place print"
#DECL ((FLD) <TUPLE <OR FIX FLOAT>> (OUTCHAN) CHANNEL)
<FPRINT "(F9.3)" .OUTCHAN .FLD>
<PRINC " min">>
<DEFINE O-F-P (FIL "AUX" (OUTCHAN .OUTCHAN)) ;"output-file print"
#DECL ((FIL) <OR STRING FALSE> (OUTCHAN) CHANNEL)
<COND (<=? .FIL ""> <PRINC "-- none --">)
(.FIL <PRINC .FIL>)
(<PRINC "-- none --">)>>
<DEFINE RS-PT (SWITCH "AUX" (OUTCHAN .OUTCHAN)) ;"restart-switch print"
#DECL ((SWITCH) ANY (OUTCHAN) CHANNEL)
<COND (<TYPE? .SWITCH FALSE-PRIME>
<PRINC "The task will not be restarted after ITS/Batch crash.">)
(.SWITCH
<PRINC "The task can be restarted after ITS/Batch crash.">)>>
<DEFINE NRS-PT (SWITCH "AUX" (OUTCHAN .OUTCHAN)) ;"night-run-switch print"
#DECL ((SWITCH) ANY (OUTCHAN) CHANNEL)
<COND (<TYPE? .SWITCH FALSE-PRIME>
<PRINC "The task can run during night and day.">)
(.SWITCH <PRINC "The task can run only at night.">)>>
<DEFINE BQCS-PT (SWITCH "AUX" (OUTCHAN .OUTCHAN))
;"batch-queue-check-switch print"
#DECL ((SWITCH) ANY (OUTCHAN) CHANNEL)
<COND (<TYPE? .SWITCH FALSE-PRIME>
<PRINC
"The Batch processor will not check the queue after running the task.">)
(.SWITCH
<PRINC
"The Batch processor will check the queue after running the task.">)>>
\
<SETG SPECS-PRINTERS ;"fcns for printing fields in pretty format"
<1 <SETG PURELIST (<IUVECTOR ,NUMBER-OF-TIMES-RUN PRINC> !,PURELIST)>>>
<PROG ((T ,SPECS-PRINTERS)) ;"save parsing and lookup"
<PUT .T ,WHEN-ORIGINATED DTP>
<PUT .T ,TIME-OF-NEXT-RUN DTP>
<PUT .T ,SCHEDULER EPRINT>
<PUT .T ,RESCHEDULE-INFO RESCHEDULE-PRINT>
<PUT .T ,WHEN-TO-STOP-RESCHEDULING DTP>
<PUT .T ,FILE-TO-RUN FNV-PRINT>
<PUT .T ,INPUT-STREAM INPUT-PRINT>
<PUT .T ,OUTPUT-FILE O-F-P>
<PUT .T ,DELIMITER-STRING DELIM-PRINT>
<PUT .T ,ACKNOWLEDGEMENT-INFO EPRINT>
<PUT .T ,RUN-TEST EPRINT>
<PUT .T ,RUN-TEST-INFO EPRINT>
<PUT .T ,LAST-STARTING-TIME DTP>
<PUT .T ,LAST-COMPLETION-TIME DTP>
<PUT .T ,LAST-CPU-TIME-USED F3-PRINT>
<PUT .T ,ACCUMULATED-CPU-TIME F3-PRINT>
<PUT .T ,NIGHT-RUN-SWITCH NRS-PT>
<PUT .T ,RESTART-SWITCH RS-PT>
<PUT .T ,BATCH-QUEUE-CHECK-SWITCH BQCS-PT>>
<SETG SPECS-HEADINGS ;"headings for printing fields in pretty format"
<1 <SETG PURELIST (<IVECTOR ,NUMBER-OF-TIMES-RUN ""> !,PURELIST)>>>
<PROG ((T ,SPECS-HEADINGS)) ;"save parsing and lookup"
<PUT .T ,TASK-ID-NUMBER "ID number: ">
<PUT .T ,TASK-NAME "Name: ">
<PUT .T ,TASK-STATE "State: ">
<PUT .T ,ORIGINATOR "Originated by: ">
<PUT .T ,WHEN-ORIGINATED "Originated at: ">
<PUT .T ,TASK-TYPE "Type: ">
<PUT .T ,TIME-OF-NEXT-RUN "To run at: ">
<PUT .T ,SCHEDULER "Scheduler: ">
<PUT .T ,RESCHEDULE-INFO "Reschedule with: ">
<PUT .T ,WHEN-TO-STOP-RESCHEDULING "Stop running after: ">
<PUT .T ,MAXIMUM-NUMBER-OF-RUNS "Maximum times to run: ">
<PUT .T ,FILE-TO-RUN "File to run: ">
<PUT .T ,INPUT-STREAM "Input: ">
<PUT .T ,OUTPUT-FILE "Output file: ">
<PUT .T ,JCL-LINE "Job-control line: ">
<PUT .T ,DELIMITER-STRING "Delimiters: ">
<PUT .T ,WORKING-DIRECTORY "Working directory: ">
<PUT .T ,TIME-LIMIT "CPU time limit (minutes): ">
<PUT .T ,ACKNOWLEDGEMENT-INFO "Acknowledgements: ">
<PUT .T ,RUN-TEST "Run test: ">
<PUT .T ,RUN-TEST-INFO "Run test info: ">
<PUT .T ,HANG-LIMIT "Hang time limit (minutes): ">
<PUT .T ,LAST-STARTING-TIME "Last started: ">
<PUT .T ,LAST-COMPLETION-TIME "Last completed: ">
<PUT .T ,LAST-CPU-TIME-USED "CPU time used on last run: ">
<PUT .T ,ACCUMULATED-CPU-TIME "CPU time used on all runs: ">
<PUT .T ,NUMBER-OF-TIMES-RUN "Number of times run so far: ">>
<SETG MODS-HEADINGS ;"only slightly different for sample mod'n"
<PUT <PUT <1 <SETG PURELIST (<EVAL ,SPECS-HEADINGS> !,PURELIST)>>
,WHEN-ORIGINATED
"Modified at: ">
,BY-WHOM-MODIFIED
"Modified by: ">>
<ENDPACKAGE>