Trailing-Edge
-
PDP-10 Archives
-
BB-L054E-RK
-
apex.r36
There are no other files named apex.r36 in the archive.
!
! COPYRIGHT (c) 1980 BY
! Digital Equipment Corporation, Maynard, MA.
!
! This software is furnished under a license and may be used
! and copied only in accordance with the terms of such
! license and with the inclusion of the above copyright
! notice. This software or any other copies thereof may not
! be provided or otherwise made available to any other
! person. No title to and ownership of the software is
! hereby transferred.
!
! The information in this software is subject to change
! without notice and should not be construed as a commitment
! by Digital Equipment Corporation.
!
! Digital assumes no responsibility for the use or
! reliability of its software on equipment which is not
! supplied by Digital.
!
!++
! FACILITY: Require File for APEX
!
! ABSTRACT:
!
!
!
!
! ENVIRONMENT: TOPS-20 / TOPS-10
!
! AUTHOR: Donald R. Brandt, CREATION DATE: 19 March 1980
!
! MODIFIED BY:
!
! Revision history follows
!
!--
!
! Edit History for APEX.R36
!
! APX001 by DRB on 14-Oct-80
! Added 3 code prefix to all error message typeouts.
! (Change made to $ERROR macro)
!
! APX002 by DRB on 15-Oct-80
! Changed max_str_len to 80
!
! APX003 by ESB on 21-Dec-81
! Add literal for source patching.
!
! 100 by HAH on 31-MAY-83
! Implemented additional patch type 'REP' (replace). No action is taken
! in GEN_CCL when this type is seen in the DPD file. This patch type is
! intended for replacement modules where no patching is required during
! the build process.
!
! 121 by RBW on 27-FEB-84
! Changed the definition of ASL: to PAT:,DIS:,SYS:,REL:,UNV: for
! TOPS-10. NOTE *** This change requires recompiling all modules!
!
LITERAL APEX_EDT = %O'121' ; ! Edit level of this module
!
! Define datatypes
!
LITERAL
DT_COMPONENT = 1,
DT_EDIT = 2,
DT_FILE = 3,
DT_LIBRARY = 4,
DT_PATCH = 5,
DT_PRODUCT = 6,
DT_TABLE = 7,
DT_FD = 8, ! Additional datatypes for checkpointing
DT_STRING = 9,
DT_IP_TABLE = 10,
DT_MP_TABLE = 11,
DT_CKP_HEADER = 12, ! Header of checkpointed data base file
DT_CKP_TRAILER = 13 ; ! Trailer of checkpointed data base file
!
! Define logical names
!
MACRO
LN_ASL = S('ASL') %, ! Logical name of autopatch search list
LN_BAK = S('BAK') %, ! Logical name of backup directory
LN_DIS = S('DIS') %, ! Logical name of distribution directory
LN_INS = S('INS') %, ! Logical name of installation directory
LN_PAT = S('PAT') %; ! Logical name of patching directory
![121] LND_ASL = S('PAT:,DIS:,SYS:') % ; ! Defn of autopatch search list
MACRO ![121]
LND_ASL = ![121]
%IF %SWITCHES(TOPS20) ![121]
%THEN ![121]
S('PAT:,DIS:,SYS:') ![121]
%ELSE ![121]
S('PAT:,DIS:,SYS:,REL:,UNV:') ![121]
%FI %; ![121]
!
! Define patch status values
!
LITERAL
PS_RET = 1, ! retrieved
PS_SEL = 2, ! selected
PS_EXC = 3, ! excluded
PS_APP = 4, ! applied
PS_INS = 5, ! installed
PS_PER = 6 ; ! permanent
!
! Define patch categories
!
LITERAL
PC_MAN = 1, ! mandatory
PC_OPT = 2 ; ! optional
!
! Define edit types
!
LITERAL
ET_FIX = 1, ![100] .FIX file
ET_REL = 2, ![100] replacement REL module
ET_REP = 3, ![100] replacement 'ready-to-go'
ET_SRC = 4 ; ![100][003] source patch
!
! Define product state values
!
LITERAL
PROD_STATE_DIS = 1, ! distribution
PROD_STATE_SUC = 2, ! SETUP completed
PROD_STATE_PSC = 3, ! Patch status changed
PROD_STATE_RBB = 4, ! ready to begin batch job
prod_state_bfq = 5, ! batch file submitted
PROD_STATE_BJS = 6, ! batch job succeeded
PROD_STATE_BJF = 7, ! batch job failed
PROD_STATE_INI = 8, ! install initiated
PROD_STATE_INC = 9, ! install completed
PROD_STATE_REI = 10, ! restore initiated
PROD_STATE_REC = 11 ; ! restore completed
!
! Define file status values used during INSTALL & RESTORE
!
LITERAL
FS_INI = 1, ! installation initiated
FS_IBC = 2, ! backup completed
FS_IRC = 3, ! replacement completed
FS_REI = 4, ! restore initiated
FS_RRC = 5 ; ! restore replacement completed
!
! The following state transitions are allowed. Although
! other transitions might seem reasonable, they are not
! allowed since they could lead to a situation where the
! patch status would be incorrect.
!
! current state legal next states transition
! ------------- ----------------- ----------
!
! DIS PSC INCLUDE/EXCLUDE
! SUC SETUP
!
! PSC PSC INCLUDE/EXCLUDE
! SUC SETUP
!
! SUC SUC SETUP
! PSC INCLUDE/EXCLUDE
! RBB BUILD
! REI * RESTORE
!
! RBB RBB BUILD
! BFS (BUILD)
! BJS (CK_BATCH)
! BJF (CK_BATCH)
! SUC SETUP
! (with caution)
! PSC INCLUDE/EXCLUDE
! (with caution)
!
! BFS BJS (CK_BATCH)
! BJF (CK_BATCH)
! SUC SETUP
! (with caution)
! PSC INCLUDE/EXCLUDE
! (with caution)
!
! BJF SUC SETUP
! PSC INCLUDE/EXCLUDE
! REI * RESTORE
!
! BJS INI INSTALL
! SUC SETUP
! PSC INCLUDE/EXCLUDE
! REI * RESTORE
!
! INI INI INSTALL
! INC (INSTALL)
!
! INC SUC SETUP
! PSC INCLUDE/EXCLUDE
! REI RESTORE
!
! REI REI RESTORE
! REC (RESTORE)
!
! REC PSC INCLUDE/EXCLUDE
! SUC SETUP
!
! * provided the product has been previously INSTALLed
!
!
! Define global values
!
LITERAL
JBVER = %O'137' ; ! Version number address (.JBVER)
LITERAL
max_str_len = 80, ! Maximum string length
! (used in CH$LEN macro)
$$EOF_FLAG = 2 ; ! EOF value returned by BUF_READ
!
! Define GALAXY error codes
! (These values are determined during the assembly of GLXMAC.MAC.)
!
LITERAL
EREOF$ = 1, ! End of File
ERTBF$ = 23 ; ! Table is full
!
! A simulated GALAXY error code
! This value is also determined in GLXEXT.MAC
!
LITERAL
ERNEF$ = %O'1000' ; ! Not .EXE format
!
! Define headers for checkpointed data file
!
!
! Header fields for master header of checkpointed data file
!
FIELD
MAST_HEADER_FIELDS =
SET
MASTER_HEADER = [0,0,36,0], ! Header word
MAST_HEADER_FORMAT = [0,0,18,0], ! Format field
MAST_HEADER_DT = [0,18,6,0], ! Datatype field
MAST_HEADER_LEN = [0,24,12,0] ! Length field of header
TES ;
LITERAL
MAST_HEADER_SZ = 1 ;
MACRO
MAST_HEADER$$ = BLOCK[MAST_HEADER_SZ] FIELD(MAST_HEADER_FIELDS) % ;
!
! Header fields for checkpointed data objects
!
FIELD
OBJ_HEADER_FIELDS =
SET
OBJECT_HEADER = [0,0,36,0], ! Header word
OBJ_HEADER_ADDRESS = [0,0,18,0], ! Address field
OBJ_HEADER_DT = [0,18,6,0], ! Datatype of object
OBJ_HEADER_LEN = [0,24,12,0] ! Length field of header
TES ;
LITERAL
OBJ_HEADER_SZ = 1 ;
MACRO
OBJ_HEADER$$ = BLOCK[OBJ_HEADER_SZ] FIELD(OBJ_HEADER_FIELDS) % ;
!
! Define common header fields for the data descriptors
!
! COMPONENT$$
! EDIT$$
! FILE$$
! LIBRARY$$
! PATCH$$
! PRODUCT$$
! TABLE$$
!
FIELD
HEADER_FIELDS =
SET
HEADER = [0,0,36,0], ! Header word
HEADER_DT = [0,0,6,0], ! Datatype field of header
HEADER_CKP_FLAG = [0,6,1,0], ! Flag used during ckpting/reloc
HEADER_LEN = [0,18,18,0] ! Length field of header
TES ;
!
! COMPONENT data descriptor
!
FIELD
COMP_FIELDS =
SET
COMP_NAME = [1,0,36,0], ! Address of ASCIZ string
COMP_CODE = [2,0,36,0], ! Address of ASCIZ string
COMP_PROD = [3,0,18,0], ! Address of "Product"
COMP_BLD = [3,18,18,0], ! Address of component build
! "File"
COMP_INP_LIST = [4,0,18,0], ! Address of "List" of input
! "Files"
COMP_OUT_LIST = [4,18,18,0] ! Address of "List" of output
! "Files"
TES ;
LITERAL
COMP_SZ = 5 ; ! Length of COMPONENT
MACRO
COMPONENT$$ = BLOCK[COMP_SZ] FIELD(HEADER_FIELDS,COMP_FIELDS) % ;
MACRO
GET_COMPONENT =
BEGIN
STACKLOCAL
c: REF COMPONENT$$ ;
$M_GMEM(comp_sz,c) ;
c[HEADER_DT] = dt_component ;
c[HEADER_LEN] = comp_sz ;
c[COMP_INP_LIST] = GET_TABLE(def_tbluk_sz) ;
c[COMP_OUT_LIST] = GET_TABLE(def_tbluk_sz) ;
.c
END % ;
!
! EDIT data descriptor
!
FIELD
EDIT_FIELDS =
SET
EDIT_NAME = [1,0,36,0], ! Address of ASCIZ string
EDIT_LIB = [2,0,18,0], ! Address of target "Library"
EDIT_FILE = [2,18,18,0], ! Address of patch "File"
EDIT_MOD_LIST = [3,0,18,0], ! Address of "List" of modules
EDIT_TYPE = [3,18,9,0] ! Type of edit
TES ;
LITERAL
EDIT_SZ = 4 ; ! Length of EDIT
MACRO
EDIT$$ = BLOCK[EDIT_SZ] FIELD(HEADER_FIELDS,EDIT_FIELDS) % ;
MACRO
GET_EDIT =
BEGIN
STACKLOCAL
e: REF EDIT$$ ;
$M_GMEM(edit_sz,e) ;
e[HEADER_DT] = dt_edit ;
e[HEADER_LEN] = edit_sz ;
e[EDIT_MOD_LIST] = GET_TABLE(def_tbluk_sz) ;
.e
END % ;
!
! FILE data descriptor
!
FIELD
FILE_FIELDS =
SET
FILE_FD = [1,0,18,0], ! Address of FD for this file
FILE_IFN = [1,18,9,0], ! Internal File Number
FILE_STATUS = [1,27,9,0], ! INSTALL/RESTORE file status
FILE_EXP_CKSUM = [2,0,18,0], ! Expected checksum of file
FILE_ACT_CKSUM = [2,18,18,0], ! Actual checksum of file
FILE_EXP_VER = [3,0,36,0], ! Expected version of file
FILE_ACT_VER = [4,0,36,0], ! Actual version of file
FILE_BACKUP = [5,0,18,0], ! Address of "File" that is
! backup instance of this file
FILE_NEWEST = [5,18,18,0] ! Address of "File" that is
! newest instance of this file
TES ;
LITERAL
FILE_SZ = 6 ; ! Length of FILE
MACRO
FILE$$ = BLOCK[FILE_SZ] FIELD(HEADER_FIELDS,FILE_FIELDS) % ;
MACRO
GET_FILE =
BEGIN
STACKLOCAL
f: REF FILE$$ ;
$M_GMEM(file_sz,f) ;
f[HEADER_DT] = dt_file ;
f[HEADER_LEN] = file_sz ;
.f
END % ;
!
! LIBRARY data descriptor
!
FIELD
LIB_FIELDS =
SET
LIB_NAME = [1,0,36,0], ! Address of ASCIZ string
LIB_PROD = [2,0,18,0], ! Address of "Product"
LIB_COMP_LIST = [2,18,18,0], ! Address of "List" of "Compo-
! nents" that use this library
LIB_FILE = [3,0,18,0], ! Address of current "File"
LIB_EDIT_LIST = [3,18,18,0], ! Address of "List" of "Edits"
LIB_EDIT_LEVEL = [4,0,36,0], ! Edit level of this library
LIB_EDT = [5,0,18,0], ! Address of edit summary "File"
LIB_STATUS = [5,18,18,0] ! Status of library
TES ;
LITERAL
LIB_SZ = 6 ; ! Length of LIBRARY
MACRO
LIBRARY$$ = BLOCK[LIB_SZ] FIELD(HEADER_FIELDS,LIB_FIELDS) % ;
MACRO
GET_LIBRARY =
BEGIN
STACKLOCAL
l: REF LIBRARY$$ ;
$M_GMEM(lib_sz,l) ;
l[HEADER_DT] = dt_library ;
l[HEADER_LEN] = lib_sz ;
l[LIB_COMP_LIST] = GET_TABLE(def_tbluk_sz) ;
l[LIB_EDIT_LIST] = GET_TABLE(def_tbluk_sz) ;
.l
END % ;
!
! PATCH data descriptor
!
FIELD
PAT_FIELDS =
SET
PAT_NAME = [1,0,36,0], ! Address of ASCIZ string
PAT_PROD = [2,0,18,0], ! Address of "Product"
PAT_EDIT_LIST = [2,18,18,0], ! Address of "List" of "Edits"
PAT_CATEGORY = [3,0,6,0], ! Patch category
PAT_LEVEL = [3,6,6,0], ! Autopatch level number
PAT_STATUS = [3,12,6,0], ! Patch status
PAT_RP_LIST = [3,18,18,0], ! Address of "List" of required
! "Patches"
PAT_DESCRIPTION = [4,0,36,0], ! Address of ASCIZ string
PAT_SPR = [5,0,36,0], ! Address of ASCIZ string
PAT_DATE = [6,0,36,0] ! Address of ASCIZ string
TES ;
LITERAL
PAT_SZ = 7 ; ! Length of PATCH
MACRO
PATCH$$ = BLOCK[PAT_SZ] FIELD(HEADER_FIELDS,PAT_FIELDS) % ;
MACRO
GET_PATCH =
BEGIN
STACKLOCAL
pa: REF PATCH$$ ;
$M_GMEM(pat_sz,pa) ;
pa[HEADER_DT] = dt_patch ;
pa[HEADER_LEN] = pat_sz ;
pa[PAT_EDIT_LIST] = GET_TABLE(def_tbluk_sz) ;
pa[PAT_RP_LIST] = GET_TABLE(def_tbluk_sz) ;
.pa
END % ;
!
! PRODUCT data descriptor
!
FIELD
PROD_FIELDS =
SET
PROD_NAME = [1,0,36,0], ! Address of ASCIZ string
PROD_CODE = [2,0,36,0], ! Address of ASCIZ string
PROD_STATUS = [3,0,4,0], ! Status code
PROD_PAT_LEVEL = [3,4,5,0], ! Patch level
PROD_PAT_COUNT = [3,9,8,0], ! Patch count
PROD_INS_FLAG = [3,17,1,0], ! Set after initial INSTALL
PROD_UTL_LIST = [3,18,18,0], ! Address of Utility "List"
PROD_PAT_LIST = [4,0,18,0], ! Address of Patch "List"
PROD_COMP_LIST = [4,18,18,0], ! Address of Component "List"
PROD_LIB_LIST = [5,0,18,0], ! Address of Library "List"
PROD_CTL_FILE = [5,18,18,0], ! Address of patch/build "File"
PROD_PCF_FILE = [6,0,18,0], ! Address of patch cmd "File"
PROD_BCF_FILE = [6,18,18,0], ! Address of Batch Communication
! "File"
PROD_BAK_LND = [7,0,36,0], ! Address of ASCIZ string
PROD_INS_LND = [8,0,36,0], ! Address of ASCIZ string
PROD_DIS_LND = [9,0,36,0], ! Address of ASCIZ string
PROD_PAT_LND = [10,0,36,0], ! Address of ASCIZ string
PROD_SP_LIST = [11,0,18,0] ! Address of selected patch
! "List"
TES ;
LITERAL
PROD_SZ = 12 ; ! Length of PRODUCT
MACRO
PRODUCT$$ = BLOCK[PROD_SZ] FIELD(HEADER_FIELDS,PROD_FIELDS) % ;
MACRO
GET_PRODUCT =
BEGIN
STACKLOCAL
p: REF PRODUCT$$ ;
$M_GMEM(prod_sz,p) ;
p[HEADER_DT] = dt_product ;
p[HEADER_LEN] = prod_sz ;
p[PROD_INS_FLAG] = false ;
p[PROD_UTL_LIST] = GET_TABLE(def_tbluk_sz) ;
p[PROD_PAT_LIST] = GET_TABLE(def_tbluk_sz) ;
p[PROD_COMP_LIST] = GET_TABLE(def_tbluk_sz) ;
p[PROD_LIB_LIST] = GET_TABLE(def_tbluk_sz) ;
p[PROD_SP_LIST] = GET_TABLE(def_tbluk_sz) ;
.p
END % ;
!
! TABLE data structure
!
! This data structure consists of a 2 word descriptor and a
! TOPS-20 TBLUK formatted table. The TBLUK portion of the
! table need not be contiguous to the descriptor. The second
! word of the descriptor points to the TBLUK table. This
! makes it possible to expand a TABLE, by pointing to a new
! TBLUK table.
!
! If t is the address of a TABLE, then the following
! references will supply these values:
!
! .t[HEADER_DT] the datatype field in the
! descriptor header
!
! .t[HEADER_LEN] the length field in the
! descriptor header
!
! .t[TABLE_REF] the address of the TBLUK
! formatted table
!
! .t[TBL_MAX_ENTRIES] the maximum entries field in
! the TBLUK table header
!
! .t[TBL_ACTUAL_ENTRIES] the actual entries field in
! the TBLUK table header
!
! .t[n,TBL_ITEM] item number n in the table
! ( 1 <= n <= max_entries )
!
! .t[n,TBL_ITEM_ADR] address field (left half) of
! item number n in the table
!
! .t[n,TBL_ITEM_VALUE] value field (right half) of
! item number n in the table
!
MACRO
!Item fields
TBL_ITEM = 0,36,1% , !Full item field
TBL_ITEM_VALUE = 0,18,1% , !Value field of item
TBL_ITEM_ADR = 18,18,1% ; !Address field of item
FIELD
TABLE_FIELDS =
SET
TABLE_REF = [1,0,18,0], ! REF pointer to TBLUK formatted
! table
TABLE_DYN_FLAG = [1,18,1,0], ! TBLUK table is dynamic storage
TABLE_CKP_FLAG = [1,19,1,0], ! Checkpoint/Relocation flag
TBL_MAX_ENTRIES = [0,0,18,1], ! Header fields of TBLUK header
TBL_ACTUAL_ENTRIES = [0,18,18,1]
TES ;
LITERAL
DEF_TBLUK_SZ = 3, ! Default size for TBLUK portion
TDESC_SZ = 2 ; ! Size of descriptor portion
STRUCTURE
TBL [i,j,k,l;tbluk_sz=def_tbluk_sz] =
[tdesc_sz + tbluk_sz + 1]
(CASE l FROM 0 TO 1 OF
SET
[0]: (TBL + i) ;
[1]: (.(TBL + 1) + i) ;
TES
)<j,k,0> ;
!
! TABLE for REF and MAP references
!
MACRO
TABLE$$ = TBL[] FIELD(HEADER_FIELDS,TABLE_FIELDS) % ;
!
! Descriptor portion of TABLE
!
MACRO
DTABLE$$(tbluk) = TBL[-1] FIELD(HEADER_FIELDS,TABLE_FIELDS)
INITIAL(TDESC_SZ^18 + DT_TABLE,tbluk) % ;
!
! TBLUK portion of TABLE
!
MACRO
TBLUK$$(size) = VECTOR[size+1] INITIAL(size,REP size of (0)) % ;
!
! Static generation of table (note REF link is null)
!
MACRO
TABLE$$$(tbl_sz) = TBL[tbl_sz] FIELD(HEADER_FIELDS,TABLE_FIELDS)
INITIAL(TDESC_SZ^18 + DT_TABLE,
0,
tbl_sz,
REP tbl_sz OF (0)) % ;
!
! Allocate a TABLE (descriptor and TBLUK portion)
!
MACRO
GET_TABLE(t_size) =
BEGIN
STACKLOCAL
t: REF TABLE$$ ;
$M_GMEM(tdesc_sz+t_size+1,t) ;
t[HEADER_DT] = dt_table ;
t[HEADER_LEN] = tdesc_sz ;
t[TABLE_REF] = .t + tdesc_sz ;
t[TABLE_DYN_FLAG] = true ;
t[TBL_MAX_ENTRIES] = t_size ;
.t
END % ;
!
! Deallocate the TBLUK portion of a table
!
MACRO
DELETE_TABLE(t) =
IF .t[TABLE_DYN_FLAG]
THEN
$M_RMEM(.t[TBL_MAX_ENTRIES],.t[TABLE_REF])
ELSE
false % ;
!
! Purge all entries in table t.
!
MACRO
PURGE_TABLE(t) =
BEGIN
LOCAL
n ;
n = 0 ;
WHILE (n=.n+1) LEQ .t[TBL_ACTUAL_ENTRIES] DO
t[.n,TBL_ITEM] = 0 ;
t[TBL_ACTUAL_ENTRIES] = 0 ;
true
END % ;
MACRO
COPY_TABLE(st,dt) =
BEGIN
LOCAL
n ;
IF .st[TBL_ACTUAL_ENTRIES] LEQ .dt[TBL_MAX_ENTRIES]
THEN
BEGIN
n = 0 ;
WHILE (n=.n+1) LEQ .st[TBL_ACTUAL_ENTRIES] DO
dt[.n,TBL_ITEM] = .st[.n,TBL_ITEM] ;
dt[TBL_ACTUAL_ENTRIES] = .st[TBL_ACTUAL_ENTRIES] ;
true
END
ELSE
false
END % ;
MACRO
EXPAND_TABLE(t) =
BEGIN
STACKLOCAL
ttem: REF TABLE$$ ;
ttem =
GET_TABLE(.t[TBL_MAX_ENTRIES] + .t[TBL_MAX_ENTRIES]/3 + 1) ;
IF COPY_TABLE(t,ttem)
THEN
IF DELETE_TABLE(t)
THEN
BEGIN
t[TABLE_REF] = .ttem[TABLE_REF] ;
$M_RMEM(.ttem[HEADER_LEN],.ttem)
END
ELSE
false
ELSE
false
END % ;
!
! Useful MACROS
!
!
! Verifys the datatype of a data descriptor.
!
! Calling sequence:
!
! CK_DATATYPE (item,type)
!
! where
! item is the address of the descriptor or the REF pointer to
! the descriptor
!
! type is the datatype to check for
!
! Invokes IDT error message and RETURN false processing if
! datatype is incorrect
!
MACRO
CK_DATATYPE (item,type) =
IF (.item[HEADER_DT] NEQ %NAME('DT_',type))
THEN
RETURN $ERROR(C$IDT,*,FMT_NUM(%NAME('DT_',TYPE)))% ;
MACRO
DATATYPE (item) = (.item[HEADER_DT] EQL %NAME('DT_',item))% ;
MACRO
CH$ASCIZ [ ] =
(%O'440700000000' OR (UPLIT (%ASCIZ %STRING (%REMAINING)))) % ;
MACRO TRUE = 1 % ;
MACRO FALSE = 0 % ;
MACRO CR_LF = %CHAR (%O'15', %O'12') % ;
MACRO
CH$LEN(a) =
BEGIN
LOCAL
p1,
p2 ;
p1 = CH$PTR(a) ;
p2 = CH$FIND_CH(max_str_len,.p1,0) ;
IF CH$FAIL(.p2)
THEN
max_str_len
ELSE
CH$DIFF(.p2,.p1)
END % ;
!
! Make a copy of ASCIZ string in dynamic memory
! s is address of string
!
MACRO
COPY_STR(s) =
BEGIN
LOCAL
a,
len ;
len = CH$LEN(s) + 1 ; ! Length of string + zero byte
$M_GMEM(((.len-1)/5)+1,a) ;
CH$COPY(.len,CH$PTR(s),
0,
.len,CH$PTR(.a) ) ;
.a ! Return address of new string
END % ;
!
! Compare two ASCIZ strings
! s1 is address of string1
! s2 is address of string2
! Returns true if strings are equal; otherwise returns false
!
MACRO
EQL_STR(s1,s2) =
BEGIN
CH$EQL(CH$LEN(s1),CH$PTR(s1),CH$LEN(s2),CH$PTR(s2))
END % ;
MACRO
OUT(f,a) =
IF NOT BUF_WRITE(f,CH$LEN(a),a)
THEN
RETURN false % ;
MACRO FMT_FILE (file) =
IF .file[FILE_IFN] EQL 0
THEN
$FMT$FD(.file[FILE_FD])
ELSE
$FMT$FD($F_FD(.file[FILE_IFN],-1)) % ;
MACRO FMT_NUM (num) =
$FMT$NUM(num) % ;
MACRO FMT_OCT (num) =
$FMT$OCT(num) % ;
MACRO FMT_VER (num) =
$FMT$VRS(num) % ;
MACRO S [] = UPLIT(%ASCIZ %STRING(%REMAINING)) % ;
MACRO TTY_ASOUT (STR_ADDR) = $K_SOUT(STR_ADDR) % ;
MACRO TTY_SOUT [] = $K_SOUT(UPLIT(%ASCIZ %STRING(%REMAINING))) % ;
MACRO TTY_FILE (file) =
IF .file[FILE_IFN] EQL 0
THEN
$T$FD(.file[FILE_FD])
ELSE
$T$FD($F_FD(.file[FILE_IFN],-1)) % ;
MACRO TTY_OK = TTY_SOUT(' [OK]') % ;
!
! Displays
! 0 patches
! 1 patch
! <value> patches
!
! depending on value.
!
MACRO
TTY_PAT_COUNT(value) =
BEGIN
IF value EQL 0
THEN
TTY(('No patches'))
ELSE
IF value EQL 1
THEN
TTY(('1 patch'))
ELSE
TTY(FMT_NUM(value),(' patches')) ;
END % ;
MACRO
TTY [] =
BEGIN
TT(%REMAINING) ;
true
END % ,
TT [a] =
%IF STRING(a)
%THEN
TTY_SOUT(%REMOVE(a))
%ELSE
TTY_ASOUT(a)
%FI % ,
STRING(c) =
%IF ARGNUM(%REMOVE(C))
%THEN
true
%ELSE
%IF %IDENTICAL(c,%REMOVE(c))
%THEN
false
%ELSE
true
%FI
%FI % ,
ARGNUM [] =
%IF %LENGTH GTR 1
%THEN
true
%ELSE
false
%FI % ;
!
! Parse a field and move the data item
!
! Calling sequence:
!
! $PM(f,adr)
!
! where f is the parse function, and adr is the address to
! store the address of the moved data item.
!
! Two of the arguments of f must be c, the count of the number
! of words in the data item, and a, the address of the data item
! within the command message returned by the parser.
!
MACRO
$PM (f,adr) =
BEGIN
f ;
$M_GMEM(.c,adr) ;
INCR n FROM 0 to .c-1 DO
(.adr + .n) = .(.a + .n)
END % ;
MACRO
$ERROR(error_code) =
BEGIN
$ERR(%EXPLODE(error_code)) ;
$ERRARG(%REMAINING) ;
false
END % ,
$ERR(type,dollar) =
EXTERNAL err_list: TABLE$$ ;
STACKLOCAL
v ;
BIND
skey = (UPLIT(%ASCIZ %STRING(%REMAINING))) ;
! TTY_SOUT(cr_lf,$ERRCHAR(type)) % , ! without prefix message
! TTY_SOUT(cr_lf,$ERRCHAR(type),'PEP',%REMAINING,' ') % , !with it
TTY_SOUT(cr_lf,$ERRCHAR(type),,%REMAINING,' ') % , !with it
$ERRARG [a] =
%IF %IDENTICAL(a,*)
%THEN
IF T_LOOKUP(err_list,skey,v)
THEN
TTY_ASOUT(.v)
%ELSE
TTY_ASOUT(a)
%FI % ,
$ERRCHAR(ch) =
%IF %IDENTICAL(ch,'W')
%THEN
'%'
%ELSE
%IF (%IDENTICAL(ch,'F') OR %IDENTICAL(ch,'C'))
%THEN
'?'
%ELSE
' '
%FI
%FI % ;
MACRO
$GERROR(n) =
S(' ('),$FMT$ERR(n),S(')') % ;