.TITLE CNTRPRC_CSV .IDENT /V1-001/ ;++ ;1 CNTRPRC_CSV ; Programme to dump monitor data as comma seperated variables (CSV) to file. ; All avaiable data is dumped in format: ; variable name,sam1,sam2, ... samN ; Header (1st line) is: ; Variable,date1,date2,...,dateN ; Data is aligned such that dates run from oldest to newest. ; Note: ; The dates are taken from the 1st record and it is ASSUMED that all other ; records follow the same time pattern. In normal operation this is safe ; however, it is not guaranteed. Anomolies in the resulting data should ; be checked against this assumption. ; The resulting file name is fixed (CSVOUTP.DAT) ;2 Modifications: ; 001 Apr-2004 PB Creation ; ;-- .library /CNTPRC.MLB/ $IODEF ;Define I/O functions and modifiers $SSDEF CNTRPRCDEF ; Counter processing .PSECT CNTRPRC_CSV_D,WRT,NOEXE,PIC,SHR,QUAD File: CNTRPRCFAB: $FAB FAC = ,- ; Access SHR = ,- ; Share with anyone FOP = CIF,- ORG = IDX,- ; Keyed file (Finally) FNM = ,- ; Filename DNM = ,- ; Filename MRS = CTPRECSIZE,- XAB = CNTRPRCXAB CNTRPRCRAB: $RAB FAB = CNTRPRCFAB,- ; Record ROP = NLK,- ; Do not lock RBF = CNTRPRCREC,- UBF = CNTRPRCREC,- USZ = CTPRECSIZE,- RSZ = CTPRECSIZE,- RAC = KEY,- ; KEY access KBF = KEY_BUF,- KSZ = 112 CNTRPRCXAB: $XABKEY REF = 0,- ; Primary key DTP = STG,- ; Key = 12 Bytes POS = 0,- ; Key position SIZ = 112,- ; Key len NXT = CNTRPRCXAB1 CNTRPRCXAB1: $XABKEY REF = 1,- ; Second key DTP = STG,- ; Key = 8 Bytes(node name space padded) POS = 0,- ; Key position SIZ = 8,- ; Key len FLG = ,- ; Duplicates, changes allowed NXT = CNTRPRCXAB2 CNTRPRCXAB2: $XABKEY REF = 2,- ; DTP = BN4,- ; FACILITY POS = 8,- ; Key position SIZ = 4,- ; Key len FLG = ,- ; Duplicates, changes allowed NXT = CNTRPRCXAB3 CNTRPRCXAB3: $XABKEY REF = 3,- ; DTP = BN4,- ; Code POS = 12,- ; Key position SIZ = 4,- ; Key len FLG = ,- ; Duplicates, changes allowed NXT = CNTRPRCXAB4 CNTRPRCXAB4: $XABKEY REF = 4,- ; DTP = STG,- ; Facility specific POS = 16,- ; Key position SIZ = 96,- ; Key len FLG = ; Duplicates, changes allowed ; .ALIGN QUAD KEY_BUF: CNTRPRCREC: .BLKB CTPRECSIZE KEY_ARRAY: .BLKB CTP_C_KEYSIZ*400 ; CSVOUTPFAB: $FAB FAC = ,- ; Access SHR = ,- ; Share with anyone RAT = CR,- FNM = ,- ; Filename DNM = ; Filename CSVOUTPRAB: $RAB FAB = CSVOUTPFAB,- ; Record RBF = FAOBUF,- UBF = FAOBUF ; FAO FAOLST: .BLKL 4000 FAOLST_LEN = .-FAOLST FAOBUF: .BLKL 5000 FAOBUF_LEN = .-FAOBUF FAODESC: FAOLEN: .LONG .-FAOBUF .ADDRESS FAOBUF SAMSTRI: .ASCID / !#(UL),/ SAMSTRF: .ASCID / !AC,!#(AD)/ TIMESTR: .ASCID / !%D,!#(AD)/ INTFMT: .ASCID /!UL,/ .ALIGN quad ; Misc OUTP: .BLKL 2000 ; Strings here OUTP_SIZ = .-OUTP TEMPBUF: .BLKB 24 TEMPDESC: .LONG .-TEMPBUF .ADDRESS TEMPBUF TEMPBUF2: .BLKB 24 TEMPDESC2: .LONG .-TEMPBUF2 .ADDRESS TEMPBUF2 TEMPDESC3: .QUAD CNTR: .LONG 0 LASTSEEN: .LONG 0 FLTLEN: .LONG 0 RECCNT: .LONG 0 CDXLT: .LONG 0 TABPNT: .LONG 0 .PSECT CNTRPRC_CSV_C,EXE,NOWRT,LONG .CALL_ENTRY MAX_ARGS=12, HOME_ARGS=TRUE, - INPUT=, - PRESERVE=, - LABEL=CNTRPRC_CSV ; $OPEN FAB=CNTRPRCFAB BSBW ERROR_CHK ; Any error fatal $CONNECT RAB=CNTRPRCRAB BSBW ERROR_CHK MOVB #RAB$C_SEQ,CNTRPRCRAB+RAB$B_RAC CLRL TABPNT 10$: ; 1ST CALL MOVW #CTPRECSIZE,CNTRPRCRAB+RAB$W_USZ MOVW #CTPRECSIZE,CNTRPRCRAB+RAB$W_RSZ $GET RAB=CNTRPRCRAB BLBS R0,20$ RET 20$: MOVAL CNTRPRCREC,R6 MOVL CTP_L_TBLPNT(R6),TABPNT PUSHAL TABPNT PUSHAL CNTRPRCREC CALLS #2,G^CSV_COUNTERS BLBS R0,30$ RET 30$: MOVW #CTPRECSIZE,CNTRPRCRAB+RAB$W_USZ MOVW #CTPRECSIZE,CNTRPRCRAB+RAB$W_RSZ $GET RAB=CNTRPRCRAB BLBS R0,40$ RET 40$: PUSHAL TABPNT PUSHAL CNTRPRCREC CALLS #2,G^CSV_COUNTERS BLBS R0,30$ RET ; Subroutines ; ERROR_CHK: .JSB_ENTRY INPUT=, - OUTPUT= BLBC R0,10$ RSB 10$: $EXIT_S R0 ; Die .CALL_ENTRY MAX_ARGS=12, HOME_ARGS=TRUE, - INPUT=, - PRESERVE=, - LABEL=CSV_COUNTERS ; Routine to format SAMTBL within CNTRPRC rec as CSV. ; ; Input = .address of CNTRREC to display ; .address of table pointer. on 1st call (=TBLPNT) pointer to 1st ; (oldest) ; rec in array is returned. On subsequent call (.ne. TBLPNT) this ; pointer is used as array number to start display at. ; Translate code to name and display this with samtbl in CSV format: ; Name, oldest sample, ..., newest sample. MOVL 4(AP),R6 MOVL @8(AP),R7 CMPL R7,CTP_L_TBLPNT(R6) BNEQ 400$ ; Br if not 1st call ; On 1st call: ; Determine start point (oldest time), create outp file, write header. ; TBLPNT is pointing to newest sample. If STCNT = MAXSAMPL , oldest ; sample is TBLPNT+1. If not (table not full), oldest sample = begin of ; table. MOVL CTP_X_STCNT(R6),R8 BBC #CTP_V_FLT,CTP_L_DTYP(R6),20$ ; Br if not Floating data CVTFL R8,R8 ; Make int 20$: CMPL R8,#CTP_C_MAXSMPL ; Table full? BEQL 30$ ; Br if so CLRL @8(AP) ; Return oldest entry pos BRW 40$ 30$: ADDL3 #1,R8,@8(AP) ; Return oldest entry pos 40$: ; Open outp file $CREATE FAB=CSVOUTPFAB BSBW ERROR_CHK ; Any error fatal $CONNECT RAB=CSVOUTPRAB BSBW ERROR_CHK MOVL @8(AP),R3 ; Index oldest time MOVL CTP_X_STCNT(R6),R4 ; Sample count BBC #CTP_V_FLT,CTP_L_DTYP(R6),360$ ; Br if not Floating data CVTFL R4,R4 ; Make int ; 360$: ; Display times ADDL3 #CTP_TQ_TIMTBL,R6,R7 ; Time origin MOVAL OUTP,R9 ; Strings MOVAL FAOLST,R8 ; Descriptors (4000) MOVL #OUTP_SIZ,R10 ; Str len 370$: MOVAQ (R7)[R3],(R8) ; Addr of 1st date/time ADDL #4,R8 ; Next list item INCL R3 ; Next index CMPL #CTP_C_MAXTBL,R3 ; If past end ... BGEQ 380$ ; CLRL R3 ; ... Wrap to begin 380$: DECL R4 ; Insert param count as next param MOVL CTP_X_STCNT(R6),(R8) ; Sample count BBC #CTP_V_FLT,CTP_L_DTYP(R6),382$ ; Br if not Floating data CVTFL (R8),(R8) ; Make int 382$: DECL (R8)+ 385$: ; Extract time from each date string for remainder of display ; Set up out desc MOVL R10,TEMPDESC3 ; Make desc MOVL R9,TEMPDESC3+4 PUSHL #2 ; TIME PUSHAL TEMPDESC3 ; PUSHAQ (R7)[R3] CALLS #3,G^EXTRACT_DATE INCL R3 ; Next index CMPL #CTP_C_MAXTBL,R3 ; If past end ... BGEQ 386$ ; CLRL R3 ; ... Wrap to begin 386$: ADDL TEMPDESC3,R9 ; Adjust pointers SUBL TEMPDESC3,R10 MOVQ TEMPDESC3,(R8) ; Add desc to list ADDL #8,R8 ; Next desc SOBGTR R4,385$ MOVL #FAOBUF_LEN,FAODESC PUSHAL FAOLST PUSHAL FAODESC PUSHAL FAODESC PUSHAL TIMESTR CALLS #4,G^SYS$FAOL BLBS R0,390$ RET 390$: MOVW FAODESC,CSVOUTPRAB+RAB$W_RSZ MOVW FAODESC,CSVOUTPRAB+RAB$W_USZ $PUT RAB=CSVOUTPRAB BLBS R0,400$ RET 400$: ; Display Corresponding 8 samples BBS #CTP_V_FLT,CTP_L_DTYP(R6),1000$ ; Br if Floating data MOVL @8(AP),R3 MOVL CTP_X_STCNT(R6),R4 ; Sample count BBC #CTP_V_FLT,CTP_L_DTYP(R6),401$ ; Br if not Floating data CVTFL R4,R4 ; Make int 401$: ADDL3 #CTP_TF_SAMTBL,R6,R7 ; SAM origin MOVAL OUTP,R9 ; Strings MOVAL FAOLST,R8 ; Descriptors (512) MOVL #OUTP_SIZ,R10 ; Str len ; Insert name as 1st param PUSHL R8 ; Addr here PUSHL CTP_L_CODE(R6) ; (TEMP) CALLS #2,G^XLATE_RMI ADDL #4,R8 SUBL #4,R10 ; Insert param count as next param MOVL R4,(R8)+ ; Sample count ; Set up out desc 405$: MOVL R10,TEMPDESC3 ; Make desc MOVL R9,TEMPDESC3+4 PUSHL (R7)[R3] ; Value PUSHAL TEMPDESC3 ; Len PUSHAL TEMPDESC3 ; PUSHAL INTFMT CALLS #4,G^SYS$FAO BLBS R0,410$ RET 410$: INCL R3 ; Next index CMPL #CTP_C_MAXTBL,R3 ; If past end ... BGEQ 415$ ; CLRL R3 ; ... Wrap to begin 415$: MOVL TEMPDESC3,(R8)+ ; Add desc to list MOVL R9,(R8)+ ADDL TEMPDESC3,R9 ; Adjust pointers SUBL TEMPDESC3,R10 SOBGTR R4,405$ MOVL #FAOBUF_LEN,FAODESC PUSHAL FAOLST PUSHAL FAODESC PUSHAL FAODESC PUSHAL SAMSTRF CALLS #4,G^SYS$FAOL BLBS R0,420$ RET 420$: MOVW FAODESC,CSVOUTPRAB+RAB$W_RSZ MOVW FAODESC,CSVOUTPRAB+RAB$W_USZ $PUT RAB=CSVOUTPRAB RET 1000$: ; Display floating data \ MOVL @8(AP),R3 MOVL CTP_X_STCNT(R6),R4 ; Sample count CVTFL R4,R4 ADDL3 #CTP_TF_SAMTBL,R6,R7 ; Time origin MOVAL OUTP,R9 ; Strings MOVAL FAOLST,R8 ; Descriptors (512) MOVL #OUTP_SIZ,R10 ; Str len 1010$: ; Set up out desc MOVL R10,TEMPDESC3 ; Make desc MOVL R9,TEMPDESC3+4 PUSHAL FLTLEN ; Len PUSHAL TEMPDESC3 ; PUSHL (R7)[R3] ; Value CALLS #3,G^FAO_FFLOAT BLBS R0,1020$ RET 1020$: INCL R3 ; Next index CMPL #CTP_C_MAXTBL,R3 ; If past end ... BGEQ 1030$ ; CLRL R3 ; ... Wrap to begin 1030$: MOVL FLTLEN,(R8)+ ; Add desc to list MOVL R9,(R8)+ ADDL FLTLEN,R9 ; Adjust pointers SUBL FLTLEN,R10 SOBGTR R4,1010$ MOVL #FAOBUF_LEN,FAODESC PUSHAL FAOLST PUSHAL FAODESC PUSHAL FAODESC PUSHAL SAMSTRF CALLS #4,G^SYS$FAOL BLBS R0,420$ RET .CALL_ENTRY MAX_ARGS=12, HOME_ARGS=TRUE, - INPUT=, - PRESERVE=, - LABEL=EXTRACT_DATE ;++ ;2 EXTRACT_DATE ; Routine to take binary time, convert it to ascii and return the date ; or time portion. The routine writes the entire date string to the outp desc ; then adjusts the len to include the selected field only. Thus the outp desc ; must be at least 23 bytes though the len returned is always 11(date) or ; 8 (time). To facilitate CSV construction, a , is added to the end of the ; field when time is requested. Thus time is retuned as 9 bytes. ;3 Inputs ; .address of .quad VMS binary time to convert ; .address of desc pointing to outp area. Must be at least 23 bytes long ; .long flag - 2 = time. any other param defaults to date. ;3 Outputs ; The entire date string is produced in the outp area and then ; manipulated to return the desired field. ;3 Returns ; SS$_NORMAL OK ; any from $ASCTIM ;-- CLRL -(SP) ; cvtflg PUSHL 4(AP) PUSHL 8(AP) PUSHL 8(AP) CALLS #4,G^SYS$ASCTIM BLBS R0,10$ RET 10$: CMPL 12(AP),#2 BEQL 20$ ; Date MOVL #11,@8(AP) MOVL #SS$_NORMAL,R0 RET ; Time 20$: MOVQ @8(AP),R6 MOVL #8,R6 ADDL3 #12,R7,R8 MOVC3 R6,(R8),(R7) ; ADD ',' MOVB #^A/,/,(R7)[R6] INCL R6 MOVQ R6,@8(AP) MOVL #SS$_NORMAL,R0 RET .END CNTRPRC_CSV