SUBROUTINE VARSCN(LINE,IBGN,LEND,LSTCHR,ID1,ID2,IVALID) C VARSCN - SCAN COMMAND LINE FOR VARIABLE NAMES. C C SCANS FOR VARIABLE NAMES OF FORM AAANNN WHERE AAA = LETTERS C BETWEEN A AND Z UP TO NON-ALPHA, CORRESPONDING TO ROW, FOLLOWED BY C NUMBERS IN THE 0-9 RANGE MAKING A DECIMAL COLUMN NUMBER. C C THE LETTERS ARE FORMED BY C A-Z ALONE GIVE ROW 1-26, COL 1. % IS ROW 27,COL1 C A1-Z1 GIVE ROW 1-26, COL 2 C AA1-ZZ1 ARE ROW 27-52, COL 2 IMPLICIT INTEGER*2 (A-Z) INCLUDE 'VKLUGPRM.FTN' C PARAMETER RRW = 32 C PARAMETER RCL = 32 ! REAL (PHYSICAL) ROWS AND COLUMNS OF SPREADSHEET C PARAMETER RRCL = 1024 C PARAMETER RRCL=RRW*RCL ! SIZE PARAMETER CUP=1,NEL=14 C NOTE COL 1 IS DUMMY. DISPLAY THE SHEET SIDEWAYS SO WE GET USUAL VISUAL C ROWS, COLS., AND ACCUMULATORS A-Z,% JUST APPEAR AS A FICTITIOUS ROW 0 C ON DISPLAY, INSTEAD OF REAL COLUMN 1 HERE. C PARAMETER DRW = 8 ! DISPLAY MAX ROWS C PARAMETER DCL = 8 ! AND COLS DIMENSION LINE(LEND) LOGICAL*1 LINE DIMENSION NRDSP(DRW,DCL),NCDSP(DRW,DCL) COMMON/D2R/NRDSP,NCDSP C NRDSP AND NCDSP ARE REAL ROW, COL OF DISPLAY ROW, COL CELLS. NOTE THAT C NOT ALL DISPLAY CELLS ARE ALWAYS ACTUALLY SHOWN; ONLY THOSE THAT FIT C ARE SHOWN; THE REST "EXIST" BUT DON'T APPEAR UNLESS ROWS ARE SMALL C ENOUGH. C C THIS PROGRAM ALSO HANDLES CELL SPECS OF FORM C P#+nnn#+nnn (or P#-nnn#-mmm) FOR Physical cells relative to our current C physical cell on the sheet (clamped at boundaries), or of form C D#+nnn#+mmm etc for Display cells relative to our current display C location as held in the DROW,DCOL cells in commons. INTEGER*2 PROW,PCOL ! PHYSICAL ROW, COL BEING HANDLED. INTEGER*2 DROW,DCOL,DCLV,DRWV INTEGER*2 RSM,CSM,AFG,ASM,VCF,CH COMMON/DCTL/PROW,PCOL,DROW,DCOL,DRWV,DCLV C DRWV,DCLV = # OF MAX ROWS, COLS ACTUALLY ON SCREEN NOW. DROW,DCOL C ARE ACTUAL "CURSOR" LOCATION. C C ZERO OUR VARIABLES LPFG=0 ! FLAG WE GOT A LOGICAL/PHYSICAL # FORM AND TYPE AFG=0 ! FLAG WE SAW AN ALPHA ASM=0 ! SUM OF ALPHAS HASHCODED (ACCUMULATOR) NSM=0 ! ACCUMULATOR FOR NUMERICS NFG=0 ! FLAG WE SAW A NUMERIC RSM=0 ! AC FOR ROWS IN # FORMS CSM=0 ! AC FOR COLS IN # FORMS ISPC=0 ! COUNTER FOR NONSPACES SEEN (USED TO STOP ON TRAILING SPACES) IF(LINE(IBGN).NE.'%')GOTO 2000 ID1=27 ID2=1 IVALID=1 LSTCHR=IBGN+1 C SPECIAL CASE FOR % = AC #27 RETURN 2000 CONTINUE DO 1 N=IBGN,LEND VCF=0 LSTCHR=N CH=LINE(N) C IGNORE SPACES AND TABS IF LEADING IF(CH.GT.32)ISPC=ISPC+1 IF(CH.GT.0.AND.CH.LE.32.AND.ISPC.EQ.0)GOTO 1 C GET CHARACTER VALUE IN. C MUST BE UPPERCASE. IF(.NOT.(CH.GE.65.AND.CH.LE.91)) GOTO 100 C CH IS AN ALPHA, RANGE A-Z VCF=1 ! VALID CHAR SEEN AFG=1 !SAW THE ALPHA IF(ASM.LT.RRCL)ASM=(CH-64)+26*ASM IF(CH.EQ.80)LPFG=1 ! FLAG WE GOT PHYS. FORM MAYBE IF(CH.EQ.68)LPFG=2 ! FLAG WE GOT DISPLAY FORM MAYBE 100 CONTINUE C EXPECT # FORMS TO HAVE # JUST AFTER 1ST ALPHA. C 35 IS ASCII VALUE OF '#' CHAR. IF(CH.EQ.35)GOTO 1000 C NEXT TEST NUMERICS IF(.NOT.(CH.GE.48.AND.CH.LE.57))GOTO 101 C CH IS A NUMERIC, RANGE 0-9 VCF=1 ! VALID CHAR SEEN NFG=1 ! FLAG WE SAW NUMERIC IF(AFG.NE.0)GOTO 102 103 CONTINUE C INVALID ... NUMERIC AND NO PRIOR ALPHA. FLAG BAD NAME AND EXIT. IVALID=0 RETURN 102 CONTINUE IF(NSM.LT.RRCL)NSM=(CH-48)+10*NSM ! CONVERT CHARS TO BINARY AS SEEN 101 CONTINUE IF(VCF.EQ.0)GOTO 2 !END ON ANY INVALID CHARACTER 1 CONTINUE 2 CONTINUE IF(AFG.EQ.0)GOTO 103 ID1=ASM ID2=1+NSM ! NOTE ID2=1 IF NO NUMERICS SEEN, MORE OTHERWISE. GOTO 1201 1000 CONTINUE C HERE HANDLE CURRENT-REFERENCED FORMS USING # AS SPECIAL CHARACTER MEANING C THE CURRENT POSITION. THESE TYPES OF REFERENCES MAY BE MOVED AROUND THE C SHEET WHICH ACCOUNTS FOR THEIR USEFULNESS. SINCE THERE IS A DISPLAY C AND PHYSICAL SHEET WHICH ARE MAPPED BY A MAPPING, ALLOW EITHER C TO BE REFERENCED. THUS, COMPLEX CALCULATIONS MAY BE DONE BUT LARGELY C HIDDEN. THE ACCUMULATORS MAY BE USED AS SCRATCH STORAGE FOR THIS C SORT OF THING. C SAW THE # SIGN, SO SEE IF THE + OR - N CAN BE DECODED. C IF NO P OR D WAS SEEN HOWEVER WE HAVE AN INVALID NAME, SO FLAG IT. IF(LPFG.EQ.0)GOTO 103 C PASS THE # SIGN PRIOR TO GETTING THE NUMERIC. LSTCHR=LSTCHR+1 CALL GN(LSTCHR,LEND,NUM,LINE) C GN GETS THE +- NN NUMBER AND RETURNS VALUE IN NUM. C LSTCHR RETURNS AS NEXT CHAR NOT USED. RSM=NUM C 35 IS ASCII FOR '#' C allow any delimiter between numbers, though we must have # at start C to delimit valid relative coordinates. C IF(LINE(LSTCHR).NE.35) GOTO 103 C IF NO SECOND # SEEN, THE FORM IS INVALID SO SAY SO AND EXIT. LSTCHR=MIN0(LSTCHR+1,LEND) CC BUMP PAST THE # IF WE SAW IT. C now get the second numeric string and bump LSTCHR past it. NUM=0 CALL GN(LSTCHR,LEND,NUM,LINE) CSM=NUM C NOW HAVE THE NUMBERS ENCODED. NOTE THAT ## IS VALID. IF(LPFG.EQ.2) GOTO 1200 C IF HERE, LPFG=1 AND WE ARE ON PHYSICAL SHEET. ID2=CSM+PCOL ID1=RSM+PROW 1201 CONTINUE IF(ID1.GT.RRW.OR.ID1.LE.0)GOTO 103 IF(ID2.GT.RCL.OR.ID2.LE.0)GOTO 103 IVALID=1 C ALL IS WELL RETURN 1200 CONTINUE C DISPLAY COLUMN RELATIVE. DRRW=DROW+RSM DRRW=MAX0(1,DRRW) DRRW=MIN0(DRW,DRRW) DCCL=DCOL+CSM DCCL=MAX0(1,DCCL) DCCL=MIN0(DCL,DCCL) C CLAMP TO WITHIN LEGAL DIMENSIONS. ID1=NRDSP(DRRW,DCCL) ID2=NCDSP(DRRW,DCCL) D CALL UVT100(CUP,11,1) D WRITE(6,6502)ID1,ID2,DRRW,DCCL D6502 FORMAT('ID1,ID2,DRRW,DCCL:',4I6) D CALL UVT100(CUP,12,1) GOTO 1201 END C C GN - GET NUMBER SUBROUTINE GN(LAST,LEND,NUM,LINE) IMPLICIT INTEGER*2(A-Z) PARAMETER CUP=1,NEL=14 DIMENSION LINE(110) LOGICAL*1 LINE LOGICAL*1 NCH INTEGER*2 CH,SFG NUM=0 JSSF=0 ISSF=0 CH=0 SFG=1 NCH=0 DO 1 N=LAST,LEND M=N NCH=LINE(N) CH=NCH IF(CH.EQ.0)GOTO 2 IF(CH.EQ.45)SFG=-1 C SFG=SIGN FLAG C 43 IS ASCII FOR +; 45 IS ASCII FOR - SIGN. C IGNORE + SIGNS IF(CH.GT.32)ISSF=ISSF+1 IF(ISSF.EQ.0.AND.CH.EQ.32)GOTO 1 C IGNORE SPACES TOO, PROVIDED THEY ARE LEADING SPACES. C (OTHERS MAY BE DELIMITERS.) IF(CH.EQ.43.OR.CH.EQ.45)JSSF=JSSF+1 IF(JSSF.GT.1.AND.(CH.EQ.43.OR.CH.EQ.45))GOTO 2 C IF WE HAVEN'T SEEN A +/- PROCESS IT HERE. IF(CH.EQ.43)GOTO 1 IF(CH.EQ.45)GOTO 1 IF(CH.LT.48.OR.CH.GT.57)GOTO 2 C TERMINATE ON ANY NON NUMERIC. SHOULD ALLOW TERMINATE ON SECOND #. IF(NUM.LT.3100)NUM=10*NUM+(CH-48) 1 CONTINUE C NEXT LINE WAS MAX0... 2 LAST=MIN0(M,LEND) NUM=NUM*SFG C ACCOUNTED FOR SIGN; NOW RETURN RETURN END