TclStack
From Pickwiki
HomePage >> BasicSource >> Github:
This program is an attempt to make TCL a more productive place for programmers. You can edit the command stack using standard bash/emacs key-bindings. There is also a stack of program files being worked on and shortcuts for the common operations of editing, compiling, running and interacting with version control.
Planned new features include tab-completion on commands, file and dictionary names (how to make it quick with thousands of entries is a problem).
The help information gives a good overview of what is currently there (though aliases, program token expansion and setting the prompt are extras not mentioned).
PRINT 'Ctrl-A Start of line Ctrl-R Toggle insert mode' PRINT 'Ctrl-B Back one char Ctrl-W Delete word' PRINT 'Ctrl-D Delete char Ctrl-X Forward word' PRINT 'Ctrl-E End of line Ctrl-Z Back word' PRINT 'Ctrl-F Forward char ' PRINT 'Ctrl-G Cancel line ' PRINT 'Ctrl-I Forward word ~xxx Search for xxx' PRINT 'Ctrl-J Delete to end .Lm,n List entry m thru n' PRINT 'Ctrl-M Accept line .Rn Restore entry n, edit' PRINT 'Ctrl-N Next line .Dm,n Delete entry m thru n' PRINT 'Ctrl-P Previous line Q Quit back to TCL' PRINT PRINT '/ List the program stack // List the stack with cvs status' PRINT '[[/Nx]] Add a New program,' PRINT '[[/Ex]] Edit the x`th program [[/WW]] Edit the program list' PRINT '[[/Wx]] VI the x`th program [[/S]] Sort the program stack' PRINT '[[/Bx]] Compile the x`th program [[/BR]] Compile and run' PRINT '[[/CI]] Checkin a program to cvs [[/D]] Show diff with cvs version'
See also:
- GetLineStack - a subroutine to allow cursor editing in wy50, vt100
CVS Integration "helpers"
*************************************************************************** * Program: STACK * Author : Ian McGowan * Created: 1989-06-13 * Updated: 2019-09-13 * License: (c) 1989-2019 Ian McGowan, released under MIT license * Comment: Stacks TCL commands, utilities for programmers *************************************************************************** * https://github.com/ianmcgowan/SCI.BP/blob/master/STACK CRT 'Version 2019-09 Autocomplete' EQUATE INSERT TO '1',REPLACE TO '-1',BEEP TO CHAR(7) EQUATE RET TO 13, ESC TO 27, UP.KEY TO 1, DOWN.KEY TO 2 EQUATE PG.UP.KEY TO 21, PG.DOWN.KEY TO 22 EQUATE NUL TO '',SPC TO ' ',TRUE TO 1, FALSE TO 0 EQUATE SEARCH TO '~', UNIX TO '!' EQUATE BELL TO CHAR(7), OTHERWISE TO 1 TERM=UPCASE(GETENV("TERM")) CS=@(-1);EOL=@(-4);EOS=@(-3);UP=@(-10);BON=@(-81);BOFF=@(-82) PROMPT NUL * LONG.LINE = 9999;LIST.DET.FLAG=0;TIME.COMMAND=0 EXECUTING = FALSE;SL.ACTIVE = FALSE * PWD=GETENV("PWD") I=LEN(PWD) ; ACC=NUL FOR F=I TO 1 STEP -1 IF PWD[F,1] = '/' THEN EXIT ACC=PWD[F,1]:ACC NEXT F * USERNAME=UPCASE(@LOGNAME) HOME.DIR=GETENV("HOME") STACK.ITEM='.STACK_':USERNAME ALIAS.ITEM='.STACK.ALIAS_':USERNAME PROGRAM.ITEM='.STACK.PROGRAM_':USERNAME SETTING.ITEM='.STACK.SETTING_':USERNAME HOME.FILE='HOME.':UPCASE(USERNAME) OPEN 'VOC' TO VOC ELSE STOP 201,'VOC' OPEN '_HOLD_' TO HOLD ELSE STOP 201,'_HOLD_' ;* Exists in every Unidata account R='DIR' ; R<2>=HOME.DIR ; R<3>='D_VOC' WRITE R ON VOC, HOME.FILE OPEN HOME.FILE TO HOME.F ELSE STOP 201, HOME.FILE OPEN 'CTLGTB' TO CTLGTB ELSE STOP 201,'CTLGTB' OPEN 'CTLG' TO CTLG ELSE STOP 201,'CTLG' OPEN 'STACK.AC' TO AC ELSE EXECUTE \CREATE.FILE STACK.AC 967,8192\ OPEN 'STACK.AC' TO AC ELSE ABORT END * SETTINGS = ';' ;* DEFAULT COMMAND SEPERATOR SETTINGS<2> = '.' ;* DEFAULT STACK CHAR SETTINGS<3> = '/' ;* DEFAULT PROG CHAR SETTINGS<4> = 9999 ;* DEFAULT MAX # LINES IN STACK SETTINGS<5> = '!vi' ;* DEFAULT SCREEN EDITOR (try !joe :) SETTINGS<6> = 'AE' ;* DEFAULT LINE EDITOR SETTINGS<7> ='* Edited :';* DEFAULT HEADER STRING SETTINGS<8> = TRUE ;* DEFAULT USE GET.LINE SUBR SETTINGS<9> = 'BP.DEV' ;* DEFAULT WORK FILE SETTINGS<10> = FALSE ;* DEFAULT = CONVERT TO UCASE SETTINGS<11> = "" ;* DEFAULT STARTUP COMMAND SETTINGS<12> = "#R#A>" ;* DEFAULT PROMPT SETTINGS<13> = -2 ;* DEFAULT X DISPLACEMENT FOR PROMPT SETTINGS<14> = "bash" ;* DEFAULT SHELL FOR UNIX COMMANDS SETTINGS<15> = "" ;* DEFAULT PROGRAM STACK TO USE * READ R FROM HOME.F, SETTING.ITEM ELSE R=NUL I=DCOUNT(SETTINGS,@AM) FOR F=1 TO I IF R<F> # NUL THEN SETTINGS<F> = R<F> NEXT F COMMAND.SEPERATOR = SETTINGS<1> STACK.CHAR = SETTINGS<2> PROG.CHAR = SETTINGS<3> MAX.STACK = SETTINGS<4> WP.VERB = SETTINGS<5> ED.VERB = SETTINGS<6> STAMP.STRING = SETTINGS<7> GET.LINE.FLAG= SETTINGS<8> WORK.FILE = SETTINGS<9> MCU.ON = SETTINGS<10> STARTUP = SETTINGS<11> PROMT = SETTINGS<12> X.DISP = SETTINGS<13> DEF.SHELL = SETTINGS<14> STACK.NAME = SETTINGS<15> WRITE SETTINGS ON HOME.F, SETTING.ITEM * IF STACK.NAME = '' THEN PROGRAM.ITEM='.STACK.PROGRAM_':USERNAME END ELSE PROGRAM.ITEM='.STACK.PROGRAM_':USERNAME:'_':STACK.NAME END READ PROGRAMS FROM HOME.F, PROGRAM.ITEM ELSE PROGRAMS = NUL * EXEC.LINE="!hostname" ; CAP.ACTIVE=TRUE ; GOSUB EXEC.SUB HOST.NAME=EXEC.CAP<1> * READ STACK FROM HOME.F, STACK.ITEM ELSE STACK = NUL PRINT DCOUNT(STACK,@AM):' commands in stack ':HOME.DIR:'/':HOME.FILE READ ALIASES FROM HOME.F, ALIAS.ITEM ELSE ALIASES = NUL * Override with my favorites for now. It's a pain to manage per system. ALIASES<1>='ACTIVE' ALIASES<1,2>='CS' ALIASES<1,3>='L' ALIASES<2>='SELECT LS.MASTER WITH NUM.OF.ASSETS > "0"' ALIASES<2,2>='CLEARSELECT' ALIASES<2,3>='LIST LS.MASTER' OLD.X.DISP=X.DISP RTN=NUL * IL9/IL10 Check IL.VER='' OPEN 'ACCOUNT.PARAMS' TO ACCOUNT.PARAMS THEN READ R FROM ACCOUNT.PARAMS, 'VERSION' ELSE R='' IL.DB=PWD IL.VER=R<4>:'/':R<8>:'.':R<26> END ELSE EXECUTE \!cat DBConfig.xml | grep DataSource | awk -F '[<>]' '{print $3}'\ CAPTURING JDBC JDBC=JDBC<1> EXECUTE \!grep \:JDBC:\ ../../jdbc-bridge/bin/jdbc.properties | grep -v "^#" | grep url\ CAPTURING IL.DB IL.DB=IL.DB<1> OSREAD VER FROM 'version.properties' ELSE VER='il.version=10' CONVERT CHAR(10) TO @AM IN VER FOR F=1 TO DCOUNT(VER,@AM) IF FIELD(VER<F>,'=',2) # '' THEN IL.VER=FIELD(VER<F>,'=',2) ; EXIT NEXT F END CRT IL.VER:' ':IL.DB IF STARTUP # NUL THEN ANS=STARTUP ; GOSUB COMMAND ; STARTUP=NUL ANS=NUL * LOOP GOSUB GET.TERM.WIDTH ;* In case terminal font or window size changes GOSUB EXPAND.PROMPT PRINT BON:PROMPT.DISP:BOFF: X = LEN(PROMPT.DISP) + X.DISP ENTRY = NUL;LEN = LONG.LINE;DISP.LEN=TERM.WIDTH-1-X GOSUB GET.INPUT ANS=ENTRY * Reread the program and command stack, since they may be modified * in another session READ PROGRAMS FROM HOME.F, PROGRAM.ITEM ELSE PROGRAMS = NUL READ STACK FROM HOME.F, STACK.ITEM ELSE STACK = NUL READ ALIASES FROM HOME.F, ALIAS.ITEM ELSE ALIASES = NUL IF RTN # ESC THEN GOSUB COMMAND REPEAT * GET.INPUT: IF GET.LINE.FLAG THEN *CALL GET.LINE.STACK(X,LEN,DISP.LEN,ENTRY,RTN) GOSUB GET.LINE END ELSE PRINT @(X):;INPUT ENTRY RTN = RET END RETURN * COMMAND: MAX.STACK=DCOUNT(STACK,@AM) BEGIN CASE * Map up and down arrows to .R1 and .Rn CASE RTN = UP.KEY ANS = '.R1' CASE RTN = PG.UP.KEY IF UNASSIGNED(P2) THEN P2 = 20 IF UNASSIGNED(P1) THEN P1 = 1 P2 = P2 + 20 P1 = P1 + 20 IF P2 > MAX.STACK THEN P2 = MAX.STACK IF P1 > MAX.STACK-20 THEN P1 = MAX.STACK-20 ANS = '.L':P1:',':P2 CASE RTN = PG.DOWN.KEY IF UNASSIGNED(P2) THEN P2 = 20 IF UNASSIGNED(P1) THEN P1 = 1 P2 = P2 - 20 P1 = P1 - 20 IF P2 < 20 THEN P2=20 IF P1 < 1 THEN P1=1 ANS = '.L':P1:',':P2 CASE ANS='?' ANS='.H' END CASE IF ANS = NUL THEN RETURN UNIX.COMMAND=FALSE IF ANS[1,1] = UNIX THEN UNIX.COMMAND=TRUE OLD.STACK = STACK START.WORD.SEARCH = 1 COMMAND.LIST = ANS COMMAND.COUNT = 1 IF STARTUP#NUL THEN EXECUTING=TRUE ELSE EXECUTING=FALSE IF UNIX.COMMAND THEN * Don't look for ; for unix commands GOSUB DO.COMMAND END ELSE LOOP ANS = FIELD(COMMAND.LIST,COMMAND.SEPERATOR,COMMAND.COUNT) UNTIL ANS = NUL DO GOSUB DO.COMMAND COMMAND.COUNT = COMMAND.COUNT + 1 REPEAT END WRITE ALIASES ON HOME.F, ALIAS.ITEM RETURN * DO.COMMAND: IF NOT(UNIX.COMMAND) THEN IF MCU.ON THEN ANS = TRIM(UPCASE(ANS)) IF ANS[1,5] # 'ALIAS' THEN GOSUB EXPAND.ALIASES GOSUB EXPAND.PROG.CHARS END IF ANS='!' THEN ANS='!':DEF.SHELL LEN.ANS = LEN(ANS) SEARCH.FOR=NUL CAP.ACTIVE=FALSE FIRST.WORD=FIELD(ANS,' ',1) UPDATE.STACK.FLAG=TRUE BEGIN CASE CASE ANS[1,1] = STACK.CHAR ANS = TRIM(UPCASE(ANS)) GOSUB STACK.COMMAND UPDATE.STACK.FLAG=FALSE CASE ANS[1,1] = PROG.CHAR ANS = TRIM(UPCASE(ANS)) GOSUB PROG.COMMAND UPDATE.STACK.FLAG=FALSE CASE ANS[1,1] = SEARCH GOSUB SEARCH.COMMAND UPDATE.STACK.FLAG=FALSE CASE UPCASE(ANS) = 'OFF' OR UPCASE(ANS) = 'Q' GOSUB WRITE.INFO STOP CASE FIRST.WORD='AC' GOSUB BUILD.AC CASE FIRST.WORD = 'ALIAS' GOSUB DO.ALIAS CASE FIRST.WORD = 'SE' FILE=FIELD(ANS,' ',2) ID=FIELD(ANS,' ',3) GOSUB SEARCH.BY.EXAMPLE CASE FIRST.WORD = 'CI' * CONTRACT INQUIRY CONTRACT=FIELD(ANS,' ',2) DATA 0 DATA 0 DATA 0 DATA 0 IF CONTRACT # '' THEN CONVERT '.' TO '-' IN CONTRACT DATA FIELD(CONTRACT,'-',1) DATA FIELD(CONTRACT,'-',2,2) END EXEC.LINE=\CMAINT.00\ ; GOSUB EXEC.SUB CASE FIRST.WORD = 'CM' * CONTRACT MAINTENANCE CONTRACT=FIELD(ANS,' ',2) DATA 1 DATA 0 DATA 0 DATA 0 IF CONTRACT # '' THEN CONVERT '.' TO '-' IN CONTRACT DATA FIELD(CONTRACT,'-',1) DATA FIELD(CONTRACT,'-',2,2) END EXEC.LINE=\CMAINT.00\ ; GOSUB EXEC.SUB CASE FIRST.WORD = 'CCI' * CUSTOMER INQUIRY DATA 0 DATA 0 DATA 0 IF FIELD(ANS,' ',2) # '' THEN DATA FIELD(ANS,' ',2) END EXEC.LINE=\CDMAINT.00\ ; GOSUB EXEC.SUB CASE FIRST.WORD = 'CCM' * CUSTOMER MAINTENANCE DATA 1 DATA 0 DATA 0 IF FIELD(ANS,' ',2) # '' THEN DATA FIELD(ANS,' ',2) END EXEC.LINE=\CDMAINT.00\ ; GOSUB EXEC.SUB CASE ANS = 'TM' DATA 1 DATA 0 EXEC.LINE=\TMAINT.00\ ; GOSUB EXEC.SUB CASE FIRST.WORD = 'CHECK.FILE' GOSUB CHECK.FILE CASE ANS = 'ICONV' CONV='I' GOSUB CONV CASE ANS = 'OCONV' CONV='O' GOSUB CONV CASE ANS = 'RULER' GOSUB GET.TERM.WIDTH GOSUB RULER CASE FIRST.WORD = 'PIVOT' GOSUB PIVOT CASE FIRST.WORD = 'PROF' GOSUB PROFILE CASE FIRST.WORD = 'DDD' GOSUB DDD CASE FIRST.WORD = 'BPI' GOSUB BPI CASE FIRST.WORD = 'SF' GOSUB SEARCH.FILE CASE FIRST.WORD = 'AF' GOSUB ATB.FIND CASE ANS='PARAM' GOSUB LIST.PARAM CASE FIRST.WORD = 'PICKLE' GOSUB PICKLE CASE ANS='SETTINGS' GOSUB SETTINGS CASE FIRST.WORD='RS' GOSUB RECALL.SHELL CASE FIRST.WORD='FIND.MENU' GOSUB FIND.MENU CASE ANS='LISTA' GOSUB LISTA CASE FIRST.WORD = 'DESC' GOSUB IL10.DESC CASE FIRST.WORD = 'XREF' GOSUB IL10.XREF CASE FIRST.WORD = 'FIELD' GOSUB IL10.AF CASE FIRST.WORD = 'NED' GOSUB IL10.NED CASE FIRST.WORD = 'NSEL' GOSUB IL10.NSEL CASE FIRST.WORD = 'SQL' GOSUB SQL.SEL CASE FIRST.WORD = 'SQLF' GOSUB SQL.FILE CASE FIRST.WORD = 'SQL-LIST' GOSUB SQL.SEL.LIST CASE OTHERWISE EXEC.LINE = ANS T1=SYSTEM(12) GOSUB EXEC.SUB IF TIME.COMMAND THEN PRINT SYSTEM(12)-T1:' ms' END CASE IF UPDATE.STACK.FLAG THEN GOSUB UPDATE.STACK RETURN * DO.ALIAS: AL = FIELD(ANS,SPC,2) STRING = NUL;I = 3 LOOP F = FIELD(ANS,SPC,I) UNTIL F = NUL DO STRING = STRING:SPC:F I = I + 1 REPEAT BEGIN CASE CASE AL = NUL AND STRING = NUL GOSUB LIST.ALIAS CASE STRING = NUL GOSUB LIST.ONE.ALIAS CASE 1 GOSUB SET.ALIAS END CASE RETURN * SET.ALIAS: STRING=STRING[2,LONG.LINE] PRINT AL:'=':STRING LOCATE AL IN ALIASES<1> BY 'AL' SETTING P THEN ALIASES<2,P> = STRING END ELSE INS AL BEFORE ALIASES<1,P>;INS STRING BEFORE ALIASES<2,P> END RETURN * LIST.ALIAS: I = DCOUNT(ALIASES<1>,@VM) FOR F = 1 TO I PRINT ALIASES<1,F>,ALIASES<2,F> NEXT F RETURN * LIST.ONE.ALIAS: LOCATE AL IN ALIASES<1> BY 'AL' SETTING P ELSE PRINT AL:' not found';RETURN X=0;LEN=99;DISP.LEN=30;ENTRY=ALIASES<2,P> GOSUB GET.INPUT IF RTN = 27 THEN RETURN ALIASES<2,P> = ENTRY IF ENTRY = NUL THEN DEL ALIASES<1,P>;DEL ALIASES<2,P> RETURN * EXEC.SUB: IF EXEC.LINE = NUL THEN RETURN IF EXEC.LINE = 'CLEARSELECT' THEN CLEARSELECT IF CAP.ACTIVE THEN EXECUTE EXEC.LINE CAPTURING EXEC.CAP END ELSE EXECUTE EXEC.LINE END IF SYSTEM(11) > 0 THEN SL.ACTIVE = TRUE ELSE SL.ACTIVE = FALSE CAP.ACTIVE=FALSE RETURN * EXPAND.PROG.CHARS: * expand //10 to be IV.BP IV.EQP.MNT for example POS = 1 LOOP I = INDEX(ANS,PROG.CHAR:PROG.CHAR,POS) UNTIL I = 0 DO VAR = NUL;IDX = I+2 LOOP C = ANS[IDX,1] UNTIL NOT(NUM(C)) OR C = NUL DO VAR = VAR:C IDX = IDX+1 REPEAT IF NUM(VAR) AND VAR > 0 THEN ANS = ANS[1,I-1]:PROGRAMS<VAR>:ANS[IDX,LONG.LINE] END ELSE POS = POS + 1 END REPEAT RETURN * EXPAND.ALIASES: SWAP SPC WITH @VM IN ANS ; POS = 1 LOOP R = ANS<1,POS> UNTIL R = NUL DO LOCATE R IN ALIASES<1> BY 'AL' SETTING P THEN ANS<1,POS> = ALIASES<2,P> POS = POS + 1 REPEAT SWAP @VM WITH SPC IN ANS RETURN * EXPAND.PROMPT: IF SL.ACTIVE THEN PROMPT.DISP='#R':SYSTEM(11):'-SEL>' OLD.X.DISP=X.DISP X.DISP=-2 END ELSE PROMPT.DISP = PROMT X.DISP=OLD.X.DISP END CTR = 1 LOOP I = INDEX(PROMPT.DISP,'#',CTR) UNTIL I = 0 DO F = PROMPT.DISP[I+1,1] L = PROMPT.DISP[1,I-1];R = TRIM(PROMPT.DISP[I+2,LONG.LINE]) BEGIN CASE CASE F = 'B' PROMPT.DISP = L:CHAR(7):R CASE F = 'A' PROMPT.DISP = L:ACC:R CASE F = 'T' PROMPT.DISP = L:OCONV(TIME(),'MTS'):R CASE F = 'D' PROMPT.DISP = L:OCONV(DATE(),'D'):R CASE F = 'E' PROMPT.DISP = L:CHAR(ESC):R CASE F = 'R' PROMPT.DISP = L:CHAR(13):CHAR(10):R CASE F = '#' PROMPT.DISP = L:'#':R CTR = CTR + 1 CASE F = 'U' PROMPT.DISP = L:USERNAME:R CASE F = 'H' PROMPT.DISP=L:FIELD(HOST.NAME,".",1):R CASE OTHERWISE CTR = CTR + 1 END CASE REPEAT RETURN * STACK.COMMAND: BEGIN CASE CASE ANS='.D' LIST.DET.FLAG=NOT(LIST.DET.FLAG) CASE ANS[1,2] = '.L' IF ANS = '.L' THEN ANS = '.L,20' GOSUB GET.PARAMS IF RANGE.ERROR THEN RETURN I = DCOUNT(STACK,@AM) IF I = 0 THEN PRINT 'No items present';RETURN IF P2 > I THEN P2 = I PRINT FOR F = P2 TO P1 STEP -1 IF LIST.DET.FLAG THEN PRINT SPC:F'R#3':" ":STACK<F,1>'L#20':' ':OCONV(STACK<F,2>,'D-YMD'):' ':OCONV(STACK<F,3>,'MTS'):' ':STACK<F,4> END ELSE PRINT SPC:F'R#3':" ":STACK<F,4> END NEXT F CASE ANS[1,2] = '.R' OR ANS[1,2] = '.X' IF STACK = NUL THEN PRINT BELL ELSE GO EDIT CASE ANS = '.P' PRINT '#R - Return #A - Account #D - Date #T - Time #P - Port' PRINT '#E - Escape #L - Level #U - User #H - Host' PRINT 'Prompt': X = 7;DISP.LEN = 60;ENTRY = PROMT;LEN = 99;GOSUB GET.INPUT PROMT = ENTRY PRINT 'Enter the X displacement for input :': ENTRY = NUL;LEN = 5;DISP.LEN = 5;X = 37;GOSUB GET.INPUT X.DISP = ENTRY IF NOT(NUM(X.DISP)) THEN X.DISP = 0 SETTINGS<12> = PROMT SETTINGS<13> = X.DISP OLD.X.DISP=X.DISP CASE ANS = '.H' CRT '--------------------------- TCL STACK COMMANDS --------------------------------' CRT 'Ctrl-A Start of line Ctrl-R Toggle insert mode' CRT 'Ctrl-B Back one char Ctrl-U Page Up' CRT 'Ctrl-D Delete char Ctrl-V Page Down' CRT 'Ctrl-E End of line Ctrl-W Delete word' CRT 'Ctrl-F Forward char Ctrl-X Forward word' CRT 'Ctrl-G Cancel line Ctrl-Z Back word' CRT 'Ctrl-I Forward word ~xyz Search for xyz' CRT 'Ctrl-J Delete to end .D Toggle detail off/on' CRT 'Ctrl-L Clear screen .Lm,n List entry m thru n' CRT 'Ctrl-M Accept line .Rn Restore entry n, edit' CRT 'Ctrl-N Next line .H Help' CRT 'Ctrl-P Previous line Q/INFO Quit back to TCL' CRT '---------------------- PROGRAM STACK COMMANDS ---------------------------------' CRT '/ List the active prog stack' CRT '/LL List available prog stacks /L BLAH Switch stack to BLAH' CRT '/Nx Add a New program /Fx Format the x`th program' CRT '/Ex Edit the x`th program /WW Edit the program list' CRT '/Wx VI the x`th program /S Sort the program stack' CRT '/Bx Compile the x`th program /BR Compile and run' CRT '---------------------------- UTILITIES ----------------------------------------' CRT ' ----------IL9---------' CRT 'AF ATB Finder, search definitions - AF MRKTNG' CRT 'DDD Search dictionary definitions - DDD LS.MASTER EQUIP' CRT 'LISTA Show users logged in, as well as locks' CRT ' ----------IL10--------' CRT 'FIELD Show IL10 attribute/field metadata - FIELD LS.NET.INVEST' CRT 'NED Edit an IL10 record - NED LS.MASTER 123-1234567-000' CRT 'NSEL Run a simple UD command - NSEL LS.INV.NUM N.CONTRACT.KEY N.DATE.DUE' CRT 'DESC Describe columns in a table - DESC LS_OI_CTD_INVOICE' CRT 'SQL Run a SQL command -SQL SELECT TOP 10 ALTERNATE_ID FROM LS_MASTER_NF' CRT 'SQLF Run a SQL command from a file - SQLF /tmp/queries/Query1.sql' CRT 'SQL-LIST SQL to L1 -SQL-LIST L1 SELECT TOP 10 ALTERNATE_ID FROM LS_MASTER_NF' CRT 'XREF Show IL10 file/table metadata - XREF LS.MASTER' CRT ' ---INFOLEASE---' CRT 'BPI List table definitions - BPI LS.CTD.PYMTHIST' CRT 'CHECK.FILE Show strings in a compiled program /P|/S - CHECK.FILE DISP.00 /P' CRT '{C}CI/CM/TM {Customer}Contract Inquiry/Maintenance/Table Maintenance' CRT 'FIND.MENU Search the menus - FIND.MENU VOID' CRT 'PARAM Show parameter file mapping' CRT 'RS Edit a recall RS DK.AUDIT.RPT' CRT ' -----GENERAL-----' CRT 'ICONV/OCONV Test format masks/Convert Data' CRT 'PICKLE Store data records in prog - PICKLE DICT LS.MASTER UATB.BIG.ATB' CRT 'PIVOT Summary data - PIVOT LS.MASTER LESSOR GROSS.CONTRACT' CRT 'PROF Profile data - PROF LS.MASTER BRANCH NUM.OF.ASSETS BOOKING.DATE' CRT 'RULER Reset term width, show ruler' CRT 'SETTINGS Change settings' CRT 'SF Search files and dictionaries - SF DICT LS.MASTER ASSETS' CASE ANS = '.T' TIME.COMMAND=NOT(TIME.COMMAND) CASE ANS = '.U' IF MCU.ON THEN MCU.ON = FALSE;PRINT 'upper case off' ELSE MCU.ON = TRUE;PRINT 'UPPER CASE ON' CASE OTHERWISE PRINT 'There is no such STACK command':BELL PRINT '? for help' END CASE RETURN * GET.PARAMS: I = INDEX(ANS,',',1) IF I # 0 THEN L = I-1;P1 = NUL LOOP IF NUM(ANS[L,1]) THEN P1 = ANS[L,1]:P1;L=L-1 ELSE EXIT REPEAT P2 = ANS[I + 1, LEN.ANS] END ELSE P1 = NUL LOOP IF NUM(ANS[LEN.ANS,1]) THEN P1 = ANS[LEN.ANS,1]:P1;LEN.ANS=LEN.ANS-1 ELSE EXIT REPEAT IF P1 = NUL THEN P1 = 1 P2 = P1 END IF P1 = NUL THEN P1 = 1 IF P2 = NUL THEN P2 = MAX.STACK IF NUM(P1) & NUM(P2) & P1 > 0 THEN RANGE.ERROR = FALSE END ELSE RANGE.ERROR = TRUE PRINT 'Range Error':BELL END RETURN * EDIT: * Some of the stuff in here is redundant, repeating COMMAND * but to gosub command introduces re-entrancy problems * That's why we use the dreaded GOTO command N = ANS[3,LEN.ANS] IF NOT(NUM(N)) THEN PRINT 'No such line number - ':N:BELL;RETURN IF N = NUL THEN N = 1 LOOP WHILE N # NUL AND STACK<N> # NUL DO PRINT UP:N 'R%3':':':EOL: ENTRY = STACK<N,4> IF ENTRY = "" THEN ENTRY = STACK<N> ;* Legacy stack commands, no timestamp X = 5;DISP.LEN = TERM.WIDTH-1-X;LEN = LONG.LINE IF ENTRY # NUL THEN OLD.ENTRY = ENTRY GOSUB GET.INPUT ANS = ENTRY END BEGIN CASE CASE RTN = UP.KEY IF SEARCH.FOR # NUL THEN GO SEARCH.COMMAND END ELSE N = N + 1 IF STACK<N> = NUL THEN N = 1 END CASE RTN = DOWN.KEY N = N - 1 IF N = 0 THEN N=1; PRINT BELL: END CASE RTN = RET UNIX.COMMAND=FALSE IF ANS[1,1] = UNIX THEN UNIX.COMMAND=TRUE IF UNIX.COMMAND THEN EXECUTING = FALSE IF N = 1 AND ENTRY = OLD.ENTRY THEN EXECUTING = TRUE GOSUB DO.COMMAND N=NUL END ELSE C.LIST = ANS C.COUNT = 1 LOOP ANS = FIELD(C.LIST,COMMAND.SEPERATOR,C.COUNT) UNTIL ANS = NUL DO EXECUTING = FALSE IF N = 1 AND ENTRY = OLD.ENTRY THEN EXECUTING = TRUE GOSUB DO.COMMAND C.COUNT = C.COUNT + 1 REPEAT N = NUL END CASE RTN = ESC N = NUL END CASE REPEAT RETURN * SEARCH.COMMAND: * Search the stack for a string IF SEARCH.FOR = NUL THEN SEARCH.FOR = ANS[2,LONG.LINE] FOUND = FALSE FOR F = START.WORD.SEARCH TO MAX.STACK UNTIL FOUND OR STACK<F> = NUL IF INDEX(STACK<F,4>,SEARCH.FOR,1) # 0 THEN FOUND = TRUE NEXT F IF FOUND THEN START.WORD.SEARCH = F ANS = '.R':F-1 GO EDIT END PRINT BELL:SEARCH.FOR:' event not found' RETURN * PROG.COMMAND: IF ANS = PROG.CHAR OR ANS=PROG.CHAR:PROG.CHAR THEN GO PRINT.PROG.INFO GOSUB PARSE.PROG.COM ANS=PROG.COM:SPC:B.FILE:SPC:B.ITEM *GOSUB UPDATE.STACK BEGIN CASE CASE PROG.COM = '/WW' WRITE PROGRAMS ON HOME.F, PROGRAM.ITEM WP.FILE=HOME.FILE WP.ITEM=PROGRAM.ITEM GOSUB WP.EDIT READ PROGRAMS FROM HOME.F, PROGRAM.ITEM ELSE PROGRAMS = NUL CASE PROG.COM = '/N' GOSUB GET.PROG.NAME IF RTN=13 THEN PROGRAMS<PROG.NUM> = PROG WRITE PROGRAMS ON HOME.F, PROGRAM.ITEM END IF B.FILE # '' THEN OPEN B.FILE TO F THEN OPTIONS='' READ DUMMY FROM F, B.ITEM ELSE PRINT B.ITEM:' not found. Use standard header? ': INPUT YORN IF YORN = 'Y' THEN HEADER=STR('*',80) HEADER<2>='* Program: ':B.ITEM HEADER<3>='* Author : ':USERNAME HEADER<4>='* Date : ':OCONV(DATE(),"D-YMD") ;* E.g. 2017-04-20 HEADER<5>='* Version: 1.0' HEADER<6>='* Comment: Do NOT skip the description' HEADER<7>=STR('*',80) WRITE HEADER ON F, B.ITEM END END CLOSE F WP.FILE=B.FILE WP.ITEM=B.ITEM GOSUB WP.EDIT END ELSE PRINT B.FILE:' is not a file in this account' END END CASE PROG.COM = '/H' OPTIONS='LESS' *CALL CVS.LOG(RTN, B.FILE, B.ITEM, OPTIONS) CASE PROG.COM = '/L' * Load a new program stack STACK.NAME=TRIM(OPTIONS) IF STACK.NAME = '' THEN PROGRAM.ITEM='.STACK.PROGRAM_':USERNAME END ELSE PROGRAM.ITEM='.STACK.PROGRAM_':USERNAME:'_':STACK.NAME END READ PROGRAMS FROM HOME.F, PROGRAM.ITEM ELSE PROGRAMS = NUL SETTINGS<15>=STACK.NAME GOSUB WRITE.INFO CASE PROG.COM = '/LL' * List the different program stacks EXEC.LINE=\SSELECT \:HOME.FILE:\ WITH @ID = ".STACK.PROGRAM]"\ GOSUB EXEC.SUB LOOP READNEXT ID ELSE EXIT PRINT ID REPEAT CASE PROG.COM = '/CI' * Check it in OPTIONS='' *CALL CVS.CHECKIN(RTN, B.FILE, B.ITEM, OPTIONS) CASE PROG.COM = '/D' * CVS Diff OPTIONS='SHOW' *CALL CVS.DIFF(RTN, B.FILE, B.ITEM, OPTIONS) CASE B.FILE[1,1] = '*' OR B.FILE='' NULL ;* Don't do anything with 'comment' or blank entries CASE PROG.COM = '/BR' GOSUB COMPILE EXEC.LINE = B.ITEM GOSUB EXEC.SUB CASE PROG.COM = '/B' GOSUB COMPILE CASE PROG.COM = '/E' OR PROG.COM = '/W' OPEN B.FILE TO F ELSE PRINT 'Cannot open ':B.FILE:BELL;RETURN READ R1 FROM F, B.ITEM ELSE R1=NUL IF PROG.COM = '/E' THEN EXEC.LINE = ED.VERB:SPC:PROG:OPTIONS GOSUB EXEC.SUB END ELSE WP.FILE=B.FILE WP.ITEM=B.ITEM GOSUB WP.EDIT END CLOSE F CASE PROG.COM = '/F' GOSUB BFORMAT CASE PROG.COM = '/R' OPEN B.FILE TO F ELSE PRINT 'Cannot open ':B.FILE:BELL;RETURN READV R FROM F, B.ITEM, 1 ELSE R=NUL CLOSE F EXEC.LINE = B.ITEM:OPTIONS GOSUB EXEC.SUB CASE PROG.COM = '/S' * A slow sort of the program stack READ REC FROM HOME.F, PROGRAM.ITEM ELSE PRINT 'CANNOT READ ':HOME.FILE:' ':PROGRAM.ITEM ; RETURN SORT='AL' ; NEW.REC='' I=DCOUNT(REC,@AM) FOR F=1 TO I L=REC<F> LOCATE L IN NEW.REC BY SORT SETTING POS ELSE NULL INS L BEFORE NEW.REC<POS> NEXT F WRITE NEW.REC ON HOME.F, PROGRAM.ITEM CASE OTHERWISE PRINT 'There is no such PROGRAM command':BELL PRINT '? for help' END CASE RETURN * COMPILE: OPTIONS='' * Check for global catalog READ DUMMY FROM CTLGTB, B.ITEM THEN PRINT B.ITEM:' is cataloged globally' OPTIONS='G' END * * Check for local catalog READ DUMMY FROM CTLG, B.ITEM THEN PRINT B.ITEM:' is cataloged locally' OPTIONS :='L' END * * Check for direct catalog READ DUMMY FROM VOC, B.ITEM THEN IF INDEX(DUMMY<2>,'/CTLG/',1)=0 THEN PRINT B.ITEM:' is cataloged direct to ':DUMMY<2> OPTIONS :='D' END END * IF LEN(OPTIONS) > 1 THEN PRINT "OPTIONS=":OPTIONS PRINT "I do not like green eggs and ham, nor do I like" PRINT "programs cataloged twice. You must fix, Sam" RETURN END * LOOP UNTIL OPTIONS#'' DO PRINT 'Catalog ':B.ITEM:' -- D)irect, L)ocal or G)lobal :': INPUT OPTIONS OPTIONS=UPCASE(OPTIONS) IF OPTIONS = '/' OR OPTIONS='' THEN RETURN * Have to enter D, L or G IF OPTIONS # 'L' AND OPTIONS # 'G' AND OPTIONS # 'D' THEN OPTIONS='' REPEAT * EXEC.LINE = 'BASIC ':B.FILE:' ':B.ITEM:' -D' ;* -D includes symbol table PRINT EXEC.LINE GOSUB EXEC.SUB * BEGIN CASE CASE OPTIONS='G' EXEC.LINE = 'CATALOG ':B.FILE:' ':B.ITEM:' FORCE' PRINT EXEC.LINE GOSUB EXEC.SUB * Global, so remove direct or local pointers READ R FROM VOC, B.ITEM THEN DELETE VOC, B.ITEM CASE OPTIONS='L' EXEC.LINE = 'CATALOG ':PROG:' LOCAL FORCE' PRINT EXEC.LINE GOSUB EXEC.SUB * Object is in CTLG file, so remove from SOURCE file OPEN B.FILE TO F ELSE PRINT 'Cannot open ':B.FILE:BELL;RETURN DELETE F, '_':B.ITEM CLOSE F CASE OPTIONS='D' EXEC.LINE = 'CATALOG ':B.FILE:' ':B.ITEM:' DIRECT FORCE' PRINT EXEC.LINE GOSUB EXEC.SUB END CASE * EXEC.LINE = 'NEWPCODE' ;* This loads a new version of globally cataloged programs GOSUB EXEC.SUB RETURN * PARSE.PROG.COM: PROG.NUM = NUL F = FIELD(ANS,SPC,1);L = LEN(F);I = L LOOP IF NUM(F[I,1]) THEN PROG.NUM = F[I,1]:PROG.NUM ELSE EXIT I = I - 1 REPEAT IF PROG.NUM = NUL THEN PROG.NUM = 1 OPTIONS = ANS[L+1,LONG.LINE] PROG.COM = ANS[1,I] PROG = PROGRAMS<PROG.NUM> B.FILE = FIELD(PROG,SPC,1) B.ITEM = FIELD(PROG,SPC,2) RETURN * GET.PROG.NAME: X = 15;DISP.LEN = 50;LEN = LONG.LINE;ENTRY = PROG PRINT 'Program Name :': GOSUB GET.INPUT ANS = UPCASE(ENTRY) IF RTN # 13 THEN RETURN GOSUB EXPAND.ALIASES IF INDEX(ANS,SPC,1) THEN B.FILE = FIELD(ANS,SPC,1) B.ITEM = FIELD(ANS,SPC,2) PROG=ANS END ELSE IF ANS = NUL THEN B.FILE = NUL ; B.ITEM = NUL ;PROG = NUL END ELSE B.FILE = WORK.FILE ; B.ITEM = ANS ; PROG = B.FILE:SPC:B.ITEM END END RETURN * PRINT.PROG.INFO: I = DCOUNT(PROGRAMS,@AM) PRINT STACK.NAME FOR F = 1 TO I IF PROGRAMS<F> # NUL THEN CH=' ' IF ANS=PROG.CHAR:PROG.CHAR THEN * We want cvs status as well FILE=FIELD(PROGRAMS<F>,' ',1) ITEM=FIELD(PROGRAMS<F>,' ',2) R='' *CALL CVS.STATUS(R,FILE,ITEM,'') STATUS=R<1> WORK.VER=R<2> CVS.VER=R<3> BEGIN CASE CASE STATUS='UPTODATE' CH=' ':WORK.VER'L#9' CASE STATUS='MODIFIED' CH='> ':WORK.VER'L#4':' ':CVS.VER'L#4' CASE 1 CH='! ':SPACE(9) END CASE END PRINT F 'L#5':CH:' ':PROGRAMS<F> END NEXT F RETURN * WRITE.INFO: WRITE STACK ON HOME.F, STACK.ITEM WRITE ALIASES ON HOME.F, ALIAS.ITEM WRITE PROGRAMS ON HOME.F, PROGRAM.ITEM WRITE SETTINGS ON HOME.F, SETTING.ITEM RETURN * UPDATE.STACK: INS ACC:@VM:DATE():@VM:TIME():@VM:ANS BEFORE STACK<1> WRITE STACK ON HOME.F, STACK.ITEM RETURN * WP.EDIT: * Edit a record using a visual editor (e.g. vi, joe or emacs) DICT=0 IF FIELD(WP.FILE,' ',1)='DICT' THEN WP.FILE=FIELD(WP.FILE,' ',2) ; DICT=1 READ REC FROM VOC, WP.FILE ELSE PRINT WP.FILE:' - no VOC item' ; RETURN IF (REC<1>#'DIR' AND REC<1>#'LD') OR DICT THEN * Copy to a temp DIR type and edit there, ignore the race conditions! IF DICT THEN WP.FILE='DICT ':WP.FILE OPEN WP.FILE TO T ELSE PRINT WP.FILE:' - cannot OPEN' ; RETURN READ R FROM T, WP.ITEM ELSE PRINT WP.ITEM:' - not found' ; RETURN WRITE R ON HOLD, WP.ITEM WP.PATH='_HOLD_' DIR.TYPE=0 END ELSE WP.PATH=REC<2> IF REC<1>='LD' THEN IF INDEX(FILE,',',1) THEN WP.PATH=REC<2>:FIELD(FILE,',',2) END ELSE WP.PATH=REC<2>:'/':FIELD(REC<2>,'/',DCOUNT(REC<2>,'/')) END END DIR.TYPE=1 END EXEC.LINE=WP.VERB:' ':WP.PATH:'/':WP.ITEM GOSUB EXEC.SUB IF NOT(DIR.TYPE) THEN * Copy back to original location READ R FROM HOLD, WP.ITEM ELSE R='' WRITE R ON T, WP.ITEM CLOSE T END RETURN * CHECK.FILE: PARAM.CTR=1 ; PROG.FLAG=0 ; FILE.FLAG=0 ; ALL.FLAG=0 LOOP P=FIELD(ANS,' ',PARAM.CTR) UNTIL P='' DO IF P[1,1] = '/' THEN P=P[2,1] BEGIN CASE CASE P='P' PROG.FLAG=1 CASE P='F' FILE.FLAG=1 CASE P='A' ALL.FLAG=1 END CASE END ELSE PROG=P END PARAM.CTR += 1 REPEAT IF PROG.FLAG=0 AND FILE.FLAG=0 THEN ALL.FLAG=1 * IF PROG # '' THEN READ CAT.PTR FROM VOC, PROG ELSE PRINT 'Cannot read VOC ':PROG ; RETURN END ELSE LOOP PRINT 'Enter the program to scan ': INPUT PROG IF PROG = '' OR PROG = '/' THEN RETURN READ CAT.PTR FROM VOC, PROG THEN EXIT PRINT 'Cannot read VOC ':PROG REPEAT END * EXECUTE "!strings ":CAT.PTR<2>:" > $HOME/FILE.LIST" * FILE.LIST='' READ R FROM HOME.F, 'FILE.LIST' THEN I=DCOUNT(R,@AM) FOR F=1 TO I TEST.FILE=R<F> IF FILE.FLAG THEN OPEN TEST.FILE TO DUMMY THEN LOCATE TEST.FILE IN FILE.LIST BY 'AL' SETTING POS ELSE INS TEST.FILE BEFORE FILE.LIST<POS> PRINT 'FILE:':TEST.FILE END CLOSE DUMMY END END IF PROG.FLAG THEN READ DUMMY FROM VOC, TEST.FILE THEN *IF DUMMY = 'C' THEN PRINT 'PROG: ':TEST.FILE IF DUMMY<1>='C' THEN PRINT 'PROG: ':TEST.FILE'L#25':' ':DUMMY<2> END END IF ALL.FLAG THEN PRINT TEST.FILE END NEXT F END RETURN * CONV: * Handy way to check ICONV/OCONV data LOOP PRINT 'Enter mask:': INPUT MASK IF MASK='' OR MASK='/' THEN RETURN PRINT 'Enter data:': INPUT DTA PRINT 'Result:': IF CONV='I' THEN PRINT ICONV(DTA,MASK) ELSE PRINT OCONV(DTA,MASK) REPEAT RETURN * RULER: CRT 'Term width=':TERM.WIDTH FOR F=1 TO TERM.WIDTH C=SEQ(0)+MOD(F,10) IF MOD(F,10) THEN PRINT CHAR(C): ELSE PRINT ' ': NEXT F PRINT SUP.NEXT=0 FOR F=1 TO TERM.WIDTH BEGIN CASE CASE MOD(F+1,10)=0 AND (F+1)/10 > 9 PRINT (F+1)/10: SUP.NEXT=1 CASE MOD(F,10)=0 AND F/10 <= 9 PRINT F/10: SUP.NEXT=0 CASE MOD(F,5)=0 AND NOT(SUP.NEXT) PRINT '+': CASE 1 IF NOT(SUP.NEXT) THEN PRINT ' ': SUP.NEXT=0 END CASE NEXT F PRINT RETURN * PIVOT: * Summarize a field, e.g. PIVOT LS.MASTER LESSOR GROSS.CONTRACT EQUIPMENT.COST FILE=FIELD(ANS," ",2) ; ATB =FIELD(ANS," ",3) ; ATB2=FIELD(ANS," ",4) ; ATB3=FIELD(ANS," ",5) ; ATB4=FIELD(ANS," ",6) OPEN "DICT ":FILE TO DICT ELSE PRINT "DICT ":FILE:' not a filename' ; RETURN READ UREC FROM DICT,"UATB.COUNTER" ELSE UREC=\I\;UREC<2>=\"1"\;UREC<4>=\CNTR\;UREC<5>=\8R\;UREC<6>=\S\ WRITE UREC ON DICT,"UATB.COUNTER" END CLOSE DICT EXEC.LINE = \SORT \:FILE:\ BY \:ATB:\ BREAK-ON \:ATB:\ TOTAL UATB.COUNTER \ IF ATB2 # "" THEN EXEC.LINE := \ TOTAL \:ATB2 IF ATB3 # "" THEN EXEC.LINE := \ TOTAL \:ATB3 IF ATB4 # "" THEN EXEC.LINE := \ TOTAL \:ATB4 EXEC.LINE := \ (IDH \ GOSUB EXEC.SUB RETURN * PROFILE: * Profile a field, e.g. PROFILE LS.MASTER REQ.SIGNATURE.PHONE FILE=FIELD(ANS," ",2) ; ATB =FIELD(ANS," ",3) ; ATBS=FIELD(ANS," ",4,99) EXEC.LINE = \SORT \:FILE:\ WITH \:ATB:\ \:ATB:\ \:ATBS GOSUB EXEC.SUB RETURN * DDD: * Tweak DICT VOC with some pickle juice R =\DICT VOC#AM#@ID#AM#D#AM#0#AM##AM#VOC#AM#30L#AM#S#AM#\ R<-1>=\DICT VOC#AM#F1#AM#D#AM#1#AM##AM##AM#5L#AM#S#AM#\ R<-1>=\DICT VOC#AM#F2#AM#D#AM#2#AM##AM##AM#50L#AM#S#AM#\ OPEN 'DICT VOC' TO FVAR ELSE RETURN FOR F=1 TO DCOUNT(R,@AM) REC=R<F> SWAP "#AM#" WITH @AM IN REC FILE=REC<1> ; DEL REC<1> ITEM=REC<1> ; DEL REC<1> WRITE REC ON FVAR,ITEM NEXT F CLOSE FVAR * * List the DICT, e.g DDD AS.MASTER EQUIP FILE = FIELD(ANS," ",2) SSTR = FIELD(ANS," ",3) FIND.STR="" IF SSTR # "" THEN FIND.STR = \WITH @ID = "[\:SSTR:\]" \ EXEC.LINE=\SORT DICT \:FILE:\ @ID F1 F2 BY F1 BY F2 \:FIND.STR:\ USING DICT VOC (I \ GOSUB EXEC.SUB RETURN * SEARCH.FILE: FILE = FIELD(ANS," ",2) ICTR=3 IF FILE='DICT' THEN ICTR+=1 ; FILE='DICT ':FIELD(ANS," ",3) OPEN FILE TO FVAR ELSE PRINT FILE:' - not found' ; RETURN SSTR = FIELD(ANS," ",ICTR) IF SSTR='' THEN PRINT 'Search for:': ; INPUT SSTR IF SSTR='' THEN RETURN * SSTR1=UPCASE(SSTR) SSTR2=DOWNCASE(SSTR) SSTR3=OCONV(SSTR,"MCT") * DATA SSTR DATA SSTR1 DATA SSTR2 DATA SSTR3 DATA "" EXEC.LINE=\ESEARCH \:FILE:\ WITH @ID # "_]" USING DICT VOC\ ; CAP.ACTIVE=TRUE GOSUB EXEC.SUB * CTR=0 ; FOUND.RECS='' LOOP READNEXT ID ELSE EXIT READ REC FROM FVAR, ID THEN IDX = INDEX(UPCASE(REC),SSTR1,1) IF IDX OR INDEX(UPCASE(ID),SSTR1,1) THEN CTR+=1 FOUND.RECS<1,CTR>=ID IDX -= 10 ; IF IDX < 1 THEN IDX=1 LINE=REC[IDX,45] CONVERT @VM TO "]" IN LINE CONVERT @AM TO "~" IN LINE LINE=OCONV(LINE,"MCP") FOUND.RECS<2,CTR>=LINE END END REPEAT CLOSE FVAR * QUIT = 0 ; CTR=1 ; MAX.ITEMS=DCOUNT(FOUND.RECS<1>,@VM) IF MAX.ITEMS=0 THEN PRINT SSTR:' Not found' ; RETURN HDR=@(-1):\SEARCHING FOR "\:SSTR1:\,\:SSTR2:\,\:SSTR3:\" IN \:FILE PRINT HDR LOOP PRINT CTR'R#4':' ':FOUND.RECS<1,CTR>'L#25':FOUND.RECS<2,CTR>'L#65' CTR+=1 IF CTR/20=INT(CTR/20) THEN GOSUB SEARCH.FILE.PROMPT IF QUIT THEN RETURN REPEAT RETURN * SEARCH.FILE.PROMPT: PRINT ; PRINT 'B)ack, E)dit #, V)iew #, W)P#, /:': INPUT OPTION BEGIN CASE CASE OPTION='B' CTR-=40 IF CTR<1 THEN CTR=1 CASE OPTION[1,1]='E' EXEC.LINE=ED.VERB:\ \:FILE:\ \:FOUND.RECS<1,OPTION[2,99]> GOSUB EXEC.SUB CTR-=20 IF CTR<1 THEN CTR=1 CASE OPTION[1,1]='W' WP.FILE=FILE WP.ITEM=FOUND.RECS<1,OPTION[2,99]> GOSUB WP.EDIT CTR-=20 IF CTR<1 THEN CTR=1 CASE OPTION[1,1]='V' PRINT CS: EXEC.LINE=\CT \:FILE:\ \:FOUND.RECS<1,OPTION[2,99]> GOSUB EXEC.SUB CTR-=20 IF CTR<1 THEN CTR=1 PRINT 'Press ENTER:': INPUT AAA CASE OPTION # '' * ENTER to keep moving forward QUIT=1 END CASE PRINT HDR RETURN * IL10.NED: OPEN '_HOLD_' TO F.HOLD ELSE STOP 201,'_HOLD_' FILE.NAME=FIELD(ANS,' ',2) K.FILE=FIELD(ANS,' ',3) CALL FILE.OPEN(PROGRAM.NAME, FILE.NAME, F.FILE, 'STOP') CALL IDS.READ(R.FILE, F.FILE, K.FILE, 0, 0, BCI.ERROR) IF BCI.ERROR # '' THEN PRINT BCI.ERROR ; R.FILE='' R.ORIG=R.FILE * LOOP PRINT DCOUNT(R.FILE,@AM):' fields in record' PRINT 'Enter E)dit, L)ist, S)ave or Q)uit:': INPUT OPT BEGIN CASE CASE OPT='L' SHOW.BPI=0 ; BPI.XREF='' OPEN 'DATABASE.FILES,IL' TO IL ELSE PRINT 201,'DATABASE.FILES,IL' ; RETURN OPEN 'IL.BPI' TO IL.BPI ELSE PRINT 201,'IL.BPI' ; RETURN READV BPI FROM IL, FILE.NAME, 14 THEN * Sample: Attached to FLOAT.INCOME bpi. N=DCOUNT(BPI,' ') BPI=FIELD(BPI,' ',N-1) READ BPI.LAYOUT FROM IL.BPI, BPI THEN * Sample: EQUATE GROSS.FINANCE TO MASTER(1) SHOW.BPI=1 FOR R=1 TO DCOUNT(BPI.LAYOUT,@AM) L=TRIM(BPI.LAYOUT<R>) IF FIELD(L,' ',1)='EQUATE' THEN FLD.NAME=FIELD(L,' ',2) FLD.POS=FIELD(FIELD(L,' ',4),'(',2) FLD.POS=FIELD(FLD.POS,')',1) BPI.XREF<FLD.POS>=FLD.NAME END NEXT R END ELSE PRINT 'Cannot read BPI:':BPI END END ELSE PRINT 'Cannot get BPI name for:':FILE.NAME END * PRINT @(-1):'FILE:':FILE.NAME:' ITEM:':K.FILE FOR F=1 TO DCOUNT(R.FILE,@AM) R=R.FILE<F> CONVERT @VM TO "|" IN R CONVERT @SVM TO "\" IN R IF SHOW.BPI THEN PRINT F'R#3':' ':BPI.XREF<F>'L#25':'=':R[1,80] END ELSE PRINT F'R#3':' ':R END NEXT F PRINT 'PRESS ENTER:': INPUT AAA CASE OPT='S' CALL IDS.WRITE(R.FILE, F.FILE, K.FILE, 0, 0) PRINT 'Saved. Press ENTER to continue:': R.ORIG=R.FILE INPUT AAA CASE OPT='E' R=R.FILE SWAP CHAR(13):CHAR(10) WITH '||' IN R WRITE R ON F.HOLD, K.FILE EXECUTE \ED _HOLD_ \:K.FILE READ R FROM F.HOLD, K.FILE ELSE R='' SWAP '||' WITH CHAR(13):CHAR(10) IN R IF R # R.FILE THEN PRINT 'Record changed, use S to save' R.FILE=R END DELETE F.HOLD, K.FILE CASE OPT='Q' IF R.FILE#R.ORIG THEN PRINT 'Record changed, are you sure (Y/N):': INPUT YORN IF YORN # 'Y' THEN OPT='' END END CASE UNTIL OPT='Q' DO REPEAT RETURN * BPI: OPEN 'DATABASE.FILES,IL' TO IL ELSE STOP 201,'DATABASE.FILES,IL' OPEN 'IL.BPI' TO IL.BPI ELSE STOP 201,'IL.BPI' BPI=FIELD(ANS,' ',2) IF BPI='' THEN PRINT 'Usage: BPI <name of infolease file|name of BPI>' ; RETURN * Param 2 can be a BPI or a FILENAME READ DUMMY FROM IL.BPI, BPI ELSE READV BPI FROM IL, BPI, 14 ELSE PRINT 'Cannot read DATABASE.FILES,IL',BPI ; RETURN * Sample: Attached to FLOAT.INCOME bpi. N=DCOUNT(BPI,' ') BPI=FIELD(BPI,' ',N-1) READ DUMMY FROM IL.BPI, BPI ELSE PRINT 'Cannot get BPI name' ; RETURN END EXEC.LINE=\AE IL.BPI \:BPI GOSUB EXEC.SUB CLOSE IL CLOSE IL.BPI RETURN * RECALL.SHELL: DATA 1 DATA 1 RECALL=FIELD(ANS,' ',2) IF RECALL # '' THEN DATA RECALL EXECUTE \RECALL.00\ RETURN * FIND.MENU: OPEN "DB.MENUS" TO MENU.F ELSE STOP 201,"DB.MENUS" STR=FIELD(ANS,' ',2) IF STR='' THEN PRINT "Enter menu or program to search for : ": ; INPUT STR IF STR="" OR STR="/" THEN RETURN END STR = OCONV(STR,"MCU") MENU.LIST='' MENU.LIST<1>=1 MENU.LIST<2>=0 MENU.CTR=1 LOOP MENU=MENU.LIST<1,MENU.CTR> PATH=MENU.LIST<2,MENU.CTR> IF MENU='' THEN EXIT GOSUB SEARCH.MENU MENU.CTR+=1 REPEAT CLOSE MENU.F RETURN * SEARCH.MENU: READ R FROM MENU.F, MENU THEN TITLES = OCONVS(R<2>,"MCU") ; PROGS = OCONVS(R<3>,"MCU") ; FLAGS = R<4> ; TYPES = R<5> I = DCOUNT(PROGS,@VM) FOR F = 1 TO I IF INDEX(PROGS<1,F>,STR,1) # 0 OR INDEX(TITLES<1,F>,STR,1) # 0 THEN PRINT MENU"R#5":" ":TITLES<1,F>"L#27":" ":TYPES<1,F>'L#1':" ":PROGS<1,F>"L#50":" ":PATH:',':F END IF FLAGS<1,F>='M' THEN MENU.LIST<1,-1>=PROGS<1,F> ; MENU.LIST<2,-1>=PATH:',':F NEXT F END RETURN * BFORMAT: STAR = '*' ; COLON = ':' ; TAB=CHAR(9) IND = 0 * * These are all commands that may have ELSE or THEN statements * (or blocks) following them SPECIAL.CASES = "GET":@AM:"INPUT":@AM:"LOCATE":@AM:"LOCK":@AM:"MATREAD":@AM:"MATREADU":@AM SPECIAL.CASES := "MATWRITE":@AM:"MATWRITEU":@AM:"OPEN":@AM:"PROCREAD":@AM SPECIAL.CASES := "PROCWRITE":@AM:"READ":@AM:"READNEXT":@AM:"READSEQ":@AM:"READT":@AM:"READU":@AM:"READV":@AM SPECIAL.CASES := "READVU":@AM:"REWIND":@AM:"SEEK":@AM:"WEOF":@AM:"WRITESEQ":@AM SPECIAL.CASES := "WRITET" * DEF.INDENT=2 FORMATS=":":@VM:"BEGIN":@VM:"CASE":@VM:"ELSE":@VM:"END":@VM:"FOR":@VM FORMATS :="IF":@VM:"LOOP":@VM:"NEXT":@VM:"REPEAT":@VM:"RETURN":@VM FORMATS :="THEN":@VM:"UNTIL":@VM:"WHILE" * THIS.IND is the amount this line will be in or outdented FORMATS<2>=0:@VM:0:@VM:-1:@VM:0:@VM:-1:@VM:0:@VM:0:@VM FORMATS<2> :=0:@VM:-1:@VM:-1:@VM:-1:@VM:0:@VM:-1:@VM:-1 * NEXT.IND is the amount that all following lines will be indented FORMATS<3>=1:@VM:2:@VM:0:@VM:1:@VM:-1:@VM:1:@VM:1:@VM FORMATS<3> :=1:@VM:-1:@VM:-1:@VM:-1:@VM:1:@VM:0:@VM:0 FORMATS<4>=DEF.INDENT * OPEN B.FILE TO FI ELSE PRINT 'Cannot open ':B.FILE ; RETURN READ REC FROM FI,B.ITEM ELSE PRINT "CANNOT READ ":B.FILE:" ":B.ITEM ; RETURN *WRITE REC ON FI,B.NAME:".BAK" SWAP CHAR(9) WITH SPACE(DEF.INDENT) IN REC * I = DCOUNT(REC,@AM) IF I < 2 THEN RETURN FOR F = 1 TO I PRINT STAR: L = REC<F> ; NEXT.LINE=REC<F+1> GOSUB FORMAT.LINE REC<F> = L NEXT F WRITE REC ON FI,B.ITEM PRINT STAR ; PRINT I:" lines of ":B.ITEM:" formatted" CLOSE FI RETURN * FORMAT.LINE: L=TRIM(L,' ','B') CONVERT TAB TO "" IN L FIRST.WORD = FIELD(L,SPC,1) LEN.FIRST.WORD = LEN(FIRST.WORD) LOCATE FIRST.WORD IN SPECIAL.CASES BY 'AL' SETTING SPECIAL ELSE SPECIAL = 0 NUM.SPACES = COUNT(L,SPC) + 1 LAST.WORD = FIELD(L,SPC,NUM.SPACES) NEXT.TO.LAST.WORD = FIELD(L,SPC,NUM.SPACES-1) THIS.IND = 0 NEXT.IND = 0 BEGIN CASE CASE L="" L="*" ;* Makes pasting code around easier with no blank lines CASE FIRST.WORD[LEN.FIRST.WORD,1] = COLON OR NUM(FIRST.WORD) * A label IND = 0 LOCATE COLON IN FORMATS<1> SETTING POS ELSE POS = 0 THIS.IND = FORMATS<2,POS> NEXT.IND = FORMATS<3,POS> CASE FIRST.WORD = "IF" LOCATE FIRST.WORD IN FORMATS<1> SETTING POS ELSE POS = 0 IF LAST.WORD = "THEN" THEN THIS.IND = FORMATS<2,POS> NEXT.IND = FORMATS<3,POS> END CASE FIRST.WORD = "END" SECOND.WORD = FIELD(L,SPC,2) IF SECOND.WORD = "ELSE" THEN LOCATE "ELSE" IN FORMATS<1> SETTING POS ELSE POS = 0 THIS.IND = -FORMATS<3,POS> NEXT.IND = FORMATS<2,POS> END ELSE IF SECOND.WORD = "CASE" THEN LOCATE "BEGIN" IN FORMATS<1> SETTING POS ELSE POS = 0 THIS.IND = -FORMATS<3,POS> NEXT.IND = -FORMATS<3,POS> END ELSE LOCATE FIRST.WORD IN FORMATS<1> SETTING POS ELSE POS = 0 THIS.IND = FORMATS<2,POS> NEXT.IND = FORMATS<3,POS> END END CASE SPECIAL * Find last word - skip until a space IF LAST.WORD = "ELSE" OR LAST.WORD = "THEN" THEN LOCATE LAST.WORD IN FORMATS<1> SETTING POS ELSE POS = 0 THIS.IND = FORMATS<2,POS> NEXT.IND = FORMATS<3,POS> END CASE FIRST.WORD = "FOR" AND NEXT.TO.LAST.WORD = "NEXT" * FOR loop on one line means do nothing CASE FIRST.WORD = "RETURN" AND TRIM(NEXT.LINE) # "*" * RETURN without a blank line means do nothing CASE 1 LOCATE FIRST.WORD IN FORMATS<1> SETTING POS ELSE POS = 0 IF POS # 0 THEN THIS.IND = FORMATS<2,POS> NEXT.IND = FORMATS<3,POS> END END CASE L = SPACE((IND+THIS.IND)*DEF.INDENT):L *L = STR(TAB,IND+THIS.IND):L ;* In my misguided youth, tabs seemed cool IND = IND + NEXT.IND RETURN * GET.LINE: * SUBROUTINE GET.LINE(X,LEN,DISP.LEN,XXDATA,RTN) * X = X POS * LEN = MAX ALLOWED LENGTH * DISP.LEN = MAX DISPLAYED LEN * XXDATA = ON INPUT VARIABLE XXDATA * = ON OUTPUT RETURNED STRING * RTN = SEQ(CHAR PRESSED TO EXIT) * ----------------- * Important globals * CP = Cursor Position, Y coordinate on the screen 0 -> DISP.LEN * CH.PTR = Pointer into string being edited 1 -> LEN * POS = Pointer to first char currently displayed 1 -> LEN * ASC.CH = The numeric value of the key just entered * ECHO OFF XXDATA = ENTRY MODE = INSERT ; TEMP.XXDATA = XXDATA BASE = @(X) ; MASK = 'L#':DISP.LEN PRINT BASE: CURR.LEN = LEN(XXDATA) GOSUB GO.END RTN='' * LOOP PRINT @(X+CP): CH=IN() ASC.CH = SEQ(CH) EXIT.FLAG=FALSE BEGIN CASE CASE ASC.CH = 1 GOSUB GO.BEGIN CASE ASC.CH = 2 GOSUB LEFT CASE ASC.CH = 4 GOSUB DEL CASE ASC.CH = 5 GOSUB GO.END CASE ASC.CH = 6 GOSUB RIGHT CASE ASC.CH = 8 GOSUB BACK CASE ASC.CH = 9 GOSUB AUTO.COMPLETE CASE ASC.CH = 10 GOSUB DEL.TO.END CASE ASC.CH = 13 EXIT.FLAG = TRUE RTN=13 CASE ASC.CH = 14 RTN=2 EXIT.FLAG=TRUE CASE ASC.CH = 16 RTN=1 EXIT.FLAG=TRUE CASE ASC.CH = 18 GOSUB INSRT CASE ASC.CH = PG.UP.KEY EXIT.FLAG=TRUE RTN=PG.UP.KEY CASE ASC.CH = PG.DOWN.KEY EXIT.FLAG=TRUE RTN=PG.DOWN.KEY CASE ASC.CH = 23 GOSUB DELETE.WORD CASE ASC.CH = 24 GOSUB FORWARD.WORD CASE ASC.CH = 7 OR ASC.CH = 12 IF ASC.CH = 12 THEN PRINT @(-1): XXDATA = '' EXIT.FLAG=TRUE RTN=13 CASE ASC.CH = 26 GOSUB BACK.WORD CASE ASC.CH = 27 GOSUB ESC.KEY CASE ASC.CH < 27 PRINT @(0):ASC.CH: CASE ASC.CH = 127 GOSUB BACK CASE 1 GOSUB ORD END CASE CURR.LEN = LEN(XXDATA) UNTIL EXIT.FLAG DO REPEAT IF XXDATA[CURR.LEN,1] = SPC THEN XXDATA = XXDATA[1,CURR.LEN-1] ECHO ON ; PRINT BASE:XXDATA MASK ENTRY=XXDATA RETURN * AUTO.COMPLETE: * Grab the current word and figure out max completion WORD='' ; WORD.CTR='' CH.PTR.TMP=CH.PTR-1 LOOP C=XXDATA[CH.PTR.TMP,1] UNTIL C=' ' OR CH.PTR.TMP=0 DO WORD=C:WORD CH.PTR.TMP-=1 REPEAT * * Count which word we're on - there are different auto-completes for 1, 2 or 3+ IF CH.PTR.TMP=0 THEN WORD.CTR=1 ;* Trying to autocomplete a command WORD='CMD_':WORD END ELSE CH.PTR.TMP-=1 LOOP C=XXDATA[CH.PTR.TMP,1] UNTIL C=' ' OR CH.PTR.TMP=0 DO CH.PTR.TMP-=1 REPEAT IF CH.PTR.TMP=0 THEN WORD.CTR=2 ;* Trying to autocomplete a filename WORD='FILE_':WORD END ELSE WORD.CTR=3 ;* Trying to autocomplete from a dictionary FNAME=FIELD(XXDATA,' ',2) WORD='DICT-':FNAME:'_':WORD END END * IF XXDATA[CURR.LEN,1] = SPC THEN XXDATA = XXDATA[1,CURR.LEN-1] CURR.LEN=LEN(XXDATA) * LOOP READ AC.LIST FROM AC, WORD ELSE CRT BEEP: ; RETURN * Ok, we have some auto-completion candidates, need to do two things * 1) Check to see if we're done, return if so, or * 2) List top 20 possible completions if there are more than one IF DCOUNT(AC.LIST<1>,@VM)=1 AND DCOUNT(AC.LIST<2,1>,@SVM)=1 THEN NEWF=AC.LIST<2>[LEN(WORD)+1,999] XXDATA:=NEWF:' ' PRINT BASE:XXDATA:EOS: CURR.LEN=LEN(XXDATA) GOSUB GO.END RETURN END ELSE CRT CS:@(0,0):BON:PROMPT.DISP:BOFF:XXDATA NUM.CP=DCOUNT(AC.LIST<1>,@VM) IF NUM.CP>20 THEN NUM.CP=20 FOR CP=1 TO NUM.CP CRT CP'R#2':') ':FIELD(AC.LIST<1,CP>,'_',2,99):' (': NUM.CP2=DCOUNT(AC.LIST<2,CP>,@SVM) NUM.CP2.MAX=NUM.CP2 IF NUM.CP2>3 THEN NUM.CP2=3 FOR CP2=1 TO NUM.CP2 CRT FIELD(AC.LIST<2,CP,CP2>,'_',2,99): IF CP2<NUM.CP2 THEN CRT ',': NEXT CP2 IF NUM.CP2 # NUM.CP2.MAX THEN CRT ' [+':NUM.CP2.MAX-NUM.CP2:']': CRT ')' NEXT CP WORD.CONTINUE=IN() ASC.VAL = SEQ(WORD.CONTINUE) CRT CS:@(0,0):BON:PROMPT.DISP:BOFF:XXDATA: BEGIN CASE CASE ASC.VAL=13 OR ASC.VAL=27 CURR.LEN=LEN(XXDATA) GOSUB GO.END RETURN CASE ASC.VAL>=32 AND ASC.VAL<127 WORD:=WORD.CONTINUE XXDATA:=WORD.CONTINUE END CASE END REPEAT RETURN * ORD: * Ordinary key pressed IF CH.PTR # LEN+1 THEN IF MODE = INSERT THEN IF CURR.LEN = LEN THEN PRINT BEEP: GOTO SKIP1 END ELSE XXDATA = XXDATA[1,CH.PTR-1]:CH:XXDATA[CH.PTR,CURR.LEN] END END ELSE XXDATA = XXDATA[1,CH.PTR-1]:CH:XXDATA[CH.PTR+1,CURR.LEN] END CH.PTR = CH.PTR + 1 IF CP # DISP.LEN THEN PRINT @(X+CP):CH: IF MODE = INSERT THEN PRINT XXDATA[CH.PTR,DISP.LEN-CP-1]: END CP = CP + 1 END ELSE POS = POS + 1 PRINT BASE:XXDATA[POS,DISP.LEN] MASK: END END ELSE PRINT BEEP: END SKIP1: RETURN * RIGHT: * There are 3 situations here - * 1 We're pressing the right arrow thru existing text (CH.PTR = CURR.LEN) * 2 We've typed text and are at the end when we press right (CH.PTR > CURR.LEN) * 3 We're in the middle of text, pressing the right arrow (CH.PTR < CURR.LEN) IF CH.PTR < LEN THEN IF CH.PTR > CURR.LEN THEN PRINT BEEP: ; GOTO SKIP2 IF CH.PTR = CURR.LEN THEN * If the last char is not a space make it one IF XXDATA[CURR.LEN,1] # SPC THEN XXDATA = XXDATA:SPC IF CP # DISP.LEN THEN PRINT @(X+CP+1):SPC: CURR.LEN = CURR.LEN + 1 END ELSE PRINT BEEP: GOTO SKIP2 END END CH.PTR = CH.PTR + 1 IF CP # DISP.LEN THEN * We're not at the end of display so just move the cursor CP = CP + 1 END ELSE * We are at the end of the display so leave cursor where * it is and scroll through line POS = POS + 1 PRINT BASE:XXDATA[POS,DISP.LEN] MASK: END END ELSE PRINT BEEP: END SKIP2: RETURN * FORWARD.WORD: * Tab key pressed - move forwards a word IF CH.PTR >= CURR.LEN THEN PRINT BEEP: END ELSE LOOP CH.PTR = CH.PTR + 1 CP = CP + 1 UNTIL XXDATA[CH.PTR,1] = SPC OR CH.PTR = CURR.LEN DO REPEAT IF CH.PTR # CURR.LEN THEN LOOP CH.PTR = CH.PTR + 1 CP = CP + 1 UNTIL XXDATA[CH.PTR,1] # SPC OR CH.PTR = CURR.LEN DO REPEAT END IF CP > DISP.LEN THEN CP = DISP.LEN POS = CH.PTR - DISP.LEN PRINT BASE:XXDATA[POS,DISP.LEN] MASK: END END RETURN * LEFT: * If we're not at the start of data, move left IF CH.PTR # 1 THEN CH.PTR = CH.PTR - 1 IF CP # 0 THEN * We're not at the start of the display so just move the cursor CP = CP - 1 END ELSE * We are at the start of the display so leave cursor and scroll POS = POS - 1 PRINT BASE:XXDATA[POS,DISP.LEN] MASK: END END ELSE PRINT BEEP: END RETURN * DEL: * Delete the character at the cursor and redisplay from this point XXDATA = XXDATA[1,CH.PTR-1]:XXDATA[CH.PTR+1,CURR.LEN] CURR.LEN = CURR.LEN - 1 PRINT BASE:XXDATA[POS,DISP.LEN] MASK: RETURN * BACK: * Backspace key pressed IF CH.PTR # 1 THEN CH.PTR = CH.PTR - 1 XXDATA = XXDATA[1,CH.PTR-1]:XXDATA[CH.PTR+1,CURR.LEN] CURR.LEN = CURR.LEN - 1 IF CP # 0 THEN CP = CP - 1 END ELSE POS = POS - 1 END PRINT BASE:XXDATA[POS,DISP.LEN] MASK: END ELSE PRINT BEEP: END RETURN * INSRT: * Toggle between insert and replace modes MODE = -MODE RETURN * ESC.KEY: * ESC pressed, or extended key - wyse50 arrow keys * Get next char of extended command ALLOW = 0 EXT.KEY=IN() EXT = SEQ(EXT.KEY) EXT.KEY = OCONV(EXT.KEY,'MCU') BEGIN CASE CASE EXT.KEY = 'D' GOSUB DELETE.WORD CASE EXT.KEY = '[' OR EXT.KEY = 'O' EXT.KEY=IN() BEGIN CASE CASE EXT.KEY = 'C' GOSUB RIGHT CASE EXT.KEY = 'D' GOSUB LEFT CASE EXT.KEY = 'A' RTN=1 EXIT.FLAG=TRUE CASE EXT.KEY = 'B' RTN=2 EXIT.FLAG=TRUE END CASE END CASE RETURN ; * From ESC key * BACK.WORD: * Shift tab pressed - go back a word IF CH.PTR = 1 THEN PRINT BEEP: END ELSE * 2 situations - either we're in a word already or * we're at the start of a word * If in a word - loop to the start of the word * otherwise skip spaces, and then move to start of word IF XXDATA[CH.PTR-1,1] # SPC THEN LOOP UNTIL XXDATA[CH.PTR-1,1] = SPC OR CH.PTR = 1 DO CH.PTR = CH.PTR - 1 CP = CP - 1 REPEAT END ELSE * Skip spaces LOOP UNTIL XXDATA[CH.PTR-1,1] # SPC OR CH.PTR = 1 DO CH.PTR = CH.PTR - 1 CP = CP - 1 REPEAT IF CH.PTR > 1 THEN * At word end - move to start of word LOOP UNTIL XXDATA[CH.PTR-1,1] = SPC OR CH.PTR = 1 DO CH.PTR = CH.PTR - 1 CP = CP - 1 REPEAT END END IF CP < 0 THEN CP = 0 POS = CH.PTR PRINT BASE:XXDATA[POS,DISP.LEN] MASK: END END RETURN * DEL.TO.END: * Delete from cursor to end of line IF CH.PTR = 1 THEN XXDATA = '' CP = 0 POS = 1 END ELSE XXDATA = XXDATA[1,CH.PTR-1] END CURR.LEN = LEN(XXDATA) PRINT BASE:XXDATA[POS,DISP.LEN] MASK: RETURN * DELETE.WORD: * Delete to space at right of cursor IF CH.PTR >= CURR.LEN THEN PRINT BEEP: END ELSE C = CH.PTR LOOP C = C + 1 UNTIL XXDATA[C,1] = SPC OR C = CURR.LEN DO REPEAT XXDATA = XXDATA[1,CH.PTR-1]:XXDATA[C+1,CURR.LEN] CURR.LEN = CURR.LEN - C + CH.PTR - 1 PRINT BASE:XXDATA[POS,DISP.LEN] MASK: END RETURN * GO.BEGIN: * Go to the start of data and redisplay CP = 0 CH.PTR = 1 POS = 1 PRINT BASE:XXDATA MASK: RETURN * GO.END: * Move to the end of data and redisplay IF XXDATA[CURR.LEN,1] # SPC THEN XXDATA = XXDATA:SPC CURR.LEN = CURR.LEN + 1 END IF CURR.LEN < DISP.LEN THEN CP = CURR.LEN - 1 POS = 1 END ELSE CP = DISP.LEN - 1 POS = CURR.LEN - DISP.LEN + 1 END CH.PTR = CURR.LEN PRINT BASE:XXDATA[POS,DISP.LEN] MASK: RETURN * ATB.FIND: OPEN "IL.TB.CHNG.LOG" TO IL.TB.CHNG.LOG ELSE STOP 201,"IL.TB.CHNG.LOG" OPEN "IL.CHANGE.LOG.INDEX" TO IL.CHANGE.LOG.INDEX ELSE STOP 201,"IL.CHANGE.LOG.INDEX" OPEN "REV.ATB.LOG" TO REV.ATB.LOG ELSE STOP 201,"REV.ATB.LOG" OPEN "HELP.TEXT.USA" TO HELP.TEXT.USA ELSE STOP 201,"HELP.TEXT.USA" MSK="L#22" ATB = FIELD(ANS," ",2) * IF ATB="" THEN PRINT "ENTER ATB NAME: ": ; INPUT ATB IF ATB="" OR ATB="/" THEN RETURN END * READ AREC FROM REV.ATB.LOG,ATB ELSE ATBREC="" ; TEST="" EXEC.LINE=\SSELECT REV.ATB.LOG = "[\:ATB:\]"\ GOSUB EXEC.SUB CTR=0 LOOP READNEXT ID ELSE EXIT CTR+=1 PRINT CTR "L#4":ID ATBREC<CTR>=ID IF MOD(CTR,23)=0 THEN PRINT "[ENTER]": ; INPUT TEST IF TEST = "/" THEN EXIT REPEAT PRINT PRINT "Enter choice (1-":CTR:"): ": ; INPUT CHOICE IF CHOICE="" OR CHOICE="/" THEN RETURN ATB=ATBREC<CHOICE> IF ATB="" THEN RETURN READ AREC FROM REV.ATB.LOG,ATB ELSE PRINT 'Not found' ; RETURN END * MAXV=DCOUNT(AREC<5>,@VM) FNAMES="" FOR J=1 TO MAXV IF AREC<5,J>[1,2] # "BK" THEN FNAMES :=AREC<5,J>:",":AREC<6,J>:" " NEXT J * READV CKEY FROM IL.CHANGE.LOG.INDEX,AREC<24>,1 ELSE CKEY="" READ CHNG_REC FROM IL.TB.CHNG.LOG,CKEY ELSE CHNG_REC="" READ HELP.TEXT FROM HELP.TEXT.USA,ATB ELSE HELP.TEXT= " NOT FOUND" CONVERT "~" TO "" IN HELP.TEXT DEP=AREC<16> CONVERT @VM TO "," IN DEP PRINT ATB PRINT PRINT "IL.BPI" MSK :AREC<1> PRINT "FILE(S)" MSK :FNAMES PRINT "FIELD" MSK :AREC<2> PRINT "CHANGE LOG INDEX" MSK :AREC<24> PRINT "CHANGE LOG KEY" MSK :CKEY PRINT "TYPE" MSK :AREC<3> PRINT "MASK" MSK :AREC<10> PRINT "S/MV" MSK :AREC<14> PRINT "CONTROLLING/DEPENDENT" MSK:AREC<15> PRINT "SUB/MASTER FIELDS" MSK :DEP PRINT "CHG DESCRIPTION" MSK :CHNG_REC<1> IF AREC<32> # "" THEN PRINT "COMMENTS" MSK :AREC<32> PRINT END PRINT MAXV=DCOUNT(HELP.TEXT<2>,@VM) FOR J=1 TO MAXV PRINT HELP.TEXT<2,J> NEXT J RETURN * GET.TERM.WIDTH: T='/tmp/':@LOGNAME:'.term' EXEC.LINE=\!tput cols > \:T ;* Always returns 80 if you capture, so use tmp file CAP.ACTIVE=FALSE GOSUB EXEC.SUB EXEC.LINE=\!cat \:T CAP.ACTIVE=TRUE GOSUB EXEC.SUB TERM.WIDTH=EXEC.CAP<1> EXEC.LINE=\!rm \:T GOSUB EXEC.SUB EXEC.LINE=\TERM \:TERM.WIDTH ; GOSUB EXEC.SUB RETURN * PICKLE: PICKLE.LIST='' * IF FIELD(ANS,' ',2)='DICT' THEN FILE='DICT ':FIELD(ANS,' ',3) ITEM=FIELD(ANS,' ',4) END ELSE FILE=FIELD(ANS,' ',2) ITEM=FIELD(ANS,' ',3) END OPEN FILE TO FVAR ELSE PRINT 'Cannot open ':FILE RETURN END READ REC FROM FVAR, ITEM ELSE PRINT 'Cannot read ':FILE:' ':ITEM RETURN END BLOB='R=""' IF FILE[1,5]='DICT ' THEN DEL REC<9> ; DEL REC<8> ;* Avoid CD probs INS ITEM BEFORE REC<1> INS FILE BEFORE REC<1> SWAP @AM WITH '#AM#' IN REC ; SWAP @VM WITH '#VM#' IN REC SWAP @SVM WITH '#SVM#' IN REC ; SWAP '\' WITH '#134#' IN REC BLOB<-1>=\S=''\ LOOP T=REC[1,70] BLOB<-1>='S:=\':T:'\' REC=REC[71,LEN(REC)] UNTIL LEN(REC)=0 DO REPEAT BLOB<-1>='R<-1>=S' BLOB<-1>='*' * * Write out basic code that when run will recreate the record BLOB<-1>='FOR F=1 TO DCOUNT(R,@AM)' BLOB<-1>=' REC=R<F>' BLOB<-1>=' SWAP "#AM#" WITH @AM IN REC ; SWAP "#VM#" WITH @VM IN REC' BLOB<-1>=' SWAP "#SVM#" WITH @SVM IN REC ; SWAP "#134#" WITH "\" IN REC' BLOB<-1>=' FILE=REC<1> ; DEL REC<1>' BLOB<-1>=' ITEM=REC<1> ; DEL REC<1>' BLOB<-1>=' PRINT FILE:" ":ITEM:' BLOB<-1>=' OPEN FILE TO FVAR ELSE STOP 201, FILE' BLOB<-1>=' WRITE REC ON FVAR,ITEM ; PRINT "*"' BLOB<-1>=' CLOSE FVAR' BLOB<-1>='NEXT F' FOR I=1 TO DCOUNT(BLOB,@AM) PRINT BLOB<I> NEXT I RETURN * SETTINGS: PRINT CS: PRINT 'COMMAND.SEP = ':SETTINGS<1> PRINT 'STACK.CHAR = ':SETTINGS<2> PRINT 'PROG.CHAR = ':SETTINGS<3> PRINT 'MAX.STACK = ':SETTINGS<4> PRINT 'WP.VERB = ':SETTINGS<5> PRINT 'ED.VERB = ':SETTINGS<6> PRINT 'STAMP.STRING = ':SETTINGS<7> PRINT 'GET.LINE.FLAG= ':SETTINGS<8> PRINT 'WORK.FILE = ':SETTINGS<9> PRINT 'MCU.ON = ':SETTINGS<10> PRINT 'STARTUP = ':SETTINGS<11> PRINT 'PROMT = ':SETTINGS<12> PRINT 'X.DISP = ':SETTINGS<13> PRINT 'DEF.SHELL = ':SETTINGS<14> PRINT ; PRINT 'Hit ENTER to accept the current default, / to Cancel' X=18 LEN=30 DISP.LEN=30 * PRINT PRINT 'The command seperator is used to run multiple commands from one entry' PRINT 'E.g. COUNT VOC ; COUNT VOC WITH F1 = "C" will run both count commands' PRINT 'Current value:':SETTINGS<1> PRINT 'COMMAND SEPERATOR:': INPUT ENTRY IF ENTRY = '/' THEN RETURN IF ENTRY = '' THEN ENTRY=SETTINGS<1> SETTINGS<1>=ENTRY * PRINT PRINT 'The stack character is what to prefix command stack operations with' PRINT 'E.g. .L or .R87 or .D uses a stack character of "."' PRINT 'Current value:':SETTINGS<2> PRINT 'STACK CHAR :': INPUT ENTRY IF ENTRY = '/' THEN RETURN IF ENTRY = '' THEN ENTRY=SETTINGS<2> SETTINGS<2>=ENTRY * PRINT PRINT 'The program character is what to prefix program stack operations with' PRINT 'E.g. /W2 or /B3 or /L uses a program character of "/"' PRINT 'Current value:':SETTINGS<3> PRINT 'PROG CHAR :': INPUT ENTRY IF ENTRY = '/' THEN RETURN IF ENTRY = '' THEN ENTRY=SETTINGS<3> SETTINGS<3>=ENTRY * PRINT PRINT 'Max lines is the maximum number of lines to hold in the command stack' PRINT 'E.g. 9999' PRINT 'Current value:':SETTINGS<4> PRINT 'MAX # LINES :': INPUT ENTRY IF ENTRY = '/' THEN RETURN IF ENTRY = '' THEN ENTRY=SETTINGS<4> SETTINGS<4>=ENTRY * PRINT PRINT 'Screen editor is what command to run to edit a program visually' PRINT 'E.g. VI or !emacs or !/home/dsiroot/joe' PRINT 'Current value:':SETTINGS<5> PRINT 'SCREEN EDITOR :': INPUT ENTRY IF ENTRY = '/' THEN RETURN IF ENTRY = '' THEN ENTRY=SETTINGS<5> SETTINGS<5>=ENTRY * PRINT PRINT 'Line editor is what command to run to edit a program' PRINT 'E.g. AE or ED' PRINT 'Current value:':SETTINGS<6> PRINT 'LINE EDITOR :': INPUT ENTRY IF ENTRY = '/' THEN RETURN IF ENTRY = '' THEN ENTRY=SETTINGS<6> SETTINGS<6>=ENTRY * PRINT PRINT 'Header string is not currently used' PRINT 'HEADER STRING :':SETTINGS<7> * PRINT PRINT 'Use enhanced input commands, allowing editing with arrow keys' PRINT 'Or just use plain INPUT command' PRINT 'Current value:':SETTINGS<8> PRINT 'USE GET.LINE SUBR:': INPUT ENTRY IF ENTRY = '/' THEN RETURN IF ENTRY = '' THEN ENTRY=SETTINGS<8> IF ENTRY='Y' OR ENTRY='1' THEN ENTRY='1' ELSE ENTRY='0' SETTINGS<8>=ENTRY * PRINT PRINT 'Default file for basic programs if none specifed' PRINT 'E.g. BP' PRINT 'Current value:':SETTINGS<9> PRINT 'WORK FILE :': INPUT ENTRY IF ENTRY = '/' THEN RETURN IF ENTRY = '' THEN ENTRY=SETTINGS<9> SETTINGS<9>=ENTRY * PRINT PRINT 'Convert commands to upper case before running' PRINT 'E.g. 1 or 0, Y or N' PRINT 'Current value:':SETTINGS<10> PRINT 'CONVERT TO UCASE :': INPUT ENTRY IF ENTRY = '/' THEN RETURN IF ENTRY = '' THEN ENTRY=SETTINGS<9> IF ENTRY='Y' OR ENTRY='1' THEN ENTRY='1' ELSE ENTRY='0' SETTINGS<9>=ENTRY * PRINT PRINT 'Command to run when stack first starts' PRINT 'E.g. LISTUSER ; WHO' PRINT 'Current value:':SETTINGS<11> PRINT 'STARTUP COMMAND :': INPUT ENTRY IF ENTRY = '/' THEN RETURN IF ENTRY = '' THEN ENTRY=SETTINGS<11> SETTINGS<11>=ENTRY * PRINT PRINT 'Default Prompt to display, use .P to change this' PRINT 'PROMPT :':SETTINGS<12> PRINT PRINT 'Adjustment for input position (if you use #R, then CR+LF is inserted,' PRINT 'and an adjustment of -2 is needed. Use .P to change this' PRINT 'X DISP FOR PROMPT:':SETTINGS<13> * PRINT PRINT 'Default shell to use with !command' PRINT 'E.g. ksh, bash, /usr/bin/ksh, /opt/freeware/bin/bash' PRINT 'Current value:':SETTINGS<14> PRINT 'SHELL :': INPUT ENTRY IF ENTRY = '/' THEN RETURN IF ENTRY = '' THEN ENTRY=SETTINGS<14> SETTINGS<14>=ENTRY * WRITE SETTINGS ON HOME.F, SETTING.ITEM RETURN * LISTA: OPEN 'ACC' TO ACC.F ELSE STOP 201,'ACC' OPEN 'INFO.STATUS' TO INFO.STATUS ELSE STOP 201,'INFO.STATUS' SELECT ACC.F USER.LIST='' LOOP READNEXT PORT ELSE EXIT READ REC FROM ACC.F, PORT THEN READ MENU FROM INFO.STATUS, PORT'R%3' ELSE MENU='TCL' MENU=MENU<DCOUNT(MENU,@AM)> ;* Show the last item USER=REC<5> DATE=REC<2> TIME=REC<3> LOCATE PORT IN USER.LIST<4> BY 'AR' SETTING POS ELSE NULL INS USER BEFORE USER.LIST<1,POS> INS DATE BEFORE USER.LIST<2,POS> INS TIME BEFORE USER.LIST<3,POS> INS PORT BEFORE USER.LIST<4,POS> INS MENU BEFORE USER.LIST<5,POS> END REPEAT *GET.LOCKS LOCK.LIST='' FLIST='' FLIST<-1>='AS.FEATURE' FLIST<-1>='AS.MASTER' FLIST<-1>='AUVB.PARAMETER' FLIST<-1>='BQ.PARAMETER' FLIST<-1>='CS.MASTER' FLIST<-1>='DATA.MASKING.PARAMETER' FLIST<-1>='DB.RECORD.LOCKS' FLIST<-1>='DE.MASTER' FLIST<-1>='FIELD.SECURITY' FLIST<-1>='INFO-SYSTEM' FLIST<-1>='IT.INSURANCE' FLIST<-1>='IT.INSURANCE.AGENT' FLIST<-1>='LS.BANK.DEPOSIT' FLIST<-1>='LS.DISCOUNT.PACKAGE' FLIST<-1>='LS.DISCOUNT.WORKSHEET' FLIST<-1>='LS.GL.HISTORY' FLIST<-1>='LS.MASTER' FLIST<-1>='LS.POST.DATED.CHECK' FLIST<-1>='LS.SUPER.QUOTE' FLIST<-1>='LS.WK.CASH' FLIST<-1>='MISC' FLIST<-1>='MM.GROUP' FLIST<-1>='PARAMETER' FLIST<-1>='PROCESSOR.PARAMETER' FLIST<-1>='TRED.FUTURE.PROC.DATES' FLIST<-1>='USERS.MENUS' FLIST<-1>='WL.FOLLOW.UP' FLIST<-1>='WL.PARAMETER' * FOR G=1 TO DCOUNT(FLIST,@AM) FILE='DB.RECORD.LOCKS,':FLIST<G> OPEN FILE TO FVAR THEN SELECT FVAR LOOP READNEXT LOCK.ID ELSE EXIT READ REC FROM FVAR, LOCK.ID THEN PORT=REC<1> DATE=REC<2> TIME=REC<3> USER=REC<4> LOCK.LIST<1,-1>=FILE LOCK.LIST<2,-1>=LOCK.ID LOCK.LIST<3,-1>=PORT LOCK.LIST<4,-1>=DATE LOCK.LIST<5,-1>=TIME LOCK.LIST<6,-1>=USER LOCATE PORT IN USER.LIST<4> SETTING POS THEN USER.LIST<6,POS>=LOCK.ID:',':USER.LIST<6,POS> END END REPEAT CLOSE FVAR END NEXT G * PRINT @(-1):'USERS' PRINT PRINT 'Port':' ':'User''L#12':' ':'Date''L#10':' ':'Time''L#8':' ': PRINT 'Time On''L#8':' ':'Menu''L#30':' ':'L' PRINT '----':' ':STR('-',12):' ':STR('-',10):' ':STR('-',8):' ': PRINT STR('-',8):' ':STR('-',30):' ':'-' FOR F=1 TO DCOUNT(USER.LIST<1>,@VM) DUR=TIME()-USER.LIST<3,F> IF DUR<0 THEN DUR+=86400 ;* Roll over midnight, add back number of seconds in a day PRINT USER.LIST<4,F>'R#4':' ': PRINT USER.LIST<1,F>'L#12':' ': PRINT USER.LIST<2,F>'D4/':' ': PRINT USER.LIST<3,F>'MTS':' ': PRINT DUR'MTS':' ': PRINT USER.LIST<5,F>'L#30':' ': IF USER.LIST<6,F>#'' THEN PRINT '*' ELSE PRINT ' ' NEXT F * PRINT PRINT 'LOCKS' PRINT PRINT 'Table''L#20':' ':'ID''L#25':' ':'Port''L#4':' ': PRINT 'Date''L#5':' ':'Time''L#5':' ':'User''L#15' PRINT STR('-',20):' ':STR('-',25):' ':STR('-',4):' ': PRINT STR('-',5):' ':STR('-',5):' ':STR('-',15) FOR L=1 TO DCOUNT(LOCK.LIST<1>,@VM) FILE=FIELD(LOCK.LIST<1,L>,',',2) PRINT FILE'L#20':' ':LOCK.LIST<2,L>'L#25':' ':LOCK.LIST<3,L>'R#4':' ': PRINT (LOCK.LIST<4,L>'D4/')[1,5]:' ':LOCK.LIST<5,L>'MT':' ':LOCK.LIST<6,L>'L#15' NEXT L * CLOSE ACC.F CLOSE INFO.STATUS * RETURN * SEARCH.BY.EXAMPLE: * Calculate all possible ATB's for an example contract @ID=ID IF FILE='' OR @ID='' THEN PRINT 'Usage: SE <FNAME> <ID>' RETURN END OPEN FILE TO F ELSE PRINT 'Cannot open ':FILE ; RETURN OPEN "DICT ":FILE TO @DICT ELSE PRINT 'Cannot open DICT ':FILE ; RETURN READ @RECORD FROM F, @ID ELSE PRINT 'Cannot read ':@ID:' in ':FILE ; RETURN CLOSE F OUTPUT='' EXECUTE \SSELECT DICT \:FILE:\ WITH F1 = "I" USING DICT VOC\ LOOP READNEXT FLD ELSE EXIT PRINT FLD:'=': VAL=CALCULATE(FLD) PRINT VAL IF @CONV # '' THEN VAL=OCONV(VAL,@CONV) *OUTPUT<-1>=FLD:'=':VAL REPEAT WRITE OUTPUT ON VOC, 'OUTPUT.TMP' EXECUTE \AE VOC OUTPUT.TMP\ RETURN * IL10.XREF: FILE.NAME = FIELD(ANS,' ',2) FIELD.NAME = FIELD(ANS,' ',3) SELECT.HDR=\BPI,FILE_NAME,FIELD_NAME,STRING_POS,TABLE_NAME,COLUMN_NAME,VALUE_TYPE,FIELD_TYPE\ SELECT.COMMAND = \SELECT\ SELECT.COMMAND := \ BPI, FILE_NAME, FIELD_NAME, STRING_POS, TABLE_NAME, COLUMN_NAME, VALUE_TYPE, FIELD_TYPE\ IF INDEX(FILE.NAME,'%',1) THEN SELECT.COMMAND := \ FROM METADATA_FIELDS WHERE (FILE_NAME LIKE '\:FILE.NAME:\' OR TABLE_NAME LIKE '\:FILE.NAME:\')\ END ELSE SELECT.COMMAND := \ FROM METADATA_FIELDS WHERE (FILE_NAME = '\:FILE.NAME:\' OR TABLE_NAME = '\:FILE.NAME:\')\ END IF FIELD.NAME # '' THEN SELECT.COMMAND :=\ AND FIELD_NAME LIKE '%\:FIELD.NAME:\%'\ SELECT.COMMAND := \ ORDER BY FILE_NAME, STRING_POS\ * GOSUB IL10.SEL RETURN * IL10.AF: FLD = FIELD(ANS,' ',2) SELECT.HDR=\BPI,FILE_NAME,FIELD_NAME,MV_POS,TABLE_NAME,COLUMN_NAME,MV/S,TYPE,LEN,SCALE\ SELECT.COMMAND = \SELECT BPI,FILE_NAME,FIELD_NAME,STRING_POS,TABLE_NAME,COLUMN_NAME,VALUE_TYPE,FIELD_TYPE,FIELD_LENGTH,SCALE\ SELECT.COMMAND :=\ FROM METADATA_FIELDS\ SELECT.COMMAND :=\ WHERE FIELD_NAME LIKE '%\:FLD:\%' OR COLUMN_NAME LIKE '%\:FLD:\%'\ GOSUB IL10.SEL RETURN * IL10.DESC: TABLE = FIELD(ANS,' ',2) SELECT.HDR=\COL,COLUMN_NAME,DATA_TYPE\ SELECT.COMMAND = \SELECT ORDINAL_POSITION, COLUMN_NAME, DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS\ SELECT.COMMAND:= \ WHERE TABLE_NAME = '\:TABLE:\'\ GOSUB IL10.SEL RETURN * IL10.NSEL: PRMT=1 EXECLINE='SELECT ':FIELD(ANS,' ',2,999) CALL EXECUTE.SELECT.SUB(EXECLINE,ERR.MSG,1,'',0,SELECTED.LIST,1,'',0,'',0,0) CTR=0 LOOP READNEXT ID FROM SELECTED.LIST ELSE EXIT CTR+=1 CRT CTR'R#6':') ':ID IF CTR/20=INT(CTR/20) AND PRMT THEN CRT ':': INPUT AAA IF AAA = '/' OR AAA='Q' THEN STOP IF AAA = 'N' THEN PRMT=0 END REPEAT RETURN * SQL.SEL: SELECT.HDR='' SELECT.COMMAND=FIELD(ANS,' ',2,200) GOSUB IL10.SEL RETURN * SQL.FILE: SELECT.HDR='' FILE=FIELD(ANS,' ',2) ;* Spaces in file name are not supported OSREAD SELECT.COMMAND FROM FILE THEN CONVERT @AM TO ' ' IN SELECT.COMMAND SWAP CHAR(13):CHAR(10) WITH ' ' IN SELECT.COMMAND GOSUB IL10.SEL END ELSE CRT FILE:' not found' END RETURN * SQL.SEL.LIST: LIST=FIELD(ANS,' ',2) SELECT.COMMAND=FIELD(ANS,' ',3,200) PRINT SELECT.COMMAND PARAM='' CALL IDS.EXECUTE.ANSI.SQL(SELECT.COMMAND,PARAM,'','',KEY.LIST) CALL CONVERT.LIST(KEY.LIST) EXECUTE \SAVE.LIST \:LIST PASSLIST KEY.LIST RETURN * IL10.SEL: PARAM='' CONVERT ',' TO @VM IN SELECT.HDR PRINT SELECT.COMMAND CALL IDS.EXECUTE.ANSI.SQL(SELECT.COMMAND,PARAM,'','',KEY.LIST) *SUBROUTINE IDS.EXECUTE.ANSI.SQL.ERROR(SQL.STRING, PARAMS, COLUMNS, TYPES, RESULTS.ARRAY, ERROR, OFFSET, LIMIT, SORT.COLUMN, ENHANCE, ALTER.SESSION,TRANSFER.CONTRACT) CALL IDS.EXECUTE.ANSI.SQL.ERROR(SELECT.COMMAND, PARAM, '', '', KEY.LIST, ERR, '', '', '', '0', '','') DISP.MAX=DCOUNT(KEY.LIST,@AM) PRINT DISP.MAX:' items selected, ERR=':ERR IF DISP.MAX=0 THEN RETURN * * Get widths W='' IF SELECT.HDR # '' THEN INS SELECT.HDR BEFORE KEY.LIST<1> DISP.MAX+=1 END FOR R=1 TO DISP.MAX FOR C=1 TO DCOUNT(KEY.LIST<R>,@VM) L=LEN(KEY.LIST<R,C>) IF L > W<C> THEN W<C>=L NEXT C NEXT R * * Print the header DISP.START=1 IF SELECT.HDR # '' THEN DISP.START=2 FOR C=1 TO DCOUNT(KEY.LIST<1>,@VM) PRINT FMT(KEY.LIST<1,C>,'L#':W<C>):' ': NEXT C PRINT * FOR C=1 TO DCOUNT(KEY.LIST<1>,@VM) PRINT STR('-',W<C>):' ': NEXT C PRINT END * Now the data FOR R=DISP.START TO DISP.MAX IF SELECT.HDR = '' THEN CRT R,: FOR C=1 TO DCOUNT(KEY.LIST<R>,@VM) PRINT FMT(KEY.LIST<R,C>,'L#':W<C>):' ': NEXT C PRINT NEXT R RETURN * LIST.PARAM: P='' P<1,-1>=STR('-', 18) ; P<2,-1>=STR('-',33) ; P<3,-1>=STR('-',30) P<1,-1>='Key Prefix' ; P<2,-1>='InfoLease Table' ; P<3,-1>='RDBMS Table' P<1,-1>=STR('-', 18) ; P<2,-1>=STR('-',33) ; P<3,-1>=STR('-',30) P<1,-1>='*00' ; P<2,-1>='Lessor Parameters' ; P<3,-1>='LESSOR_NF' P<1,-1>='*00A' ; P<2,-1>='Temporary Lessor' ; P<3,-1>='TEMP_LESSOR_NF' P<1,-1>='*00B' ; P<2,-1>='Additional Lessor' ; P<3,-1>='ADDL_LESSOR_NF' P<1,-1>='*00GL' ; P<2,-1>='Multiple Bookset' ; P<3,-1>='MULTIPLE_BOOKSET_NF' P<1,-1>='*00UD' ; P<2,-1>='Lessor User-Defined' ; P<3,-1>='LESSOR_USER_NF' P<1,-1>='*ACH' ; P<2,-1>='Lessor ACH Flags' ; P<3,-1>='LESSOR_ACH_FLAGS_NF' P<1,-1>='*ADVICE*' ; P<2,-1>='Advice Follow-up' ; P<3,-1>='ADVICE_FOLLOW_UP_NF' P<1,-1>='*COMMISSION' ; P<2,-1>='Commission' ; P<3,-1>='COMMISSION_NF' P<1,-1>='*WARNING.MESSAGES' ; P<2,-1>='Lessor Warning Messages' ; P<3,-1>='LESSOR_WARNING_MESSAGES_NF' P<1,-1>='[Lessor Id]' ; P<2,-1>='Lessor Address' ; P<3,-1>='LS_ADDRESS_NF' P<1,-1>='00*00' ; P<2,-1>='Lease System Parameters' ; P<3,-1>='PARAMETER_NF' P<1,-1>='00*00A' ; P<2,-1>='Temporary Lease System Params' ; P<3,-1>='TEMP_PARAMETER_NF' P<1,-1>='00*00B' ; P<2,-1>='Additional Lease System Params' ; P<3,-1>='ADDL_PARAMETER_NF' P<1,-1>='00*00IRR' ; P<2,-1>='IRR Parameter' ; P<3,-1>='IRR_PARAMETER_NF' P<1,-1>='00*00RPT' ; P<2,-1>='Report Parameter' ; P<3,-1>='RPT_PARAMETER_NF' P<1,-1>='10*' ; P<2,-1>='Personnel' ; P<3,-1>='PERSONNEL_INFO_NF' P<1,-1>='12*' ; P<2,-1>='Office' ; P<3,-1>='OFFICE_DATA_NF' P<1,-1>='13*' ; P<2,-1>='Vendor/Dealer' ; P<3,-1>='PARAM_ADDRESS_NF' P<1,-1>='13APA*' ; P<2,-1>='Additional Vendor/Dealer Address' ; P<3,-1>='ADDL_PARAM_ADDRESS_NF' P<1,-1>='14*' ; P<2,-1>='Reason Code' ; P<3,-1>='REASON_CODE_NF' P<1,-1>='15*' ; P<2,-1>='Collateral Code' ; P<3,-1>='TB_COLLATERAL_NF' P<1,-1>='16*' ; P<2,-1>='Equipment Category' ; P<3,-1>='EQUIP_CODE_DEFAULTS_NF' P<1,-1>='17*' ; P<2,-1>='Tax Description' ; P<3,-1>='TAX_DESC_TBL_NF' P<1,-1>='18*' ; P<2,-1>='Property Tax Status' ; P<3,-1>='PROP_TAX_STATUS_TBL_NF' P<1,-1>='19*' ; P<2,-1>='Region' ; P<3,-1>='REGION_TABLE_NF' P<1,-1>='20*' ; P<2,-1>='Remit To' ; P<3,-1>='REMIT_ADDRESS_NF' P<1,-1>='21*' ; P<2,-1>='Base Rate Indicator' ; P<3,-1>='FLOAT_BANK_NF' P<1,-1>='22*' ; P<2,-1>='Broker Address' ; P<3,-1>='BROKER_TABLE_NF' P<1,-1>='23*' ; P<2,-1>='General Ledger Account' ; P<3,-1>='GL_ACCT_TABLE_NF' P<1,-1>='24*' ; P<2,-1>='Branch' ; P<3,-1>='BRANCH_DATA_NF' P<1,-1>='26*' ; P<2,-1>='Department' ; P<3,-1>='DEPARTMENT_NF' P<1,-1>='27*' ; P<2,-1>='Business' ; P<3,-1>='TB_BUSINESS_NF' P<1,-1>='28*' ; P<2,-1>='Program Type' ; P<3,-1>='PROG_TYPE_DEFAULTS_NF' P<1,-1>='29*' ; P<2,-1>='Payment Plan' ; P<3,-1>='TB_PAYMENT_PLAN_NF' P<1,-1>='30*' ; P<2,-1>='Promotion' ; P<3,-1>='PROMOTION_TBL_NF' P<1,-1>='31*' ; P<2,-1>='Account Type' ; P<3,-1>='TB_ACCT_TYPE_NF' P<1,-1>='32*' ; P<2,-1>='Business Type' ; P<3,-1>='TB_BUSINESS_TYPE_NF' P<1,-1>='33*' ; P<2,-1>='Application Status' ; P<3,-1>='TB_STATUS_NF' P<1,-1>='34*' ; P<2,-1>='Disposition Payment Type' ; P<3,-1>='TB_DISP_PAYMENT_TYPE_NF' P<1,-1>='35*' ; P<2,-1>='Disposition/Inventory' ; P<3,-1>='DISP_INVENT_TABLE_NF' P<1,-1>='36*' ; P<2,-1>='Bank Additional User-Defined' ; P<3,-1>='AUS_BANKS_NF' P<1,-1>='39*' ; P<2,-1>='Product Line' ; P<3,-1>='PROD_LINE_DEFAULTS_NF' P<1,-1>='40*' ; P<2,-1>='Insurance Type' ; P<3,-1>='TB_INSURANCE_TYPE_NF' P<1,-1>='41*' ; P<2,-1>='Insurance Status' ; P<3,-1>='TB_INSURANCE_STATUS_NF' P<1,-1>='42*' ; P<2,-1>='Contract Status' ; P<3,-1>='CONTRACT_STATUS_INFO_NF' P<1,-1>='43*' ; P<2,-1>='Guaranteed Residual' ; P<3,-1>='TB_GUARANTEED_RESIDUAL_NF' P<1,-1>='45*' ; P<2,-1>='Country Code' ; P<3,-1>='COUNTRY_CODES_NF' P<1,-1>='ACTIVITY.DE*' ; P<2,-1>='Activity (Inv. Interface)' ; P<3,-1>='INV_INT_DATA_ELEMENTS_NF' P<1,-1>='ADDL.BUYOUT*' ; P<2,-1>='Additional Buyout Info' ; P<3,-1>='ADDL_BUYOUT_DEFAULT_NF' P<1,-1>='ADJ*' ; P<2,-1>='Adjustment Code' ; P<3,-1>='ADJUSTMENT_CODE_TBL_NF' P<1,-1>='ADMIN*' ; P<2,-1>='Administrative Code' ; P<3,-1>='TB_ADMINISTRATIVE_CODE_NF' P<1,-1>='AP.INTERFACE*1' ; P<2,-1>='API Parameters' ; P<3,-1>='API_PARAMETERS_NF' P<1,-1>='ASSET.DE*' ; P<2,-1>='Asset (Inv. Interface)' ; P<3,-1>='INV_INT_DATA_ELEMENTS_NF' P<1,-1>='ASSET.STATUS*' ; P<2,-1>='Asset Status' ; P<3,-1>='TB_ASSET_STATUS_NF' P<1,-1>='ASSOCIATION*' ; P<2,-1>='Association' ; P<3,-1>='ASSOC_REL_PARTY_NF' P<1,-1>='BANK*' ; P<2,-1>='Bank Address' ; P<3,-1>='BANK_ADDRESS_NF' P<1,-1>='BANK.ADDL*' ; P<2,-1>='Additional Bank Address' ; P<3,-1>='ADDL_BANK_ADDRESS_NF' P<1,-1>='BI.TYPE*' ; P<2,-1>='Blended Income Type' ; P<3,-1>='TB_BLENDED_INCOME_TYPE_NF' P<1,-1>='BID*' ; P<2,-1>='Blended Income Defaults' ; P<3,-1>='BLENDED_INCOME_DEF_NF' P<1,-1>='BLENDED.INCOME*' ; P<2,-1>='Blended Income Parameter' ; P<3,-1>='BLENDED_INCOME_TBL_NF' P<1,-1>='BUS.PLAN*' ; P<2,-1>='Business Plan' ; P<3,-1>='BUS_PLAN_DEFAULTS_NF' P<1,-1>='BUS.SEG*' ; P<2,-1>='Business Segment' ; P<3,-1>='BUS_SEGMENT_NF' P<1,-1>='BUYOUT*' ; P<2,-1>='Buyout Parameters' ; P<3,-1>='BUYOUT_DEFAULT_NF' P<1,-1>='CADDR.DE*' ; P<2,-1>='Customer Address (Inv. Interface)' ; P<3,-1>='INV_INT_DATA_ELEMENTS_NF' P<1,-1>='CCA*' ; P<2,-1>='CCA Class' ; P<3,-1>='CCA_CLASS_DEPR_NF' P<1,-1>='CHECK.TYPE*' ; P<2,-1>='Check Type' ; P<3,-1>='CHECK_TYPE_NF' P<1,-1>='CHRG.DE*' ; P<2,-1>='Charge Info (Inv. Interface)' ; P<3,-1>='INV_INT_DATA_ELEMENTS_NF' P<1,-1>='CHRG.TYPE*' ; P<2,-1>='Open Item Charge Types' ; P<3,-1>='CHARGE_TYPE_TABLE_NF' P<1,-1>='CHRG.TYPE.INDEX*' ; P<2,-1>='Open Item Charge Type Indexes' ; P<3,-1>='CHARGE_TYPE_INDEX_NF' P<1,-1>='CNTC.DE*' ; P<2,-1>='Contact (Inv. Interface)' ; P<3,-1>='INV_INT_DATA_ELEMENTS_NF' P<1,-1>='CURRENCY*' ; P<2,-1>='Currency Code' ; P<3,-1>='CURRENCY_CODES_NF' P<1,-1>='DEALER.DISTRICT*' ; P<2,-1>='Dealer District' ; P<3,-1>='TB_DEALER_DISTRICT_NF' P<1,-1>='DEALER.PARAM*' ; P<2,-1>='Dealer Parameter' ; P<3,-1>='DEALER_PARAM_NF' P<1,-1>='DEALER.REGION*' ; P<2,-1>='Dealer Region' ; P<3,-1>='TB_DEALER_REGION_NF' P<1,-1>='DEALER.SALESMAN*' ; P<2,-1>='Dealer Salesman' ; P<3,-1>='DLR_SALESMAN_NF' P<1,-1>='DEALER.SERIES*' ; P<2,-1>='Dealer Series' ; P<3,-1>='TB_DEALER_SERIES_NF' P<1,-1>='DEALER.STATUS*' ; P<2,-1>='Dealer Status' ; P<3,-1>='DEALER_STATUS_NF' P<1,-1>='DLR.RECOURSE*' ; P<2,-1>='Dealer Recourse' ; P<3,-1>='TB_DEALER_RECOURSE_NF' P<1,-1>='EARLY.TERM.OPTION*' ; P<2,-1>='Early Term Option' ; P<3,-1>='TB_EARLY_TERM_OPTION_NF' P<1,-1>='ER*' ; P<2,-1>='Exchange Rate' ; P<3,-1>='EXCHANGE_RATE_NF' P<1,-1>='FAC*' ; P<2,-1>='Void Factura Reason' ; P<3,-1>='TB_VOID_FACTURA_REASON_NF' P<1,-1>='FIN.CLASS*' ; P<2,-1>='Finance Class' ; P<3,-1>='TB_FINANCE_CLASS_NF' P<1,-1>='FIN.PLAN*' ; P<2,-1>='Finance Plan' ; P<3,-1>='TB_FINANCE_PLAN_NF' P<1,-1>='FOLLOW.UP*' ; P<2,-1>='Follow Up' ; P<3,-1>='FOLLOW_UP_CODES_NF' P<1,-1>='GL.LINK.INDEX*' ; P<2,-1>='General Ledger Link Index' ; P<3,-1>='TB_GL_LINK_INDEX_NF' P<1,-1>='GROUP.MISC.CODES*' ; P<2,-1>='Group Misc GL Codes' ; P<3,-1>='GROUP_MISC_CODES_NF' P<1,-1>='HOLIDAY.TBL*' ; P<2,-1>='Holiday/Weekend' ; P<3,-1>='HOLIDAY_WEEKEND_NF' P<1,-1>='IDC.DESC*' ; P<2,-1>='IDC Description' ; P<3,-1>='TB_IDC_DESC_NF' P<1,-1>='INVOICE.FORMAT*' ; P<2,-1>='Invoice Format' ; P<3,-1>='INVOICE_FORMAT_TABLE_NF' P<1,-1>='IP*' ; P<2,-1>='Insurance Parameter' ; P<3,-1>='INSURANCE_PARAMETER_NF' P<1,-1>='IRS.CAT*' ; P<2,-1>='IRS Category/Tax' ; P<3,-1>='IRS_CAT_DEFAULTS_NF' P<1,-1>='ITP' ; P<2,-1>='Insurance Tape Parameter' ; P<3,-1>='INS_TAPE_PARAMETER_NF' P<1,-1>='L.NATIONALITY*' ; P<2,-1>='Nationality' ; P<3,-1>='TB_NATIONALITY_NF' P<1,-1>='LANG*' ; P<2,-1>='Language' ; P<3,-1>='TB_LANGUAGE_NF' P<1,-1>='LEGAL.S*' ; P<2,-1>='Legal Status' ; P<3,-1>='TB_LEGAL_STATUS_NF' P<1,-1>='LESSEE.CONTACT*' ; P<2,-1>='Lessee Contact Permitted' ; P<3,-1>='TB_LESSEE_CONTACT_PERMIT_NF' P<1,-1>='LESSOR.SUB*' ; P<2,-1>='Lessor Subsidiary' ; P<3,-1>='SUBSIDIARY_ADDRESS_NF' P<1,-1>='LKE.POOL*' ; P<2,-1>='Like Kind Exchange Pool' ; P<3,-1>='TB_LIKE_KIND_EXCHANGE_PO_NF' P<1,-1>='LOCAL.SIC.CODE*' ; P<2,-1>='Local SIC Code' ; P<3,-1>='LOCAL_SIC_CODE_TBL_NF' P<1,-1>='LOCKBOX.PARAMS' ; P<2,-1>='Lockbox Parameters' ; P<3,-1>='LOCKBOX_PARAMETERS_NF' P<1,-1>='MILE.CAT*' ; P<2,-1>='Mileage Category' ; P<3,-1>='TB_MILEAGE_CATEGORY_NF' P<1,-1>='MISC.PARAM*' ; P<2,-1>='Miscellaneous Parameters' ; P<3,-1>='MISC_PARAM_DEFAULTS_NF' P<1,-1>='MMR.ASSET.DE*' ; P<2,-1>='MMR Asset (Inv. Interface)' ; P<3,-1>='INV_INT_DATA_ELEMENTS_NF' P<1,-1>='MMR.ASSET.RATE.DE*' ; P<2,-1>='MMR Asset Rate (Inv. Interface)' ; P<3,-1>='INV_INT_DATA_ELEMENTS_NF' P<1,-1>='MMR.CHRG.DE*' ; P<2,-1>='MMR Charge (Inv. Interface)' ; P<3,-1>='INV_INT_DATA_ELEMENTS_NF' P<1,-1>='NJS.FLAG' ; P<2,-1>='NJS Flag' ; P<3,-1>='NJS_FLAG_NF' P<1,-1>='PAYMENT.STATUS*' ; P<2,-1>='Payment Status' ; P<3,-1>='TB_PAYMENT_STATUS_NF' P<1,-1>='PAYMENT.TYPE*' ; P<2,-1>='Payment Type' ; P<3,-1>='PYMT_TYPE_NF' P<1,-1>='PENDING.CODE*' ; P<2,-1>='Pending Code' ; P<3,-1>='PENDING_CODE_TBL_NF' P<1,-1>='POLICY.STATUS*' ; P<2,-1>='Policy Status' ; P<3,-1>='TB_POLICY_STATUS_NF' P<1,-1>='PROGRAM.CONTROL*' ; P<2,-1>='Program Control' ; P<3,-1>='TB_PROGRAM_CONTROL_NF' P<1,-1>='PUR.OPT*' ; P<2,-1>='Purchase Option' ; P<3,-1>='PURCHASE_OPTION_TABLE_NF' P<1,-1>='PURPOSE.LOAN*' ; P<2,-1>='Purpose Of Loan' ; P<3,-1>='TB_PURPOSE_OF_LOAN_NF' P<1,-1>='PUT.TO*' ; P<2,-1>='Put To' ; P<3,-1>='TB_PUT_TO_NF' P<1,-1>='QUOTE.BUYOUT*' ; P<2,-1>='Quote Buyout' ; P<3,-1>='QUOTE_BUYOUT_TBL_NF' P<1,-1>='RCPT*' ; P<2,-1>='Void Receipt Reason' ; P<3,-1>='TB_VOID_RECEIPT_REASON_NF' P<1,-1>='RECOURSE*' ; P<2,-1>='Recourse' ; P<3,-1>='TB_RECOURSE_CODE_NF' P<1,-1>='RECOVERY.STATUS*' ; P<2,-1>='Recovery Status' ; P<3,-1>='TB_RECOVERY_STATUS_NF' P<1,-1>='RELATIONSHIP*' ; P<2,-1>='Relationship' ; P<3,-1>='RELATIONSHIP_DATA_NF' P<1,-1>='REM.PUR.OPTION*' ; P<2,-1>='Remarketing Purchase Option' ; P<3,-1>='TB_REMARKETING_PURCHASE_NF' P<1,-1>='RENEWAL.OPTION*' ; P<2,-1>='Renewal Option' ; P<3,-1>='RENEWAL_OPTION_NF' P<1,-1>='REPO.STATUS*' ; P<2,-1>='Repossession Status' ; P<3,-1>='REPOSSESSION_CODE_NF' P<1,-1>='RESERVE*' ; P<2,-1>='Reserve Code' ; P<3,-1>='TB_RESERVE_CODE_NF' P<1,-1>='RESIDUAL.GUAR*' ; P<2,-1>='Residual Guarantee' ; P<3,-1>='TB_RESIDUAL_GUARANTEE_NF' P<1,-1>='RESIDUAL.OWNER*' ; P<2,-1>='Residual Owner' ; P<3,-1>='TB_RESIDUAL_OWNER_NF' P<1,-1>='RESIDUAL.SHARING*' ; P<2,-1>='Residual Sharing' ; P<3,-1>='TB_RESIDUAL_SHARING_NF' P<1,-1>='RESTOCKING.FEE*' ; P<2,-1>='Restocking Fee Obligation' ; P<3,-1>='TB_RESTOCK_FEE_OBLIGATIO_NF' P<1,-1>='RETURN.COSTS.PD*' ; P<2,-1>='Return Costs Paid' ; P<3,-1>='TB_RETURN_COSTS_PAID_NF' P<1,-1>='REVS.PT*' ; P<2,-1>='REVS Plate Type' ; P<3,-1>='TB_REVS_PLATE_TYPE_NF' P<1,-1>='REVS.ST*' ; P<2,-1>='REVS State' ; P<3,-1>='TB_REVS_STATE_NF' P<1,-1>='SCAN.LINE.DE*' ; P<2,-1>='Scan Line (Inv. Interface)' ; P<3,-1>='INV_INT_DATA_ELEMENTS_NF' P<1,-1>='SCORE.DECISION*' ; P<2,-1>='Credit Score Decision' ; P<3,-1>='TB_CREDIT_SCORE_DECISION_NF' P<1,-1>='SCORE.STATUS*' ; P<2,-1>='Credit Score Status' ; P<3,-1>='CREDIT_SCORE_STATUS_NF' P<1,-1>='SCORING.CODE*' ; P<2,-1>='Scoring Code' ; P<3,-1>='SCORING_CODE_NF' P<1,-1>='SEC.PARTY*' ; P<2,-1>='Secure Party' ; P<3,-1>='LESSOR_SEC_PARTY_NF' P<1,-1>='SOURCE*' ; P<2,-1>='Source' ; P<3,-1>='TB_SOURCE_NF' P<1,-1>='SPECIAL.INST*' ; P<2,-1>='Special Instructions' ; P<3,-1>='TB_SPECIAL_INSTRUCTIONS_NF' P<1,-1>='SPLIT.DE*' ; P<2,-1>='Invoice Interface Data Elements' ; P<3,-1>='INV_INT_DATA_ELEMENTS_NF' P<1,-1>='SSP' ; P<2,-1>='System Security' ; P<3,-1>='SC_SECURE_PARAM_NF' P<1,-1>='UCC.STATE*' ; P<2,-1>='Filing State' ; P<3,-1>='FILING_STATE_NF' P<1,-1>='UCC.STATUS*' ; P<2,-1>='Filing Status' ; P<3,-1>='FILING_STATUS_TABLE_NF' P<1,-1>='UCC.TITLE.CODE*' ; P<2,-1>='Filing Code' ; P<3,-1>='FILING_CODE_NF' P<1,-1>='UK.POOL*' ; P<2,-1>='UK Pool' ; P<3,-1>='UK_POOL_NUM_NF' P<1,-1>='USG.ASSET.DE*' ; P<2,-1>='Usage Asset (Inv. Interface)' ; P<3,-1>='INV_INT_DATA_ELEMENTS_NF' P<1,-1>='USG.CHRG.DE*' ; P<2,-1>='Usage Charge (Inv. Interface)' ; P<3,-1>='INV_INT_DATA_ELEMENTS_NF' P<1,-1>='VLMAKE*' ; P<2,-1>='Vehicle Make' ; P<3,-1>='TB_VEHICLE_MAKE_NF' P<1,-1>='VLMODEL*' ; P<2,-1>='Vehicle Model' ; P<3,-1>='TB_VEHICLE_MODEL_NF' P<1,-1>='VLOPT*' ; P<2,-1>='Vehicle Option' ; P<3,-1>='TB_VEHICLE_OPTION_NF' P<1,-1>='WAREHOUSE*' ; P<2,-1>='Warehouse Location' ; P<3,-1>='TB_WAREHOUSE_LOCATION_NF' P<1,-1>='WHOLESALE.PLAN*' ; P<2,-1>='Wholesale Plan' ; P<3,-1>='TB_WHOLESALE_PLAN_NF' P<1,-1>='WL.FOLLOW-UP.CODE*' ; P<2,-1>='Worklist Follow-Up Codes' ; P<3,-1>='WORKLIST_FOLLOW_UP_CODES_NF' P<1,-1>='WP.PARAM' ; P<2,-1>='Word Processing' ; P<3,-1>='WP_PARAM_NF' P<1,-1>=STR('-', 18) ; P<2,-1>=STR('-',33) ; P<3,-1>=STR('-',30) FOR F=1 TO DCOUNT(P<1>,@VM) PRINT '|':P<1,F>'L#18':'|':P<2,F>'L#33':'|':P<3,F>'L#30':'|' NEXT F RETURN * BUILD.AC: * Check for a DICT request IF FIELD(ANS,' ',2)='DICT' THEN DICT=FIELD(ANS,' ',3) OPEN 'DICT',DICT TO DVAR ELSE CRT 'Cannot open DICT':DICT ; RETURN SELECT DVAR ID.LIST='' LOOP READNEXT ID ELSE EXIT READ R FROM DVAR, ID ELSE CONTINUE IF R<1>='D' OR R<1>='I' OR R<1>='V' THEN ID.LIST<-1>='DICT-':DICT:'_':ID END REPEAT GOSUB ADD.TO.AC RETURN END * * Build auto-complete list of VOC commands CLEARFILE AC L1='' ; L2='' * EXECUTE \SELECT VOC WITH F1 = "C" "V"\ RTNLIST L1 ID.LIST='' LOOP READNEXT ID FROM L1 ELSE EXIT READ R FROM VOC, ID ELSE CONTINUE ID.LIST<-1>='CMD_':ID REPEAT GOSUB ADD.TO.AC * * Build auto-complete list for filenames * EXECUTE \SELECT VOC WITH F1 = "F" "LF" "DIR" "LD" AND WITH @ID # "TMP]"\ RTNLIST L1 ID.LIST='' LOOP READNEXT ID FROM L1 ELSE EXIT READ R FROM VOC, ID ELSE CONTINUE ID.LIST<-1>='FILE_':ID IF R<1>='LF' OR R<1>='LD' THEN * Multi-level file or dir, dive deeper E=\SELECT DICT \:ID:\ WITH @ID = "@]" AND WITH F1 = "LF" "LD" USING DICT VOC\ *CRT E EXECUTE E RTNLIST L2 CAPTURING DUMMY LOOP READNEXT ID2 FROM L2 ELSE EXIT ID2=ID:',':ID2[2,99] ID.LIST<-1>='FILE_':ID2 REPEAT END REPEAT GOSUB ADD.TO.AC RETURN * ADD.TO.AC: NUM.ITEMS=DCOUNT(ID.LIST,@AM) CRT NUM.ITEMS:' ITEMS' FOR I=1 TO NUM.ITEMS ID=ID.LIST<I> L=LEN(ID) FOR C=1 TO LEN(ID) PRE=ID[1,C] READ NODE FROM AC, PRE ELSE NODE='' * Now insert pointers to one level down PTR=ID[1,C+1] LOCATE PTR IN NODE<1> BY 'AL' SETTING POS THEN LOCATE ID IN NODE<2,POS> BY 'AL' SETTING POS2 ELSE NULL INS ID BEFORE NODE<2,POS, POS2> END ELSE INS PTR BEFORE NODE<1,POS> INS ID BEFORE NODE<2,POS> END WRITE NODE ON AC, PRE NEXT C NEXT I RETURN *