Table of Contents

FSEEDIT

Table Of Contents

  • [00005] FULL SCREEN EDITOR AND SCREEN MGT FACILITY.
  • [00124] DSPLCOD - CONVERT ONE CHARACTER TO LOWER CASE OR DISPLAY.
  • [00147] SQUELCH - SUPPRESS LOWER-CASE FOR LINE IMAGE.
  • [00171] HALT - SET WARNING MESSAGE AND FLAG COMMAND SHUTDOWN.
  • [00192] CHKVICTIM - CHECK FOR SMFEX-IMPOSED SESSION ABORT.
  • [00212] CONCAT - CONCATENATE TWO INTERNAL LINE IMAGES.
  • [00239] NOPOP - POP POSITION STACK WITHOUT USING IT.
  • [00262] WINDOLIN - FORCE ADDRESS INTO FILE IMAGE.
  • [00285] WINDOPOS - VALIDATE POSITION WITHIN FILE.
  • [00309] FWDNUM - MOVE FORWARDS UNTIL NUMBERED LINE FOUND.
  • [00345] BAKNUM - BACK UP IN FILE UNTIL NUMBERED LINE.
  • [00378] POSN - POSITION TO LINE WITH DESIRED SEQUENCE NUMBER.
  • [00424] FITNUM - CHECK SEQUENCING GAP AND SELECT INCREMENT.
  • [00498] SPLICE - SPLICE PORTIONS OF LINES IN WORKFILE.
  • [00539] MAKEPAGE - COMPUTE BOUNDS FOR SECTION OF FILE.
  • [00591] SETMARK - SET BOTH OR SECOND MARKER REGISTERS.
  • [00655] FORCEFILE - GET FILE INTO SOME BRACKET.
  • [00690] REL2ABS - CONVERT RELATIVE LINE ADDRESS TO ABSOLUTE.
  • [00713] CHECKFILPTR - CONVERT DIRECTORY ADDRESS TO BRACKET.
  • [00802] TOKEN - LOOK FOR NEXT SYNTAX ELEMENT.
  • [00962] SCANNER - MASTER COMMAND SYNTAX SCANNER/DEFAULTER.
  • [01060] GETMARK - GET DATA FOR A MARKER.
  • [01529] SCNLIN - SCAN LINE ADDRESS SYNTAX.
  • [01796] SCANSET - SCAN SYNTAX OF SET SUBCOMMANDS.
  • [02374] SCANVIEW - SCAN PARAMETERS OF “SET VIEW” COMMAND.
  • [02405] FRMTSCR - FORMAT THE SCREEN FOR THE “SET VIEW” COMMAND.
  • [02576] SCRNSIZES - SET SIZE VALUES ASSOCIATED WITH SCREEN.
  • [02604] SCANFUNC - SCAN/EXECUTE SET KEY COMMAND.
  • [02734] SCNTAB - PARSE SYNTAX FOR *IN* FIELD REFERENCE.
  • [02790] SCANSTR - PARSE CHARACTER STRING SYNTAX.
  • [03008] SCNEOC - VERIFY END OF COMMAND.
  • [03025] SCNONOFF - PARSE YES/NO SYNTAX.
  • [03057] SCNEQVAL - PARSE NUMERIC SYNTAX PARAMETER.
  • [03084] SCNEQNAM - PARSE ARBITRARY ALPHANUMERIC WORD.
  • [03120] SCNFILE - SCAN PARENTHESIZED FILENAME.
  • [03153] SCNCHAR - PARSE ARBITRARY PUNCTUATION OR ALTERNATE NAME.
  • [03198] SCNLSTCOL - PARSE A LIST OF NUMBERS INTO TAB VECTOR.
  • [03248] SCNFILOPT - SCAN OPTIONS ALLOWABLE ON “FSE” COMMAND.
  • [03344] EXPANDCMDS - EXPAND MICROS FROM IN COMMAND LINE.
  • [03419] EXPANDNUM - GENERATE NUMBER SPECIFIED BY L.
  • [03574] PROCPARM - EXPAND MICRO FOR PROCEDURE PARAMETERS.
  • [03658] FINDER - SEARCH CURRENT LINE OF TEXT IN ONE OF EIGHT WAYS.
  • [03710] FIND - FIND STRING.
  • [03904] SUBST - TEXT SUBSTITUTION FOR REPLACE COMMAND.
  • [04041] XSHOW - DISPLAY LINE AND TEST WIDTH.
  • [04056] YSHOW - DISPLAY LINE.
  • [04074] PRINTL - PRINT LINE.
  • [04165] CHECKWIDE - CHECK LINE FOR EXCESS WIDTH.
  • [04194] GETMOD - PROMPT FOR ALTERATION MASK.
  • [04245] APPEND - APPEND TTYLIN ONTO LIN.
  • [04271] STRETCH - ADD BLANKS INSIDE A LINE IMAGE.
  • [04307] SQUEEZE - REMOVE BLANKS THEN NONBLANKS THEN BLANKS.
  • [04371] DOCENTER - ALIGN TEXT IN CENTER OF MARGINS.
  • [04428] DOMOD - PERFORM MASKED ALTERATIONS ON LINE IMAGE.
  • [04568] MULTMOV - COPY/MOVE COMMANDS, EASY CONDITIONS.
  • [04602] DOSEGMENT - MULTMOV INTERNAL ALGORITHM.
  • [04753] SAVEPROT - SAVE COPY OF LINE IMAGE FOR EDITFIELD.
  • [04781] MERGEPROT - MERGE MODIFIED LINE WITH PROTECTED FIELD.
  • [04819] SETFIELD - ESTABLISH TAB-FIELD RESTRICTIONS.
  • [04869] SETFIRST - SET PARAMETERS FOR FIRST LINE OF RANGE.
  • [04899] SETLAST - SET PARAMETERS FOR LAST LINE OF RANGE.
  • [04925] EXEC - FAN-OUT TO TEXT MANIPULATOR FOR ONE LINE OF RANGE.
  • [05006] SETCHRPTR - SETUP CHARACTER POINTERS.
  • [05036] DODELETE - ACTUAL LINE/STRING REMOVAL.
  • [05218] GETESCAPE - DETERMINE IF INPUT DATA AT/NEAR END.
  • [05263] DOTAB - EXPAND SOFT-TABS.
  • [05327] EXECINS - PROCESS ONE ONE LINE OF LINE-MODE INPUT.
  • [05420] DORANGE - PROCESS RANGE OF LINES FOR COMMAND.
  • [05462] EXECONE - EXECUTE COMMAND PROCESSOR FOR ONE LINE.
  • [05597] COMPARLIN - COMPARE INTERNAL LINE TO DISPLAY KEYWORD.
  • [05729] GETPROCNXT - GET NEXT COMMAND LINE FROM PROCEDURE.
  • [05765] CLEARPROC - GET OUT OF PROCEDURE EXECUTION MODE.
  • [05794] PRECONNECT - FIRST STEP IN CONNECTING TO MULTI-USER EDITOR.
  • [05827] CONNECT - ACTUAL ATTEMPT TO CONNECT TO MULTI.
  • [05874] POSTCONNECT - VERIFY REVIVAL OF SINGLE-USER EDITOR.
  • [05927] ERRJUMP - ISSUE ERROR MESSAGE AND JUMP TO FRESH COMMANDS.
  • [06025] VFYLOCK - VERIFY PERMISSION TO CHANGE CURRENT FILE.
  • [06043] PUSHBACK - PUSH CURRENT FILES AND SPLITS ONTO BACKSTACK.
  • [06076] SAMEBACK - TEST WHETHER FILES/SPLITS CHANGED.
  • [06099] DECRBACK - DECREMENT FILE SELECTION QUEUE.
  • [06117] RESTSAVPOS - RESTORE SAVED POSITION.
  • [06153] EXCHSAVPOS - EXCHANGE CURRENT POSITION WITH SAVED POSITION.
  • [06241] STORCURPOS - STORE CURRENT POSITION.
  • [06279] DOBACK - REVERT TO EARLIER FILE SELECTION.
  • [06409] CHECKGLOBAL - SEE IF GLOBAL SEARCH/CHANGE IN EFFECT.
  • [06443] LASTGLOBAL - DETERMINE IF LAST ITERATION OF CHANGE.
  • [06468] ASKUSER - ASK QUESTION EITHER SCREEN OR LINE.
  • [06577] PROCESS - STEADY-STATE MAIN PROCESS OF EDITOR.

Source Code

FSEEDIT.txt
  1. PROC FSEEDIT;
  2. BEGIN
  3.  
  4. #
  5. *** FSEEDIT - FULL SCREEN EDITOR AND SCREEN MGT FACILITY.
  6. *
  7. * COPYRIGHT CONTROL DATA SYSTEMS INC. 1992.
  8. #
  9.  
  10. DEF LISTCON #0#;
  11.  
  12. CONTROL EJECT; # UNIVERSAL DEFINITIONS #
  13.  
  14. *IFCALL SINGLE,COMFSGL
  15. *IFCALL ONLY,COMFONL
  16. *IFCALL MULTI,COMFMLT
  17. *CALL COMFFSE
  18.  
  19. # EXTERNAL REF'S AND DEF'S #
  20.  
  21.  
  22. CONTROL IFEQ MULTI,1;
  23. XREF ARRAY RENTSTK [1:MAXREENT]; # SUBROUTINE STACK #
  24. BEGIN
  25. ITEM RSTK;
  26. END
  27. XREF ITEM RSTKPTR;
  28. CONTROL FI;
  29.  
  30.  
  31. CONTROL IFEQ MULTI,1;
  32. XREF PROC VOLUNTEER; # OFFER TO SURRENDER SUBTASK #
  33. XREF PROC CLEARINT; # PROCLAIM WE SAW USRBRK #
  34. XREF PROC FATALTRAP; # MONITOR PROCESSING FOR EDITOR TROUBLE #
  35. XREF PROC CLEARQUE; # MONITOR NO LONGER NEEDS TASKREQUE BIT #
  36. CONTROL IFEQ METERING,1;
  37. XREF PROC BGNMETER; # ISSUE START-OF-SESSION STATS #
  38. CONTROL FI;
  39. CONTROL FI;
  40.  
  41. XDEF
  42. BEGIN
  43. *CALL COMFXED
  44. END
  45.  
  46. XREF
  47. BEGIN
  48. *CALL COMFXSB
  49. *CALL COMFXTI
  50. *CALL COMFXFO
  51. *CALL COMFXSC
  52. *CALL COMFXWK
  53. *CALL COMFXVT
  54. END
  55.  
  56. CONTROL IFEQ SINGLE,1;
  57. XREF
  58. BEGIN
  59. *CALL COMFXCM
  60. END
  61. CONTROL FI;
  62.  
  63. XREF
  64. BEGIN
  65. CONTROL IFEQ SINGLE,1;
  66. *CALL COMFXFL
  67. CONTROL FI;
  68. END
  69.  
  70. XREF # XTRNL CIO PROCS #
  71. BEGIN
  72. PROC READ; # ALL SAME AS #
  73. PROC READC; # CORRESPONDING MACROS #
  74. PROC WRITE;
  75. PROC WRITEF;
  76. PROC WRITER;
  77. PROC WRITEC;
  78. CONTROL IFEQ SINGLE,1;
  79. PROC EVICT;
  80. PROC RETERN;
  81. PROC REWIND;
  82. PROC RECALL;
  83. CONTROL FI;
  84. END
  85.  
  86. XREF # XTRNL MISCELLANEOUS #
  87. BEGIN
  88. PROC DISSJ; # DISABLE/ENABLE SSJ= #
  89. PROC VDTGTN;
  90. PROC VDTGTO;
  91. PROC EXCHWD;
  92. PROC MOVEWD;
  93. PROC ZEROWD;
  94. FUNC FASTFND B; # OPTIMIZED STRING SEARCH #
  95. FUNC FASTLNB; # FIND LAST NON-BLANK #
  96. FUNC LENGTH; # LENGTH OF INTERNAL LINE #
  97. FUNC LINESZ;
  98. FUNC FIXCTL B; # FIX UNWANTED CONTROL BYTES #
  99. CONTROL IFEQ SINGLE,1;
  100. PROC MESSAGE; # MESSAGE MACRO #
  101. PROC DISTCON; # DISABLE TERMINAL CONTROL #
  102. PROC ABORT; # ABORT MACRO #
  103. PROC SYSREQ;
  104. PROC ROLLTE;
  105. PROC TSTATUS;
  106. CONTROL FI;
  107. END
  108.  
  109. # COMMON DATA AREAS #
  110.  
  111. *CALL COMFDS1
  112. *CALL COMFVD2
  113. *CALL COMFDS2
  114.  
  115. # EDITOR SYNTAX TABLES #
  116.  
  117. *CALL COMFTAB
  118. PAGE # VARIOUS USEFUL LITTLE ROUTINES #
  119.  
  120.  
  121. PROC DSPLCOD(WORD);
  122. BEGIN
  123. #
  124. ** DSPLCOD - CONVERT ONE CHARACTER TO LOWER CASE OR DISPLAY.
  125. *
  126. * DSPLCOD SUPPRESSES CASE OF INTERNAL CHARACTERS. IT IS
  127. * ALSO DEFINED TO CONVERT FROM INTERNAL CHARACTER SET TO
  128. * DISPLAY. THUS THE FIRST 64 CHARACTERS OF INTERNAL MUST
  129. * EQUAL DISPLAY CODE. WE ENFORCE THIS WITH COMPILE-TIME
  130. * CHECKS FOR "A", "Z", AND SEMICOLON.
  131. *
  132. * ENTRY WORD - INTERNAL CHARSET VALUE TO CONVERT.
  133. *
  134. * EXIT WORD - CONVERTED.
  135. #
  136. CONTROL IFNQ CLETTERA,1; ERROR; CONTROL FI;
  137. CONTROL IFNQ CLETTERZ,26; ERROR; CONTROL FI;
  138. CONTROL IFNQ CSEMCOLON,O"77"; ERROR; CONTROL FI;
  139. ITEM WORD;
  140. WORD=XLTINTDSP[WORD];
  141. END # OF DSPLCOD #
  142.  
  143.  
  144. PROC SQUELCH(TEXTLIN);
  145. BEGIN
  146. #
  147. ** SQUELCH - SUPPRESS LOWER-CASE FOR LINE IMAGE.
  148. *
  149. * ENTRY TEXTLIN - INTERNAL CHARSET LINE IMAGE.
  150. *
  151. * EXIT TEXTLIN - ALL ALPHABETICS ARE UPPER CASE.
  152. *
  153. * MACROS GETCHAR, SETCHAR.
  154. *
  155. * CALLS DSPLCOD, LENGTH.
  156. #
  157. ARRAY TEXTLIN[0:99]; ITEM TEXTLINE;
  158. ITEM TMP1, TMP2;
  159. FOR TMP1=0 STEP 1 UNTIL LENGTH(TEXTLIN) DO
  160. BEGIN
  161. GETCHAR(TEXTLINE,TMP1,TMP2);
  162. DSPLCOD(TMP2);
  163. SETCHAR(TEXTLINE,TMP1,TMP2);
  164. END
  165. END # OF SQUELCH #
  166.  
  167.  
  168. PROC HALT(STR);
  169. IOBEGIN(HALT)
  170. #
  171. ** HALT - SET WARNING MESSAGE AND FLAG COMMAND SHUTDOWN.
  172. *
  173. * ENTRY STR - ERROR MESSAGE, DISPLAY WITH DOLLAR SIGN.
  174. *
  175. * EXIT ERRSTRING - EQUAL TO STR.
  176. * FOUND - FALSE.
  177. * LINCTR - INFINITE.
  178. #
  179. ITEM STR C(80);
  180. FOUND=FALSE;
  181. LINCTR=LARGENUM;
  182. ERRSTRING=STR;
  183. IOEND # OF HALT #
  184.  
  185.  
  186. CONTROL IFEQ MULTI,1;
  187.  
  188.  
  189. PROC CHKVICTIM;
  190. IOBEGIN(CHKVICTIM)
  191. #
  192. ** CHKVICTIM - CHECK FOR SMFEX-IMPOSED SESSION ABORT.
  193. *
  194. * CHKVICTIM LOOKS FOR SMFEX-DETECTED CATASTROPHES. THIS
  195. * CURRENTLY INCLUDES ONLY UNRECOVERABLE ECS PARITY ERRORS.
  196. *
  197. * ENTRY SMFVICTIM - FLAG.
  198. *
  199. * EXIT VIA FATAL IF NEED TO ABORT.
  200. *
  201. * CALLS FATAL.
  202. #
  203. IF SMFVICTIM THEN FATAL(ERRSTRING);
  204. IOEND # OF CHKVICTIM #
  205.  
  206. CONTROL FI;
  207.  
  208.  
  209. PROC CONCAT(LIN1,LIN2);
  210. BEGIN
  211. #
  212. ** CONCAT - CONCATENATE TWO INTERNAL LINE IMAGES.
  213. *
  214. * ENTRY LIN1, LIN2 - THE LINE IMAGES IN INTERNAL CHARSET.
  215. *
  216. * EXIT LIN1 - HAS LIN2 APPENDED TO IT.
  217. *
  218. * MACROS GETCHAR, SETCHAR.
  219. *
  220. * CALLS LENGTH.
  221. #
  222. ARRAY LIN1; ITEM LINE1;
  223. ARRAY LIN2; ITEM LINE2;
  224. ITEM TMP1, TMP2, TMP3, TMP4;
  225. TMP1=LENGTH(LIN1);
  226. TMP2=LENGTH(LIN2);
  227. FOR TMP3=0 STEP 1 WHILE TMP3 LQ TMP2 AND TMP1+TMP3 LQ BUFCM1 DO
  228. BEGIN
  229. GETCHAR(LINE2,TMP3,TMP4);
  230. SETCHAR(LINE1,TMP1+TMP3,TMP4);
  231. END
  232. SETCHAR(LINE1,TMP1+TMP3,CENDLINE);
  233. END # OF CONCAT #
  234.  
  235.  
  236. PROC NOPOP; # LIKE POP BUT DONT MOVE #
  237. BEGIN
  238. #
  239. ** NOPOP - POP POSITION STACK WITHOUT USING IT.
  240. *
  241. * NOPOP DIFFERS FROM POP IN THAT WHILE BOTH POP THE LEVEL
  242. * OF THE POSITIONING STACK, NOPOP DISCARDS THE STACK VALUES
  243. * WHILE POP REPOSITIONS TO THE SAVED LOCATION IN THE FILE.
  244. *
  245. * ENTRY POSITIONING STACK PREVIOUSLY PUSHED.
  246. *
  247. * EXIT STACKPTR DECREMENTED.
  248. *
  249. * CALLS FATAL.
  250. #
  251. IF STACKPTR LS 0 THEN
  252. BEGIN
  253. FATAL(" FILE POSITION STACK UNDERFLOWED (2).$");
  254. END
  255. STACKPTR=STACKPTR-1;
  256. END # OF NOPOP #
  257.  
  258.  
  259. PROC WINDOLIN(LINEPARM,FILEPARM);
  260. BEGIN
  261. #
  262. ** WINDOLIN - FORCE ADDRESS INTO FILE IMAGE.
  263. *
  264. * WINDOLIN FORCES LINEPARM TO BE IN BOUNDS FOR THE FILEPARM.
  265. *
  266. * ENTRY LINEPARM - LINE ADDRESS.
  267. * FILEPARM - BRACKET NUMBER FOR FILE.
  268. * TOPF(FILEPARM), BOTF(FILEPARM) - BOUNDS.
  269. *
  270. * EXIT LINEPARM - IN BOUNDS.
  271. * FOUND - TRUE OR FALSE FOR VALIDITY OF ORIGINAL VALUE.
  272. #
  273. ITEM LINEPARM, FILEPARM;
  274. FOUND=FALSE;
  275. IF TOPF(FILEPARM) EQ BOTF(FILEPARM)-1 THEN LINEPARM=TOPF(FILEPARM);
  276. ELSE IF LINEPARM LQ TOPF(FILEPARM) THEN LINEPARM=TOPF(FILEPARM)+1;
  277. ELSE IF LINEPARM GQ BOTF(FILEPARM) THEN LINEPARM=BOTF(FILEPARM)-1;
  278. ELSE FOUND=TRUE;
  279. END # OF WINDOLIN #
  280.  
  281.  
  282. PROC WINDOPOS(LINEPARM,FILEPARM);
  283. BEGIN
  284. #
  285. ** WINDOPOS - VALIDATE POSITION WITHIN FILE.
  286. *
  287. * WINDOPOS IS LIKE WINDOLIN EXCEPT THAT IT ALLOWS THE
  288. * POSITION TO BE JUST ABOVE THE TOP OF THE FILE.
  289. *
  290. * ENTRY LINEPARM - AS WINDOLIN.
  291. * FILEPARM - AS WINDOLIN.
  292. * TOPF(), BOTF() - AS WINDOLIN.
  293. *
  294. * EXIT LINEPARM - AS WINDOLIN.
  295. * FOUND - AS WINDOLIN.
  296. #
  297. ITEM LINEPARM, FILEPARM;
  298. FOUND=FALSE;
  299. IF TOPF(FILEPARM) EQ BOTF(FILEPARM)-1 THEN LINEPARM=TOPF(FILEPARM);
  300. IF LINEPARM LS TOPF(FILEPARM) THEN LINEPARM=TOPF(FILEPARM);
  301. ELSE IF LINEPARM GQ BOTF(FILEPARM) THEN LINEPARM=BOTF(FILEPARM)-1;
  302. ELSE FOUND=TRUE;
  303. END # OF WINDOPOS #
  304.  
  305.  
  306. PROC FWDNUM;
  307. IOBEGIN(FWDNUM)
  308. #
  309. ** FWDNUM - MOVE FORWARDS UNTIL NUMBERED LINE FOUND.
  310. *
  311. * FWDNUM ADVANCES THE CURRENT POSITION IN THE WORKFILE
  312. * UNTIL A NUMBERED LINE IS FOUND. NOTE THAT WE ASSUME THE
  313. * CALLER HAS VERIFIED THAT WE EXPECT NUMBERED LINES.
  314. *
  315. * ENTRY CURRENT, CURFILE - WHERE WE ARE.
  316. * BOTF(CURFILE) - BOUNDS.
  317. * USRBRK - CONTINUOUSLY CHECKED.
  318. *
  319. * EXIT CURRENT - UPDATED.
  320. *
  321. * MACROS MOD.
  322. *
  323. * CALLS FWDZ, GETLNUM, VOLUNTEER(MULTI).
  324. *
  325. * USES LINENO, WIDTHFOUND, DORNGCTR.
  326. #
  327. LINENO=NINES;
  328. WIDTHFOUND=0;
  329. FOR DORNGCTR=1 STEP 1 WHILE WIDTHFOUND EQ 0 AND
  330. CURRENT LS BOTF(CURFILE)-1 AND USRBRK EQ 0 DO
  331. BEGIN
  332. FWDZ;
  333. GETLNUM;
  334. IF WIDTHFOUND EQ 0 THEN LINENO=NINES;
  335. CONTROL IFEQ MULTI,1;
  336. IF MOD(DORNGCTR,VOLLINES) EQ 0 THEN VOLUNTEER;
  337. CONTROL FI;
  338. END
  339. IOEND # OF FWDNUM #
  340.  
  341.  
  342. PROC BAKNUM;
  343. IOBEGIN(BAKNUM)
  344. #
  345. ** BAKNUM - BACK UP IN FILE UNTIL NUMBERED LINE.
  346. *
  347. * BAKNUM IS LIKE FWDNUM EXCEPT OPPOSITE DIRECTION.
  348. *
  349. * ENTRY CURRENT, CURFILE - WHERE WE ARE.
  350. * TOPF(CURFILE) - BOUNDS.
  351. * USRBRK - CONTINUOUSLY CHECKED.
  352. *
  353. * EXIT CURRENT - UPDATED.
  354. *
  355. * MACROS MOD.
  356. *
  357. * CALLS BAKZ, GETLNUM, VOLUNTEER(MULTI).
  358. *
  359. * USES LINENO, WIDTHFOUND, DORNGCTR.
  360. #
  361. LINENO=0;
  362. WIDTHFOUND=0;
  363. FOR DORNGCTR=1 STEP 1 WHILE WIDTHFOUND EQ 0 AND
  364. CURRENT GR TOPF(CURFILE)+1 AND USRBRK EQ 0 DO
  365. BEGIN
  366. BAKZ;
  367. GETLNUM;
  368. CONTROL IFEQ MULTI,1;
  369. IF MOD(DORNGCTR,VOLLINES) EQ 0 THEN VOLUNTEER;
  370. CONTROL FI;
  371. END
  372. IOEND # OF BAKNUM #
  373.  
  374.  
  375. PROC POSN;
  376. IOBEGIN(POSN)
  377. #
  378. ** POSN - POSITION TO LINE WITH DESIRED SEQUENCE NUMBER.
  379. *
  380. * POSN MOVES FORWARDS OR BACKWARDS AS NEEDED TO GET TO
  381. * THE NEAREST LINE WITH THE RIGHT SEQUENCE NUMBER. WE
  382. * ASSUME THE CALLER HAS VERIFIED WE EXPECT NUMBERS.
  383. *
  384. * ENTRY LINNUM1 - DESIRED SEQUENCE NUMBER.
  385. * CURFILE, CURF(CURFILE) - STARTING LOCATION.
  386. * TOPF(CURFILE), BOTF(CURFILE) - BOUNDS.
  387. * USRBRK - CONTINUOUSLY CHECKED.
  388. *
  389. * EXIT CURRENT - UPDATED.
  390. *
  391. * MACROS MOD.
  392. *
  393. * CALLS POSZ, GETLNUM, BAKZ, VOLUNTEER(MULTI), FWDZ, BAKNUM.
  394. *
  395. * USES DORNGCTR, LINENO.
  396. #
  397. POSZ(CURF(FILNUM));
  398. GETLNUM;
  399. FOR DORNGCTR=1 STEP 1 WHILE CURRENT GR TOPF(FILNUM) AND
  400. (LINENO GR LINNUM1 OR WIDTHFOUND EQ 0) AND USRBRK EQ 0 DO
  401. BEGIN
  402. BAKZ;
  403. GETLNUM;
  404. CONTROL IFEQ MULTI,1;
  405. IF MOD(DORNGCTR,VOLLINES) EQ 0 THEN VOLUNTEER;
  406. CONTROL FI;
  407. END
  408. FOR DORNGCTR=1 STEP 1 WHILE CURRENT LS BOTF(FILNUM)-1 AND
  409. (LINENO LS LINNUM1) AND USRBRK EQ 0 DO
  410. BEGIN
  411. FWDZ;
  412. GETLNUM;
  413. CONTROL IFEQ MULTI,1;
  414. IF MOD(DORNGCTR,VOLLINES) EQ 0 THEN VOLUNTEER;
  415. CONTROL FI;
  416. END
  417. IF LINENO GR LINNUM1 THEN BAKNUM;
  418. IOEND # OF POSN #
  419.  
  420.  
  421. PROC FITNUM;
  422. IOBEGIN(FITNUM)
  423. #
  424. ** FITNUM - CHECK SEQUENCING GAP AND SELECT INCREMENT.
  425. *
  426. * FITNUM IS USED WITH SEQUENCE NUMBERED FILES TO SEE IF
  427. * THERE IS AN ADEQUATE GAP IN VALUES OF ADJACENT SEQUENCE
  428. * NUMBERS TO FIT IN AS MANY LINES AS WE WISH. AN INCREMENT
  429. * IS CHOSEN FOR NUMBERING OF THE LINES TO BE ADDED.
  430. *
  431. * ENTRY CURFILE - WHICH FILE BRACKET.
  432. * NUMBERED[CURFILE] - WHETHER TO DO ANYTHING.
  433. * CURRENT - LINE AFTER WHICH TO ADD BLOCK.
  434. * DINCR - DEFAULT NUMBERING INCREMENT.
  435. * LINPTR3 - TARGET, SHOULD EQUAL CURRENT.
  436. * LINPTR1, LINPTR2 - INDICATE SIZE OF BLOCK.
  437. * LIMIT - ALSO INDICATES SIZE OF BLOCK.
  438. * LINNUM3 - SEQUENCE VALUE AT TARGET.
  439. * BOTF(CURFILE) - BOUNDS.
  440. *
  441. * EXIT VIA ERRJUMP IF IT CANNOT BE DONE.
  442. * INCR - NEW SEQUENCING INCREMENT.
  443. * LINENO - FIRST SEQUENCE MINUS INCR.
  444. *
  445. * CALLS GETLNUM, PUSH, FWDNUM, POP, MIN, MAX.
  446. *
  447. * USES LINNUM1, LINNUM2, LCOUNT.
  448. #
  449.  
  450. IF NUMBERED[CURFILE] NQ 0 THEN
  451. BEGIN
  452. GETLNUM;
  453. IF WIDTHFOUND LQ 0 THEN
  454. BEGIN
  455. PUSH;
  456. BAKNUM;
  457. POP;
  458. END
  459. LINNUM1=MIN(LINNUM3,NINES);
  460. LINNUM1=MAX(LINNUM1,LINENO);
  461. IF CURRENT GQ BOTF(CURFILE)-1 THEN LINNUM2=NINES;
  462. ELSE
  463. BEGIN
  464. PUSH;
  465. FWDNUM;
  466. LINNUM2=LINENO;
  467. POP;
  468. END
  469. LINNUM2=MAX(LINNUM2,LINNUM1+1);
  470. LINNUM2=MIN(LINNUM2,NINES+1);
  471. LCOUNT=MIN(LIMIT,ABS(LINPTR2-LINPTR1)+1); # NEEDED #
  472. GETLNUM;
  473. IF LINNUM1 GR LINENO THEN # USER SPECIFIED START #
  474. BEGIN
  475. IF LCOUNT GR LINNUM2-LINNUM1
  476. THEN ERRJUMP("NOT ENOUGH ROOM FOR INSERTION$");
  477. INCR=(LINNUM2-LINNUM1)/LCOUNT;
  478. INCR=MAX(INCR,1);
  479. INCR=MIN(INCR,DINCR);
  480. LINENO=LINNUM1-INCR;
  481. END
  482. ELSE # COMPUTED START #
  483. BEGIN
  484. IF LCOUNT GQ LINNUM2-LINNUM1
  485. THEN ERRJUMP("NOT ENOUGH ROOM FOR INSERTION$");
  486. INCR=(LINNUM2-LINNUM1)/(LCOUNT+1);
  487. INCR=MAX(INCR,1);
  488. INCR=MIN(INCR,DINCR);
  489. LINENO=LINNUM1;
  490. END
  491. END
  492. IOEND # OF FITNUM #
  493.  
  494.  
  495. PROC SPLICE;
  496. IOBEGIN(SPLICE)
  497. #
  498. ** SPLICE - SPLICE PORTIONS OF LINES IN WORKFILE.
  499. *
  500. * SPLICE CONCATENATES TWO ADJACENT LINES IN THE FILE. THIS
  501. * ROUTINE IS DESIGNED TO BE EXECUTED AFTER DORANGE PROCESSING,
  502. * AS IT NO-OPS FOR ONE-LINE RANGES. IT ALSO DELETES IN THE
  503. * CASE THAT THE SPLICED LINE PAIR IS OF ZERO LENGTH.
  504. *
  505. * ENTRY LIN - LINE IMAGE FOR SECOND LINE.
  506. * CURFILE, CURRENT - ADDRESS OF SECOND LINE.
  507. * CHRPTR3 - IGNORED.
  508. * FIRSTRANGE, LASTRANGE - WHETHER AT BOUNDS OF RANGE.
  509. * (AS LEFT OVER FROM DORANGE)
  510. *
  511. * EXIT CHRPTR3 - UNCHANGED.
  512. *
  513. * CALLS BAKZ, PUSHTEMP, POPTEMP, DOJOIN, DELX, LENGTH.
  514. *
  515. * USES (WITH RESTORATION) - TEMP, CHRPTR3.
  516. #
  517. IF NOT (FIRSTRANGE AND LASTRANGE) THEN
  518. BEGIN # MULTIPLE STUBS TO MERGE #
  519. BAKZ; # TO CUT-DOWN FIRST LINE #
  520. PUSHTEMP;
  521. TEMP=CHRPTR3;
  522. CHRPTR3=0; # ASSURE DOJOIN IS SIMPLE #
  523. DOJOIN(0); # ADD ON CUT-DOWN LAST LINE #
  524. CHRPTR3=TEMP; # RESTORE CHRPTR3 #
  525. POPTEMP;
  526. END
  527. # DELETE MERGED LINE-PAIR IFF TOTALLY CUT DOWN #
  528. IF LENGTH(LIN) EQ 0 THEN
  529. BEGIN
  530. DELX;
  531. IF CURRENT GR TOPF(CURFILE) THEN BAKZ;
  532. END
  533. IOEND # OF SPLICE #
  534.  
  535.  
  536. PROC MAKEPAGE(PAGSIZ,FILEPARM); # COMPUTE PAGE BOUNDARIES #
  537. BEGIN
  538. #
  539. ** MAKEPAGE - COMPUTE BOUNDS FOR SECTION OF FILE.
  540. *
  541. * MAKEPAGE IS USED BY THE VIEW COMMAND IN LINE MODE TO
  542. * DETERMINE THE SECTION OF THE FILE TO BE PRINTED, BASED
  543. * ON RECENT USAGE OF VIEW COMMANDS. THE SCANNER IS CALLED
  544. * BEFORE MAKEPAGE.
  545. *
  546. * ENTRY LINCTR - NOMINAL ADDRESS TO PRINT.
  547. * PAGSIZ - DESIRED SIZE OF VIEW AREA.
  548. * FILEPARM - WHICH FILE BRACKET.
  549. * FORWARD, BACKWARD - FROM SCANNER.
  550. * PAGELAST - WHETHER LAST COMMAND WAS VIEW ALSO.
  551. * REGLINE[RNGTOPREG], REGLINE[RNGBOTREG] - LAST RANGE
  552. * PRINTED IF PAGELAST IS TRUE.
  553. *
  554. * EXIT LINPTR1, LINPTR2 - COMPUTED BOUNDARIES.
  555. * LINCTR - FORCED TO FIT IF NOT ALREADY.
  556. *
  557. * CALLS WINDOLIN.
  558. #
  559. ITEM PAGSIZ, FILEPARM;
  560.  
  561. IF FORWARD THEN
  562. BEGIN
  563. IF PAGELAST THEN LINPTR1=REGLINE[RNGBOTREG];
  564. ELSE LINPTR1=LINCTR;
  565. END
  566. ELSE IF BACKWARD THEN
  567. BEGIN
  568. IF PAGELAST THEN LINPTR1=REGLINE[RNGTOPREG]-PAGSIZ+1;
  569. ELSE LINPTR1=LINCTR-PAGSIZ+1;
  570. END
  571. ELSE LINPTR1=LINCTR-(PAGSIZ/2);
  572.  
  573. WINDOLIN(LINPTR1,FILEPARM); # TO KEEP IN BOUNDS #
  574.  
  575. LINPTR2=LINPTR1+PAGSIZ-1;
  576. WINDOLIN(LINPTR2,FILEPARM); # TO KEEP IN BOUNDS #
  577.  
  578. IF LINCTR LS LINPTR1 OR LINCTR GR LINPTR2 THEN
  579. BEGIN
  580. IF BACKWARD THEN LINCTR=LINPTR1;
  581. ELSE LINCTR=LINPTR2;
  582. END
  583. WINDOLIN(LINCTR,FILEPARM); # MERELY AS STANDARD FOR CMD SKIP #
  584.  
  585. END # OF MAKEPAGE #
  586.  
  587.  
  588. PROC SETMARK(POSITION,CURSOR);
  589. BEGIN # START OF SETMARK #
  590. #
  591. ** SETMARK - SET BOTH OR SECOND MARKER REGISTERS.
  592. *
  593. * SETMARK IS CALLED TO SET MARKER REGISTERS. IF NO OR BOTH
  594. * MARKERS ARE ALREADY FILLED, WE START OVER AND SET THE
  595. * FIRST ONE. IF THE FIRST HAS BEEN PREVIOUSLY SET, WE
  596. * SET THE SECOND ONE. IF THE FILE ASSOCIATION HAS CHANGED
  597. * BETWEEN SETTING THE FIRST AND SECOND, WE START OVER AND
  598. * SET THE FIRST ONE. ANY TIME WE SET THE FIRST ONE, WE
  599. * ALSO DEFAULT THE SECOND ONE TO MATCH THE FIRST.
  600. *
  601. * ENTRY POSITION - LINE ADDRESS TO MARK.
  602. * CURSOR - HORIZONTAL CURSOR POSITION TO MARK.
  603. * NUMMARKS - NUMBER OF PREVIOUS MARKS.
  604. * CURFILE - FILE BRACKET FOR POSITION AND CURSOR.
  605. * FDLF(CURFILE) - SETUP.
  606. * MRKFILE[0] - SETUP IF NUMMARKS IS ONE.
  607. *
  608. * EXIT NUMMARKS - UPDATED.
  609. * REGLINE[MARKREG] - SETUP IF FIRST MARK SET.
  610. * REGLINE[MARKREG+1] - SETUP IF SECOND MARK SET.
  611. * MRKFILE[1-2] - SETUP.
  612. * MRKCHAR[1-2] - SETUP.
  613. *
  614. * CALLS PAINTMARKS.
  615. #
  616. ITEM POSITION, CURSOR;
  617.  
  618. IF (NUMMARKS GQ 2) OR
  619. (NUMMARKS EQ 1 AND MRKFILE[0] NQ FDLF(CURFILE)) THEN
  620. BEGIN
  621. PAINTMARKS(3);
  622. NUMMARKS=0;
  623. END
  624. REGLINE[MARKREG+NUMMARKS]=POSITION;
  625. REGLINE[MARKTOP+NUMMARKS]=TOPF(CURFILE);
  626. MRKFILE[NUMMARKS]=FDLF(CURFILE);
  627. MRKCHAR[NUMMARKS]=CURSOR;
  628. NUMMARKS=NUMMARKS+1;
  629. IF NUMMARKS EQ 2 THEN
  630. BEGIN
  631. IF REGLINE[MARKREG] GR POSITION
  632. OR (REGLINE[MARKREG] EQ POSITION AND MRKCHAR[0] GR CURSOR) THEN
  633. BEGIN
  634. REGLINE[MARKREG] = = REGLINE[MARKREG+1];
  635. REGLINE[MARKTOP] = = REGLINE[MARKTOP+1];
  636. MRKFILE[0] = = MRKFILE[1];
  637. MRKCHAR[0] = = MRKCHAR[1];
  638. END
  639. END
  640. ELSE
  641. BEGIN
  642. REGLINE[MARKREG+1]=REGLINE[MARKREG];
  643. REGLINE[MARKTOP+1]=REGLINE[MARKTOP];
  644. MRKFILE[1]=MRKFILE[0];
  645. MRKCHAR[1]=MRKCHAR[0];
  646. END
  647. PAINTMARKS(1);
  648.  
  649. END # OF SETMARK #
  650.  
  651.  
  652. PROC FORCEFILE;
  653. IOBEGIN(FORCEFILE)
  654. #
  655. ** FORCEFILE - GET FILE INTO SOME BRACKET.
  656. *
  657. * FORCE FILE SPECIFIED BY READNAM TO BE OPEN FOR SYNTAX
  658. * SCANNERS WHICH NEED TO STUDY ITS BRACKETING. RETURN
  659. * FILNUM AS THE BRACKET IN WHICH THE FILE IS OPEN. WE USE
  660. * CURFILE AS THE BRACKET ONLY IF THE CURRENT FILE IS ONE AND
  661. * THE SAME AS THE REQUESTED FILE. IN ALL OTHER CASES WE USE
  662. * THE OPPOSITE BRACKET NUMBER.
  663. *
  664. * ENTRY CURFILE - BRACKET WHICH CANNOT BE DISTURBED.
  665. * READNAM - FILE WE MUST GET OPENED.
  666. *
  667. * EXIT FILNUM - THE BRACKET INTO WHICH READNAM IS OPEN.
  668. *
  669. * CALLS PUSH, OPENFILE, POP.
  670. *
  671. * USES CHARPARM, GETPARM.
  672. #
  673. FILNUM=CURFILE;
  674. IF READNAM EQ PADNAME(FILENAM[FILNUM]) THEN IORET
  675. FILNUM=FILNUM LXR 3; # FLIP BRACKET AND RESCAN #
  676. IF READNAM NQ PADNAME(FILENAM[FILNUM]) THEN
  677. BEGIN # OPEN INTO OTHER BRACKET #
  678. CHARPARM=0;
  679. GETPARM=0;
  680. PUSH;
  681. OPENFILE;
  682. POP;
  683. END
  684. IOEND # OF FORCEFILE #
  685.  
  686.  
  687. PROC REL2ABS(LINEPTR,FILEPTR);
  688. BEGIN
  689. #
  690. ** REL2ABS - CONVERT RELATIVE LINE ADDRESS TO ABSOLUTE.
  691. *
  692. * REL2ABS TAKES A LINE ADDRESS WHICH IS RELATIVE TO ITS
  693. * WORKFILE FILE IMAGE, AND CONVERTS TO AN ABSOLUTE WORKFILE
  694. * LINE ADDRESS, FOR ONE OF THE CURRENTLY BRACKETED FILES.
  695. *
  696. * ENTRY LINEPTR - RELATIVE LINE ADDRESS.
  697. * FILEPTR - WHICH BRACKET.
  698. * CURFILE - WHICH BRACKET IF FILEPTR IS ZERO.
  699. * TOPF() - SETUP.
  700. *
  701. * EXIT LINEPTR - CONVERTED.
  702. #
  703. ITEM LINEPTR, FILEPTR;
  704. IF LINEPTR LS 0 THEN RETURN;
  705. IF FILEPTR EQ 0 THEN LINEPTR=LINEPTR+TOPF(CURFILE);
  706. ELSE LINEPTR=LINEPTR+TOPF(FILEPTR);
  707. END # OF REL2ABS #
  708.  
  709.  
  710. PROC CHECKFILPTR;
  711. IOBEGIN(CHECKFILPTR)
  712. #
  713. ** CHECKFILPTR - CONVERT DIRECTORY ADDRESS TO BRACKET.
  714. *
  715. * CHECKFILPTR CONVERTS (MATCHES) A FILE DIRECTORY LINE
  716. * ADDRESS INTO A BRACKET NUMBER. IT IS A NO-OP FOR
  717. * ANY PARAMETER VALUE OF ZERO. IT OPENS THE FILE INTO
  718. * THE NON-CURRENT BRACKET IF NOT ALREADY BRACKETED.
  719. *
  720. * ENTRY FILPTR1 - FDLF POINTER OR ZERO.
  721. * FDLF(1-2) - SETUP.
  722. * CURFILE - CURRENT (NON-PREFERRED) BRACKET.
  723. *
  724. * EXIT FILPTR1 - CONVERTED TO BRACKET ORDINAL.
  725. *
  726. * CALLS PUSH, POSZ, SCANFDL, FORCEFILE, POP.
  727. *
  728. * USES READNAM, FILNUM.
  729. #
  730. IF FILPTR1 EQ 0 THEN IORET
  731. ELSE IF FILPTR1 EQ FDLF(1) AND FILPTR1 EQ FDLF(2)
  732. THEN FILPTR1=CURFILE;
  733. ELSE IF FILPTR1 EQ FDLF(1) THEN FILPTR1=1;
  734. ELSE IF FILPTR1 EQ FDLF(2) THEN FILPTR1=2;
  735. ELSE
  736. BEGIN
  737. PUSH;
  738. POSZ(FILPTR1);
  739. SCANFDL(READNAM);
  740. FORCEFILE;
  741. FILPTR1=FILNUM;
  742. POP;
  743. END
  744. IOEND # OF CHECKFILPTR #
  745.  
  746.  
  747. PROC EXTENDFILE(BOOL);
  748. BEGIN
  749. #
  750. * EXTENDFILE - EXTEND FILE FOR INSERT/COPY/MOVE.
  751. *
  752. * ENTRY EXTENDSIZE - HOW MUCH CURSOR BEYOND END OF FILE.
  753. * PROCESSNDX - WHETHER/WHICH INSERT/COPY/MOVE.
  754. * BOTF(FILNUM), FILNUM - END OF FILE.
  755. * LINPTR1, LINPTR2 - RANGE BOUNDARIES.
  756. * BOOL - WHETHER LINPTR1, LINPTR2 SHOULD RELOCATE.
  757. *
  758. * EXIT EXTENDSIZE - ZERO IF FILE EXTENDED.
  759. * THISEXTEND - FORMER VALUE OF EXTENDSIZE.
  760. * LINPTR1, LINPTR2, BOTF(FILNUM) - RELOCATED.
  761. *
  762. * CALLS INSX, POSZ.
  763. *
  764. * USES CURFILE(RESTORED).
  765. *
  766. * NOTE EXTENDFILE IS OPERATIVE ONLY IN SINGLE USER VERSION.
  767. * FOR MULTI, SCANNER MUST ASSURE THIS IS NO-OP.
  768. #
  769. ITEM BOOL B;
  770. CONTROL IFEQ SINGLE,1;
  771. IF EXTENDSIZE GR 0 THEN
  772. BEGIN
  773. IF PROCESSNDX EQ KEYST"CCMD" OR PROCESSNDX EQ KEYST"ICMD"
  774. OR PROCESSNDX EQ KEYST"MCMD" THEN
  775. BEGIN # EXTEND FILE TO TARGET #
  776. CURFILE = = FILNUM; # PRESERVE AND FLIPFLOP #
  777. POSZ(BOTF(CURFILE)-1);
  778. LINE[0]=NULLIN;
  779. FOR LINCTR=1 STEP 1 UNTIL EXTENDSIZE DO
  780. BEGIN # EXTEND FILE TO TARGET ADDR #
  781. # MANUALLY RELOCATE LINPTR1, LINPTR2 AS NEEDED #
  782. IF BOOL THEN
  783. BEGIN
  784. IF CURRENT LS LINPTR1 THEN LINPTR1=LINPTR1+1;
  785. IF CURRENT LS LINPTR2 THEN LINPTR2=LINPTR2+1;
  786. END
  787. INSX; # EXTEND FILE #
  788. END
  789. CURF(CURFILE)=CURRENT;
  790. THISEXTEND=EXTENDSIZE;
  791. EXTENDSIZE=0;
  792. CURFILE = = FILNUM;
  793. END
  794. END
  795. CONTROL FI;
  796. END # OF EXTENDFILE #
  797. PAGE # TOKEN -- SCANS COMMAND SYNTAX #
  798.  
  799. PROC TOKEN;
  800. BEGIN
  801. #
  802. ** TOKEN - LOOK FOR NEXT SYNTAX ELEMENT.
  803. *
  804. * TOKEN SCANS THE COMMAND TEXT FROM SOME CURRENT POSITION
  805. * UNTIL SOMETHING IS SEEN. WE EAT BLANKS, AND MUST
  806. * EVENTUALLY REACH SOME DELIMITER OR A CONSTANT (INTEGER) OR
  807. * A KEYWORD. IF IT IS A CONSTANT, WE DECODE ITS WHOLE VALUE
  808. * AND LEAVE THE CURRENT POSITION JUST AFTER THE LAST DIGIT.
  809. * IF IT IS A KEYWORD, WE GATHER UP ITS WHOLE TEXT, LEAVE THE
  810. * CURRENT POSITION JUST AFTER THE LAST LETTER, AND SEARCH
  811. * THE COMMAND TABLES FOR A MATCH, SETTING VARIOUS VARIABLES
  812. * TO SHOW THE RESULT OF THE MATCH.
  813. *
  814. * WE ARE CALLED BY THE OUTER LOGIC OF PROCESS TO GLEAN OUT
  815. * COMMAND KEYWORDS. WE ARE CALLED BY ALL SORTS OF PEOPLE,
  816. * INCLUDING A VARIETY OF COMMAND PROCESSING ROUTINES, TO
  817. * ADVANCE THE SYNTAX SCAN TO COMPLETE THE COMMAND.
  818. *
  819. * ENTRY SCANPOS - WHERE TO SCAN IN CMDLIN.
  820. * CMDLIN - COMMAND TEXT, INTERNAL LINE IMAGE.
  821. * SEARCHTYPE - WHICH IF ANY KEYWORD TABLE TO MATCH.
  822. *
  823. * EXIT TOKENPOS - WHERE WE FOUND SOMETHING.
  824. * TOKENTYPE - CLASSIFICATION OF TOKEN.
  825. * TOKENVAL - BINARY VALUE IF NUMERIC.
  826. * TOKENSYM - KEYWORD IF ALPHA.
  827. * TOKENCHAR - FIRST OR ONLY CHARACTER OF TOKEN.
  828. * TOKENLEN - NUMBER OF CHARACTERS IN TOKEN.
  829. * KEYWDNDX - WHICH KEYWORD MATCHED IT.
  830. * SCANPOS - INCREMENTED BEYOND TOKEN.
  831. * CMDLIN - ANY MICROS ARE EXPANDED.
  832. *
  833. * MACROS GETCHAR.
  834. *
  835. * CALLS LENGTH, EXPAND, DSPLCOD.
  836. #
  837. ITEM TMP1, TMP2, TMP3;
  838. ITEM QUIT B;
  839. ITEM CMDLEN;
  840.  
  841. # TOKENSW MUST MATCH TYPST #
  842.  
  843. SWITCH TOKENSW TKDIGIT, TKPLUS, TKMINUS, TKDELIMIT,
  844. TKCOLON, TKPAREN,
  845. TKEQUAL, TKLETTER, TKSEMI, TKEOL, TKOTHER, TKCONTROL;
  846.  
  847. # ALPHANUM MUST MATCH KEYWDTYPE VALUES #
  848.  
  849. ITEM ALPHANUM=O"42000000000000000000"; # WHICH TYPES ALLOW DIGITS #
  850. PAGE # START OF TOKEN #
  851.  
  852.  
  853. TOKENSTART: # FIRST EAT ANY BLANKS #
  854.  
  855. CMDLEN=LENGTH(CMDLIN);
  856. GETCHAR(CMDLINE,SCANPOS,TMP1);
  857. WHYLE TMP1 EQ CBLANK DO
  858. BEGIN
  859. SCANPOS=SCANPOS+1;
  860. GETCHAR(CMDLINE,SCANPOS,TMP1);
  861. END
  862. # EAT ONE COMMA #
  863. IF TMP1 EQ CCOMMA THEN SCANPOS=SCANPOS+1;
  864. GETCHAR(CMDLINE,SCANPOS,TMP1);
  865. WHYLE TMP1 EQ CBLANK DO # EAT ADDITIONAL BLANKS #
  866. BEGIN
  867. SCANPOS=SCANPOS+1;
  868. GETCHAR(CMDLINE,SCANPOS,TMP1);
  869. END
  870.  
  871. # SET UP TOKEN DESCRIPTORS #
  872. # DISPATCH FOR TOKEN #
  873. TOKENPOS=SCANPOS;
  874. TOKENCHAR=TMP1;
  875. IF SCANPOS GQ CMDLEN OR TMP1 EQ CCOMMA THEN TOKENCHAR=CENDLINE;
  876. TOKENTYPE=TYPE[TOKENCHAR];
  877. SCANPOS=SCANPOS+1;
  878. GOTO TOKENSW[TOKENTYPE];
  879.  
  880. # END-OF-LINE AND NULL CASES #
  881. TKEOL: TKEQUAL: TKPLUS: TKSEMI:
  882. TKCOLON: TKDELIMIT: TKPAREN:
  883. TKOTHER: TKCONTROL:
  884. RETURN;
  885.  
  886.  
  887. TKMINUS: # HYPHEN IS SELF IF ALONE, COMMENT IF DOUBLE #
  888. GETCHAR(CMDLINE,TOKENPOS+1,TMP1);
  889. IF TMP1 EQ CMINUS THEN
  890. BEGIN
  891. TOKENTYPE=TYPST"EOL";
  892. TOKENCHAR=CENDLINE;
  893. TOKENPOS=LENGTH(CMDLIN);
  894. SCANPOS=TOKENPOS;
  895. END
  896. RETURN;
  897.  
  898.  
  899.  
  900. # NUMERIC CONSTANT #
  901. TKDIGIT:
  902. IF B<KEYWDTYPE,1>ALPHANUM NQ 0 THEN GOTO TKLETTER;
  903. TOKENVAL=TOKENCHAR-CDIGIT0;
  904. QUIT=FALSE;
  905. WHYLE NOT QUIT DO
  906. BEGIN
  907. GETCHAR(CMDLINE,SCANPOS,TMP1);
  908. IF TYPE[TMP1] EQ TYPST"DIGIT" AND SCANPOS-TOKENPOS LQ 10 THEN
  909. BEGIN
  910. TOKENVAL=TOKENVAL*10+TMP1-CDIGIT0;
  911. SCANPOS=SCANPOS+1;
  912. END
  913. ELSE QUIT=TRUE;
  914. END
  915. RETURN;
  916. # ALPHABETIC KEYWORD #
  917. TKLETTER:
  918. # GATHER UP KEYWORD, SUPPRESS CASE AND USE REGULAR CHAR #
  919. TMP1=TOKENCHAR;
  920. TOKENLEN=0;
  921. QUIT=FALSE;
  922. WHYLE NOT QUIT DO
  923. BEGIN
  924. DSPLCOD(TMP1);
  925. IF TOKENLEN LS 10 THEN
  926. BEGIN
  927. C<TOKENLEN,10-TOKENLEN>TOKENSYM=C<9,1>TMP1;
  928. TOKENLEN=TOKENLEN+1;
  929. END
  930. GETCHAR(CMDLINE,SCANPOS,TMP1);
  931. IF TYPE[TMP1] NQ TYPST"LETTER" THEN
  932. BEGIN
  933. IF TYPE[TMP1] NQ TYPST"DIGIT" OR
  934. B<KEYWDTYPE,1>ALPHANUM EQ 0 THEN
  935. BEGIN
  936. QUIT=TRUE;
  937. TEST;
  938. END
  939. END
  940. SCANPOS=SCANPOS+1;
  941. END
  942.  
  943. # KEYWORD SEARCH #
  944.  
  945. KEYWDNDX=-1;
  946. IF KEYWDTYPE EQ 0 THEN RETURN;
  947.  
  948. MATCHKEY(TMP3);
  949.  
  950. IF KEYWDNDX LS 0 THEN RETURN;
  951. TMP3=MIN(TMP3,TOKENLEN);
  952. SCANPOS=TOKENPOS+TMP3;
  953. TOKENLEN=TMP3;
  954.  
  955. END # OF TOKEN #
  956. PAGE # SCANNER - UNIVERSAL SYNTAX DRIVER #
  957.  
  958.  
  959. PROC SCANNER;
  960. IOBEGIN(SCANNER)
  961. #
  962. ** SCANNER - MASTER COMMAND SYNTAX SCANNER/DEFAULTER.
  963. *
  964. * SCANNER DRIVES ALL SYNTAX SCANNING FOR THOSE COMMANDS
  965. * WHICH HAVE FAIRLY STANDARD SYNTACTICAL RULES AND SEMANTIC
  966. * ELEMENTS. THIS CATEGORY OF COMMANDS INCLUDES ALL WHICH
  967. * USE RANGES, LINES, POSITIONS, LIMITS, AND TABS. OTHER
  968. * SYNTAXES SUPPORTED BY SCANNER INCLUDE "FORWARD" AND
  969. * "BACKWARD" KEYWORD, I.E., DIRECTION/DEFAULT-RANGE, AND
  970. * CHARACTER STRINGS. ON THE OTHER HAND, SCANNER IS NOT
  971. * DESIGNED TO SUPPORT PARSING OF COMMANDS SUCH AS "SET"
  972. * WHICH REQUIRE SPECIAL KEYWORDS, ARBITRARY SYMBOL NAMES, OR
  973. * INTEGER PARAMETERS.
  974. *
  975. * SCANNER OPERATES AS A LOOP UNTIL END OF COMMAND LINE OR
  976. * END OF COMMAND DELIMITER (SEMICOLON), BRANCHING OUT ON A
  977. * CASE STATEMENT FOR EACH TOKEN ENCOUNTERED. VARIOUS SCAN
  978. * SUBROUTINES ARE USED HEAVILY.
  979. *
  980. * ENTRY COMMAND VERB SCANNED, TOKEN ADVANCED.
  981. * TOKENPOS - SETUP.
  982. * THE FOLLOWING MUST BE DEFAULTED BY CALLER -
  983. * NONDEFAULT, TXTINCMD, BACKWARD, FORWARD,
  984. * FOUND, CURRENT, CURFILE, CURSPLIT.
  985. * LIMIT - DEFAULT LIMIT COUNT. USUALLY -1 TO SHOW
  986. * THAT NORMAL DEFAULTS CAN APPLY. CAN ALSO BE
  987. * -2 TO SHOW NO DEFAULTS TO BE SUPPLIED.
  988. * WHICHLIN - WHICH LINE POINTER VARIABLE EXPECTED.
  989. * WHICHSTR - WHICH STRING VARIABLE EXPECTED.
  990. * CURCURSOR, OLDCURSOR - RESIDUAL CURSOR POSITIONS.
  991. * OLDLINPTR - RESIDUAL LINE POINTER.
  992. * EXECNDX - WHICH COMMAND WE ARE PROCESSING.
  993. * NUMMARKS - HOW MANY MARKS ARE AVAILABLE.
  994. * SCREENMODE - WHETHER SCREEN OR LINE.
  995. * TOPF(), TOPS(), BOTS(), ASCII[] - SETUP.
  996. * BOTF(), FDLF() - SETUP.
  997. *
  998. * EXIT LINPTR1,2,3 - SOURCE AND TARGET ADDRESSES.
  999. * FILPTR1,2,3 - SOURCE AND TARGET FILE BRACKETS.
  1000. * CHRPTR1,2,3 - SOURCE AND TARGET CURSORS.
  1001. * LINNUM1,2,3 - SOURCE AND TARGET SEQUENCES.
  1002. * LIMIT - REPEAT COUNT. UNCHANGED IF NO EXPLICIT SYNTAX
  1003. * AND DEFAULT WAS -2.
  1004. * SCANBLOCK, SCANWORD, SCANUPPER - SPECIAL OPTIONS.
  1005. * SCANHOME - SPECIAL OPTION.
  1006. * NONDEFAULT - TRUE IF SOMETHING SCANNED.
  1007. * SCANPOS - ADVANCED BEYOND LAST RECOGNIZABLE SYNTAX.
  1008. * BACKWARD, FORWARD - POSSIBLY SET.
  1009. * CHARRANGE - CHARACTER/LINE RANGE BOUNDS.
  1010. * TXTINCMD - POSSIBLY TRUE.
  1011. * FOUND - WHETHER SOURCE/TARGET IN BOUNDS.
  1012. * FDLF(1-2) - DIFFERENT FILES MAY BE OPEN.
  1013. * CURFILE - FILE TO PROCESS FOR SOURCE RANGE.
  1014. * PROMPTING - POSSIBLY SET.
  1015. * LOCSTRING1, LOCSTRING2, CHGSTRING, TTYLIN - POSSIBLY
  1016. * FILLED WITH CHARACTER STRINGS IN INTERNAL FORMAT.
  1017. * TABVECTOR - POSSIBLY REDEFINED.
  1018. * FIELDNDX, FIELDFLG, FIELDTARGET - POSSIBLY SET.
  1019. * NUMMARKS - POSSIBLY CLEARED.
  1020. * EXECNDX - CERTAIN CHANGES POSSIBLE.
  1021. *
  1022. * USES ALL TOKENXXXX VARIABLES, WHICHLIN, WHICHDGT, WHICHSTR,
  1023. * FILNUM, FORCEFIELD, READNAM, FOUNDOTHER.
  1024. *
  1025. * CALLS TOKEN, SCNTAB, MAX, SCNLIN, ERRJUMP, SCANSTR,
  1026. * SCNFILE, FORCEFILE, GETMARK, PAINTMARKS, SCNEOC,
  1027. * CHECKFILPTR, REL2ABS, WINDOPOS, WINDOLIN, SQUELCH.
  1028. #
  1029.  
  1030. XREF LABEL QQSINGLE;
  1031.  
  1032. # SCANSW MUST MATCH TYPST #
  1033.  
  1034. SWITCH SCANSW SCDIGIT, SCPLUS, SCMINUS, SCDELIMIT,
  1035. SCCOLON,
  1036. SCPAREN, SCEQUAL, SCALPHA,
  1037. SCSEMI, SCEOL, SCOTHER, SCCTRL;
  1038.  
  1039. # KEYMATCH ARRAY MUST MATCH SECTION OF KEYSTR TABLE #
  1040. # MUST ALSO MATCH SCANKEYSW. #
  1041.  
  1042. DEF NUMSCANKEYS #20#;
  1043.  
  1044. ARRAY MATCHKEYS [0:NUMSCANKEYS]; ITEM KEYMATCH C(0,0,10) = [
  1045. "ALL", "BLANK", "CURRENT", "END", "FIRST", "HOME",
  1046. "IN", "LAST", "MARK", "NEXT", "PREVIOUS", "QUIET",
  1047. "REPEAT", "SCREEN", "TO", "UPPER", "WORD", "X", "Y", "Z" ];
  1048.  
  1049. SWITCH SCANKEYSW SKALL, SKBLOCK, SKCURRENT, SKEND, SKFIRST,
  1050. SKHOME, SKIN, SKLAST, SKMARK, SKNEXT, SKPREVIOUS, SKQUIET,
  1051. SKREPEAT, SKSCREEN, SKTO, SKUPPER, SKWORD, SKX, SKY, SKZ;
  1052.  
  1053. # FOLLOWING TEMPORARIES MUST BE USED ONLY INSTANTANEOUSLY #
  1054. ITEM TMP1, TMP2, BOOL B;
  1055.  
  1056.  
  1057. PROC GETMARK(WHICH,LINPARM,FILPARM,CHRPARM);
  1058. BEGIN
  1059. #
  1060. ** GETMARK - GET DATA FOR A MARKER.
  1061. *
  1062. * ENTRY WHICH - WHICH MARKER, 1 OR 2.
  1063. *
  1064. * EXIT LINPARM, FILPARM, CHRPARM - MARKER VALUES.
  1065. * CHARRANGE - FORCED TRUE AS NEEDED.
  1066. #
  1067. ITEM WHICH, LINPARM, FILPARM, CHRPARM;
  1068. LINPARM=REGLINE[MARKREG-1+WHICH]-REGLINE[MARKTOP-1+WHICH];
  1069. FILPARM=MRKFILE[WHICH-1];
  1070. CHRPARM=MRKCHAR[WHICH-1];
  1071. IF CHRPARM GQ 0 THEN CHARRANGE=TRUE;
  1072. END # OF GETMARK #
  1073. PAGE # SCANNER - MAIN CODE #
  1074.  
  1075. CHRPTR1=-1;
  1076. CHRPTR2=-1;
  1077. CHRPTR3=-1;
  1078. LINPTR1=-1;
  1079. LINPTR2=-1;
  1080. LINPTR3=-1;
  1081. FILPTR1=0;
  1082. FILPTR2=0;
  1083. FILPTR3=0;
  1084. LINNUM1=-1;
  1085. LINNUM2=-1;
  1086. LINNUM3=-1;
  1087. SCANBLOCK=FALSE;
  1088. SCANWORD=FALSE;
  1089. SCANUPPER=FALSE;
  1090. SCANHOME=FALSE;
  1091. SCANMARK = FALSE;
  1092. SCANSFILE = FALSE;
  1093. SCANTO = FALSE;
  1094. SCNLINX = FALSE;
  1095. SCNLINY = FALSE;
  1096. SCNLINZ = FALSE;
  1097. SCNONCE = FALSE;
  1098. SCHSTRSPEC=FALSE;
  1099. WHICHDGT=WHICHLIN;
  1100. KEYWDTYPE=2;
  1101. SCANPOS=TOKENPOS;
  1102. FORCEFIELD=FALSE;
  1103. FIELDTARGET=0;
  1104.  
  1105. # FILE EXTENSION IS ONLY ALLOWED IN SINGLE USER VERSION #
  1106. # FOR THREE SPECIFIC COMMAND TYPES #
  1107.  
  1108. IF EXTENDSIZE NQ 0 THEN
  1109. BEGIN
  1110. IF OKEXTEND[PROCESSNDX] THEN
  1111. BEGIN
  1112. CONTROL IFEQ MULTI,1;
  1113. GOTO QQSINGLE;
  1114. CONTROL FI;
  1115. END
  1116. ELSE
  1117. BEGIN
  1118. EXTENDSIZE=0;
  1119. END
  1120. END
  1121. PAGE # MAIN SCANNER LOOP STARTS HERE #
  1122.  
  1123.  
  1124. SCANTOKEN:
  1125. TOKEN;
  1126. SCANLOOP:
  1127. GOTO SCANSW[TOKENTYPE];
  1128.  
  1129.  
  1130. SCDIGIT:
  1131. IF WHICHDGT EQ DIGITST"LIMIT" THEN
  1132. BEGIN
  1133. LIMIT=MAX(TOKENVAL,1);
  1134. NONDEFAULT=TRUE;
  1135. TOKEN;
  1136. WHICHDGT=WHICHLIN;
  1137. END
  1138. ELSE SCNLIN;
  1139. GOTO SCANLOOP;
  1140.  
  1141. SCPLUS: SCMINUS:
  1142. SCNLIN;
  1143. GOTO SCANLOOP;
  1144.  
  1145. SCCOLON:
  1146. WHICHLIN=2;
  1147. WHICHDGT=2;
  1148. GOTO SCANTOKEN;
  1149.  
  1150. SCPAREN:
  1151. SCNLIN;
  1152. GOTO SCANLOOP;
  1153.  
  1154. SCDELIMIT:
  1155. IF WHICHSTR LQ 0 THEN ERRJUMP("STRING NOT ALLOWED$");
  1156. IF NOT FORCEFIELD THEN
  1157. BEGIN
  1158. FIELDFLG=FALSE; FIELDNDX=0;
  1159. END
  1160. SCANSTR;
  1161. GOTO SCANLOOP;
  1162.  
  1163.  
  1164. SKALL:
  1165. IF WHICHDGT EQ DIGITST"LIMIT" THEN
  1166. BEGIN
  1167. LIMIT=LARGENUM;
  1168. TOKEN;
  1169. END
  1170. ELSE
  1171. BEGIN
  1172. IF LINPTR1 NQ -1 OR LINPTR2 NQ -1 THEN
  1173. BEGIN
  1174. ERRJUMP("ONLY ONE RANGE ALLOWED$");
  1175. END
  1176. FILNUM=CURFILE;
  1177. TOKEN;
  1178. IF TOKENTYPE EQ TYPST"PAREN" THEN
  1179. BEGIN
  1180. SCNFILE(READNAM);
  1181. SCANSFILE = TRUE; # NOTE THAT WE HAVE SCANNED #
  1182. FORCEFILE;
  1183. END
  1184. LINPTR1=1;
  1185. LINPTR2=BOTF(FILNUM)-1-TOPF(FILNUM);
  1186. FILPTR1=FDLF(FILNUM);
  1187. WHICHLIN=3;
  1188. WHICHDGT=WHICHLIN;
  1189. NONDEFAULT=TRUE;
  1190. END
  1191. GOTO SCANLOOP;
  1192.  
  1193. SKBLOCK:
  1194. SCANBLOCK=TRUE;
  1195. GOTO SCANTOKEN;
  1196.  
  1197. SKEND:
  1198. IF OKEND[PROCESSNDX] THEN EXECNDX=EXECST"APPEND";
  1199. ELSE ERRJUMP("CHARACTER SEQUENCE NOT RECOGNIZED$");
  1200. GOTO SCANTOKEN;
  1201.  
  1202. SKHOME:
  1203. IF OKHOME[PROCESSNDX] THEN SCANHOME=TRUE;
  1204. ELSE ERRJUMP("CHARACTER SEQUENCE NOT RECOGNIZED$");
  1205. GOTO SCANTOKEN;
  1206.  
  1207. SKPREVIOUS:
  1208. IF OKMOVE[PROCESSNDX] AND WHICHLIN GR 3 THEN
  1209. BEGIN
  1210. # NOTE "TO PREVIOUS" IS A SPECIAL CASE FOR COPY/MOVE WITH NO #
  1211. # ADDITIONAL SYNTAX ALLOWED, AND SEMANTICS DETERMINED BY #
  1212. # CHARACTER VERSUS LINE BOUNDARIES FOR SOURCE RANGE #
  1213. IF NOT CHARRANGE THEN
  1214. BEGIN
  1215. FILNUM=CURFILE;
  1216. EXTENDFILE(FALSE);
  1217. LINPTR3=CURRENT-TOPF(CURFILE)-1;
  1218. END
  1219. END
  1220. ELSE
  1221. BEGIN
  1222. IF FORWARD OR BACKWARD THEN ERRJUMP("ONLY ONE RANGE ALLOWED$");
  1223. WHICHDGT=DIGITST"LIMIT";
  1224. NONDEFAULT=TRUE;
  1225. IF LIMIT EQ -1 THEN LIMIT=1;
  1226. BACKWARD=TRUE;
  1227. FORWARD=FALSE;
  1228. END
  1229. GOTO SCANTOKEN;
  1230.  
  1231. SKCURRENT: SKFIRST: SKLAST: SKX: SKY: SKZ:
  1232. # NOTE SCNLIN CAN ENABLE CHARRANGE FOR X,Y,Z #
  1233. SCNLIN;
  1234. GOTO SCANLOOP;
  1235.  
  1236. SKMARK:
  1237. SCANMARK = TRUE;
  1238. IF CMDWASDLTE[0] THEN
  1239. BEGIN # IF COMMAND WAS "DELETE" #
  1240. KILLMARKS = TRUE; # KILL THE MARKS #
  1241. FORCEAUTOP[0] = FALSE;
  1242. FORCEAUTOR[0] = FALSE;
  1243. END
  1244. IF NUMMARKS NQ 0 THEN
  1245. BEGIN
  1246. # NOTE GETMARK ROUTINE CAN ENABLE CHARRANGE #
  1247. IF WHICHLIN EQ 3 THEN GETMARK(1,LINPTR3,FILPTR3,CHRPTR3);
  1248. ELSE
  1249. BEGIN
  1250. GETMARK(1,LINPTR1,FILPTR1,CHRPTR1);
  1251. GETMARK(2,LINPTR2,FILPTR2,CHRPTR2);
  1252. END
  1253. NONDEFAULT=TRUE;
  1254. NUMMARKS = 2;
  1255. END
  1256. WHICHLIN=3;
  1257. WHICHDGT=WHICHLIN;
  1258. IF NOT FORCEFIELD THEN
  1259. BEGIN # IF NO *IN* OPTION ON THIS COMMAND #
  1260. FIELDNDX = 0; # ELIMINATE TAB FIELD RESTRICTION #
  1261. FIELDFLG = FALSE;
  1262. END
  1263. GOTO SCANTOKEN;
  1264.  
  1265. SKNEXT:
  1266. IF OKMOVE[PROCESSNDX] AND WHICHLIN GR 3 THEN
  1267. BEGIN
  1268. # NOTE "TO NEXT" IS A SPECIAL CASE FOR COPY/MOVE WITH NO #
  1269. # ADDITIONAL SYNTAX ALLOWED, AND SEMANTICS DETERMINED BY #
  1270. # CHARACTER VERSUS LINE BOUNDARIES FOR SOURCE RANGE #
  1271. IF NOT CHARRANGE THEN
  1272. BEGIN
  1273. FILNUM=CURFILE;
  1274. EXTENDFILE(FALSE);
  1275. LINPTR3=CURRENT-TOPF(CURFILE);
  1276. END
  1277. END
  1278. ELSE
  1279. BEGIN
  1280. IF FORWARD OR BACKWARD THEN ERRJUMP("ONLY ONE RANGE ALLOWED$");
  1281. WHICHDGT=DIGITST"LIMIT";
  1282. IF LIMIT EQ -1 THEN LIMIT=1;
  1283. FORWARD=TRUE;
  1284. BACKWARD=FALSE;
  1285. NONDEFAULT=TRUE;
  1286. END
  1287. GOTO SCANTOKEN;
  1288.  
  1289. SKQUIET:
  1290. DONTPRINT=TRUE;
  1291. GOTO SCANTOKEN;
  1292.  
  1293. SKREPEAT:
  1294. NONDEFAULT=TRUE;
  1295. IF LIMIT EQ -1 THEN LIMIT=1;
  1296. WHICHDGT=DIGITST"LIMIT";
  1297. GOTO SCANTOKEN;
  1298.  
  1299. SKSCREEN:
  1300. IF LINPTR1 NQ -1 OR LINPTR2 NQ -1 THEN
  1301. BEGIN
  1302. ERRJUMP("ONLY ONE RANGE ALLOWED$");
  1303. END
  1304. IF SCREENMODE THEN
  1305. BEGIN
  1306. LINPTR1=TOPS(CURSPLIT)+1-TOPF(CURFILE);
  1307. LINPTR2=BOTS(CURSPLIT)-1-TOPF(CURFILE);
  1308. IF WHICHLIN GQ 3 THEN
  1309. BEGIN
  1310. LINPTR3=LINPTR2;
  1311. IF BACKWARD THEN LINPTR3=LINPTR1;
  1312. END
  1313. NONDEFAULT=TRUE;
  1314. DONTPRINT=TRUE;
  1315. END
  1316. ELSE ERRJUMP("SCREEN MODE REQUIRED$");
  1317. WHICHLIN=3;
  1318. WHICHDGT=WHICHLIN;
  1319. GOTO SCANTOKEN;
  1320.  
  1321. SKIN:
  1322. WHICHDGT=DIGITST"TAB";
  1323. TOKEN; # ADVANCE NEXT SYNTAX #
  1324. SCNTAB; # ANALYZE AND SET *IN* MARGINS #
  1325. GOTO SCANLOOP;
  1326.  
  1327. SKTO:
  1328. IF NOT OKTARGET[PROCESSNDX] THEN
  1329. BEGIN
  1330. ERRJUMP("PARAMETER NOT VALID FOR THIS DIRECTIVE$");
  1331. END
  1332. SCANTO = TRUE;
  1333. SCNONCE = FALSE;
  1334. WHICHLIN=4;
  1335. WHICHDGT=WHICHLIN;
  1336. NONDEFAULT=TRUE;
  1337. GOTO SCANTOKEN;
  1338.  
  1339. SKWORD:
  1340. SCANWORD=TRUE;
  1341. GOTO SCANTOKEN;
  1342.  
  1343. SKUPPER:
  1344. SCANUPPER=TRUE;
  1345. IF NOT OKUPPER[PROCESSNDX] THEN
  1346. BEGIN
  1347. ERRJUMP("PARAMETER NOT VALID FOR THIS DIRECTIVE$");
  1348. END
  1349. GOTO SCANTOKEN;
  1350.  
  1351.  
  1352. SCALPHA:
  1353. FOR TMP1=0 STEP 1 WHILE KEYWDNDX GQ 0 AND TMP1 LQ NUMSCANKEYS DO
  1354. BEGIN
  1355. IF KEYMATCH[TMP1] EQ KEYWORD[KEYWDNDX]
  1356. THEN GOTO SCANKEYSW[TMP1];
  1357. END
  1358. ERRJUMP("CHARACTER SEQUENCE NOT RECOGNIZED$");
  1359.  
  1360.  
  1361. SCSEMI: SCEOL: SCOTHER: SCCTRL: SCEQUAL:
  1362.  
  1363. # VERIFY END OF SYNTAX #
  1364.  
  1365. SCNEOC;
  1366.  
  1367. # VERIFY SOURCE RANGE WITHIN ONE FILE, AND CONVERT FILE SELECTIONS #
  1368. # FROM FILE DIRECTORY IDS INTO OPEN BRACKET ORDINALS #
  1369.  
  1370. IF FILPTR2 NQ 0 THEN
  1371. BEGIN
  1372. IF FILPTR1 NQ 0 AND FILPTR1 NQ FILPTR2
  1373. THEN ERRJUMP("RANGE MUST BE IN SAME FILE$");
  1374. FILPTR1=FILPTR2;
  1375. END
  1376. CHECKFILPTR; # CONVERT FILPTR1 #
  1377. FILPTR2=FILPTR1; # AND FILPTR2 ALSO #
  1378.  
  1379. # VERIFY THAT BOTH FILES FOR A DUAL-FILE OPERATION CAN BE #
  1380. # OPENED INTO THE TWO BRACKETS, AND CONVERT TARGET FILE SELECTION #
  1381. # FROM FILE DIRECTORY ID INTO OPEN BRACKET ORDINAL #
  1382.  
  1383. IF FILPTR1 NQ 0 AND FILPTR3 NQ 0 AND FILPTR1 NQ FILPTR3
  1384. THEN CURFILE=FILPTR1; # ASSURE NEEDED FILES AVAIL #
  1385. FILPTR1 = = FILPTR3;
  1386. CHECKFILPTR; # CONVERT FILPTR3 #
  1387. FILPTR3 = = FILPTR1;
  1388. IF FILPTR3 EQ 0 THEN FILPTR3=CURFILE;
  1389.  
  1390. # CONVERT LINPTRS TO ABSOLUTE WORKFILE ORDINALS #
  1391.  
  1392. REL2ABS(LINPTR1,FILPTR1);
  1393. REL2ABS(LINPTR2,FILPTR2);
  1394. REL2ABS(LINPTR3,FILPTR3);
  1395.  
  1396. # NOW FILL IN DEFAULTS #
  1397.  
  1398. IF LIMIT EQ -1 THEN
  1399. BEGIN
  1400. IF LINPTR2 EQ -1 THEN LIMIT=1;
  1401. ELSE LIMIT=LARGENUM;
  1402. END
  1403.  
  1404. IF LINPTR1 EQ -1 THEN
  1405. BEGIN
  1406. CHRPTR1=0;
  1407. IF FORWARD AND NOT OKSEARCH[PROCESSNDX] THEN LINPTR1=CURRENT+1;
  1408. ELSE IF BACKWARD THEN
  1409. BEGIN
  1410. IF OKSEARCH[PROCESSNDX] THEN
  1411. BEGIN
  1412. LINPTR1=CURRENT;
  1413. IF CURCURSOR GR 0 THEN CHRPTR1=CURCURSOR-1;
  1414. ELSE
  1415. BEGIN
  1416. CHRPTR1=BUFCM1;
  1417. LINPTR1=CURRENT-1;
  1418. END
  1419. END
  1420. ELSE LINPTR1=CURRENT-1;
  1421. END
  1422. ELSE
  1423. BEGIN
  1424. LINPTR1=CURRENT;
  1425. IF SCANWORD OR CHARRANGE THEN CHRPTR1=CURCURSOR;
  1426. IF OKSEARCH[PROCESSNDX] THEN
  1427. BEGIN
  1428. CHRPTR1=CURCURSOR;
  1429. IF LASTPROCESS EQ PROCESSNDX
  1430. AND (NOT(SCHSTRSPEC) OR FORWARD)
  1431. AND CURCURSOR EQ OLDCURSOR
  1432. AND LINPTR1 EQ OLDLINPTR
  1433. THEN CHRPTR1=CHRPTR1+STRINGLEN;
  1434. END
  1435. END
  1436. FILPTR1=CURFILE;
  1437. END
  1438.  
  1439. IF LINPTR2 EQ -1 THEN
  1440. BEGIN
  1441. FILNUM=FILPTR1;
  1442. IF FILNUM EQ 0 THEN FILNUM=CURFILE;
  1443. IF BACKWARD THEN LINPTR2=TOPF(FILNUM)+1;
  1444. ELSE LINPTR2=BOTF(FILNUM)-1;
  1445. END
  1446.  
  1447. IF LINPTR3 EQ -1 THEN
  1448. BEGIN
  1449. FILNUM=FILPTR3;
  1450. EXTENDFILE(TRUE);
  1451. LINPTR3=CURRENT;
  1452. CHRPTR3=CURCURSOR;
  1453. END
  1454.  
  1455. IF OKSEARCH[PROCESSNDX] AND (BACKWARD OR LINPTR1 GR LINPTR2) THEN
  1456. BEGIN
  1457. IF CHRPTR1 LS 0 THEN CHRPTR1=BUFCM1;
  1458. IF CHRPTR2 LS 0 THEN CHRPTR2=0;
  1459. END
  1460. CHRPTR1=MAX(CHRPTR1,0);
  1461. IF CHRPTR2 LS 0 THEN CHRPTR2=BUFCM1;
  1462. IF CHRPTR2 EQ 0 AND NOT (CHARRANGE OR OKSEARCH[PROCESSNDX])
  1463. THEN CHRPTR2=BUFCM1;
  1464. IF CHRPTR3 LS 0 THEN
  1465. BEGIN
  1466. IF CHARRANGE THEN CHRPTR3=CURCURSOR;
  1467. ELSE CHRPTR3=0;
  1468. END
  1469.  
  1470. WINDOPOS(LINPTR3,FILPTR3);
  1471.  
  1472. # SINGLE USER VERSION ONLY MUST MAKE FILE EXTENSION EXACT #
  1473.  
  1474. CONTROL IFEQ SINGLE,1;
  1475. IF THISEXTEND NQ 0 THEN
  1476. BEGIN
  1477. PUSH;
  1478. CURFILE=FILPTR3;
  1479. WHYLE LINPTR3 LS BOTF(FILPTR3)-1 AND THISEXTEND GR 0 DO
  1480. BEGIN
  1481. POSZ(BOTF(FILPTR3)-1);
  1482. DELX;
  1483. THISEXTEND=THISEXTEND-1;
  1484. IF CURRENT LS LINPTR1 THEN LINPTR1=LINPTR1-1;
  1485. IF CURRENT LS LINPTR2 THEN LINPTR2=LINPTR2-1;
  1486. END
  1487. POP;
  1488. END
  1489. WINDOPOS(LINPTR3,FILPTR3);
  1490. CONTROL FI;
  1491.  
  1492. IF FILPTR1 EQ 0 THEN FILPTR1=CURFILE;
  1493. CURFILE=FILPTR1;
  1494. WINDOLIN(LINPTR1,CURFILE);
  1495. FOUNDOTHER=FOUND;
  1496. WINDOLIN(LINPTR2,CURFILE);
  1497. FOUND=FOUND AND FOUNDOTHER;
  1498.  
  1499. IF LINPTR1 GR LINPTR2
  1500. OR (LINPTR1 EQ LINPTR2 AND CHRPTR1 GR CHRPTR2) THEN
  1501. BEGIN
  1502. BACKWARD=TRUE;
  1503. LINPTR1 = = LINPTR2;
  1504. CHRPTR1 = = CHRPTR2;
  1505. END
  1506.  
  1507. IF BACKWARD AND NOT OKREVERSE[PROCESSNDX] THEN
  1508. BEGIN
  1509. BACKWARD=FALSE;
  1510. IF LIMIT LS LARGENUM
  1511. THEN LINPTR1=MAX(LINPTR1,LINPTR2-MAX(LIMIT,1)+1);
  1512. END
  1513.  
  1514. IF WHICHSTR NQ 0 AND ASCII[CURFILE] LQ 1 THEN
  1515. BEGIN
  1516. SQUELCH(LOCSTRING1);
  1517. SQUELCH(LOCSTRING2);
  1518. SQUELCH(CHGSTRING1);
  1519. SQUELCH(TTYLIN);
  1520. END
  1521.  
  1522. IOEND # OF SCANNER #
  1523. PAGE # SCAN STUFF -- SCNLIN #
  1524.  
  1525.  
  1526. PROC SCNLIN;
  1527. IOBEGIN(SCNLIN)
  1528. #
  1529. ** SCNLIN - SCAN LINE ADDRESS SYNTAX.
  1530. *
  1531. * SCNLIN IS CAPABLE OF PARSING ONE LINE ADDRESS EXPRESSION.
  1532. * IT IS INTENDED TO BE CALLED ONLY BY SCANNER. SCNLIN
  1533. * ASSUMES THE CALLER HAS POSITIONED THE TOKEN AT A
  1534. * GENUINE LINE ADDRESS EXPRESSION.
  1535. *
  1536. * ENTRY WHICHLIN - WHICH LINE PARAMETER TO SET.
  1537. * LINPTR1,2,3 - POSSIBLE PARAMETERS.
  1538. * CHRPTR1,2,3 - DITTO.
  1539. * FILPTR1,2,3 - DITTO.
  1540. * LINNUM1,2,3 - DITTO.
  1541. * CURFILE - DEFAULT FILE BRACKET.
  1542. * TOKENPOS, SCANPOS - BRACKET CURRENT SYNTAX.
  1543. * CURF(), TOPF(), BOTF() - SETUP.
  1544. * NUMBERED[] - SETUP.
  1545. * REGLINE[XYZREG], REGLINE[XYZTOP] - SETUP.
  1546. * XYZCHAR[], XYZFILE[] - SETUP.
  1547. *
  1548. * EXIT ONE SET OF LINPTRX, CHRPTRX, FILPTRX, LINNUMX -
  1549. * DESCRIBE SCANNED EXPRESSION.
  1550. * OTHER SETS OF LINPTRX, CHRPTRX, FILPTRX, LINNUMX -
  1551. * USED TEMPORARILY THEN RESTORED.
  1552. * IF FILPTRX SET, IN FDLF FORMAT NOT BRACKET.
  1553. * FILE BRACKETS POSSIBLY RE-OPENED.
  1554. * CHARRANGE - CAN BE FORCED TRUE FOR X,Y,Z.
  1555. * PAGELAST - FALSE.
  1556. * NONDEFAULT - TRUE.
  1557. * WHICHLIN - INCREMENTED.
  1558. * WHICHDGT - MATCHES WHICHLIN.
  1559. * SCANPOS, TOKENPOS - ADVANCED BEYOND SYNTAX.
  1560. *
  1561. * USES READNAM, FILNUM, ORIGSCNLIN, TEMP(RESTORES),
  1562. * ALL TOKENXXXX VARIABLES.
  1563. *
  1564. * CALLS PUSHTEMP, MIN, SCNFILE, ERRJUMP, FORCEFILE,
  1565. * TOKEN, PUSH, POSN, POP, POPTEMP.
  1566. #
  1567.  
  1568. # SCNLINSW MUST MATCH TYPST. SLKEYSW MATCHES LINEKEYWD. #
  1569.  
  1570. SWITCH SCNLINSW SLDIGIT, SLPLUS, SLMINUS, SLDELIMIT,
  1571. SLCOLON,
  1572. SLPAREN, SLEQUAL, SLLETTER, SLSEMI,
  1573. SLEOL, SLOTHER, SLCONTROL;
  1574.  
  1575. SWITCH SLKEYSW SLCURRENT, SLFIRST, SLLAST, SLX, SLY, SLZ;
  1576.  
  1577. ARRAY LINEKEYS[0:5]; ITEM LINEKEYWD C(0,0,10) = [ "CURRENT",
  1578. "FIRST", "LAST", "X", "Y", "Z" ];
  1579.  
  1580. ITEM TMP1; # CAN BE USED ONLY INSTANTANEOUSLY #
  1581.  
  1582. WHICHLIN=MIN(WHICHLIN,3);
  1583. IF WHICHLIN NQ 2 THEN ORIGSCNLIN=TOKENPOS;
  1584. FILNUM=CURFILE;
  1585. NONDEFAULT=TRUE;
  1586. PAGELAST=FALSE; # SINCE NON-DEFAULT USED #
  1587. PUSHTEMP; # ALLOCATE TEMP VARIABLE FOR SCRATCH #
  1588. IF WHICHLIN EQ 2 THEN
  1589. BEGIN
  1590. IF FILPTR1 NQ 0 AND FDLF(CURFILE) NQ FILPTR1
  1591. THEN FILNUM=CURFILE LXR 3;
  1592. LINPTR1 == LINPTR2;
  1593. FILPTR1 == FILPTR2;
  1594. LINNUM1 == LINNUM2;
  1595. CHRPTR1 == CHRPTR2;
  1596. END
  1597. ELSE IF WHICHLIN EQ 3 THEN
  1598. BEGIN
  1599. LINPTR1 == LINPTR3;
  1600. FILPTR1 == FILPTR3;
  1601. LINNUM1 == LINNUM3;
  1602. CHRPTR1 == CHRPTR3;
  1603. END
  1604.  
  1605. CHRPTR1=0; # DEFAULT CHARACTER POINTERS #
  1606. IF WHICHLIN EQ 2 THEN CHRPTR1=BUFCM1;
  1607.  
  1608.  
  1609. SCNLINLOOP: # THIS IS THE MAIN LOOP #
  1610. GOTO SCNLINSW[TOKENTYPE]; # DISPATCH BY SYNTAX #
  1611.  
  1612. SLDELIMIT: SLCOLON:
  1613. SLSEMI: SLEOL: SLOTHER: SLCONTROL: SLEQUAL:
  1614. GOTO SLDONE;
  1615.  
  1616. SLPAREN:
  1617. # SCAN FILE NAME. IF MATCHES CURRENT FILE, WE CAN CONTINUE #
  1618. # SCANNING. IF NOT, WE MUST ACCESS FILE AND RE-START ENTIRE#
  1619. # SCAN SO THAT RELOCATABLE VALUES WILL BE FRESH. #
  1620. IF SCANSFILE THEN
  1621. BEGIN # IF ALREADY SCANNED SOURCE #
  1622. IF NOT SCANTO THEN
  1623. BEGIN # IF NO *TO* #
  1624. ERRJUMP ("*TO* REQUIRED BEFORE DESTINATION FILE$");
  1625. END
  1626. END
  1627. SCNFILE(READNAM);
  1628. IF READNAM NQ PADNAME(FILENAM[FILNUM]) THEN
  1629. BEGIN
  1630. IF WHICHLIN EQ 2 THEN
  1631. BEGIN
  1632. WHICHLIN=1;
  1633. LINPTR2=-1;
  1634. FILPTR2=0;
  1635. LINNUM2=-1;
  1636. CHRPTR2=-1;
  1637. END
  1638. FORCEFILE;
  1639. LINPTR1=CURF(FILNUM)-TOPF(FILNUM);
  1640. FILPTR1=FDLF(FILNUM); # ASSURE ONLY ONE MORE TRY #
  1641. IF SCNONCE THEN
  1642. BEGIN # IF ERROR IN SYNTAX #
  1643. TMP1 = 0;
  1644. IF SCNLINZ THEN TMP1 = O"32";
  1645. IF SCNLINY THEN TMP1 = O"31";
  1646. IF SCNLINX THEN TMP1 = O"30";
  1647. IF TMP1 EQ 0 THEN
  1648. BEGIN # IF NOT *XYZ* ERROR #
  1649. TOKENPOS = ORIGSCNLIN;
  1650. ERRJUMP ("ONLY ONE RANGE ALLOWED$");
  1651. END
  1652. GOTO SLERROR;
  1653. END
  1654. SCNONCE = TRUE;
  1655. SCANPOS=ORIGSCNLIN; # FORCE ENTIRE EXPRESSION RESCAN #
  1656. TOKEN;
  1657. GOTO SCNLINLOOP;
  1658. END
  1659. ELSE
  1660. BEGIN
  1661. SCANSFILE = TRUE;
  1662. IF NOT SCANTO THEN
  1663. BEGIN # IF NOT TARGET FILE #
  1664. TMP1 = 0;
  1665. IF SCNLINZ AND XYZFILE[2] NQ FDLF(FILNUM) THEN TMP1 = O"32";
  1666. IF SCNLINY AND XYZFILE[1] NQ FDLF(FILNUM) THEN TMP1 = O"31";
  1667. IF SCNLINX AND XYZFILE[0] NQ FDLF(FILNUM) THEN TMP1 = O"30";
  1668. IF TMP1 NQ 0 THEN GOTO SLERROR;
  1669. END
  1670. END
  1671. GOTO SLDONE;
  1672.  
  1673. SLCURRENT:
  1674. IF WHICHLIN EQ 3 THEN EXTENDFILE(FALSE);
  1675. LINPTR1=CURF(FILNUM)-TOPF(FILNUM);
  1676. SLCUR2:
  1677. FILPTR1=FDLF(FILNUM);
  1678. SLCUR3:
  1679. TOKEN; # TO GLEAN OUT MORE #
  1680. SLCUR4:
  1681. IF TOKENTYPE EQ TYPST"PLUS" THEN GOTO SLPLUS2;
  1682. IF TOKENTYPE EQ TYPST"MINUS" THEN GOTO SLMINUS2;
  1683. GOTO SLDONE;
  1684.  
  1685. SLFIRST:
  1686. LINPTR1=1;
  1687. GOTO SLCUR2; # MORE SYNTAX?? #
  1688.  
  1689. SLLAST:
  1690. LINPTR1=BOTF(FILNUM)-1-TOPF(FILNUM);
  1691. GOTO SLCUR2; # MORE SYNTAX?? #
  1692.  
  1693. SLPLUS:
  1694. IF WHICHLIN EQ 3 THEN EXTENDFILE(FALSE);
  1695. LINPTR1=CURF(FILNUM)-TOPF(FILNUM);
  1696. FILPTR1=FDLF(FILNUM);
  1697. SLPLUS2:
  1698. TEMP=1;
  1699. SLPLUS3:
  1700. TOKEN;
  1701. IF TOKENTYPE EQ TYPST"DIGIT" THEN
  1702. BEGIN
  1703. LINPTR1=LINPTR1+TEMP*TOKENVAL;
  1704. TOKEN;
  1705. END
  1706. ELSE LINPTR1=LINPTR1+TEMP;
  1707. LINNUM1=-1;
  1708. GOTO SLCUR4;
  1709.  
  1710. SLMINUS:
  1711. IF WHICHLIN EQ 3 THEN EXTENDFILE(FALSE);
  1712. LINPTR1=CURF(FILNUM)-TOPF(FILNUM);
  1713. FILPTR1=FDLF(FILNUM);
  1714. SLMINUS2:
  1715. TEMP=-1;
  1716. GOTO SLPLUS3;
  1717.  
  1718. SLX:
  1719. SCNLINX = TRUE;
  1720. TEMP=0;
  1721. SLX2:
  1722. LINPTR1=REGLINE[XYZREG+TEMP]-REGLINE[XYZTOP+TEMP];
  1723. FILPTR1=XYZFILE[TEMP];
  1724. CHRPTR1=XYZCHAR[TEMP];
  1725. IF CHRPTR1 GQ 0 THEN CHARRANGE=TRUE;
  1726. GOTO SLCUR3;
  1727.  
  1728. SLY:
  1729. SCNLINY = TRUE;
  1730. TEMP=1;
  1731. GOTO SLX2;
  1732.  
  1733. SLZ:
  1734. SCNLINZ = TRUE;
  1735. TEMP=2;
  1736. GOTO SLX2;
  1737.  
  1738. SLDIGIT:
  1739. IF NUMBERED[FILNUM] NQ 0 THEN
  1740. BEGIN
  1741. LINNUM1=TOKENVAL;
  1742. PUSH; # REMEMBER WHERE WE ARE #
  1743. POSN; # SEARCH FOR THAT LINE #
  1744. LINPTR1=CURRENT-TOPF(FILNUM);
  1745. POP;
  1746. END
  1747. ELSE LINPTR1=TOKENVAL;
  1748. GOTO SLCUR2; # FOR MORE SYNTAX #
  1749.  
  1750. SLLETTER:
  1751. FOR TMP1=0 STEP 1 UNTIL 5 DO
  1752. BEGIN
  1753. IF KEYWORD[KEYWDNDX] EQ LINEKEYWD[TMP1]
  1754. THEN GOTO SLKEYSW[TMP1];
  1755. END
  1756.  
  1757. SLDONE:
  1758. IF TOKENTYPE EQ TYPST"PAREN" THEN GOTO SLPAREN;
  1759.  
  1760.  
  1761. POPTEMP;
  1762. IF WHICHLIN EQ 2 THEN
  1763. BEGIN
  1764. CHRPTR1 == CHRPTR2;
  1765. LINPTR1 == LINPTR2;
  1766. FILPTR1 == FILPTR2;
  1767. LINNUM1 == LINNUM2;
  1768. END
  1769. ELSE IF WHICHLIN EQ 3 THEN
  1770. BEGIN
  1771. CHRPTR1 == CHRPTR3;
  1772. LINPTR1 == LINPTR3;
  1773. FILPTR1 == FILPTR3;
  1774. LINNUM1 == LINNUM3;
  1775. END
  1776. WHICHLIN=WHICHLIN+1;
  1777. WHICHDGT=WHICHLIN;
  1778.  
  1779. IORET;
  1780.  
  1781. SLERROR:
  1782. ERRSTRING = " POINTER NOT SET IN FILE ";
  1783. C<26,07>ERRSTRING = C<0,7>READNAM;
  1784. C<00,01>ERRSTRING = TMP1;
  1785. C<33,01>ERRSTRING = "$";
  1786. TOKENPOS = ORIGSCNLIN;
  1787. ERRJUMP (ERRSTRING);
  1788.  
  1789. IOEND # OF SCNLIN #
  1790. PAGE # SCANSET - FOR "SET" COMMAND #
  1791.  
  1792.  
  1793. PROC SCANSET;
  1794. IOBEGIN(SCANSET)
  1795. #
  1796. ** SCANSET - SCAN SYNTAX OF SET SUBCOMMANDS.
  1797. *
  1798. * SCANSET IS CALLED WHEN THE SET COMMAND VERB HAS BEEN
  1799. * RECOGNIZED. THIS ROUTINE DETERMINES THE SUBCOMMAND, THEN
  1800. * SCANS SUB-SYNTAX AS APPROPRIATE AND PERFORMS ALL
  1801. * SUBCOMMAND EXECUTION.
  1802. *
  1803. * ENTRY SCANPOS, TOKENPOS - IDENTIFY SUBCOMMAND SYNTAX.
  1804. *
  1805. * EXIT COMMAND FULLY EXECUTED.
  1806. * VIA QQSINGLE IN MULTI-USER VERSION FOR TRANSITION
  1807. * TO SINGLE-USER WITH RE-EXECUTION.
  1808. * SCANPOS, TOKENPOS - ADVANCED BEYOND END OF COMMAND.
  1809. * SCANNER MAY BE CALLED FOR SOME SUBCOMMANDS.
  1810. * SETMARK POSSIBLY CALLED.
  1811. * SCREEN MODE INITIALIZATION POSSIBLE.
  1812. * TABVECTOR POSSIBLY SETUP.
  1813. * X,Y,Z REGISTER POSSIBLY SETUP.
  1814. * CURRENT FILE POSSIBLY RENAMED.
  1815. * TABCHAR POSSIBLY SETUP.
  1816. * INCR, DINCR - POSSIBLY SETUP.
  1817. * SCANKEY POSSIBLY CALLED.
  1818. * FLOAT, NUMBERED[CURFILE] - POSSIBLY REDEFINED.
  1819. * FKEYNUMROW - POSSIBLY REDEFINED.
  1820. * CHARRANGE - POSSIBLY DEFINED.
  1821. * AUDITOFF - POSSIBLY REDEFINED.
  1822. * USRUMLIN, USRNUMCOL, EDITFIELD, USRSPLTSIZ -
  1823. * POSSIBLY REDEFINED.
  1824. * WIDTH - POSSIBLY REDEFINED.
  1825. *
  1826. * CALLS AUDITEND, CLEARSCREEN, COPYTABS, ERRJUMP, FSEEDIT,
  1827. * MIN, MAX, PAINTALL, SCANFUNC, SCANNER, SCNCHAR,
  1828. * SCNEOC, SCNEQNAM, SCNEQVAL, SCNLSTCOL, SCNONOFF,
  1829. * SETMARK, SETUPSCREEN, TOKEN, TTSYNC, VDTGTA,
  1830. * VDTSTD, VDTSTM.
  1831. *
  1832. * USES KEYWDTYPE, ALL TOKENXXXX VARIABLES, LINPTR1,
  1833. * LINPTR2, LINCTR, VTMODEL, LINPTR3, LINNUM1, LINNUM2,
  1834. * READNAM, KEYWDNDX, WHICHDGT.
  1835. #
  1836.  
  1837. CONTROL IFEQ MULTI,1;
  1838. XREF LABEL QQSINGLE;
  1839. CONTROL FI;
  1840.  
  1841. ITEM TMP1, TMP2, BOOL B, TMPNAM C(7);
  1842.  
  1843. DEF NUMSETKEYS #21#;
  1844. ARRAY SETKEYS[0:NUMSETKEYS]; ITEM SETKEY C(0,0,10) = [
  1845. "ANNOUNCE", "CHAR", "DCOLON", "ECHO", "FILENAME",
  1846. "HEADER", "INCREMENT", "JUMP", "KEY", "LINE", "MARK",
  1847. "NUMBER", "PROMPT", "REWRITE", "SCREEN", "TABS",
  1848. "UNDO", "VIEW", "WORD", "X", "Y", "Z" ];
  1849.  
  1850. SWITCH SETSW SSANNOUNCE, SSCHAR, SSDORAC, SSECHO, SSFILE,
  1851. SSHEADER, SSINCR, SSJUMP, SSKEY, SSLINE, SSMARK,
  1852. SSNUMBER, SSPROMPT, SSREWRITE, SSSCREEN, SSTABS,
  1853. SSUNDO, SSVIEW, SSWORD, SSX, SSY, SSZ;
  1854.  
  1855.  
  1856. KEYWDTYPE=3;
  1857. SCANPOS=TOKENPOS;
  1858. TOKEN;
  1859. IF TOKENTYPE NQ TYPST"LETTER" THEN
  1860. BEGIN
  1861. ERRJUMP("KEYWORD MUST FOLLOW SET$");
  1862. END
  1863. TMP1=-1;
  1864. FOR TMP2=0 STEP 1 UNTIL NUMSETKEYS DO
  1865. BEGIN
  1866. IF KEYWORD[KEYWDNDX] EQ SETKEY[TMP2] THEN TMP1=TMP2;
  1867. END
  1868. IF TMP1 LS 0 THEN ERRJUMP("KEYWORD MUST FOLLOW SET$");
  1869. TOKEN;
  1870. GOTO SETSW[TMP1];
  1871.  
  1872. SSDORAC: # *DC* OR ASCII COLONS ON EXIT #
  1873. SCNONOFF(BOOL);
  1874. SCNEOC;
  1875. ZEROCOLOUT = BOOL; # DO AS USER ASKS #
  1876. ZEROCOLASK = TRUE; # COLON QUESTION "ASKED" #
  1877. GOTO SSDONE;
  1878.  
  1879. SSECHO: # SET ECHO ON OR OFF #
  1880. SCNONOFF(BOOL);
  1881. SCNEOC;
  1882. ECHOOFF = NOT BOOL; # SET ECHO ON OR OFF #
  1883. GOTO SSDONE;
  1884.  
  1885. SSJUMP: # AUTO INDENT, BLOCK LANGUAGES #
  1886. SCNONOFF(BOOL);
  1887. SCNEOC;
  1888. AUTOINDENT = BOOL; # DO AS USER ASKS #
  1889. GOTO SSDONE;
  1890.  
  1891. SSREWRITE: # SET REWRITE (CHANGED FLAG) #
  1892. SCNONOFF(BOOL);
  1893. SCNEOC;
  1894. IF LOCKED[CURFILE] EQ 0 THEN
  1895. BEGIN # IF FILE IS NOT LOCKED #
  1896. IF BOOL THEN
  1897. BEGIN # IF USER WANTS CHANGED #
  1898. CHANGED[CURFILE] = 1;
  1899. IF FILENAM[1] EQ FILENAM[2] THEN
  1900. BEGIN # IF SAME FILE IN BOTH SPLITS #
  1901. CHANGED[1] = 1;
  1902. CHANGED[2] = 1;
  1903. END
  1904. END
  1905. ELSE
  1906. BEGIN # CLEAR CHANGED STATUS #
  1907. CHANGED[CURFILE] = 0;
  1908. IF FILENAM[1] EQ FILENAM[2] THEN
  1909. BEGIN # IF SAME FILE IN BOTH SPLITS #
  1910. CHANGED[1] = 0;
  1911. CHANGED[2] = 0;
  1912. END
  1913. END
  1914. END
  1915. ELSE
  1916. BEGIN # LOCKED FILE, REJECT CHANGE #
  1917. IF BOOL THEN ERRJUMP("CANNOT CHANGE READ-ONLY FILE$");
  1918. END
  1919. GOTO SSDONE;
  1920.  
  1921. SSMARK:
  1922. SCANNER;
  1923. LINPTR2=MIN(LINPTR2,LINPTR1+LIMIT-1);
  1924. IF SCANWORD THEN
  1925. BEGIN
  1926. SETMARK(LINPTR1,CHRPTR1);
  1927. NEWCURSOR=CURCURSOR+1;
  1928. IF WHICHLIN GR 2 THEN
  1929. BEGIN
  1930. SETMARK(LINPTR2,CHRPTR2);
  1931. NEWCURSOR=CHRPTR2+1;
  1932. END
  1933. END
  1934. ELSE
  1935. BEGIN
  1936. SETMARK(LINPTR1,-1);
  1937. IF WHICHLIN GR 2 THEN
  1938. BEGIN
  1939. SETMARK(LINPTR2,-1);
  1940. LINPTR1=LINPTR2;
  1941. END
  1942. POSZ(LINPTR1);
  1943. IF SCREENMODE THEN
  1944. BEGIN # IF SCREENMODE #
  1945. IF CURRENT EQ TOPS(CURSPLIT) + NUMROWS[CURSPLIT] THEN
  1946. BEGIN # IF LAST LINE IN SPLIT #
  1947. FORCEAUTOP[0] = TRUE;
  1948. END
  1949. ELSE
  1950. BEGIN # CHECK FOR LAST LINE IN FILE #
  1951. IF CURRENT + 1 EQ BOTS(CURSPLIT) THEN FORCEAUTOR[0] = TRUE;
  1952. END
  1953. END
  1954. IF (SCREENMODE AND CURRENT+1 LS BOTS(CURSPLIT))
  1955. OR (CURRENT+1 LS BOTF(CURFILE) AND NOT SCREENMODE) THEN
  1956. BEGIN
  1957. FWDZ;
  1958. NEWCURSOR=0;
  1959. END
  1960. END
  1961. GOTO SSDONE;
  1962.  
  1963. SSTABS:
  1964. SCNLSTCOL;
  1965. IF SCREENMODE THEN COPYTABS;
  1966. GOTO SSDONE;
  1967.  
  1968. SSX:
  1969. LINCTR=0;
  1970. SSX2:
  1971. SCANNER;
  1972. IF SCANWORD THEN XYZCHAR[LINCTR]=CHRPTR1;
  1973. ELSE XYZCHAR[LINCTR]=-1;
  1974. REGLINE[XYZREG+LINCTR]=LINPTR1;
  1975. REGLINE[XYZTOP+LINCTR]=TOPF(CURFILE);
  1976. XYZFILE[LINCTR]=FDLF(CURFILE);
  1977. GOTO SSDONE;
  1978.  
  1979. SSY:
  1980. LINCTR=1;
  1981. GOTO SSX2;
  1982.  
  1983. SSZ:
  1984. LINCTR=2;
  1985. GOTO SSX2;
  1986.  
  1987.  
  1988. CONTROL IFEQ MULTI,1;
  1989.  
  1990. SSANNOUNCE: SSCHAR: SSFILE: SSHEADER: SSINCR: SSKEY: SSLINE:
  1991. SSNUMBER: SSPROMPT: SSSCREEN: SSUNDO: SSVIEW: SSWORD:
  1992. GOTO QQSINGLE;
  1993.  
  1994. CONTROL FI;
  1995.  
  1996. CONTROL IFEQ SINGLE,1;
  1997.  
  1998.  
  1999. SSANNOUNCE:
  2000. WHICHSTR=1;
  2001. TTYLINE[0]=NULLIN;
  2002. IF TOKENTYPE EQ TYPST"DELIMIT" THEN SCANSTR;
  2003. SCNEOC;
  2004. LINPTR3=1;
  2005. C<0,1>ERRSTRING=" ";
  2006. FOR LINPTR1=0 STEP 1 UNTIL MIN(LENGTH(TTYLIN)-1,77) DO
  2007. BEGIN
  2008. GETCHAR(TTYLINE,LINPTR1,LINPTR2);
  2009. DSPLCOD(LINPTR2);
  2010. C<LINPTR1,1>ERRSTRING=LINPTR2;
  2011. LINPTR3=LINPTR1+1;
  2012. END
  2013. IF LINPTR3 LAN 1 EQ 0 THEN C<LINPTR3,1>ERRSTRING="$";
  2014. ELSE C<LINPTR3,2>ERRSTRING=" $";
  2015. GOTO SSDONE;
  2016.  
  2017. SSCHAR:
  2018. TMP1 = 0; # SET *SET CHAR TAB* FLAG #
  2019. IF TOKENTYPE EQ TYPST"LETTER" THEN
  2020. BEGIN
  2021. KEYWDTYPE = 10;
  2022. SCANPOS = TOKENPOS;
  2023. TOKEN;
  2024. IF KEYWDNDX NQ KEYST"CTAB" THEN
  2025. BEGIN # IF NOT *SET CHAR TAB* #
  2026. IF KEYWDNDX EQ KEYST"CCTL" THEN
  2027. BEGIN # IF *SET CHAR CONTROL* #
  2028. TMP1 = 1; # SET *SET CHAR CONTROL* FLAG #
  2029. END
  2030. ELSE
  2031. BEGIN # IF NOT *SET CHAR CONTROL* #
  2032. SCANPOS = TOKENPOS; # SET UP TAB CHARACTER RESCAN #
  2033. END
  2034. END
  2035. KEYWDTYPE = 0;
  2036. TOKEN;
  2037. END
  2038. SCNCHAR;
  2039. IF TMP1 NQ 0 THEN
  2040. BEGIN # IF *SET CHAR CONTROL* #
  2041. IF LINPTR1 EQ CNOTHING THEN LINPTR1 = CBLANK;
  2042. IF LINPTR1 NQ UNPRINT THEN
  2043. BEGIN # IF CHARACTER CHANGED #
  2044. UNPRINT = LINPTR1;
  2045. IF SCREENMODE THEN
  2046. BEGIN # IF SCREEN MODE #
  2047. FOR LINPTR1 = TITLEROW[1] + 1 STEP 1 UNTIL
  2048. TITLEROW[1] + NUMROWS[1] DO ROWPAINT[LINPTR1] = TRUE;
  2049. IF SPLITFILE[2] NQ 0 THEN
  2050. BEGIN # IF SPLIT SCREEN #
  2051. FOR LINPTR1 = TITLEROW[2] + 1 STEP 1 UNTIL
  2052. TITLEROW[2] + NUMROWS[2] DO ROWPAINT[LINPTR1] = TRUE;
  2053. END
  2054. END
  2055. END
  2056. END
  2057. ELSE TABCHAR = LINPTR1; # IF *SET CHAR TAB* #
  2058. SCNEOC;
  2059. GOTO SSDONE;
  2060.  
  2061. SSFILE:
  2062. SCNEQNAM(READNAM);
  2063. SCNEOC;
  2064. IF READNAM EQ PADNAME(WORKORG) THEN
  2065. BEGIN # IF SAME AS WORKFILE NAME #
  2066. ERRJUMP("FILE NAME IN USE$");
  2067. END
  2068. FOR FILNUM=1 STEP 1 UNTIL 2 DO
  2069. BEGIN # ASSURE DIRECTORY UPTODATE #
  2070. IF PADNAME(FILENAM[FILNUM]) NQ " " THEN CLOSEFILE;
  2071. END
  2072. PUSH;
  2073. POSZ(TOPC(FILECTL)+1);
  2074. WHYLE CURRENT LS BOTC(FILECTL) DO
  2075. BEGIN # VERIFY UNIQUE NAME #
  2076. SCANFDL(LINPTR1);
  2077. IF READNAM EQ C<0,7>LINPTR1 AND READNAM NQ "ZZZNULL"
  2078. AND CURRENT NQ FDLF(CURFILE) THEN
  2079. BEGIN # IF FILE NAME IN USE #
  2080. POP;
  2081. ERRJUMP("FILE NAME IN USE$");
  2082. END
  2083. FWDZ;
  2084. END
  2085. POP;
  2086. TMPNAM=TRIMNAME(READNAM);
  2087. FOR FILNUM=1 STEP 1 UNTIL 2 DO
  2088. BEGIN
  2089. IF FDLF(FILNUM) EQ FDLF(CURFILE) THEN
  2090. BEGIN
  2091. IF SPLITFILE[1] EQ FILNUM THEN LASTNAME[1]=TMPNAM;
  2092. IF SPLITFILE[2] EQ FILNUM THEN LASTNAME[2]=TMPNAM;
  2093. FILENAM[FILNUM]=TMPNAM;
  2094. CHANGED[FILNUM]=1;
  2095. LOCKED[FILNUM]=0;
  2096. IF NOT WRITEABLE(READNAM) OR
  2097. READNAM EQ "ZZZNULL" THEN LOCKED[FILNUM]=1;
  2098. END
  2099. END
  2100. FOR FILNUM=1 STEP 1 UNTIL 2 DO
  2101. BEGIN # ASSURE DIRECTORY UPTODATE #
  2102. IF PADNAME(FILENAM[FILNUM]) NQ " " THEN CLOSEFILE;
  2103. END
  2104. GOTO SSDONE;
  2105.  
  2106. SSHEADER:
  2107. SCNONOFF(BOOL);
  2108. SCNEOC;
  2109. IF BOOL THEN SHORTTITLE=FALSE;
  2110. ELSE SHORTTITLE=TRUE;
  2111. IF SCREENMODE THEN
  2112. BEGIN
  2113. ROWPAINT[TITLEROW[1]]=TRUE;
  2114. IF SPLITFILE[2] NQ 0 THEN ROWPAINT[TITLEROW[2]]=TRUE;
  2115. END
  2116. GOTO SSDONE;
  2117.  
  2118. SSINCR:
  2119. SCNEQVAL;
  2120. SCNEOC;
  2121. IF LINPTR1 LQ 0 OR LINPTR1 GQ NINES
  2122. THEN ERRJUMP("LINE INCREMENT VALUE TOO LARGE$");
  2123. INCR=LINPTR1;
  2124. DINCR=LINPTR1;
  2125. GOTO SSDONE;
  2126.  
  2127. SSKEY:
  2128. SCANFUNC;
  2129. GOTO SSDONE;
  2130.  
  2131. SSLINE:
  2132. SCNEOC;
  2133. CLEARSCREEN;
  2134. GOTO SSDONE;
  2135.  
  2136. SSNUMBER:
  2137. KEYWDTYPE=8;
  2138. SCANPOS=TOKENPOS;
  2139. TOKEN;
  2140. KEYWDTYPE=0;
  2141. TOKEN;
  2142. SCNEOC;
  2143. IF KEYWDNDX EQ KEYST"NBAS" OR KEYWDNDX EQ KEYST"NFOR" THEN
  2144. BEGIN
  2145. FLOAT=FALSE;
  2146. IF KEYWDNDX EQ KEYST"NBAS" THEN BLANKS=1;
  2147. ELSE BLANKS=0;
  2148. NUMWIDBLK=NUMWIDTH+BLANKS;
  2149. FOR TMP1 = 1 STEP 1 UNTIL 2 DO # IF SPLIT IS USED THEN RESET #
  2150. BEGIN
  2151. IF FDLF(TMP1) EQ FDLF(CURFILE) THEN NUMBERED[TMP1]=1;
  2152. END
  2153. END
  2154. ELSE IF KEYWDNDX EQ KEYST"NAUT" THEN
  2155. BEGIN
  2156. FLOAT=TRUE;
  2157. FOR TMP1 = 1 STEP 1 UNTIL 2 DO # IF SPLIT IS USED THEN RESET #
  2158. BEGIN
  2159. IF FDLF(TMP1) EQ FDLF(CURFILE) THEN NUMBERED[TMP1]=0;
  2160. END
  2161. END
  2162. ELSE IF KEYWDNDX EQ KEYST"NONE" THEN
  2163. BEGIN
  2164. FLOAT=FALSE;
  2165. FOR TMP1 = 1 STEP 1 UNTIL 2 DO # IF SPLIT IS USED THEN RESET #
  2166. BEGIN
  2167. IF FDLF(TMP1) EQ FDLF(CURFILE) THEN NUMBERED[TMP1]=0;
  2168. END
  2169. END
  2170. ELSE ERRJUMP("CHARACTER SEQUENCE NOT RECOGNIZED$");
  2171. GOTO SSDONE;
  2172.  
  2173. SSPROMPT:
  2174. LINPTR1=1;
  2175. WHYLE TOKENTYPE EQ TYPST"DIGIT" OR TOKENTYPE EQ TYPST"LETTER" DO
  2176. BEGIN
  2177. IF TOKENTYPE EQ TYPST"DIGIT" THEN
  2178. BEGIN # IF SET PROMPT 1/2/3 #
  2179. SCNEQVAL;
  2180. FKEYNUMROW=MIN(MAX(LINPTR1,0),3);
  2181. END
  2182. ELSE
  2183. BEGIN # IF SET PROMPT SHIFT/NOSHIFT #
  2184. KEYWDTYPE = 11;
  2185. SCANPOS = TOKENPOS;
  2186. TOKEN;
  2187. KEYWDTYPE = 3;
  2188. IF KEYWDNDX EQ KEYST"PYDK" THEN SFKEYSHOW = 1;
  2189. ELSE IF KEYWDNDX EQ KEYST"PNDK" THEN SFKEYSHOW = 0;
  2190. ELSE ERRJUMP("CHARACTER SEQUENCE NOT RECOGNIZED$");
  2191. TOKEN;
  2192. LINPTR1 = FKEYNUMROW; # PRESERVE CURRENT PROMPT ROWS #
  2193. END
  2194. END
  2195. SCNEOC;
  2196. LINPTR2=FKEYROW;
  2197. FKEYNUMROW=MIN(MAX(LINPTR1,0),3);
  2198. IF SCREENMODE THEN
  2199. BEGIN # IF SCREEN MODE #
  2200. IF SPLITFILE[2] NQ 0 THEN SETUPSCREEN(1,2,USRSPLTSZ);
  2201. ELSE SETUPSCREEN(1,0,0);
  2202. IF FKEYROW NQ LINPTR2 THEN
  2203. BEGIN # IF THERE WAS A CHANGE #
  2204. IF TABATTRCHR[0] AND NUMMARKS NQ 0 THEN
  2205. PAINTREST(MIN(FKEYROW,LINPTR2)-1);
  2206. ELSE
  2207. PAINTREST(MIN(FKEYROW,LINPTR2));
  2208. END
  2209. END
  2210. GOTO SSDONE;
  2211.  
  2212. SSSCREEN:
  2213. IF SYNTAXCHAR[TOKENCHAR] THEN # IF MODEL SPECIFIED #
  2214. BEGIN
  2215. IF SCREENMODE THEN CLEARSCREEN;
  2216. TTLIN("YOU CANNOT SPECIFY A MODEL ON THE$");
  2217. TTLIN("*SET SCREEN* EDITOR COMMAND. YOU$");
  2218. TTLIN("SHOULD USE THE *QUIT* COMMAND TO$");
  2219. TTLIN("END THIS EDIT SESSION, THEN USE THE$");
  2220. TTLIN("*SCREEN* COMMAND TO DEFINE YOUR$");
  2221. TTLIN("TERMINAL MODEL. THEN YOU CAN START$");
  2222. TTLIN("THE EDITOR AGAIN.$");
  2223. ERRJUMP(" $");
  2224. END
  2225. ELSE # MODEL NOT SPECIFIED #
  2226. BEGIN
  2227. SCNEOC;
  2228. IF NOT INTERACT THEN GOTO SSDONE; # IF BATCH MODE #
  2229. IF NOT SCREENMODE THEN # IF LINE MODE #
  2230. BEGIN
  2231. TTSYNC;
  2232. VDTSTM(1,TMP1); # SET SCREEN MODE #
  2233. END
  2234. FKEYCHARS=6;
  2235. FKEYSHOW=8;
  2236. END
  2237. IF SCREENMODE THEN # IF SCREEN MODE #
  2238. BEGIN
  2239. SCRNSIZES; # SET SCREEN SIZE VALUES #
  2240. IF TABLOCKMDE[0] THEN
  2241. BEGIN # IF BLOCK MODE TYPE TERMINAL #
  2242. SINGLEONLY = TRUE; # DO NOT CONNECT TO MULTI #
  2243. IF USRNUMCOL GR 1 THEN
  2244. BEGIN # IF NOT FIRST SET UP OF SCREEN #
  2245. USRNUMCOL = MIN(USRNUMCOL,VTXMAX-1);
  2246. END
  2247. ELSE
  2248. BEGIN # FIRST SET UP OF SCREEN #
  2249. USRNUMCOL = VTXMAX - 1;
  2250. END
  2251. END
  2252. ELSE
  2253. BEGIN # CHARACTER MODE TYPE #
  2254. IF USRNUMCOL GR 1 THEN
  2255. BEGIN # IF NOT FIRST SET UP OF SCREEN #
  2256. USRNUMCOL = MIN(USRNUMCOL,VTXMAX);
  2257. END
  2258. ELSE
  2259. BEGIN # NOT FIRST SET UP OF SCREEN #
  2260. USRNUMCOL = VTXMAX;
  2261. END
  2262. END
  2263. IF USRNUMLIN GR 1 THEN
  2264. BEGIN # IF NOT FIRST SET UP OF SCREEN #
  2265. USRNUMLIN = MIN(USRNUMLIN,VTYMAX);
  2266. END
  2267. ELSE
  2268. BEGIN # NOT FIRST SET UP OF SCREEN #
  2269. USRNUMLIN = VTYMAX;
  2270. END
  2271. IF SPLITFILE[2] NQ 0 THEN SETUPSCREEN(1,2,USRSPLTSZ);
  2272. ELSE SETUPSCREEN(1,0,0);
  2273. COPYTABS;
  2274. PAINTALL;
  2275. END
  2276. GOTO SSDONE;
  2277.  
  2278. SSUNDO:
  2279. SCNONOFF(BOOL);
  2280. SCNEOC;
  2281. IF BOOL THEN AUDITOFF=FALSE;
  2282. ELSE
  2283. BEGIN
  2284. AUDITEND;
  2285. AUDITOFF=TRUE;
  2286. END
  2287. GOTO SSDONE;
  2288.  
  2289. SSVIEW:
  2290. SCANVIEW;
  2291. GOTO SSDONE;
  2292.  
  2293. SSWORD:
  2294. KEYWDTYPE=4;
  2295. SCANPOS=TOKENPOS;
  2296. KEYWDNDX=-1;
  2297. TOKEN;
  2298. IF KEYWDNDX EQ KEYST"XFIL" THEN
  2299. BEGIN
  2300. KEYWDTYPE=1;
  2301. TOKEN;
  2302. SCNEQVAL;
  2303. FILLLEFT=MAX(MIN(LINPTR1-1,BUFCHAR-2),0);
  2304. FILLFIRST=FILLLEFT;
  2305. IF SYNTAXCHAR[TOKENCHAR] THEN
  2306. BEGIN
  2307. SCNEQVAL;
  2308. FILLRIGHT=MAX( MIN(LINPTR1-1,BUFCM1), FILLLEFT+1);
  2309. END
  2310. ELSE
  2311. BEGIN
  2312. FILLRIGHT=FILLLEFT;
  2313. FILLLEFT=0;
  2314. FILLFIRST=FILLLEFT;
  2315. END
  2316. IF SYNTAXCHAR[TOKENCHAR] THEN
  2317. BEGIN
  2318. SCNEQVAL;
  2319. FILLFIRST=MAX(MIN(LINPTR1-1,BUFCHAR-2),0);
  2320. END
  2321. IF SYNTAXCHAR[TOKENCHAR] THEN
  2322. BEGIN # IF SOMETHING ELSE SPECIFIED #
  2323. IF(C<0,1>TOKENSYM EQ "Y" AND TOKENLEN EQ 1) OR
  2324. (C<0,3>TOKENSYM EQ "YES" AND TOKENLEN EQ 3) THEN
  2325. BEGIN # IF RIGHT JUSTIFY REQUESTED #
  2326. RIGHTJUST[0] = TRUE;
  2327. END
  2328. ELSE
  2329. BEGIN # CHECK FOR NO RIGHT JUSTIFY #
  2330. IF(C<0,1>TOKENSYM EQ "N" AND TOKENLEN EQ 1) OR
  2331. (C<0,2>TOKENSYM EQ "NO" AND TOKENLEN EQ 2) THEN
  2332. BEGIN # IF NOT REQUESTED #
  2333. RIGHTJUST[0] = FALSE;
  2334. END
  2335. ELSE
  2336. BEGIN # SOMETHING, BUT NOT YES OR NO #
  2337. ERRJUMP("MUST SPECIFY YES OR NO$");
  2338. END
  2339. END
  2340. TOKEN;
  2341. END
  2342. SCNEOC;
  2343. END
  2344. ELSE IF KEYWDNDX EQ KEYST"XCHA" THEN
  2345. BEGIN
  2346. TOKEN;
  2347. SCNCHAR;
  2348. SCNEOC;
  2349. B<LINPTR1 LAN 31,1>WORDFLAG[LINPTR1/32]=B<LINPTR1 LAN 31,1>
  2350. WORDFLAG[LINPTR1/32] LXR 1;
  2351. IF B<LINPTR1 LAN 31,1>WORDFLAG[LINPTR1/32] EQ 0 THEN
  2352. BEGIN
  2353. ERRSTRING="CHARACTER DEFINED AS PUNCTUATOR$";
  2354. END
  2355. ELSE
  2356. BEGIN
  2357. ERRSTRING="CHARACTER DEFINED AS ALPHANUMERIC$";
  2358. END
  2359. END
  2360. ELSE ERRJUMP("PARAMETER NOT VALID FOR THIS DIRECTIVE$");
  2361. GOTO SSDONE;
  2362.  
  2363. CONTROL FI;
  2364.  
  2365. SSDONE:
  2366.  
  2367. IOEND # OF SCANSET #
  2368. PAGE # SCANVIEW - SET VIEW COMMANDS #
  2369.  
  2370.  
  2371. PROC SCANVIEW;
  2372. BEGIN
  2373. #
  2374. ** SCANVIEW - SCAN PARAMETERS OF "SET VIEW" COMMAND.
  2375. *
  2376. * ENTRY SCANPOS, TOKENPOS - BRACKET TOKEN AFTER VIEW.
  2377. *
  2378. * EXIT ONE OR MORE OF FOLLWING SETUP -
  2379. * USRNUMLIN, USRNUMCOL, USRSPLTSZ, EDITFIELD, WIDTH.
  2380. * LINPTR2 - NEGATIVE IF NO SCREEN REDEFINE NEEDED.
  2381. * POSITIVE DENOTES VTMODEL TO REDEFINE.
  2382. * SCANPOS, TOKENPOS - ADVANCED TO END OF COMMAND.
  2383. *
  2384. * CALLS TOKEN, SCNEQVAL, ERRJUMP, MIN, SCNEOC.
  2385. *
  2386. * USES LINPTR1, ALL TOKENXXXX VARIABLES, WHICHDGT,
  2387. * KEYWDTYPE, KEYWDNDX, LINPTR3.
  2388. #
  2389. DEF MAXVIEWNDX #6#;
  2390. ARRAY VIEWCONTROL [0:MAXVIEWNDX];
  2391. BEGIN
  2392. ITEM VIEWKEY U(0,00,30)=[ KEYST"VCOL", KEYST"VLIN", KEYST"VOFF",
  2393. KEYST"VSPL", KEYST"VEDI", KEYST"VWAR", KEYST"VIN" ];
  2394. ITEM VIEWNDX U(0,30,30)=[ 1, 0, 3, 2, 4, 5 ,6 ];
  2395. END
  2396. SWITCH SCANVIEWSW SVNUMLIN, SVNUMCOL, SVSPLTSZ, SVOFFSET,
  2397. SVEDTFLD, SVWIDTH, SVINFLD;
  2398.  
  2399. PROC FRMTSCR;
  2400. # TITLE FRMTSCR - FORMAT THE SCREEN. #
  2401.  
  2402. BEGIN # FRMTSCR #
  2403.  
  2404. #
  2405. ** FRMTSCR - FORMAT THE SCREEN FOR THE "SET VIEW" COMMAND.
  2406. *
  2407. * ENTRY SCREENMODE - SETUP.
  2408. * USRNUMCOL - SETUP.
  2409. * USRNUMLIN - SETUP.
  2410. *
  2411. * EXIT USRNUMLIN - SETUP.
  2412. * USRNUMCOL - SETUP.
  2413. * USRSPLTSZ - SETUP.
  2414. *
  2415. * CALLS COPYTABS, PAINTALL, SETUPSCREEN, VDTSTD.
  2416. *
  2417. * USES SPLITFILE.
  2418. #
  2419.  
  2420. IF SCREENMODE THEN # IF SCREEN MODE #
  2421. BEGIN
  2422. SCRNSIZES; # SET SCREEN SIZE VALUES #
  2423. IF TABLOCKMDE[0] THEN
  2424. BEGIN # IF BLOCK MODE TYPE TERMINAL #
  2425. USRNUMCOL = MIN(USRNUMCOL,VTXMAX-1);
  2426. END
  2427. ELSE
  2428. BEGIN # CHARACTER MODE TYPE #
  2429. USRNUMCOL = MIN(USRNUMCOL,VTXMAX);
  2430. END
  2431. USRNUMLIN = MIN(USRNUMLIN,VTYMAX);
  2432. IF SPLITFILE[2] NQ 0 THEN SETUPSCREEN(1,2,USRSPLTSZ);
  2433. ELSE SETUPSCREEN(1,0,0);
  2434. COPYTABS;
  2435. PAINTALL;
  2436. END
  2437.  
  2438. END # FRMTSCR #
  2439.  
  2440. # MAIN CODE STARTS HERE. #
  2441.  
  2442. WHICHDGT=0;
  2443. WHYLE TOKENTYPE EQ TYPST"DIGIT" OR TOKENTYPE EQ
  2444. TYPST"LETTER" DO
  2445. BEGIN
  2446. IF TOKENTYPE EQ TYPST"LETTER" THEN
  2447. BEGIN
  2448. KEYWDTYPE=5;
  2449. SCANPOS=TOKENPOS;
  2450. KEYWDNDX=-1;
  2451. WHICHDGT=-1;
  2452. TOKEN;
  2453. FOR LINPTR3=0 STEP 1 UNTIL MAXVIEWNDX DO
  2454. BEGIN
  2455. IF KEYWDNDX EQ VIEWKEY[LINPTR3]
  2456. THEN WHICHDGT=VIEWNDX[LINPTR3];
  2457. END
  2458. IF WHICHDGT LS 0 THEN
  2459. BEGIN
  2460. ERRJUMP("CHARACTER SEQUENCE NOT RECOGNIZED$");
  2461. END
  2462. TOKEN;
  2463. END
  2464. IF TOKENTYPE EQ TYPST"DIGIT" OR TOKENTYPE EQ TYPST"EQUAL" THEN
  2465. BEGIN
  2466. SCNEQVAL;
  2467. IF WHICHDGT GR MAXVIEWNDX THEN ERRJUMP("TOO MANY PARAMETERS$");
  2468. GOTO SCANVIEWSW[WHICHDGT];
  2469.  
  2470. SVNUMLIN:
  2471. IF USRNUMLIN NQ MAX(9,LINPTR1 - 1) THEN
  2472. BEGIN # IF REAL CHANGE #
  2473. IF SCREENMODE AND LINPTR1 - 1 LS USRNUMLIN THEN VDTCLS;
  2474. USRNUMLIN = MAX(9,LINPTR1 - 1);
  2475. FRMTSCR; # FORMAT THE SCREEN #
  2476. END
  2477. XSHIFT[1] = MIN(XSHIFT[1],BUFCHAR-(VTXMAX+1+ATTCOUNT));
  2478. XSHIFT[2] = MIN(XSHIFT[2],BUFCHAR-(VTXMAX+1+ATTCOUNT));
  2479. GOTO SVNEXT;
  2480.  
  2481. SVNUMCOL:
  2482. IF USRNUMCOL NQ MAX(9,LINPTR1 - 1) THEN
  2483. BEGIN # IF REAL CHANGE #
  2484. IF TABVTSCLRS[0] OR LINPTR1 GR USRNUMCOL THEN
  2485. BEGIN # IF SCREEN NEEDS REPAINTING #
  2486. USRNUMCOL = MAX(9,LINPTR1 - 1);
  2487. FRMTSCR; # FORMAT THE SCREEN #
  2488. END
  2489. ELSE
  2490. BEGIN # SCREEN DOES NOT NEED REPAINT #
  2491. IF SCREENMODE THEN
  2492. BEGIN # IF IN SCREEN MODE #
  2493. USRNUMCOL = MAX(9,LINPTR1 - 1);
  2494. SCRNSIZES; # SET SCREEN SIZE VALUES #
  2495. USRNUMCOL = MIN(USRNUMCOL,VTXMAX);
  2496. USRNUMLIN = MIN(USRNUMLIN,VTYMAX);
  2497. COPYTABS;
  2498. IF FKEYNUMROW GR 0 THEN
  2499. BEGIN # IF PROMPTS MUST BE REPAINTED #
  2500. PAINTREST(FKEYROW);
  2501. END
  2502. END
  2503. END
  2504. END
  2505. XSHIFT[1] = MIN(XSHIFT[1],BUFCHAR-(VTXMAX+1+ATTCOUNT));
  2506. XSHIFT[2] = MIN(XSHIFT[2],BUFCHAR-(VTXMAX+1+ATTCOUNT));
  2507. GOTO SVNEXT;
  2508.  
  2509. SVSPLTSZ:
  2510. IF USRSPLTSZ NQ LINPTR1 THEN
  2511. BEGIN # IF REAL CHANGE #
  2512. SCRNPT1 = MAX(0,FKEYNUMROW*(2+SHIFTFKEY)-1);
  2513. USRSPLTSZ = MIN(MAX(LINPTR1,1),(USRNUMLIN-(SCRNPT1+4)));
  2514. IF SCREENMODE THEN
  2515. BEGIN # IF SCREEN MODE #
  2516. IF SPLITFILE[2] NQ 0 THEN
  2517. BEGIN # IF SPLIT SCREEN MODE #
  2518. SETUPSCREEN(1,2,USRSPLTSZ);
  2519. FOR LINPTR1 = USRNUMLIN-(USRSPLTSZ-1) STEP 1 UNTIL SCRNPT1 DO
  2520. BEGIN # UNTIL DONE FOR SPLIT AREA #
  2521. ROWPAINT[SCRNPT1]= TRUE;
  2522. END
  2523. END
  2524. END
  2525. END
  2526. GOTO SVNEXT;
  2527.  
  2528. SVOFFSET:
  2529. IF XSHIFT[CURSPLIT] NQ MAX(LINPTR1-1,0) THEN
  2530. BEGIN # IF REAL CHANGE #
  2531. XSHIFT[CURSPLIT] = MIN(MAX(LINPTR1-1,0),
  2532. BUFCHAR-(VTXMAX+1+ATTCOUNT));
  2533. IF SCREENMODE THEN
  2534. BEGIN # IF SCREEN MODE #
  2535. FOR LINPTR1 = TITLEROW[CURSPLIT] STEP 1 UNTIL
  2536. TITLEROW[CURSPLIT] + NUMROWS[CURSPLIT] DO
  2537. ROWPAINT[LINPTR1] = TRUE;
  2538. END
  2539. END
  2540. GOTO SVNEXT;
  2541.  
  2542. SVEDTFLD:
  2543. EDITFIELD=MIN(LINPTR1,BUFCHAR);
  2544. GOTO SVNEXT;
  2545.  
  2546. SVWIDTH:
  2547. WIDTH=MIN(LINPTR1,BUFCHAR);
  2548. GOTO SVNEXT;
  2549.  
  2550. SVINFLD:
  2551. DFINFIELD=MAX(0,MIN(LINPTR1,BUFCHAR));
  2552. IF TOKENTYPE EQ TYPST"DIGIT" THEN
  2553. BEGIN # IF SECOND VALUE SUPPLIED #
  2554. SCNEQVAL;
  2555. DFINBGN = DFINEND;
  2556. DFINEND = MAX(0,MIN(LINPTR1,BUFCHAR));
  2557. END
  2558. IF DFINEND EQ 0 THEN DFINEND=BUFCHAR;
  2559. IF DFINBGN GR DFINEND THEN DFINBGN==DFINEND;
  2560. DFINBGN=MAX(1,DFINBGN);
  2561. GOTO SVNEXT;
  2562.  
  2563. SVNEXT:
  2564. WHICHDGT=WHICHDGT+1;
  2565.  
  2566. END
  2567. END
  2568. SCNEOC;
  2569. END # OF SCANVIEW #
  2570. PAGE # SCRNSIZES - SET SCREEN SIZES #
  2571.  
  2572.  
  2573. PROC SCRNSIZES;
  2574. BEGIN
  2575. #
  2576. ** SCRNSIZES - SET SIZE VALUES ASSOCIATED WITH SCREEN.
  2577. *
  2578. * SETS SCREEN ROWS, COLUMNS AND LABEL LINE AND PADDING SIZES.
  2579. *
  2580. * ENTRY USRNUMCOL = SPECIFIED NUMBER OF COLUMNS - 1.
  2581. * USRNUMLIN = SPECIFIED NUMBER OF LINES - 1.
  2582. *
  2583. * EXIT VTXMAX = MAXIMUM COLUMN NUMBER FOR SELECTED FORMAT.
  2584. * VTYMAX = MAXIMUM ROW NUMBER FOR SELECTED FORMAT.
  2585. * FKEYLEN = LENGTH OF FUNCTION KEY LABEL LINES.
  2586. * FKEYPAD = NUMBER OF BLANKS TO BE ADDED BEFORE AND
  2587. * AFTER EACH FUNCTION KEY LABEL BLOCK.
  2588. *
  2589. * CALLS VTDSTD.
  2590. *
  2591. * USES FKEYLEN, FKEYPAD.
  2592. #
  2593.  
  2594. VDTSTD(USRNUMCOL+1,USRNUMLIN+1);
  2595. FKEYPAD = (VTXMAX+1-(FKEYCHARS+4)*FKEYSHOW)/(FKEYSHOW*2);
  2596. FKEYLEN = (2*FKEYPAD+FKEYCHARS+4)*FKEYSHOW-1;
  2597. END # END OF SCRNSIZES #
  2598. PAGE # SCANFUNC - SCAN "FUNCTION" CMD #
  2599. CONTROL IFEQ SINGLE,1;
  2600.  
  2601. PROC SCANFUNC;
  2602. BEGIN
  2603. #
  2604. ** SCANFUNC - SCAN/EXECUTE SET KEY COMMAND.
  2605. *
  2606. * SCANFUNC IS INTENDED TO BE CALLED ONLY BY SCANSET.
  2607. * SCANFUNC HANDLES FUNCTION KEY REDEFINITION. THIS
  2608. * ROUTINE COMPLETES SYNTAX SCAN AND EXECUTES THE COMMAND.
  2609. *
  2610. * ENTRY TOKENPOS - POINTS AFTER "SET KEY".
  2611. * FKEYNUMROW - WHETHER TO SET ROWPAINT.
  2612. *
  2613. * EXIT TOKENPOS, SCANPOS - ADVANCED TO END OF COMMAND.
  2614. * FKEYNAME[ANY,ANY] - REDEFINED.
  2615. * ROWPAINT[] - SET IF NEEDED.
  2616. *
  2617. * USES ALL TOKENXXXX VARIABLES, FKEYNDX, KEYWDTYPE,
  2618. * TTYLIN, WHICHSTR, LINCTR, LINPTR1, LINNUM1, TMPLIN.
  2619. *
  2620. * MACROS GETCHAR.
  2621. *
  2622. * CALLS DSPLCOD, SCANSTR, SETSCREEN, TOKEN.
  2623. #
  2624. BASED ARRAY KEYLIN[0:99]; ITEM KEYLINE;
  2625. ITEM EXPECT; # 0=CONTENT, 1=LABEL #
  2626. ITEM WEDIDIT B;
  2627. ITEM KEY, SHIFT;
  2628.  
  2629. EXPECT=0;
  2630. SHIFT=1;
  2631. WEDIDIT=FALSE;
  2632. KEY=1;
  2633. KEYWDTYPE=7;
  2634. SCANPOS=TOKENPOS;
  2635.  
  2636. SFLOOP:
  2637. TOKEN;
  2638. SFLOOP2:
  2639.  
  2640. IF TOKENTYPE EQ TYPST"DIGIT" THEN
  2641. BEGIN
  2642. KEY=MIN(MAX(TOKENVAL,1),POSFKEYS);
  2643. GOTO SFLOOP;
  2644. END
  2645.  
  2646. IF TOKENTYPE EQ TYPST"LETTER" THEN
  2647. BEGIN
  2648. IF KEYWDNDX EQ KEYST"KSHI" THEN
  2649. BEGIN # SHIFT KEYWORD #
  2650. SHIFT=-1;
  2651. GOTO SFLOOP;
  2652. END
  2653. ELSE IF KEYWDNDX EQ KEYST"KLAB" THEN
  2654. BEGIN # LABEL KEYWORD #
  2655. EXPECT=1;
  2656. GOTO SFLOOP;
  2657. END
  2658. ELSE
  2659. BEGIN
  2660. IF SCREENMODE THEN
  2661. BEGIN # IF SCREEN SETUP NEEDED #
  2662. IF SPLITFILE[2] EQ 0 THEN SETUPSCREEN(1,0,0);
  2663. ELSE SETUPSCREEN(1,2,USRSPLTSZ);
  2664. IF FKEYNUMROW NQ 0 THEN PAINTREST(FKEYROW);
  2665. END
  2666. ERRJUMP("CHARACTER SEQUENCE NOT RECOGNIZED$");
  2667. END
  2668. END
  2669.  
  2670. IF TOKENTYPE EQ TYPST"DELIMIT" THEN
  2671. BEGIN
  2672.  
  2673. WEDIDIT=TRUE;
  2674. TTYLINE[0]=NULLIN;
  2675. WHICHSTR=1;
  2676. SCANSTR; # PUTS INTO TTYLIN #
  2677.  
  2678. # ALWAYS SET LABEL #
  2679. FKEYNAME[KEY*SHIFT]=" ";
  2680. LINCTR=LENGTH(TTYLIN);
  2681. FOR LINPTR1=0 STEP 1 UNTIL MIN(5,LINCTR-1) DO
  2682. BEGIN
  2683. GETCHAR(TTYLINE,LINPTR1,LINNUM1);
  2684. DSPLCOD(LINNUM1);
  2685. C<LINPTR1,1>FKEYNAME[KEY*SHIFT]=LINNUM1;
  2686. END
  2687. IF EXPECT EQ 0 THEN # SET CONTENT IF NOT EXPLICIT LABEL #
  2688. BEGIN
  2689. EXPECT=1;
  2690. P<KEYLIN>=LOC(FKEYSTRING[KEY*SHIFT]);
  2691. FKEYSTRING[KEY*SHIFT]=NULLIN;
  2692. FOR LINPTR1=0 STEP 1 UNTIL MIN(14,LINCTR-1) DO
  2693. BEGIN
  2694. GETCHAR(TTYLINE,LINPTR1,LINNUM1);
  2695. SETCHAR(KEYLINE,LINPTR1,LINNUM1);
  2696. SETCHAR(KEYLINE,LINPTR1+1,CENDLINE);
  2697. END
  2698. IF LINCTR GQ 14 THEN
  2699. BEGIN
  2700. PUSH;
  2701. POSZ(TOPK(FKEYS)+KEY*SHIFT+POSFKEYS);
  2702. FOR LINPTR1=0 STEP 1 UNTIL LINCTR-1 DO
  2703. BEGIN
  2704. GETCHAR(TTYLINE,LINPTR1,LINNUM1);
  2705. SETCHAR(LINE,LINPTR1,LINNUM1);
  2706. SETCHAR(LINE,LINPTR1+1,CENDLINE);
  2707. END
  2708. REPY;
  2709. POP;
  2710. END
  2711. END
  2712.  
  2713. GOTO SFLOOP2;
  2714. END
  2715.  
  2716. SCNEOC;
  2717.  
  2718. IF SCREENMODE THEN
  2719. BEGIN # IF SCREEN SETUP NEEDED #
  2720. IF SPLITFILE[2] EQ 0 THEN SETUPSCREEN(1,0,0);
  2721. ELSE SETUPSCREEN(1,2,USRSPLTSZ);
  2722. IF FKEYNUMROW NQ 0 THEN PAINTREST(FKEYROW);
  2723. END
  2724.  
  2725. END # OF SCANFUNC #
  2726.  
  2727. CONTROL FI;
  2728. PAGE # MISCELLANEOUS SCANNERS #
  2729.  
  2730.  
  2731. PROC SCNTAB;
  2732. BEGIN
  2733. #
  2734. ** SCNTAB - PARSE SYNTAX FOR *IN* FIELD REFERENCE.
  2735. *
  2736. * ENTRY SCANNER ADVANCED TO TOKEN AFTER *IN* KEYWORD.
  2737. * FORCEFIELD - WHETHER YET INITIALIZED FIELD.
  2738. * WHICHLIN - WHETHER SET FIELDNDX OR FIELDTARGET.
  2739. * WHICHDGT - INDICATES TAB FIELD EXPECTED.
  2740. *
  2741. * EXIT FORCEFIELD - TRUE.
  2742. * TOKEN ADVANCED PAST NUMERIC SYNTAX.
  2743. * FIELDNDX, FIELDTARGET - ONE OF THESE IS SETUP.
  2744. * WHICHDGT - EQUAL TO WHICHLIN.
  2745. *
  2746. * CALLS TOKEN, ERRJUMP.
  2747. #
  2748. ITEM TMP1, TMP2;
  2749.  
  2750. IF NOT FORCEFIELD THEN
  2751. BEGIN
  2752. FIELDNDX=0;
  2753. FIELDTARGET=0;
  2754. END
  2755. FORCEFIELD=TRUE;
  2756. FIELDFLG=TRUE;
  2757. WHICHDGT=WHICHLIN;
  2758. IF TOKENTYPE NQ TYPST"DIGIT" THEN
  2759. BEGIN # IF *IN* ALONE, DEFAULT COLUMNS #
  2760. INFLDBGN=MAX(0,DFINBGN-1);
  2761. INFLDEND=MAX(0,DFINEND-1);
  2762. IF WHICHLIN LS 4 THEN FIELDNDX=-1; ELSE FIELDTARGET=-1;
  2763. END
  2764. ELSE
  2765. BEGIN # IF ONE OR MORE VALUES #
  2766. TMP1=TOKENVAL;
  2767. TOKEN; # ADVANCE NEXT SYNTAX #
  2768. IF TOKENTYPE NQ TYPST"DIGIT" THEN
  2769. BEGIN # IF TAB FIELD INSTEAD OF COLUMNS #
  2770. IF TMP1 LQ 0 THEN ERRJUMP("TAB FIELD ORDINAL OUT OF BOUNDS$");
  2771. IF WHICHLIN LS 4 THEN FIELDNDX=TMP1; ELSE FIELDTARGET=TMP1;
  2772. END
  2773. ELSE
  2774. BEGIN # IF COLUMNS INSTEAD OF TAB FIELD #
  2775. TMP2=TOKENVAL;
  2776. TOKEN; # ADVANCE NEXT SYNTAX #
  2777. IF TMP2 EQ 0 THEN TMP2=BUFCHAR;
  2778. INFLDBGN=MAX(0,MIN(BUFCM1,TMP1-1));
  2779. INFLDEND=MAX(0,MIN(BUFCM1,TMP2-1));
  2780. IF INFLDEND LS INFLDBGN THEN INFLDBGN==INFLDEND;
  2781. IF WHICHLIN LS 4 THEN FIELDNDX=-1; ELSE FIELDTARGET=-1;
  2782. END
  2783. END
  2784. END # OF SCNTAB #
  2785.  
  2786.  
  2787. PROC SCANSTR;
  2788. BEGIN
  2789. #
  2790. ** SCANSTR - PARSE CHARACTER STRING SYNTAX.
  2791. *
  2792. * SCANSTR IS CALLED BY SCANNER WHEN SCANNER DETECTS ONE
  2793. * OF THE STRING DELIMITER PUNTUATION MARKS. SCANSTR ANALYSES
  2794. * THE ENTIRE REMAINDER OF THE COMMAND LINE, THEN DETERMINES
  2795. * WHAT PORTION OF THE COMMAND LINE REALLY PROVIDES STRINGS
  2796. * FOR THE CURRENT COMMAND, AND LEAVES FOR SCANNER ANY
  2797. * PARAMETERS BEYOND THE STRINGS OR ANY ADDITIONAL COMMANDS
  2798. * BEYOND THE STRINGS.
  2799. *
  2800. * ALLOWABLE SYNTAX COMBINATIONS FOR "LOCATE" COMMAND -
  2801. *
  2802. * /TEXT
  2803. * /TEXT/MORE STUFF
  2804. * /TEXT1/./TEXT2 (ELLIPSIS)
  2805. * /TEXT1/./TEXT2/MORE STUFF
  2806. *
  2807. * ALLOWABLE SYNTAX COMBINATIONS FOR "REPLACE" COMMAND -
  2808. *
  2809. * /OLD// (REPLACE WITH NULL)
  2810. * /OLD/NEW
  2811. * /OLD/NEW/MORE STUFF
  2812. * //NEW (USE PREVIOUS SEARCH)
  2813. * //NEW/MORE STUFF
  2814. * /// (PREVIOUS SEARCH, NULL REPLACE)
  2815. * /OLD1/./OLD2// (ELLIPSIS VARIATIONS)
  2816. * /OLD1/./OLD2/NEW
  2817. * /OLD1/./OLD2/NEW/MORE STUFF
  2818. *
  2819. * ALLOWABLE SYNTAX FOR "INSERT", "ALTER", "SET KEY" -
  2820. *
  2821. * /TEXT
  2822. * /TEXT/MORE STUFF
  2823. *
  2824. * ENTRY SCANPOS, TOKENPOS BRACKET INITIAL DELIMETER.
  2825. * WHICHSTR - 1=COMMAND IS "INSERT" , "ALTER", "SK".
  2826. * 2=COMMAND IS "LOCATE".
  2827. * 3=COMMAND IS "REPLACE".
  2828. * TOKENCHAR - THE PUNCTUATION MARK USED AS DELIMITER.
  2829. *
  2830. * EXIT SCANPOS, TOKENPOS - ADVANCED FOR SCANNER TO CONTINUE.
  2831. * ELLIPSIS, TXTINCMD - MODE FLAGS.
  2832. * WORDSEARCH, UPPERSEARCH - FALSE FOR LOCATE, REPLACE.
  2833. * WHICHSTR - SET TO MINUS ONE.
  2834. * LOCSTRING1, LOCSTRING2 - ONE OR BOTH SET FOR "L", "R".
  2835. * CHGSTRING1 - SET FOR "R".
  2836. * LOCSTRLEN1, LOCSTRLEN2, CHGSTRLEN1 - SET PER STRINGS.
  2837. * TTYLIN - SET FOR "I", "A".
  2838. * SCHSTRSPEC - SET FOR REPEATED LOCATE/REPLACE.
  2839. *
  2840. * MACROS GETCHAR, SETCHAR.
  2841. *
  2842. * CALLS MOVESTR(INTERNAL), TOKEN, ERRJUMP.
  2843. *
  2844. * USES ALL TOKENXXXX VARIABLES.
  2845. #
  2846. ITEM TMP1,TMP2,TMP3;
  2847. ITEM NUMSTRING, POINTER, DELIM, CHAR, NONDOT B;
  2848. ARRAY STRINGCTL [1:5];
  2849. BEGIN
  2850. ITEM CTLWORD U(0,0,60); # USED TO CLEAR ALL FIELDS #
  2851. ITEM ALLDOTS B(0,0,1);
  2852. ITEM CLOSED B(0,1,1);
  2853. ITEM TEXTPOS U(0,12,12);
  2854. ITEM TEXTLEN U(0,24,12);
  2855. ITEM AFTERPOS U(0,36,12);
  2856. END
  2857.  
  2858. PROC MOVESTR(WHICH,BUF,LEN,MAXLEN);
  2859. # TITLE MOVESTR - MOVE STRING. #
  2860.  
  2861. BEGIN # MOVESTR #
  2862.  
  2863. #
  2864. * MOVESTR - MOVE STRING.
  2865. *
  2866. * *MOVESTR* MOVES A STRING FROM THE COMMAND LINE TO THE
  2867. * LINE BUFFER.
  2868. *
  2869. * PROC MOVESTR(WHICH,BUF,LEN,MAXLEN)
  2870. *
  2871. * ENTRY WHICH - TYPE OF STRING.
  2872. * BUF - LINE BUFFER TO UPDATE.
  2873. * LEN - LINE BUFFER LENGTH.
  2874. * MAXLEN - MAXIMUM STRING LENGTH.
  2875. *
  2876. * EXIT STRING MOVED TO LINE BUFFER.
  2877. *
  2878. * MACROS GETCHAR, SETCHAR.
  2879. *
  2880. * CALLS ERRJUMP.
  2881. #
  2882.  
  2883. ARRAY BUF[0:99];
  2884. BEGIN # ARRAY BUF #
  2885. ITEM LINEBUF I; # LINE BUFFER #
  2886. END # ARRAY BUF #
  2887.  
  2888. ITEM WHICH I; # TYPE OF STRING #
  2889. ITEM LEN I; # LINE BUFFER LENGTH #
  2890. ITEM MAXLEN I; # MAXIMUM STRING LENGTH #
  2891. ITEM TMP1 I; # TEMPORARY STORAGE #
  2892.  
  2893. IF TEXTLEN[WHICH] GR MAXLEN THEN # IF STRING TOO LARGE #
  2894. BEGIN
  2895. ERRJUMP("STRING GREATER THAN 80 CHARACTERS$");
  2896. END
  2897. LEN=TEXTLEN[WHICH];
  2898. LINEBUF[0]=NULLIN;
  2899. FOR TMP1=1 STEP 1 UNTIL LEN DO # MOVE STRING #
  2900. BEGIN
  2901. GETCHAR(CMDLINE,TEXTPOS[WHICH]+TMP1-1,TMP2);
  2902. SETCHAR(LINEBUF,TMP1-1,TMP2);
  2903. END
  2904. SETCHAR(LINEBUF,LEN,CENDLINE);
  2905. SCHSTRSPEC=TRUE; # SEARCH STRING SPECIFIED #
  2906.  
  2907. END # MOVESTR #
  2908.  
  2909.  
  2910. # MAIN CODE STARTS HERE #
  2911.  
  2912. NUMSTRING=0;
  2913. POINTER=TOKENPOS;
  2914. DELIM=TOKENCHAR;
  2915.  
  2916. LOOP:
  2917. NUMSTRING=NUMSTRING+1;
  2918. CTLWORD[NUMSTRING]=0;
  2919. TEXTPOS[NUMSTRING]=POINTER+1;
  2920. NONDOT=FALSE;
  2921. TMP1=-1;
  2922. FOR TMP2=POINTER+1 STEP 1 WHILE TMP2 LS LENGTH(CMDLIN)
  2923. AND TMP1 LS 0 DO
  2924. BEGIN
  2925. GETCHAR(CMDLINE,TMP2,TMP3);
  2926. IF TMP3 NQ DELIM AND TMP3 NQ CPERIOD THEN NONDOT=TRUE;
  2927. IF TMP3 EQ DELIM THEN TMP1=TMP2;
  2928. END
  2929. IF TMP1 GQ 0 THEN
  2930. BEGIN
  2931. CLOSED[NUMSTRING]=TRUE;
  2932. TEXTLEN[NUMSTRING]=TMP1-TEXTPOS[NUMSTRING];
  2933. IF TEXTLEN[NUMSTRING] GR 0 AND NOT NONDOT
  2934. THEN ALLDOTS[NUMSTRING]=TRUE;
  2935. AFTERPOS[NUMSTRING]=TMP1+1;
  2936. POINTER=TMP1;
  2937. IF NUMSTRING LQ 4 THEN GOTO LOOP;
  2938. END
  2939. ELSE
  2940. BEGIN
  2941. TEXTLEN[NUMSTRING]=LENGTH(CMDLIN)-TEXTPOS[NUMSTRING];
  2942. AFTERPOS[NUMSTRING]=LENGTH(CMDLIN);
  2943. #GOTO PHASE2#
  2944. END
  2945.  
  2946. PHASE2:
  2947. IF WHICHSTR EQ 1 THEN # INSERT, ALTER, SET KEY #
  2948. BEGIN
  2949. MOVESTR(1,TTYLIN,TMP1,BUFCM1);
  2950. TXTINCMD=TRUE;
  2951. SCANPOS=AFTERPOS[1];
  2952. END
  2953. ELSE IF WHICHSTR EQ 2 THEN # LOCATE #
  2954. BEGIN
  2955. WORDSEARCH=FALSE;
  2956. UPPERSEARCH=FALSE;
  2957. IF ALLDOTS[2] AND NUMSTRING GQ 3 THEN
  2958. BEGIN
  2959. ELLIPSIS=TRUE;
  2960. IF TEXTLEN[1] NQ 0 THEN MOVESTR(1,LOCSTRING1,LOCSTRLEN1,80);
  2961. IF TEXTLEN[3] NQ 0 THEN MOVESTR(3,LOCSTRING2,LOCSTRLEN2,80);
  2962. SCANPOS=AFTERPOS[3];
  2963. END
  2964. ELSE
  2965. BEGIN
  2966. IF TEXTLEN[1] NQ 0 THEN MOVESTR(1,LOCSTRING1,LOCSTRLEN1,80);
  2967. ELLIPSIS=FALSE;
  2968. SCANPOS=AFTERPOS[1];
  2969. END
  2970. END
  2971. ELSE IF WHICHSTR EQ 3 THEN # REPLACE #
  2972. BEGIN
  2973. WORDSEARCH=FALSE;
  2974. UPPERSEARCH=FALSE;
  2975. IF ALLDOTS[2] AND NUMSTRING GQ 4 THEN
  2976. BEGIN
  2977. IF TEXTLEN[4] EQ 0 AND NOT CLOSED[4]
  2978. THEN ERRJUMP("MISSING REPLACEMENT STRING$");
  2979. ELLIPSIS=TRUE;
  2980. IF TEXTLEN[1] NQ 0 THEN MOVESTR(1,LOCSTRING1,LOCSTRLEN1,80);
  2981. IF TEXTLEN[3] NQ 0 THEN MOVESTR(3,LOCSTRING2,LOCSTRLEN2,80);
  2982. MOVESTR(4,CHGSTRING1,CHGSTRLEN1,80);
  2983. SCANPOS=AFTERPOS[4];
  2984. END
  2985. ELSE IF NUMSTRING GQ 2 THEN
  2986. BEGIN
  2987. IF TEXTLEN[2] EQ 0 AND NOT CLOSED[2]
  2988. THEN ERRJUMP("MISSING REPLACEMENT STRING$");
  2989. IF TEXTLEN[1] NQ 0 THEN
  2990. BEGIN
  2991. MOVESTR(1,LOCSTRING1,LOCSTRLEN1,80);
  2992. ELLIPSIS=FALSE;
  2993. END
  2994. MOVESTR(2,CHGSTRING1,CHGSTRLEN1,80);
  2995. SCANPOS=AFTERPOS[2];
  2996. END
  2997. END
  2998.  
  2999. WHICHSTR=-1;
  3000. TOKEN;
  3001.  
  3002. END # OF SCANSTR #
  3003.  
  3004.  
  3005. PROC SCNEOC;
  3006. BEGIN
  3007. #
  3008. ** SCNEOC - VERIFY END OF COMMAND.
  3009. *
  3010. * SCNEOC IS CALLED TO MAKE SURE THERE IS NO UNSCANNED
  3011. * SYNTAX LEFT IN THE CURRENT COMMAND.
  3012. *
  3013. * ENTRY SCANPOS, TOKENPOS BRACKET CURRENT SYNTAX.
  3014. * TOKENCHAR IS CURRENT CHARACTER.
  3015. *
  3016. * CALLS ERRJUMP.
  3017. #
  3018. IF SYNTAXCHAR[TOKENCHAR] THEN ERRJUMP("TOO MANY PARAMETERS$");
  3019. END # OF SCNEOC #
  3020.  
  3021.  
  3022. PROC SCNONOFF(BOOL);
  3023. BEGIN
  3024. #
  3025. ** SCNONOFF - PARSE YES/NO SYNTAX.
  3026. *
  3027. * SCNONOFF RECOGNIZES YES/NO KEYWORDS AND TELLS THE CALLER
  3028. * WHICH WAS FOUND. SCNONOFF IS CALLED WHEN A YES/NO
  3029. * KEYWORD IS EXPECTED BUT HAS NOT YET BEEN ENCOUNTERED.
  3030. * THUS SCNONOFF VERIFIES THAT ONE OF THESE WORDS IS NEXT.
  3031. *
  3032. * ENTRY SCANPOS, TOKENPOS - BRACKET NEXT TOKEN.
  3033. * TOKENTYPE, KEYWDNDX - WHAT THE NEXT TOKEN IS.
  3034. *
  3035. * EXIT BOOL - WHICH KEYWORD.
  3036. * VIA ERRJUMP IF NEITHER.
  3037. * TOKENPOS, SCANPOS - ADVANCED TO NEXT TOKEN.
  3038. *
  3039. * CALLS TOKEN, ERRJUMP.
  3040. #
  3041. ITEM BOOL B;
  3042. SCANPOS=TOKENPOS;
  3043. KEYWDTYPE=3;
  3044. TOKEN;
  3045. IF TOKENTYPE EQ TYPST"LETTER" AND C<0,1>KEYWORD[KEYWDNDX] EQ "Y"
  3046. THEN BOOL=TRUE;
  3047. ELSE IF TOKENTYPE EQ TYPST"LETTER" AND C<0,1>KEYWORD[KEYWDNDX]
  3048. EQ "N" THEN BOOL=FALSE;
  3049. ELSE ERRJUMP("MUST SPECIFY YES OR NO$");
  3050. TOKEN;
  3051. END # OF SCNONOFF #
  3052.  
  3053.  
  3054. PROC SCNEQVAL; # SCAN "=VALUE" #
  3055. BEGIN
  3056. #
  3057. ** SCNEQVAL - PARSE NUMERIC SYNTAX PARAMETER.
  3058. *
  3059. * SCNEQVAL IS USED BY COMMAND SCANNERS OTHER THAN "SCANNER"
  3060. * ITSELF. (SCANNER ITSELF HANDLES OR ROUTES TREATMENT OF
  3061. * NUMERIC PARAMETERS ON ITS OWN) SCNEQVAL IS USED BY COMMAND
  3062. * SCANNERS THAT EXPECT/DEMAND A NUMERIC VALUE. AN EQUAL
  3063. * SIGN IS ALLOWED TO PRECEED THE PARAMETER.
  3064. *
  3065. * ENTRY SCANPOS, TOKENPOS - BRACKET NEXT TOKEN.
  3066. * TOKENTYPE, TOKENVAL - DESCRIBE NEXT TOKEN.
  3067. *
  3068. * EXIT LINPTR1 - VALUE OF NUMBER.
  3069. * VIA ERRJUMP IF NO NUMBER FOUND.
  3070. * SCANPOS, TOKENPOS - ADVANCED TO NEXT TOKEN.
  3071. *
  3072. * CALLS TOKEN, ERRJUMP.
  3073. #
  3074. IF TOKENTYPE EQ TYPST"EQUAL" THEN TOKEN;
  3075. IF TOKENTYPE NQ TYPST"DIGIT" THEN ERRJUMP("VALUE MUST BE NUMERIC$");
  3076. LINPTR1=TOKENVAL;
  3077. TOKEN; # ADVANCE TO NEXT SYNTAX #
  3078. END # OF SCNEQVAL #
  3079.  
  3080.  
  3081. PROC SCNEQNAM(NAME);
  3082. BEGIN
  3083. #
  3084. ** SCNEQNAM - PARSE ARBITRARY ALPHANUMERIC WORD.
  3085. *
  3086. * SCNEQNAM SCANS AN ARBITRARY ALPHANUMERIC WORD, POSSIBLY
  3087. * PRECEEDED BY AN EQUAL SIGN.
  3088. *
  3089. * ENTRY TOKENPOS, SCANPOS - BRACKET CURRENT SYNTAX.
  3090. * TOKENTYPE - DESCRIBES CURRENT SYNTAX.
  3091. *
  3092. * EXIT NAME - THE WORD SCANNED.
  3093. * SCANPOS, TOKENPOS - ADVANCED.
  3094. * SCNNAMPTR - POINTS TO WORD.
  3095. *
  3096. * CALLS TOKEN, ERRJUMP.
  3097. *
  3098. * USES ALL TOKENXXXX VARIABLES, KEYWDTYPE.
  3099. #
  3100. ITEM NAME C(7), TMP1;
  3101. IF TOKENTYPE EQ TYPST"EQUAL" THEN TOKEN;
  3102. IF TOKENTYPE NQ TYPST"LETTER" AND TOKENTYPE NQ TYPST"DIGIT"
  3103. THEN ERRJUMP("MUST SPECIFY FILE NAME$");
  3104. ELSE
  3105. BEGIN
  3106. TMP1=KEYWDTYPE;
  3107. KEYWDTYPE=0; # ENABLE MIXED LETTERS DIGITS #
  3108. SCANPOS=TOKENPOS; # SET FOR RESCAN #
  3109. TOKEN; # RESCAN THE CURRENT SYNTAX #
  3110. KEYWDTYPE=TMP1;
  3111. NAME=C<0,7>TOKENSYM;
  3112. SCNNAMPTR=SCANPOS;
  3113. TOKEN; # NEXT SYNTAX #
  3114. END
  3115. END # OF SCNEQNAM #
  3116.  
  3117. PROC SCNFILE(NAME);
  3118. BEGIN
  3119. #
  3120. ** SCNFILE - SCAN PARENTHESIZED FILENAME.
  3121. *
  3122. * SCNFILE IS CALLED WHEN AN OPENING PARENTHESIS HAS BEEN
  3123. * DETECTED, AND PARSES OUT THE FILENAME AND ADVANCES THE
  3124. * SYNTAX BEYOND THE CLOSING PARENTHESIS.
  3125. *
  3126. * ENTRY SCANPOS, TOKENPOS - BRACKET CURRENT SYNTAX.
  3127. * TOKENCHAR - CURRENT CHARACTER.
  3128. *
  3129. * EXIT NAME - THE ARBITRARY ALPHANUMERIC WORD.
  3130. * SCANPOS, TOKENPOS - ADVANCED TO NEXT SYNTAX.
  3131. *
  3132. * CALLS TOKEN, SCNEQNAM.
  3133. *
  3134. * USES SCNNAMPTR, ALL TOKENXXXX VARIABLES.
  3135. #
  3136. ITEM NAME C(7);
  3137. SCNNAMPTR=TOKENPOS;
  3138. IF TOKENCHAR EQ CLPAREN THEN
  3139. BEGIN
  3140. TOKEN;
  3141. SCNEQNAM(NAME);
  3142. SCNNAMPTR=TOKENPOS;
  3143. IF TOKENCHAR EQ CRPAREN THEN SCNNAMPTR=TOKENPOS+1;
  3144. END
  3145. SCANPOS=SCNNAMPTR;
  3146. TOKEN;
  3147. END # OF SCNFILE #
  3148.  
  3149.  
  3150. PROC SCNCHAR;
  3151. BEGIN
  3152. #
  3153. ** SCNCHAR - PARSE ARBITRARY PUNCTUATION OR ALTERNATE NAME.
  3154. *
  3155. * SCNCHAR IS CALLED WHEN WE EXPECT AN ARBITRARY PUNCTUATION
  3156. * MARK AS THE NEXT SYNTAX, OR AN ALTERNATE KEYWORD FOR
  3157. * BLANK OR SEMICOLON.
  3158. *
  3159. * ENTRY SCANPOS, TOKENPOS - BRACKET CURRENT SYNTAX.
  3160. * TOKENCHAR - CURRENT CHARACTER.
  3161. *
  3162. * EXIT LINPTR1 - THE CHARACTER. CONVERTED TO ACTUAL
  3163. * CHARACTER IF ALTERNATE KEYWORD WAS USED.
  3164. * SCANPOS, TOKENPOS - ADVANCED TO NEXT SYNTAX.
  3165. *
  3166. * MACROS GETCHAR.
  3167. *
  3168. * CALLS TOKEN.
  3169. *
  3170. * USES ALL TOKENXXXX VARIABLES, KEYWDTYPE(RESTORED).
  3171. #
  3172. ITEM TMP1;
  3173. IF NOT SYNTAXCHAR[TOKENCHAR] THEN LINPTR1=CNOTHING;
  3174. ELSE
  3175. BEGIN
  3176. TMP1=KEYWDTYPE;
  3177. KEYWDTYPE=0; # ENABLE MIXED LETTERS DIGITS #
  3178. SCANPOS=TOKENPOS; # SET FOR RESCAN #
  3179. TOKEN; # RESCAN THE CURRENT SYNTAX #
  3180. IF TOKENTYPE EQ TYPST"LETTER" AND C<0,7>TOKENSYM EQ "BLANK"
  3181. THEN LINPTR1=CBLANK;
  3182. ELSE IF TOKENTYPE EQ TYPST"LETTER" AND C<0,7>TOKENSYM EQ "SEMI"
  3183. THEN LINPTR1=CSEMCOLON;
  3184. ELSE
  3185. BEGIN
  3186. GETCHAR(CMDLINE,TOKENPOS,LINPTR1);
  3187. SCANPOS=TOKENPOS+1;
  3188. END
  3189. KEYWDTYPE=TMP1;
  3190. TOKEN;
  3191. END
  3192. END # OF SCNCHAR #
  3193.  
  3194.  
  3195. PROC SCNLSTCOL;
  3196. BEGIN
  3197. #
  3198. ** SCNLSTCOL - PARSE A LIST OF NUMBERS INTO TAB VECTOR.
  3199. *
  3200. * SCNLSTCOL IS CALLED WHEN A LIST OF NUMBERS IS EXPECTED.
  3201. * WE DECODE EACH NUMBER AND PACK UP TO 20 OF THEM INTO
  3202. * EIGHT-BIT FIELDS IN A THREE-WORD VECTOR. THIS IS CURRENTLY
  3203. * NEEDED ONLY FOR THE "SET TABS" COMMAND.
  3204. *
  3205. * ENTRY TOKENPOS, SCANPOS - BRACKET FIRST NUMBER.
  3206. * TOKENVAL - VALUE OF FIRST NUMBER.
  3207. *
  3208. * EXIT TABVECTOR - ZEROED OR FILLED WITH PACKED LIST.
  3209. * TOKENPOS, SCANPOS - ADVANCED TO END OF COMMAND.
  3210. *
  3211. * CALLS TOKEN, ERRJUMP, SCNEOC.
  3212. *
  3213. * USES LINPTR1, LINPTR2, LINNUM1, LINNUM2, ALL TOKENXXXX.
  3214. #
  3215. ARRAY TEMPTABS [1:TABWORDS];
  3216. BEGIN
  3217. ITEM TMPTABWRD;
  3218. END
  3219.  
  3220. FOR LINPTR1=1 STEP 1 UNTIL TABWORDS DO
  3221. BEGIN
  3222. TMPTABWRD[LINPTR1]=0;
  3223. END
  3224. LINPTR2=0;
  3225. LINPTR1=1; # FIRST LEGAL COLUMN #
  3226. WHYLE TOKENTYPE EQ TYPST"DIGIT" AND LINPTR2 LS USERTABS DO
  3227. BEGIN
  3228. IF TOKENVAL LS LINPTR1 OR TOKENVAL GR BUFCHAR
  3229. THEN ERRJUMP("TAB STOP OUT OF BOUNDS$");
  3230. IF TOKENVAL GR 1 THEN
  3231. BEGIN
  3232. LINNUM1=LINPTR2/7;
  3233. LINNUM2=MOD(LINPTR2,7);
  3234. B<LINNUM2*8,8>TMPTABWRD[LINNUM1+1]=TOKENVAL-1;
  3235. LINPTR2=LINPTR2+1;
  3236. END
  3237. LINPTR1=TOKENVAL+1;
  3238. TOKEN;
  3239. END
  3240. SCNEOC;
  3241. MOVEWD(TABWORDS,TEMPTABS,TABVECTOR);
  3242. END # OF SCNLSTCOL #
  3243.  
  3244.  
  3245. PROC SCNFILOPT;
  3246. BEGIN
  3247. #
  3248. ** SCNFILOPT - SCAN OPTIONS ALLOWABLE ON "FSE" COMMAND.
  3249. *
  3250. * SCNFILOPT PROVIDES ALL SCANNING FOR THE
  3251. * "FSE" COMMAND ONCE THE COMMAND VERB HAS BEEN RECOGNIZED.
  3252. * THE CALLER IS RESPONSIBLE TO CALL SCNEOC AFTER SCNFILOPT.
  3253. *
  3254. * ENTRY TOKENPOS, SCANPOS - BRACKET FIRST SYNTAX AFTER VERB.
  3255. *
  3256. * EXIT TOKENPOS, SCANPOS - BRACKET LAST KNOWN SYNTAX.
  3257. * GETPARM, CHARPARM - SET PER SYNTAX.
  3258. * FILNUM - 1 OR 2 PER "SPLIT" KEYWORD.
  3259. * SCREENMODE - ELIGIBLE TO USE "SPLIT" KEYWORD.
  3260. *
  3261. * CALLS SCNEQNAM, ERRJUMP, TOKEN.
  3262. *
  3263. * USES KEYWDTYPE, ALL TOKENXXXX VARIABLES.
  3264. #
  3265. DEF SFOMAXOPT #7#;
  3266. DEF SFOMAXLBL #5#;
  3267.  
  3268. STATUS SFOST
  3269. CSET1,
  3270. CSET2,
  3271. CSET3,
  3272. GET,
  3273. SPLIT,
  3274. READ;
  3275.  
  3276. SWITCH SFOLABELS SFOCS1, SFOCS2, SFOCS3, SFOGET, SFOSPLIT, SFOREAD;
  3277.  
  3278. ARRAY SFOMATCHES [0:SFOMAXOPT];
  3279. BEGIN
  3280. ITEM SFOKEY U(0,0,30) = [KEYST"XDIS", KEYST"XNOR",
  3281. KEYST"XASC", KEYST"XASC8", KEYST"XA8", KEYST"XGET",
  3282. KEYST"XSPL", KEYST"XREA" ];
  3283. ITEM SFOLBL U(0,30,30) = [ SFOST"CSET1", SFOST"CSET1",
  3284. SFOST"CSET2", SFOST"CSET3", SFOST"CSET3", SFOST"GET",
  3285. SFOST"SPLIT", SFOST"READ" ];
  3286. END
  3287. ITEM TMP1, TMP2;
  3288.  
  3289. SCNEQNAM(READNAM);
  3290. GETPARM=0;
  3291. CHARPARM=0;
  3292. FILNUM=1;
  3293. KEYWDTYPE=4;
  3294. SCANPOS=TOKENPOS;
  3295. KEYWDNDX=-1;
  3296. TOKEN;
  3297. WHYLE TOKENTYPE EQ TYPST"LETTER" OR TOKENTYPE EQ TYPST"DIGIT" DO
  3298. BEGIN
  3299. TMP2=-1;
  3300. FOR TMP1=0 STEP 1 UNTIL SFOMAXOPT DO IF SFOKEY[TMP1] EQ
  3301. KEYWDNDX THEN TMP2=SFOLBL[TMP1];
  3302. IF TMP2 LS 0 THEN
  3303. BEGIN
  3304. ERRJUMP("PARAMETER NOT VALID FOR THIS DIRECTIVE$");
  3305. END
  3306. GOTO SFOLABELS[TMP2];
  3307.  
  3308. SFOCS1:
  3309. CHARPARM=1;
  3310. GOTO SFODONE;
  3311.  
  3312. SFOCS2:
  3313. CHARPARM=2;
  3314. GOTO SFODONE;
  3315.  
  3316. SFOCS3:
  3317. CHARPARM=3;
  3318. GOTO SFODONE;
  3319.  
  3320. SFOGET:
  3321. GETPARM=2;
  3322. GOTO SFODONE;
  3323.  
  3324. SFOSPLIT:
  3325. FILNUM=2;
  3326. IF NOT SCREENMODE THEN ERRJUMP("SCREEN MODE REQUIRED$");
  3327. GOTO SFODONE;
  3328.  
  3329. SFOREAD:
  3330. GETPARM=3;
  3331. GOTO SFODONE;
  3332.  
  3333. SFODONE:
  3334. KEYWDNDX=-1;
  3335. TOKEN;
  3336. END
  3337. END # OF SCNFILOPT #
  3338. PAGE # MICRO EXPANSION #
  3339.  
  3340.  
  3341. PROC EXPANDCMDS;
  3342. BEGIN
  3343. #
  3344. ** EXPANDCMDS - EXPAND MICROS FROM IN COMMAND LINE.
  3345. *
  3346. * EXPANDCMDS IS CALLED WHEN THE MAIN PROCESS DRIVER FINDS
  3347. * THAT THE MAIN SCREEN PROMPT FOR COMMANDS YIELDED ONE OR
  3348. * MORE MICROS (AMPERSAND SYMBOLS) SPECIFICALLY IN THE
  3349. * CONVERSION OF FUNCTION KEY STRIKES INTO COMMAND TEXT,
  3350. * OR IN FETCHING OF COMMAND LINES FROM PROCEDURES.
  3351. *
  3352. * ENTRY CMDLIN - COMMAND STRING CONTAINING MICROS.
  3353. * EXPANDAT - POINTS TO FIRST AMPERSAND.
  3354. * PROCACTIVE - MUST BE TRUE IF FORCED FALSE, OTHERWISE
  3355. * TREAT CALL AS NO-OP.
  3356. * CURFILE - CURRENT FILE BRACKET.
  3357. * FILENAM[CURFILE] - CURRENT FILE NAME.
  3358. * CURRENT - CURRENT LINE ADDRESS.
  3359. * TOPF(CURFILE) - UPPER BOUND FOR FILE.
  3360. * CURCURSOR - CURRENT CHARACTER POSITION IN FILE.
  3361. * LIN - TEXT OF CURRENT FILE LINE.
  3362. * ERRSTRING - USER'S ANNOUNCEMENT FOR "&?".
  3363. *
  3364. * EXIT CMDLIN - EXPANDED.
  3365. * &C REPLACED WITH CURRENT COLUMN.
  3366. * &F REPLACED WITH CURRENT FILENAME.
  3367. * &L REPLACED WITH CURRENT LINE ORDINAL.
  3368. * &P REPLACED WITH CURRENT PROCEDURE FILE NAME.
  3369. * &T REPLACED WITH CURRENT TERMINAL.
  3370. * &W REPLACED WITH CURRENT TEXT WORD.
  3371. * &Z REPLACED WITH CURRENT WORKFILE.
  3372. * &DIGIT REPLACED WITH PROC PARAMETER.
  3373. * &? REPLACED WITH INTERACTIVE INPUT.
  3374. * && REPLACED WITH &.
  3375. * EXPANDAT - DESTROYED.
  3376. *
  3377. * MACROS GETCHAR, SETCHAR, MOD.
  3378. *
  3379. * CALLS EXPANDNUM(INTERNAL), DSPLCOD, MIN, LSHIFT, RSHIFT,
  3380. * LENGTH, PROCPARM, ASKUSER.
  3381. #
  3382. ITEM TMP1;
  3383. ITEM I,J,K,L,M;
  3384. ITEM MSG C(80);
  3385. ITEM INCR;
  3386.  
  3387.  
  3388. PROC EXPANDNAME(NAME);
  3389. BEGIN
  3390. #
  3391. * EXPANDNAME - GENERATE NAME SPECIFIED IN PARAMETER.
  3392. #
  3393. ITEM NAME;
  3394. L=7;
  3395. FOR I=6 STEP -1 UNTIL 0 DO
  3396. BEGIN
  3397. K=B<I*6,6>NAME;
  3398. CONTROL IFNQ CBLANK,O"55"; ERROR; CONTROL FI;
  3399. IF K EQ CBLANK OR K EQ 0 THEN L=I;
  3400. END
  3401. L=MIN(L,BUFCM1-EXPANDAT); # ASSURE IT FITS #
  3402. LSHIFT(CMDLIN,EXPANDAT+2,2); # REMOVE &F #
  3403. RSHIFT(CMDLIN,EXPANDAT,L); # MAKE ROOM FOR NAME #
  3404. FOR I=0 STEP 1 UNTIL L-1 DO
  3405. BEGIN
  3406. # NEXT CODE REQUIRES INTERNAL CHARSET MAPS ON DISPLAY CODE #
  3407. CONTROL IFNQ CLETTERA,1; ERROR; CONTROL FI;
  3408. K=B<I*6,6>NAME;
  3409. SETCHAR(CMDLINE,J,K); # STORE NAME #
  3410. J=J+1;
  3411. END
  3412. INCR=L;
  3413. END # EXPANDNAME #
  3414.  
  3415.  
  3416. PROC EXPANDNUM;
  3417. BEGIN
  3418. #
  3419. ** EXPANDNUM - GENERATE NUMBER SPECIFIED BY L.
  3420. *
  3421. * ENTRY L - NUMBER TO ENCODE.
  3422. * CMDLIN - LINE IMAGE.
  3423. * POSITION - CHARACTER LOCATION OF AMPERSAND.
  3424. *
  3425. * EXIT CMDLIN - UPDATED.
  3426. * INCR - INCREMENTED
  3427. * L - DESTROYED.
  3428. *
  3429. * USES I, K.
  3430. *
  3431. * NOTE SEE HEADER DOCUMENTATION FOR EXPAND.
  3432. #
  3433. LSHIFT(CMDLIN,EXPANDAT+1,1);
  3434. I=0;
  3435. INCR=1;
  3436. WHYLE L NQ 0 OR I EQ 0 DO
  3437. BEGIN
  3438. K=MOD(L,10)+CDIGIT0;
  3439. SETCHAR(CMDLINE,EXPANDAT,K);
  3440. L=L/10;
  3441. I=I+1;
  3442. IF L NQ 0 THEN
  3443. BEGIN
  3444. RSHIFT(CMDLIN,EXPANDAT,1);
  3445. INCR=INCR+1;
  3446. END
  3447. END
  3448. END # OF EXPANDNUM #
  3449.  
  3450.  
  3451. # MAIN CODE OF EXPAND STARTS HERE #
  3452.  
  3453. WHYLE EXPANDAT LS LENGTH(CMDLIN) DO
  3454. BEGIN
  3455. GETCHAR(CMDLINE,EXPANDAT,TMP1);
  3456. IF TMP1 NQ CAMPER THEN EXPANDAT=EXPANDAT+1;
  3457. ELSE
  3458. BEGIN
  3459. INCR=1;
  3460. J=EXPANDAT;
  3461. GETCHAR(CMDLINE,EXPANDAT+1,K);
  3462. DSPLCOD(K); # MAKE UPPER CASE #
  3463. IF K EQ CLETTERF THEN # &F = FILENAME #
  3464. BEGIN
  3465. EXPANDNAME(FILENAM[CURFILE]);
  3466. END
  3467. ELSE IF K EQ CLETTERW THEN # &W = CURRENT WORD #
  3468. BEGIN
  3469. L=0; # LENGTH OF WORD #
  3470. IF CURCURSOR LS LENGTH(LIN) THEN # MUST MEASURE #
  3471. BEGIN
  3472. J=CURCURSOR;
  3473. GETCHAR(LINE,J,K);
  3474. IF K EQ CBLANK THEN
  3475. BEGIN
  3476. WHYLE K EQ CBLANK DO
  3477. BEGIN
  3478. J=J+1;
  3479. GETCHAR(LINE,J,K);
  3480. END
  3481. END
  3482. IF K EQ CENDLINE THEN J=J-1;
  3483. IF B<K LAN 31,1>WORDFLAG[K/32] EQ 0 THEN J=J-1;
  3484. WHYLE J GQ 0 AND B<K LAN 31,1>WORDFLAG[K/32] EQ 1 DO
  3485. BEGIN
  3486. J=J-1;
  3487. GETCHAR(LINE,J,K);
  3488. END
  3489. I=J+1;
  3490. GETCHAR(LINE,I,K);
  3491. WHYLE K NQ CENDLINE AND B<K LAN 31,1>WORDFLAG[K/32] EQ 1 DO
  3492. BEGIN
  3493. I=I+1;
  3494. GETCHAR(LINE,I,K);
  3495. L=L+1;
  3496. END
  3497. END
  3498. L=MAX(L,1);
  3499. L=MIN(L,BUFCM1-EXPANDAT); # ASSURE FITS #
  3500. LSHIFT(CMDLIN,EXPANDAT+2,2); # EXTRACT &W #
  3501. RSHIFT(CMDLIN,EXPANDAT,L);
  3502. FOR I=1 STEP 1 UNTIL L DO # INSERT WORD #
  3503. BEGIN
  3504. GETCHAR(LINE,J+I,K);
  3505. SETCHAR(CMDLINE,EXPANDAT+I-1,K);
  3506. END
  3507. INCR=L;
  3508. END
  3509. ELSE IF K EQ CLETTERL THEN
  3510. BEGIN
  3511. L=CURRENT-TOPF(CURFILE);
  3512. EXPANDNUM;
  3513. END
  3514. ELSE IF K EQ CLETTERC THEN
  3515. BEGIN
  3516. L=CURCURSOR+1;
  3517. EXPANDNUM;
  3518. END
  3519. ELSE IF K EQ CLETTERP THEN
  3520. BEGIN # &P = PROCEDURE FILE NAME #
  3521. EXPANDNAME(PROCNAM);
  3522. END
  3523. ELSE IF K EQ CLETTERZ THEN
  3524. BEGIN
  3525. EXPANDNAME(WORKORG);
  3526. END
  3527. ELSE IF K EQ CLETTERT THEN
  3528. BEGIN
  3529. IF SCREENMODE THEN
  3530. BEGIN
  3531. C<00,07>M=TABMODNAME[0]; # TERMINAL PROCEDURE #
  3532. EXPANDNAME(M);
  3533. END
  3534. ELSE
  3535. BEGIN
  3536. M="LINE "; # LINE PROCEDURE #
  3537. EXPANDNAME(M);
  3538. END
  3539. END
  3540. ELSE IF K GR CDIGIT0 AND K LQ CDIGIT9 AND PROCACTIVE THEN
  3541. BEGIN
  3542. K=K-CDIGIT0; # PARAMETER NUMBER #
  3543. CONTROL IFEQ SINGLE,1;
  3544. PROCPARM(CMDLIN,J,K,BUFCM1,INCR);
  3545. CONTROL FI;
  3546. END
  3547. ELSE IF K EQ CAMPER THEN LSHIFT(CMDLIN,EXPANDAT+1,1);
  3548. ELSE IF K EQ CQUESTION THEN
  3549. BEGIN
  3550. MSG=ERRSTRING; # PRESERVE ANNOUNCEMENT #
  3551. IF MSG EQ " $" THEN MSG="ENTER TEXT$";
  3552. ASKUSER(MSG,QCCKWRD);
  3553. LSHIFT(CMDLIN,EXPANDAT+2,2); # KILL MICRO #
  3554. L=LENGTH(TTYLIN);
  3555. RSHIFT(CMDLIN,EXPANDAT,L);
  3556. FOR I=0 STEP 1 UNTIL L-1 DO
  3557. BEGIN
  3558. GETCHAR(TTYLINE,I,J);
  3559. SETCHAR(CMDLINE,EXPANDAT+I,J);
  3560. END
  3561. INCR=L;
  3562. END
  3563. EXPANDAT=EXPANDAT+INCR;
  3564. END
  3565. END
  3566. END # EXPANDCMDS #
  3567.  
  3568.  
  3569. CONTROL IFEQ SINGLE,1;
  3570.  
  3571. PROC PROCPARM(TXTLIN,POS,NDX,MAXPOS,INCR);
  3572. BEGIN
  3573. #
  3574. ** PROCPARM - EXPAND MICRO FOR PROCEDURE PARAMETERS.
  3575. *
  3576. * PROCPARM IS CALLED BY EXPAND TO EXPAND ONE PROC PARAMETER
  3577. * MICRO, WHICH CONSISTS OF AN AMPERSAND FOLLOWED BY A DIGIT
  3578. * REPRESENTING THE PARAMETER ORDINAL. IF THERE ARE NOT
  3579. * ENOUGH PARAMETERS PROVIDED, THEN NULL OUT THE MICRO.
  3580. *
  3581. * ENTRY TXTLIN - INTERNAL LINE IMAGE PROVIDING TEXT.
  3582. * POS - WHERE THE MICRO IS IN TXTLIN.
  3583. * NDX - WHICH PARAMETER IS REQUESTED BY THE MICRO.
  3584. * MAXPOS - MAX CHARACTER CAPACITY IN TXTLIN.
  3585. *
  3586. * EXIT TXTLIN - UPDATED.
  3587. * POS - INCREMENTED PAST EXPANSION.
  3588. *
  3589. * MACROS GETCHAR, SETCHAR.
  3590. *
  3591. * CALLS LSHIFT, RSHIFT.
  3592. #
  3593. ARRAY TXTLIN [0:99]; ITEM TXTLINE;
  3594. ITEM POS,NDX,MAXPOS,INCR;
  3595. ITEM TMP1,TMP2,TMP3,TMP4,TMP5,TMP6;
  3596. # FIRST SKIP PREVIOUS PARAMETERS AND BRACKET DESIRED PARM #
  3597. TMP1=PARMPTR;
  3598. FOR TMP2=1 STEP 1 UNTIL NDX DO
  3599. BEGIN
  3600. GETCHAR(PARMLINE,TMP1,TMP3);
  3601. # SKIP LEADING BLANKS #
  3602. WHYLE TMP3 EQ CBLANK DO
  3603. BEGIN
  3604. TMP1=TMP1+1;
  3605. GETCHAR(PARMLINE,TMP1,TMP3);
  3606. END
  3607. IF TMP3 EQ CCOMMA THEN TMP1=TMP1+1; # SKIP LEAD COMMA #
  3608. GETCHAR(PARMLINE,TMP1,TMP3);
  3609. WHYLE TMP3 EQ CBLANK DO # SKIP FURTHER BLANKS #
  3610. BEGIN
  3611. TMP1=TMP1+1;
  3612. GETCHAR(PARMLINE,TMP1,TMP3);
  3613. END
  3614. TMP4=TMP1; # SAVE START #
  3615. IF TMP3 NQ CCOMMA THEN # NOT SKIPPED PARAMETER #
  3616. BEGIN
  3617. # SKIP TO NEXT DELIMETER #
  3618. TMP5=CBLANK; # TWO NORMAL DELIMITERS #
  3619. TMP6=CCOMMA;
  3620. IF TYPE[TMP3] EQ TYPST"DELIMIT" THEN
  3621. BEGIN # STRING NEEDS EXACT DELIMIT #
  3622. TMP5=TMP3;
  3623. TMP6=TMP3;
  3624. END
  3625. IF TMP3 NQ CENDLINE THEN TMP3=-1;
  3626. WHYLE TMP3 NQ TMP5 AND TMP3 NQ TMP6 AND TMP3 NQ CENDLINE DO
  3627. BEGIN # LOOK FOR EITHER DELIM OR EOL #
  3628. TMP1=TMP1+1;
  3629. GETCHAR(PARMLINE,TMP1,TMP3);
  3630. END
  3631. # IF STOPPED DUE TO STRING END, ADVANCE PAST IT #
  3632. IF TMP3 EQ TMP5 AND TMP5 NQ CBLANK THEN TMP1=TMP1+1;
  3633. END
  3634. END
  3635. TMP1=TMP1-TMP4; # LENGTH #
  3636. TMP1=MIN(TMP1,MAXPOS-LENGTH(TXTLIN));
  3637. LSHIFT(TXTLIN,POS+2,2); # KILL @DIGIT #
  3638. RSHIFT(TXTLIN,POS,TMP1); # MAKE ROOM #
  3639. FOR TMP2=0 STEP 1 UNTIL TMP1-1 DO
  3640. BEGIN # COPY THE PARAMETER #
  3641. GETCHAR(PARMLINE,TMP4+TMP2,TMP3);
  3642. SETCHAR(TXTLINE,POS+TMP2,TMP3);
  3643. END
  3644. POS=POS+TMP1; # ADVANCE PAST EXPANSION #
  3645. INCR=TMP1;
  3646. END # OF PROCPARM #
  3647.  
  3648. CONTROL FI;
  3649. PAGE # UTILITY ROUTINES ONLY FOR EXEC #
  3650.  
  3651.  
  3652. FUNC FINDER(POS,LEN) B;
  3653. # TITLE FINDER - SEARCH CURRENT LINE OF TEXT IN ONE OF EIGHT WAYS. #
  3654.  
  3655. BEGIN # FINDER #
  3656.  
  3657. #
  3658. ** FINDER - SEARCH CURRENT LINE OF TEXT IN ONE OF EIGHT WAYS.
  3659. *
  3660. * FUNC FINDER(POS,LEN)
  3661. *
  3662. * ENTRY FINDCONTROL - WHICH MANNER OF SEARCH.
  3663. * 0 = SIMPLE TEXT SEARCH.
  3664. * NONZERO = COMPLEX SEARCH.
  3665. * LIN - LINE OF TEXT TO SEARCH.
  3666. * LOCSTRING1, LOCSTRING2 - ONE OR BOTH STRINGS TO MATCH.
  3667. * LOCSTRLEN1, LOCSTRLEN2 - LENGTHS OF STRINGS.
  3668. * FIELDFLG, FIELDBGN, FIELDEND - COLUMN MODE, LIMITS.
  3669. * WORDSEARCH - MODE.
  3670. * UPPERSEARCH - MODE.
  3671. * ELLIPSIS - MODE.
  3672. * BACKWARD - MODE.
  3673. *
  3674. * EXIT FINDER - SUCCESS OR FAILURE.
  3675. * POS - CHARACTER POSITION WHERE WE MATCHED.
  3676. * LEN - LENGTH OF TOTAL MATCHED AREA.
  3677. *
  3678. * MACROS GETCHAR.
  3679. *
  3680. * CALLS FASTFND, FASTLNB, FIND, LENGTH.
  3681. *
  3682. * NOTE FINDCONTROL VALUES ARE DESIGNED TO FUNCTION AS
  3683. * INDEPENDENT BITS.
  3684. #
  3685.  
  3686. ITEM BOOL B; # FOUND FLAG #
  3687. ITEM FIRSTPOS I; # FIRST CHARACTER POSITION #
  3688. ITEM LASTPOS I; # LAST CHARACTER POSITION #
  3689. ITEM LEN I; # LENGTH OF MATCHED AREA #
  3690. ITEM LINLEN I; # LINE LENGTH #
  3691. ITEM LOOPINDEX1 I; # LOOP INDEX #
  3692. ITEM POS I; # CHARACTER POSITION OF MATCH #
  3693. ITEM QUIT B; # QUIT FLAG #
  3694. ITEM TMP1 I; # TEMPORARY STORAGE #
  3695. ITEM TMP2 I; # TEMPORARY STORAGE #
  3696. ITEM TMP3 I; # TEMPORARY STORAGE #
  3697. ITEM TMP4 I; # TEMPORARY STORAGE #
  3698. ITEM TMP5 I; # TEMPORARY STORAGE #
  3699.  
  3700. DEF BOTHCASE #O"03760 00000 00000 00000"#;
  3701. DEF CASELESS #O"01760 00000 00000 00000"#;
  3702.  
  3703.  
  3704. FUNC FIND(STRING,STRLEN,SLWOTS,POSITION) B;
  3705. # TITLE FIND - FIND STRING. #
  3706.  
  3707. BEGIN # FIND #
  3708.  
  3709. #
  3710. ** FIND - FIND STRING.
  3711. *
  3712. * THE FIND ROUTINE IS DEPENDENT ON THE INTERNAL
  3713. * CHARACTER SET WORD FORMATTING.
  3714. *
  3715. * FUNC FIND(STRING,STRLEN,SLWOTS,POSITION)
  3716. *
  3717. * ENTRY POSITION - POSITION IN STRING.
  3718. * STRING - STRING TO SEARCH.
  3719. * STRLEN - STRING LENGTH.
  3720. * SLWOTS - STRING LENGTH WITHOUT TRAILING SPACES.
  3721. *
  3722. * EXIT BOOL - SUCCESS OR FAILURE.
  3723. *
  3724. * MACROS DSPLCOD, GETCHAR.
  3725. *
  3726. * CALLS DSPLCOD, FASTFND.
  3727. #
  3728.  
  3729. CONTROL IFNQ CLETTERA,1; BAD; CONTROL FI;
  3730. CONTROL IFNQ CLOWERA,65; BAD; CONTROL FI;
  3731.  
  3732. ARRAY STRING [0:99] P(1);
  3733. BEGIN # ARRAY STRING #
  3734. ITEM STRINGWORD I; # STRING WORD #
  3735. END # ARRAY STRING #
  3736.  
  3737. ITEM LOOPINDEX2 I; # LOOP INDEX #
  3738. ITEM POSITION I; # POSITION IN STRING #
  3739. ITEM STRLEN I; # STRING LENGTH #
  3740. ITEM SLWOTS I; # STRING LENGTH W/O TRAIL SPACES #
  3741. ITEM TMP1 I; # TEMPORARY STORAGE #
  3742. ITEM TMP2 I; # TEMPORARY STORAGE #
  3743. ITEM TMP3 I; # TEMPORARY STORAGE #
  3744. ITEM TMP4 I; # TEMPORARY STORAGE #
  3745. ITEM TMP5 I; # TEMPORARY STORAGE #
  3746. ITEM TMP6 I; # TEMPORARY STORAGE #
  3747.  
  3748. LOOPINDEX2=0;
  3749. BOOL=FALSE;
  3750. IF FIELDFLG THEN
  3751. SLWOTS=MAX(SLWOTS,MIN(STRLEN,STRLEN-FIELDEND+LASTPOS));
  3752. WHYLE (NOT BOOL) AND (FIRSTPOS LQ LASTPOS)
  3753. AND (LOOPINDEX2 LQ BUFCHAR) DO
  3754. BEGIN
  3755. LOOPINDEX2=LOOPINDEX2+1;
  3756. IF UPPERSEARCH THEN
  3757. BEGIN
  3758. POSITION=FIRSTPOS;
  3759. WHYLE (NOT BOOL) AND (POSITION LQ LASTPOS-SLWOTS+1) DO
  3760. BEGIN
  3761. TMP6=MIN(STRLEN,LASTPOS-POSITION+1);
  3762. GETCHAR(LINE,POSITION,TMP2);
  3763. GETCHAR(STRINGWORD,0,TMP3);
  3764. TMP4=TMP2;
  3765. TMP5=TMP3;
  3766. DSPLCOD(TMP4);
  3767. DSPLCOD(TMP5);
  3768. IF B<TMP2 LAN 31,1>WORDFLAG[TMP2/32] EQ 1 AND
  3769. B<TMP4 LAN 31,1>WORDFLAG[TMP4/32] EQ 1 THEN TMP2=TMP4;
  3770. IF B<TMP3 LAN 31,1>WORDFLAG[TMP3/32] EQ 1 AND
  3771. B<TMP5 LAN 31,1>WORDFLAG[TMP5/32] EQ 1 THEN TMP3=TMP5;
  3772. IF TMP2 EQ TMP3 THEN
  3773. BEGIN
  3774. BOOL=TRUE;
  3775. FOR TMP1=1 STEP 1 WHILE BOOL AND TMP1 LS TMP6 DO
  3776. BEGIN
  3777. GETCHAR(LINE,POSITION+TMP1,TMP2);
  3778. GETCHAR(STRINGWORD,TMP1,TMP3);
  3779. TMP4=TMP2;
  3780. TMP5=TMP3;
  3781. DSPLCOD(TMP4);
  3782. DSPLCOD(TMP5);
  3783. IF B<TMP2 LAN 31,1>WORDFLAG[TMP2/32] EQ 1 AND
  3784. B<TMP4 LAN 31,1>WORDFLAG[TMP4/32] EQ 1 THEN TMP2=TMP4;
  3785. IF B<TMP3 LAN 31,1>WORDFLAG[TMP3/32] EQ 1 AND
  3786. B<TMP5 LAN 31,1>WORDFLAG[TMP5/32] EQ 1 THEN TMP3=TMP5;
  3787. IF TMP2 NQ TMP3 THEN BOOL=FALSE;
  3788. END
  3789. END
  3790. IF NOT BOOL THEN POSITION=POSITION+1;
  3791. END
  3792. END
  3793. ELSE BOOL=FASTFND(LIN,LASTPOS,FIRSTPOS,STRING,STRLEN-1,SLWOTS-1,
  3794. POSITION,BOTHCASE);
  3795. IF BOOL AND WORDSEARCH THEN
  3796. BEGIN
  3797. IF POSITION NQ MIN(FIELDBGN,FIELDEND) THEN
  3798. BEGIN
  3799. GETCHAR(LINE,POSITION-1,TMP5);
  3800. IF B<TMP5 LAN 31,1>WORDFLAG[TMP5/32] EQ 1 THEN BOOL=FALSE;
  3801. END
  3802. IF BOOL AND POSITION+STRLEN LS MAX(FIELDBGN,FIELDEND) THEN
  3803. BEGIN
  3804. GETCHAR(LINE,POSITION+STRLEN,TMP5);
  3805. IF B<TMP5 LAN 31,1>WORDFLAG[TMP5/32] EQ 1 THEN BOOL=FALSE;
  3806. END
  3807. END
  3808. IF NOT BOOL THEN
  3809. BEGIN
  3810. FIRSTPOS=1+MAX(FIRSTPOS,POSITION);
  3811. IF NOT (WORDSEARCH OR UPPERSEARCH) THEN FIRSTPOS=LARGENUM;
  3812. END
  3813. END
  3814. FIND=BOOL;
  3815.  
  3816. END # FIND #
  3817.  
  3818.  
  3819.  
  3820. # MAIN FINDER CODE STARTS HERE #
  3821.  
  3822. LINLEN=LENGTH(LIN);
  3823. LASTPOS=LINLEN-1;
  3824. FINDER=FALSE;
  3825. IF LASTPOS LS NUMWIDBLK THEN RETURN;
  3826.  
  3827. IF FINDCONTROL EQ 0 THEN
  3828. BEGIN
  3829. BOOL=FASTFND(LIN,LASTPOS,FIELDBGN,LOCSTRING1,LOCSTRLEN1-1,
  3830. FASTLNB(LOCSTRING1)-1,TMP2,BOTHCASE);
  3831. IF BOOL THEN
  3832. BEGIN
  3833. POS=TMP2;
  3834. LEN=LOCSTRLEN1;
  3835. END
  3836. FINDER=BOOL;
  3837. RETURN;
  3838. END
  3839.  
  3840. # ELSE NEED COMPLEX SEARCH ALGORITHM #
  3841.  
  3842. FIRSTPOS=MIN(FIELDBGN,FIELDEND);
  3843. LASTPOS=MAX(FIELDBGN,FIELDEND);
  3844. IF FIELDFLG THEN
  3845. BEGIN
  3846. IF BACKWARD THEN
  3847. BEGIN
  3848. IF (FIELDEND GQ LINLEN AND FIELDEND LS BUFCM1)
  3849. OR FIELDEND GR FIELDBGN THEN RETURN;
  3850. END
  3851. ELSE
  3852. BEGIN
  3853. IF (FIELDBGN GQ LINLEN AND FIELDBGN LS BUFCM1)
  3854. OR FIELDBGN GR FIELDEND THEN RETURN;
  3855. END
  3856. END
  3857. ELSE
  3858. BEGIN
  3859. IF (NOT BACKWARD) AND FIELDBGN GQ FIELDEND THEN LASTPOS=BUFCM1;
  3860. END
  3861. FIRSTPOS=MIN(FIRSTPOS,LINLEN-1);
  3862. LASTPOS=MIN(LASTPOS,LINLEN-1);
  3863. LOOPINDEX1=0;
  3864. QUIT=FALSE;
  3865. WHYLE NOT QUIT DO
  3866. BEGIN
  3867. LOOPINDEX1=LOOPINDEX1+1;
  3868. TMP2=FIRSTPOS;
  3869. IF ELLIPSIS THEN
  3870. BOOL=FIND(LOCSTRING1,LOCSTRLEN1,LOCSTRLEN1,TMP1);
  3871. ELSE
  3872. BOOL=FIND(LOCSTRING1,LOCSTRLEN1,FASTLNB(LOCSTRING1),TMP1);
  3873. TMP3=TMP1;
  3874. TMP4=LOCSTRLEN1;
  3875. IF ELLIPSIS AND BOOL THEN
  3876. BEGIN
  3877. FIRSTPOS=TMP3+TMP4;
  3878. IF FIRSTPOS LS LINLEN THEN
  3879. BOOL=FIND(LOCSTRING2,LOCSTRLEN2,FASTLNB(LOCSTRING2),TMP1);
  3880. ELSE BOOL=FALSE;
  3881. TMP4=TMP1+LOCSTRLEN2-TMP3;
  3882. END
  3883. IF BOOL THEN
  3884. BEGIN
  3885. FINDER=TRUE;
  3886. POS=TMP3;
  3887. LEN=TMP4;
  3888. FIRSTPOS=TMP2+1;
  3889. END
  3890. ELSE QUIT=TRUE;
  3891. IF (NOT BACKWARD) OR FIRSTPOS GQ LINLEN THEN QUIT=TRUE;
  3892. IF LOOPINDEX1 GQ BUFCHAR THEN QUIT=TRUE;
  3893. END
  3894.  
  3895. END # FINDER #
  3896.  
  3897.  
  3898. PROC SUBST;
  3899. # TITLE SUBST - TEXT SUBSTITUTION FOR REPLACE COMMAND. #
  3900.  
  3901. BEGIN # SUBST #
  3902.  
  3903. #
  3904. ** SUBST - TEXT SUBSTITUTION FOR REPLACE COMMAND.
  3905. *
  3906. * THE SUBST ROUTINE IS CRUCIAL TO THE S COMMAND. IT DOES THE
  3907. * ACTUAL SEARCHING AND ALTERATION WITHIN THE CURRENT LINE.
  3908. * WE USE THE FINDER FUNCTION. OUR OUTER LOOP JUST KEEPS
  3909. * LOOKING FOR MORE AND MORE TARGET STRINGS ACROSS THE LINE.
  3910. * FOR EACH OF THEM, WE SUBSTITUTE, BUT ONLY AFTER WE HAVE
  3911. * ACCOUNTED FOR CHANGES IN LENGTH THAT CAN SHUFFLE TRAILING
  3912. * TEXT. TO ACCOMODATE FIELD-ORIENTATION, WE KEEP A COPY OF
  3913. * THE ORIGINAL TEXT AND REBUILD THE FINAL PART.
  3914. *
  3915. * PROC SUBST
  3916. *
  3917. * ENTRY LIN - INTERNAL LINE IMAGE TO SEARCH/CHANGE.
  3918. * LOCSTRING1, LOCSTRING2 - SEARCH KEY(S).
  3919. * CHGSTRING1 - REPLACEMENT TEXT.
  3920. * LOCSTRLEN1, LOCSTRLEN2, CHGSTRLEN1 - LENGTHS.
  3921. * FINDCONTROL - PER "FINDER" HEADER DOCUMENTATION.
  3922. * FIELDFLG, FIELDBGN, FIELDEND - PER FINDER.
  3923. * ELLIPSIS, WORDSEARCH, UPPERSEARCH - PER FINDER.
  3924. * SUBSTONCE - LOOP ONCE OR TO EXHAUSTION.
  3925. *
  3926. * EXIT LIN - CHANGED IF SEARCH SUCCEEDED.
  3927. * FOUND - WHETHER SEARCH SUCCEEDED.
  3928. *
  3929. * MACROS GETCHAR, SETCHAR.
  3930. *
  3931. * CALLS LENGTH, MOVEWD, FINDER, TRIMPAD.
  3932. *
  3933. * USES FIELDBGN WITH RESTORATION.
  3934. #
  3935.  
  3936. ITEM DELTA I; # CHANGE REQUESTED #
  3937. ITEM FINDBGN I; # BEGINNING OF FIELD #
  3938. ITEM FINDLEN I; # LENGTH OF FIELD #
  3939. ITEM HOLDBGN I; # HOLD BEGINNING OF FIELD #
  3940. ITEM HOLDEND I; # HOLD ENDING OF FIELD #
  3941. ITEM LINLEN I; # LINE LENGTH #
  3942. ITEM LOOPINDEX I; # LOOP INDEX #
  3943. ITEM QUIT B; # COMPLETE FLAG #
  3944. ITEM SUMDELTA I; # TOTAL CHANGE REQUESTED #
  3945. ITEM TMP1 I; # TEMPORARY STORAGE #
  3946. ITEM TMP2 I; # TEMPORARY STORAGE #
  3947.  
  3948. FOUND=FALSE;
  3949.  
  3950. IF NOT FINDER(FINDBGN,FINDLEN) THEN RETURN;
  3951.  
  3952. HOLDBGN=FIELDBGN; # MODIFY FIELD AND RESTORE #
  3953. HOLDEND=FIELDEND;
  3954. LINLEN=LENGTH(LIN);
  3955. SUMDELTA=0;
  3956. LOOPINDEX=0;
  3957. FOR TMP1=LINLEN+1 STEP 1 UNTIL BUFCM1 DO SETCHAR(LINE,TMP1,CBLANK);
  3958. MOVEWD(BUFWIDP1,LIN,TMPLIN);
  3959.  
  3960. QUIT=FALSE;
  3961. WHYLE FINDER(FINDBGN,FINDLEN) AND NOT QUIT DO
  3962. BEGIN
  3963. LINLEN=MAX(LINLEN,FINDBGN+FINDLEN);
  3964. LOOPINDEX=LOOPINDEX+1;
  3965. FOUND=TRUE;
  3966. NEWCURSOR=FINDBGN;
  3967. STRINGLEN=CHGSTRLEN1;
  3968. DELTA=FINDLEN-CHGSTRLEN1;
  3969. SUMDELTA=SUMDELTA+DELTA;
  3970. IF DELTA GR 0 THEN # SHRINK FIELD #
  3971. BEGIN
  3972. FOR TMP1=FINDBGN+FINDLEN STEP 1 UNTIL LINLEN DO
  3973. BEGIN
  3974. GETCHAR(LINE,TMP1,TMP2);
  3975. SETCHAR(LINE,TMP1-DELTA,TMP2);
  3976. END
  3977. END
  3978. ELSE IF DELTA LS 0 THEN # FIELD GROWS #
  3979. BEGIN
  3980. FOR TMP1=LINLEN STEP -1 UNTIL FINDBGN+FINDLEN DO
  3981. BEGIN
  3982. IF TMP1-DELTA LQ BUFCM1 THEN
  3983. BEGIN
  3984. GETCHAR(LINE,TMP1,TMP2);
  3985. SETCHAR(LINE,TMP1-DELTA,TMP2);
  3986. END
  3987. END
  3988. END
  3989. FOR TMP1=FINDBGN STEP 1 UNTIL FINDBGN+CHGSTRLEN1-1 DO
  3990. BEGIN
  3991. IF TMP1 LQ BUFCM1 THEN
  3992. BEGIN
  3993. GETCHAR(CHGSTR1,TMP1-FINDBGN,TMP2);
  3994. SETCHAR(LINE,TMP1,TMP2);
  3995. END
  3996. END
  3997. SETCHAR(LINE,BUFCHAR,CENDLINE);
  3998. LINLEN=LENGTH(LIN);
  3999. IF BACKWARD THEN
  4000. BEGIN
  4001. FIELDBGN=FINDBGN-1;
  4002. IF FIELDBGN LS FIELDEND THEN QUIT=TRUE;
  4003. END
  4004. ELSE
  4005. BEGIN
  4006. IF FIELDEND GR FINDBGN THEN FIELDEND=FIELDEND-DELTA;
  4007. FIELDBGN=FINDBGN+CHGSTRLEN1;
  4008. IF FIELDFLG AND FIELDBGN GR FIELDEND THEN QUIT=TRUE;
  4009. IF FIELDBGN GQ LINLEN THEN QUIT=TRUE;
  4010. END
  4011. IF SUBSTONCE THEN QUIT=TRUE;
  4012. IF LOOPINDEX GQ BUFCHAR THEN QUIT=TRUE;
  4013. END
  4014.  
  4015. IF NOT FOUND THEN RETURN;
  4016. FIELDBGN=HOLDBGN; # RESTORE FIELD #
  4017. FIELDEND=HOLDEND;
  4018. IF FIELDNDX GR 0 THEN
  4019. BEGIN
  4020. FIELDEND=MAX(FIELDBGN,FIELDEND);
  4021. FOR TMP1=LINLEN STEP 1 UNTIL FIELDEND DO SETCHAR(LINE,TMP1,CBLANK);
  4022. FOR TMP1=1 STEP 1 UNTIL SUMDELTA DO
  4023. BEGIN
  4024. SETCHAR(LINE,FIELDEND-TMP1+1,CBLANK);
  4025. END
  4026. FOR TMP1=FIELDEND+1 STEP 1 UNTIL BUFCM1 DO
  4027. BEGIN
  4028. GETCHAR(TMPLINE,TMP1,TMP2);
  4029. SETCHAR(LINE,TMP1,TMP2);
  4030. END
  4031. END
  4032. SETCHAR(LINE,BUFCHAR,CENDLINE);
  4033. TRIMPAD; # REMOVE BLANKS #
  4034.  
  4035. END # SUBST #
  4036.  
  4037.  
  4038. PROC XSHOW;
  4039. IOBEGIN(XSHOW)
  4040. #
  4041. ** XSHOW - DISPLAY LINE AND TEST WIDTH.
  4042. *
  4043. * ENTRY LIN - LINE OF TEXT.
  4044. * DONTPRINT, SCREENMODE - CONTROL DISPLAY.
  4045. *
  4046. * CALLS CHECKWIDE, YSHOW.
  4047. #
  4048. YSHOW;
  4049. CHECKWIDE;
  4050. IOEND # OF XSHOW #
  4051.  
  4052.  
  4053. PROC YSHOW;
  4054. IOBEGIN(YSHOW)
  4055. #
  4056. ** YSHOW - DISPLAY LINE.
  4057. *
  4058. * ENTRY LIN - TEXT TO DISPLAY.
  4059. * DONTPRINT, SCREENMODE - CONTROL DISPLAY.
  4060. * LCOUNT - EXISTING WORK ACCOUNTING.
  4061. *
  4062. * EXIT LCOUNT - INCREMENTED.
  4063. *
  4064. * CALLS PRINTL.
  4065. #
  4066. IF NOT (DONTPRINT OR SCREENMODE) THEN PRINTL;
  4067. LCOUNT=LCOUNT+1; # ACCURATE COUNT #
  4068. IOEND # OF YSHOW #
  4069.  
  4070.  
  4071. PROC PRINTL;
  4072. IOBEGIN(PRINTL)
  4073. #
  4074. ** PRINTL - PRINT LINE.
  4075. *
  4076. * PRINTL PRINTS AN INTERNAL LINE IMAGE IN LINE MODE. FLOAT
  4077. * LINE ORDINALS ARE PRINTED FOR CERTAIN CONDTIONS.
  4078. *
  4079. * ENTRY SCREENMODE - SHOULD NOT BE CALLED UNLESS OFF.
  4080. * LIN - INTERNAL LINE IMAGE TO PRINT.
  4081. * FLOAT - MODE FOR DISPLAY OF ORDINALS.
  4082. * CURRENT, CURFILE - WHERE WE ARE IN FILES.
  4083. * TOPF(CURFILE) - BOUNDS/RELOCATION FACTOR.
  4084. * NUMBERED[CURFILE] - OVERRIDES FLOAT IF NON-ZERO.
  4085. * USRNUMCOL - NQ 1, IF SET BY *SET VIEW COLUMNS*.
  4086. *
  4087. * CALLS PUSHTEMP, CONVOUT, TTLPAD, TTSTR, TTSYNC, VDTWTC,
  4088. * VDTWTO, POPTEMP. FORMERLY ALSO FIXCTL.
  4089. *
  4090. * USES TEMP WITH RESTORATION.
  4091. *
  4092. * NOTE SINCE FSE ALWAYS DRIVES TERMINAL IN EITHER 6/12
  4093. * ASCII OR 8/12 TRANSPARENT MODES, WE CAN COMMENT-OUT
  4094. * LOGIC USING FIXCTL TO SUPPRESS ACCIDENTAL/MALICIOUS
  4095. * ISSUANCE OF NOS CONTROL BYTES. THIS OLD LOGIC
  4096. * SHOULD BE RE-ENABLED IF THE EDITOR IS MODIFIED
  4097. * TO DRIVE THE TERMINAL IN SIMPLE DISPLAY CODE.
  4098. * PRINTL PLACES AN END OF LINE CHARACTER (INTERNAL)
  4099. * INTO THE INTERNAL LINE IMAGE BEFORE TRANSLATION
  4100. * AND THEN RESTORES THE ACTUAL CHARACTER. THIS
  4101. * ALLOWS THE USE OF *SET VIEW COLUMNS* IN LINE MODE.
  4102. * USRNUMCOL IS OFFSET BY FIVE TO PREVENT AUTOMATIC
  4103. * TERMINAL WRAPPING AND CORRECT FOR LINE NUMBERS
  4104. * FROM 1 TO 9999. FOR LINES PAST 9999 THE USER
  4105. * SHOULD DO A SET VIEW COLUMNS TO A SMALLER VALUE.
  4106. #
  4107. PUSHTEMP;
  4108. IF USRNUMCOL NQ 1 THEN
  4109. BEGIN # IF USER HAS SET COLUMNS #
  4110. GETCHAR(LINE,USRNUMCOL-5,TEMP);
  4111. SETCHAR(LINE,USRNUMCOL-5,CENDLINE);
  4112. END
  4113. CONTROL IFEQ SINGLE,1;
  4114. IF TTYOUTPUT OR ASCII[CURFILE] GQ 2 THEN CONVOUT(LIN,2);
  4115. ELSE CONVOUT(LIN,1);
  4116. CONTROL FI;
  4117. CONTROL IFEQ MULTI,1;
  4118. CONVOUT(LIN,2);
  4119. CONTROL FI;
  4120. IF USRNUMCOL NQ 1 THEN
  4121. BEGIN # IF USER HAS SET COLUMNS #
  4122. SETCHAR(LINE,USRNUMCOL-5,TEMP);
  4123. END
  4124. #IF FIXCTL(BUFWID2P1,TMPLIN) THEN TTLIN(APPROPO WARNING)#
  4125. IF FLOAT AND NUMBERED[CURFILE] EQ 0 THEN
  4126. BEGIN
  4127. CONTROL IFEQ SINGLE,1;
  4128. TEMP=CURRENT-TOPF(CURFILE);
  4129. IF TTYOUTPUT THEN
  4130. BEGIN
  4131. IF TEMP GR 9999 THEN TTLPAD(TEMP,8," ");
  4132. ELSE TTLPAD(TEMP,4," ");
  4133. TTSTR(BLANKWRD);
  4134. END
  4135. ELSE
  4136. BEGIN
  4137. ITEM POS, BUFF C(10);
  4138. BUFF=" ";
  4139. POS=7;
  4140. WHYLE TEMP NQ 0 DO
  4141. BEGIN
  4142. C<POS,1>BUFF=O"33"+MOD(TEMP,10);
  4143. POS=POS-1;
  4144. TEMP=TEMP/10;
  4145. END
  4146. VDTWTO(BUFF);
  4147. END
  4148. CONTROL FI;
  4149. CONTROL IFEQ MULTI,1;
  4150. TEMP=CURRENT-TOPF(CURFILE);
  4151. IF TEMP GR 9999 THEN TTLPAD(TEMP,8," ");
  4152. ELSE TTLPAD(TEMP,4," ");
  4153. TTSTR(BLANKWRD);
  4154. CONTROL FI;
  4155. END
  4156. TTSYNC;
  4157. VDTWTC(TMPLIN);
  4158. POPTEMP;
  4159. IOEND # OF PRINTL #
  4160.  
  4161.  
  4162. PROC CHECKWIDE;
  4163. IOBEGIN(CHECKWIDE)
  4164. #
  4165. ** CHECKWIDE - CHECK LINE FOR EXCESS WIDTH.
  4166. *
  4167. * CHECKWIDE ENFORCES THE "SET VIEW WARN" PARAMETER BY
  4168. * TESTING LINE IMAGE LENGTH AND FOR OVERSIZE LINE, WE
  4169. * SET UP THE WARNING MESSAGE AND TRIGGER SHUTDOWN OF
  4170. * DORANGE PROCESSING.
  4171. *
  4172. * ENTRY LIN - INTERNAL LINE IMAGE TO TEST.
  4173. * WIDTH - THRESHHOLD.
  4174. * NUMWIDBLK - FOR SEQUENCED FILES, NUMBER OF DIGITS.
  4175. *
  4176. * EXIT ERRSTRING - SET VIA "HALT" IF WIDE.
  4177. * LINCTR - LARGENUM IF WIDE TO STOP DORANGE.
  4178. *
  4179. * CALLS LENGTH, HALT.
  4180. #
  4181. IF LENGTH(LIN) GR WIDTH+NUMWIDBLK
  4182. AND PROCESSNDX NQ KEYST"DCMD"
  4183. AND PROCESSNDX NQ KEYST"HCMD" THEN
  4184. BEGIN
  4185. HALT("WIDE LINE$");
  4186. LINCTR=LARGENUM;
  4187. END
  4188. IOEND # OF CHECKWIDE #
  4189.  
  4190.  
  4191. PROC GETMOD;
  4192. IOBEGIN(GETMOD)
  4193. #
  4194. ** GETMOD - PROMPT FOR ALTERATION MASK.
  4195. *
  4196. * GETMOD IS CALLED ANYTIME THE ALTER COMMAND REQUIRES
  4197. * ADDITIONAL INTERACTION WITH THE USER TO OBTAIN THE
  4198. * CHARACTER STRING WHICH WILL MASK THE ALTERATIONS.
  4199. *
  4200. * ENTRY LINPTR1 - LINE ADDRESS FOR START OF RANGE.
  4201. * FLOAT - CONTROLS PROMPT ALIGNMENT FOR LINEMODE.
  4202. * SCREENMODE - SHOULD BE OFF IF THIS ROUTINE CALLED.
  4203. * CURFILE - WHICH FILE BRACKET IS TO BE ALTERED.
  4204. * NUMBERED[CURFILE] - CONTROL PROMPTS ALIGNMENT.
  4205. * ASCII[CURFILE] - CONTROLS LOWERCASE SUPPRESSION.
  4206. *
  4207. * EXIT TTYLIN - CONTAINS ALTERATION MASK.
  4208. *
  4209. * CALLS PUSHTEMP, TTST, POSZ, PRINTL, PROMPT, CONVIN, TRIM,
  4210. * SQUELCH, POPTEMP.
  4211. *
  4212. * USES TEMP WITH RESTORATION, LIN, CURRENT.
  4213. #
  4214. PUSHTEMP;
  4215. CONTROL IFEQ SINGLE,1;
  4216. IF NOT INTERACT THEN
  4217. BEGIN
  4218. PROMPT(NULLWRD);
  4219. GOTO GETMOD2;
  4220. END
  4221. CONTROL FI;
  4222. IF FLOAT OR NUMBERED[CURFILE] NQ 0 THEN TEMP=0;
  4223. ELSE TEMP=4;
  4224. TTST(" ",TEMP);
  4225. POSZ(LINPTR1);
  4226. PRINTL;
  4227. IF NUMBERED[CURFILE] NQ 0 THEN TEMP=NUMWIDBLK-4;
  4228. ELSE IF FLOAT AND CURRENT-TOPF(CURFILE) GR 9999 THEN TEMP=5;
  4229. ELSE IF FLOAT THEN TEMP=1;
  4230. ELSE TEMP=0;
  4231. TTST(" ",TEMP);
  4232. IF TEMP LAN 1 EQ 1 THEN PROMPT(AQCCKWRD);
  4233. ELSE PROMPT(AQCKWRD);
  4234. GETMOD2:
  4235. CONVIN(TTYLIN,2);
  4236. TRIM(TTYLIN,1);
  4237. IF ASCII[CURFILE] LQ 1 THEN SQUELCH(TTYLIN);
  4238. POPTEMP;
  4239. IOEND # OF GETMOD #
  4240.  
  4241.  
  4242. PROC APPEND;
  4243. BEGIN
  4244. #
  4245. ** APPEND - APPEND TTYLIN ONTO LIN.
  4246. *
  4247. * APPEND MERGES TWO INTERNAL LINE IMAGES WITH SOFT-TABS
  4248. * INTERPRETED AS NEEDED.
  4249. *
  4250. * ENTRY LIN - INTERNAL LINE IMAGE TO APPEND ONTO.
  4251. * TTYLIN - INTERNAL LINE IMAGE TO APPEND.
  4252. *
  4253. * ENTRY LIN - UPDATED.
  4254. * TMPLIN - POSSIBLY DESTROYED.
  4255. *
  4256. * CALLS TRIMPAD, CONCAT, EXCHWD, DOTAB.
  4257. #
  4258. ITEM TMP1;
  4259. TRIMPAD;
  4260. TMP1=LENGTH(LIN);
  4261. CONCAT(LIN,TTYLIN);
  4262. EXCHWD(BUFWIDP1,LIN,TTYLIN); # SO DOTAB WORKS #
  4263. DOTAB(TMP1,TMP1,NUMWIDBLK);
  4264. EXCHWD(BUFWIDP1,TTYLIN,LIN);
  4265. END # OF APPEND #
  4266.  
  4267.  
  4268. PROC STRETCH;
  4269. BEGIN
  4270. #
  4271. ** STRETCH - ADD BLANKS INSIDE A LINE IMAGE.
  4272. *
  4273. * STRETCH ADDS 30 BLANKS INSIDE A LINE WITH ATTENTION
  4274. * TO THE EDITFIELD RESTRICTION.
  4275. *
  4276. * ENTRY LIN - INTERNAL LINE IMAGE.
  4277. * CURCURSOR - WHERE TO ADD 30 BLANKS.
  4278. *
  4279. * EXIT LIN - UPDATED.
  4280. *
  4281. * MACROS SETCHAR.
  4282. *
  4283. * CALLS SAVEPROT, LENGTH, RSHIFT, TRIMPAD, MERGEPROT.
  4284. *
  4285. * USES PROTLIN.
  4286. #
  4287. ITEM TMP1, TMP2;
  4288. TMP1=CURCURSOR;
  4289. SAVEPROT;
  4290. IF TMP1 LS LENGTH(LIN) THEN
  4291. BEGIN
  4292. RSHIFT(LIN,TMP1,30);
  4293. FOR TMP2=TMP1 STEP 1 UNTIL
  4294. TMP1+29 DO SETCHAR(LINE,TMP2,CBLANK);
  4295. END
  4296. TRIMPAD;
  4297. MERGEPROT;
  4298. END # OF STRETCH #
  4299.  
  4300.  
  4301. PROC SQUEEZE;
  4302. # TITLE SQUEEZE - REMOVE BLANKS THEN NONBLANKS THEN BLANKS. #
  4303.  
  4304. BEGIN # SQUEEZE #
  4305.  
  4306. #
  4307. ** SQUEEZE - REMOVE BLANKS THEN NONBLANKS THEN BLANKS.
  4308. *
  4309. * PROC SQUEEZE
  4310. *
  4311. * ENTRY LIN - INTERNAL LINE IMAGE.
  4312. * CURCURSOR - WHERE IN LIN TO UPDATE.
  4313. *
  4314. * EXIT LIN - UPDATED.
  4315. *
  4316. * MACROS GETCHAR, SETCHAR.
  4317. *
  4318. * CALLS LENGTH, LSHIFT, MERGEPROT, SAVEPROT, TRIMPAD.
  4319. *
  4320. * USES PROTLIN.
  4321. #
  4322.  
  4323. ITEM TMP1 I; # TEMPORARY STORAGE #
  4324. ITEM TMP2 I; # TEMPORARY STORAGE #
  4325. ITEM TMP3 I; # TEMPORARY STORAGE #
  4326.  
  4327. TMP1=CURCURSOR;
  4328. SAVEPROT;
  4329. IF TMP1 LS LENGTH(LIN) THEN
  4330. BEGIN
  4331. TMP2=TMP1;
  4332. GETCHAR(LINE,TMP2,TMP3);
  4333. IF TMP3 EQ CBLANK THEN
  4334. BEGIN
  4335. WHYLE TMP3 EQ CBLANK DO
  4336. BEGIN
  4337. TMP2=TMP2+1;
  4338. GETCHAR(LINE,TMP2,TMP3);
  4339. END
  4340. END
  4341. ELSE
  4342. BEGIN
  4343. IF B<TMP3 LAN 31,1>WORDFLAG[TMP3/32] EQ 0 THEN TMP2=TMP2+1;
  4344. ELSE
  4345. BEGIN
  4346. WHYLE B<TMP3 LAN 31,1>WORDFLAG[TMP3/32] EQ 1 DO
  4347. BEGIN
  4348. TMP2=TMP2+1;
  4349. GETCHAR(LINE,TMP2,TMP3);
  4350. END
  4351. WHYLE TMP3 EQ CBLANK DO
  4352. BEGIN
  4353. TMP2=TMP2+1;
  4354. GETCHAR(LINE,TMP2,TMP3);
  4355. END
  4356. END
  4357. END
  4358. LSHIFT(LIN,TMP2,TMP2-TMP1);
  4359. END
  4360. TRIMPAD;
  4361. MERGEPROT;
  4362.  
  4363. END # SQUEEZE #
  4364.  
  4365.  
  4366. CONTROL IFEQ SINGLE,1;
  4367.  
  4368. PROC DOCENTER;
  4369. BEGIN
  4370. #
  4371. ** DOCENTER - ALIGN TEXT IN CENTER OF MARGINS.
  4372. *
  4373. * ENTRY LIN - INTERNAL LINE IMAGE.
  4374. * FILLEFT, FILLRIGHT - MARGINS.
  4375. * CURFILE, NUMBERED[CURFILE] - CONTROL TEXT ALIGNMENT.
  4376. *
  4377. * EXIT LIN - UPDATED.
  4378. *
  4379. * MACROS GETCHAR, SETCHAR.
  4380. *
  4381. * CALLS GETLNUM, LSHIFT, RSHIFT, TRIM, LENGTH, SETLNUM.
  4382. *
  4383. * USES LINENO, WIDTHFOUND.
  4384. #
  4385. ITEM TMP1, TMP2, TMP3, TMP4;
  4386. # FIND FIRST NON-BLANK #
  4387. TMP1=-1;
  4388. IF NUMBERED[CURFILE] NQ 0 THEN
  4389. BEGIN
  4390. GETLNUM;
  4391. LSHIFT(LIN,NUMWIDBLK,NUMWIDBLK);
  4392. END
  4393. TRIM(LIN,0);
  4394. TMP4=LENGTH(LIN);
  4395. FOR TMP2=0 STEP 1 UNTIL TMP4 DO
  4396. BEGIN
  4397. GETCHAR(LINE,TMP2,TMP3);
  4398. IF TMP3 NQ CBLANK AND TMP1 LS 0 THEN TMP1=TMP2;
  4399. END
  4400. # CENTER LINE ONLY IF NON-NULL AND NOT TOO LARGE #
  4401. TMP4=TMP4-TMP1;
  4402. IF TMP1 GQ 0 AND TMP4 LQ FILLRIGHT-FILLLEFT+1 THEN
  4403. BEGIN
  4404. # ELIMINATE LEADING BLANKS #
  4405. LSHIFT(LIN,TMP1,TMP1);
  4406. # COMPUTE PADDING FACTOR AND REALIGN #
  4407. TMP2=(FILLRIGHT-FILLLEFT+1)-TMP4; # NUMBER OF XTRA BLANKS #
  4408. TMP2=TMP2/2; # SPLIT THE DIFFERENCE #
  4409. TMP2=TMP2+FILLLEFT; # ADD FIELD START POINT #
  4410. RSHIFT(LIN,0,TMP2);
  4411. FOR TMP1=1 STEP 1 UNTIL TMP2 DO SETCHAR(LINE,TMP1-1,CBLANK);
  4412. END
  4413. # RESTORE SEQUENCE NUMBER #
  4414. IF NUMBERED[CURFILE] NQ 0 THEN
  4415. BEGIN
  4416. RSHIFT(LIN,0,NUMWIDTH+BLANKS);
  4417. FOR TMP1=1 STEP 1 UNTIL NUMWIDTH DO SETCHAR(LINE,TMP1-1,CDIGIT0);
  4418. SETLNUM;
  4419. END
  4420. END # OF DOCENTER #
  4421.  
  4422. CONTROL FI;
  4423.  
  4424.  
  4425. PROC DOMOD;
  4426. BEGIN
  4427. #
  4428. ** DOMOD - PERFORM MASKED ALTERATIONS ON LINE IMAGE.
  4429. *
  4430. * DOMOD IMPLEMENTS THE TEXT PROCESSING FOR THE ALTER
  4431. * COMMAND. WE SCAN THE TTYLIN, AND ACT UPON EACH CHARACTER
  4432. * ALTERING LIN. THE CALLER IS RESPONSIBLE FOR HONORING THE
  4433. * EDITFIELD RESTRICTION.
  4434. *
  4435. * ENTRY LIN - INTERNAL LINE IMAGE.
  4436. * TTYLIN - ALTERATION MASK.
  4437. * COPCHAR, BLKCHAR, DELCHAR, INSCHAR, TRNCHAR -
  4438. * ACTION SYMBOLS.
  4439. *
  4440. * EXIT LIN - UPDATED.
  4441. *
  4442. * MACROS GETCHAR, SETCHAR.
  4443. *
  4444. * CALLS PAD, MOVEWD, LENGTH, TRIMPAD.
  4445. *
  4446. * USES TMPLIN.
  4447. #
  4448. ITEM TMP1,TMP2,TMP3;
  4449. ITEM NEWPOS,TTYCHAR;
  4450. ITEM LINLEN, TTYLEN;
  4451. ITEM LINPOS,TTYPOS;
  4452.  
  4453. LINLEN=LENGTH(LIN);
  4454. TTYLEN=LENGTH(TTYLIN);
  4455. PAD(LIN);
  4456. MOVEWD(BUFWIDP1,LIN,TMPLIN);
  4457. LINPOS=NUMWIDBLK;
  4458. TTYPOS=0;
  4459. NEWPOS=LINPOS;
  4460.  
  4461. WHYLE TTYPOS LS TTYLEN AND LINPOS LQ BUFCM1 AND
  4462. NEWPOS LQ BUFCM1 DO
  4463. BEGIN
  4464. GETCHAR(TTYLINE,TTYPOS,TTYCHAR);
  4465.  
  4466. IF TTYCHAR EQ COPCHAR THEN # COPY 1 CHAR #
  4467. BEGIN
  4468. GETCHAR(TMPLINE,NEWPOS,TMP2);
  4469. SETCHAR(LINE,LINPOS,TMP2);
  4470. NEWPOS=NEWPOS+1;
  4471. TTYPOS=TTYPOS+1;
  4472. LINPOS=LINPOS+1;
  4473. END
  4474.  
  4475. ELSE IF TTYCHAR EQ BLKCHAR THEN # GEN A BLANK #
  4476. BEGIN
  4477. SETCHAR(LINE,LINPOS,CBLANK);
  4478. NEWPOS=NEWPOS+1;
  4479. TTYPOS=TTYPOS+1;
  4480. LINPOS=LINPOS+1;
  4481. END
  4482.  
  4483. ELSE IF TTYCHAR EQ DELCHAR THEN # DELETE A BUNCH #
  4484. BEGIN
  4485. # FIND OUT HOW MANY #
  4486. TMP2=0;
  4487. FOR TMP1=TTYPOS STEP 1 UNTIL TTYLEN DO
  4488. BEGIN
  4489. GETCHAR(TTYLINE,TMP1,TMP3);
  4490. IF TMP2 EQ 0 AND TMP3 NQ DELCHAR THEN TMP2=TMP1;
  4491. END
  4492. # TMP2 GUARANTEED #
  4493. TMP2=TMP2-TTYPOS; # NOW LENGTH OF DELETION #
  4494. TTYPOS=TTYPOS+TMP2;
  4495. NEWPOS=NEWPOS+TMP2;
  4496. END
  4497.  
  4498. ELSE IF TTYCHAR EQ INSCHAR THEN # INSERT A BUNCH #
  4499. BEGIN
  4500. # SCAN FOR ENTIRE INSERT #
  4501. TMP2=0;
  4502. FOR TMP1=TTYPOS+1 STEP 1 UNTIL TTYLEN DO
  4503. BEGIN
  4504. GETCHAR(TTYLINE,TMP1,TMP3);
  4505. IF TMP2 EQ 0 AND TMP3 EQ DELCHAR THEN TMP2=TMP1;
  4506. END
  4507. # TMP2 NOT GUARANTEED #
  4508. IF TMP2 EQ 0 THEN TMP2=TTYLEN;
  4509. # NOW COPY INSERTED SECTION #
  4510. FOR TMP1=TTYPOS+1 STEP 1 WHILE TMP1 LS TMP2
  4511. AND LINPOS LQ BUFCM1 DO
  4512. BEGIN
  4513. GETCHAR(TTYLINE,TMP1,TMP3);
  4514. SETCHAR(LINE,LINPOS,TMP3);
  4515. LINPOS=LINPOS+1;
  4516. END
  4517. # NOW COPY TYPED-OVER SECTION #
  4518. FOR TMP1=0 STEP 1 UNTIL TMP2-TTYPOS DO
  4519. BEGIN
  4520. IF LINPOS GQ BUFCHAR OR NEWPOS GQ BUFCHAR THEN TEST;
  4521. GETCHAR(TMPLINE,NEWPOS,TMP3);
  4522. SETCHAR(LINE,LINPOS,TMP3);
  4523. NEWPOS=NEWPOS+1;
  4524. LINPOS=LINPOS+1;
  4525. END
  4526. TTYPOS=MIN(TMP2+1,TTYLEN);
  4527. END
  4528.  
  4529. ELSE IF TTYCHAR EQ TRNCHAR THEN # TRUNCATE SOURCE #
  4530. BEGIN
  4531. FOR TMP1=NEWPOS STEP 1 UNTIL BUFCM1
  4532. DO SETCHAR(TMPLINE,TMP1,CBLANK);
  4533. TTYPOS=TTYPOS+1;
  4534. END
  4535.  
  4536. ELSE # JUST OVERSTRIKE #
  4537. BEGIN
  4538. SETCHAR(LINE,LINPOS,TTYCHAR);
  4539. TTYPOS=TTYPOS+1;
  4540. NEWPOS=NEWPOS+1;
  4541. LINPOS=LINPOS+1;
  4542. END
  4543.  
  4544. END # OF LOOP #
  4545. # FINALLY COPY BACK ANY TRAILING PART FROM TMPLIN #
  4546. TMP3=LINPOS;
  4547. FOR TMP1=NEWPOS STEP 1 UNTIL BUFCM1 DO
  4548. BEGIN
  4549. GETCHAR(TMPLINE,TMP1,TMP2);
  4550. IF TMP3 LQ BUFCM1 THEN
  4551. BEGIN
  4552. SETCHAR(LINE,TMP3,TMP2);
  4553. TMP3=TMP3+1;
  4554. END
  4555. END
  4556. SETCHAR(LINE,TMP3,CENDLINE);
  4557.  
  4558. TRIMPAD;
  4559.  
  4560. END # OF DOMOD #
  4561.  
  4562.  
  4563. CONTROL IFEQ MULTI,1;
  4564.  
  4565. PROC MULTMOV;
  4566. IOBEGIN(MULTMOV)
  4567. #
  4568. ** MULTMOV - COPY/MOVE COMMANDS, EASY CONDITIONS.
  4569. *
  4570. * MULTMOV PERFORMS THE COPY AND MOVE COMMANDS IN MULTI-USER
  4571. * MODE UNDER EASY CONDITIONS - LESS THAN 40 LINES IN THE
  4572. * SOURCE BLOCK AND LINE BOUNDARIES AS OPPOSED TO CHARACTER
  4573. * BOUNDARIES.
  4574. *
  4575. * ENTRY COMMAND PROCESSOR HAS RECOGNIZED VERB.
  4576. * TOKEN ADVANCED BUT NO OTHER SCANNING DONE.
  4577. * TOKENTYPE, SCANPOS, TOKENPOS, ETC - AS ABOVE.
  4578. * CURFILE, CURSPLIT, CURRENT - DEFAULT ADDRESS.
  4579. * CHARRANGE - CHARACTER OR LINE RANGE BOUNDS.
  4580. * SCREENMODE - FINAL POSITIONING/PRINTING.
  4581. * WIDTH - THIS SETTING WILL BE IGNORED.
  4582. * BLANKS - THIS SETTING WILL BE IGNORED.
  4583. *
  4584. * EXIT CURFILE, CURRENT - FINAL RESTING PLACE.
  4585. * (ANOTHER FILE MAY HAVE BEEN OPENED)
  4586. *
  4587. * CALLS DOSEGMENT(INTERNAL), MIN, POSZ, PUSH, SQUELCH,
  4588. * SETLNUM, TRIMPAD, INSX, DORANGE, POP, DELX, FWDZ,
  4589. * SCANNER, FITNUM, HALT, VFYLOCK.
  4590. *
  4591. * USES LINPTR1-3, CHRPTR1-3, FILPTR1-3, LINNUM1-3,
  4592. * LINCTR, LIMIT, LINENO, P<LINEBUF>, LCOUNT,
  4593. * REGLINE[RNGTOPREG], REGLINE[RNGBOTREG], FOUND.
  4594. #
  4595.  
  4596. XREF LABEL QQSINGLE;
  4597.  
  4598.  
  4599. PROC DOSEGMENT;
  4600. IOBEGIN(DOSEGMENT)
  4601. #
  4602. ** DOSEGMENT - MULTMOV INTERNAL ALGORITHM.
  4603. *
  4604. * DOSEGMENT EXISTS BECAUSE THE MAJOR ALGORITHM OF MULTMOV
  4605. * MUST BE EXECUTED TWICE - THUS THIS ROUTINE CONSOLIDATES
  4606. * CODE. THE ALGORITHM MUST OPERATE ON (POTENTIALLY) TWO
  4607. * SEGMENTS TO PREVENT AN INFINITE DUPLICATION OF FILE
  4608. * CONTENT FOR A COPY TO A TARGET WITHIN THE SOURCE RANGE.
  4609. *
  4610. * ENTRY LINPTR1, LINPTR2 - FIRST AND LAST LINES OF SOURCE.
  4611. * LIMIT - NUMBER OF LINES IN SOURCE.
  4612. * LINPTR3 - TARGET ADDRESS TO INSERT AFTER.
  4613. * FILPTR1, FILPTR3 - FILE ASSOCIATIONS.
  4614. * TWO LEVELS OF POSITIONING STACK - USED TO PRESERVE
  4615. * SECOND SEGMENT BOUNDS WHILE PROCESSING FIRST.
  4616. *
  4617. * EXIT TWO LEVELS OF STACK - RELOCATED PROPERLY.
  4618. * LINPTR1, LINPRT2, LINPTR3 - POSSIBLY DESTROYED.
  4619. * LCOUNT - NUMBER OF LINES PROCESSED IS INCREMENTED.
  4620. *
  4621. * USES LINCTR, REGLINE[RNGTOPREG].
  4622. *
  4623. * NOTE SEE HEADER FOR MULTMOV.
  4624. #
  4625.  
  4626. # POSITION TO SOURCE AND PROCESS SEGMENT #
  4627. POSZ(LINPTR1);
  4628. FOR LINPTR3=1 STEP 1 WHILE LINPTR3 LQ LIMIT AND USRBRK EQ 0 DO
  4629. BEGIN
  4630. PUSH; # KEEP TRACK OF SOURCE POSITION #
  4631. P&lt;LINEBUF>=0; # SUPPRESS WORKIO LINE BUFFER READOUT #
  4632. POSZ(REGLINE[RNGTOPREG]); # GET TO TARGET ADDRESS #
  4633. P&lt;LINEBUF>=LOC(LIN); # RESTORE NORMAL WORKIO FUNCTION #
  4634. CURFILE=FILPTR3;
  4635. IF ASCII[FILPTR1] GQ 2 AND ASCII[FILPTR3] LQ 1
  4636. THEN SQUELCH(LIN); # FIX UP TEXT OF LINE #
  4637. LINENO=LINENO+INCR;
  4638. SETLNUM;
  4639. SETCHAR(LINE,EDITFIELD,CENDLINE); # CLEAR TO END OF LINE #
  4640. TRIMPAD;
  4641. INSX; # COPY ONE LINE #
  4642. REGLINE[RNGTOPREG]=CURRENT; # UPDATE TARGET ADDRESS #
  4643. POP; # BACK TO SOURCE RANGE #
  4644. IF FILCMDNDX EQ FILCMDST"MOVE" THEN DELX;
  4645. LCOUNT=LCOUNT+1; # ADJUST OFFICIAL WORK COUNT #
  4646. FWDZ; # ADVANCE WITHIN RANGE #
  4647. END
  4648. IOEND # OF DOSEGMENT #
  4649.  
  4650.  
  4651. # MULTMOV ACTUAL CODE STARTS HERE #
  4652.  
  4653. LCOUNT=TOKENPOS; # TEMPORARY MECHANISM FOR SNGLMOV #
  4654. SCANNER; # GET ALL ADDRESSES #
  4655.  
  4656. IF EXECNDX EQ EXECST"MOVE" THEN
  4657. BEGIN # IF MOVE COMMAND #
  4658. VFYLOCK;
  4659. IF SCANMARK THEN KILLMARKS = TRUE;
  4660. END
  4661. CURFILE = = FILPTR3;
  4662. VFYLOCK;
  4663. CURFILE = = FILPTR3;
  4664.  
  4665. IF TOPF(CURFILE) EQ BOTF(CURFILE)-1 THEN
  4666. BEGIN
  4667. HALT("EMPTY FILE$");
  4668. END
  4669. ELSE IF NOT FOUND THEN
  4670. BEGIN
  4671. HALT("OUT OF BOUNDS$");
  4672. END
  4673. IF NOT FOUND THEN IORET
  4674.  
  4675. LINPTR2=MIN(LINPTR2,LINPTR1+LIMIT-1); # TIGHTEN BOUNDS #
  4676. LIMIT=LINPTR2-LINPTR1+1;
  4677.  
  4678. IF LIMIT GQ 40 OR CHARRANGE OR FIELDTARGET NQ 0
  4679. THEN GOTO QQSINGLE;
  4680.  
  4681. # TEST THAT LINE NUMBERS CAN BE FITTED IF NEEDED #
  4682. POSZ(LINPTR3);
  4683. FITNUM;
  4684. NUMWIDBLK=0;
  4685. IF NUMBERED[FILPTR3] NQ 0 THEN NUMWIDBLK=NUMWIDTH+BLANKS;
  4686.  
  4687. # CHECK FOR INCOMPATIBLE CHARACTER SETS. IF TARGET FILE IS #
  4688. # EMPTY, WE CHANGE ITS CHARACTER SET. OTHERWISE, DOSEGMENT #
  4689. # WILL SUPPRESS CASE OF TEXT. #
  4690. IF ASCII[FILPTR1] GQ 2 AND ASCII[FILPTR3] EQ 0
  4691. AND BOTF(FILPTR3)-TOPF(FILPTR3)-1 EQ THISEXTEND
  4692. THEN ASCII[FILPTR3]=ASCII[FILPTR1];
  4693.  
  4694. # CHECK FOR TARGET INSIDE RANGE. STORE ON STACK THE (FIRST) AND #
  4695. # (LAST) LINES TO BE PROCESSED AS SECOND SEGMENT. #
  4696. IF LINPTR3 GQ LINPTR1 AND LINPTR3 LS LINPTR2 THEN
  4697. BEGIN
  4698. POSZ(LINPTR3+1);
  4699. PUSH;
  4700. POSZ(LINPTR2);
  4701. PUSH;
  4702. LINPTR2=LINPTR3; # CUT OFF FIRST SEGMENT #
  4703. LIMIT=LINPTR2-LINPTR1+1;
  4704. END
  4705. ELSE
  4706. BEGIN
  4707. POSZ(0); # INDICATE NO SECOND SEGMENT #
  4708. PUSH;
  4709. PUSH;
  4710. END
  4711.  
  4712. # STORE TARGET ADDRESS IN RELOCATABLE REGISTER #
  4713. REGLINE[RNGTOPREG]=LINPTR3;
  4714.  
  4715. LCOUNT=0; # INITIALIZE ACTUAL LINE COUNT #
  4716.  
  4717. DOSEGMENT;
  4718.  
  4719. # NOW RETRIEVE BOUNDS FOR SECOND SEGMENT #
  4720. POP;
  4721. LINPTR2=CURRENT;
  4722. POP;
  4723. LINPTR1=CURRENT;
  4724. LIMIT=LINPTR2-LINPTR1+1;
  4725.  
  4726. IF CURRENT GR 0 THEN DOSEGMENT;
  4727.  
  4728. CURFILE=FILPTR3;
  4729.  
  4730. # FINAL POSITIONING AND PRINTING #
  4731. IF SCREENMODE THEN POSZ(REGLINE[RNGTOPREG]-LCOUNT+1);
  4732. ELSE
  4733. BEGIN
  4734. POSZ(REGLINE[RNGTOPREG]);
  4735. IF NOT DONTPRINT THEN
  4736. BEGIN
  4737. LINPTR1=CURRENT-LCOUNT+1;
  4738. LINPTR2=BOTF(FILPTR3)-1;
  4739. LIMIT=LCOUNT;
  4740. EXECNDX=EXECST"TYPE";
  4741. DORANGE;
  4742. END
  4743. END
  4744.  
  4745. IOEND # OF MULTMOV #
  4746.  
  4747. CONTROL FI;
  4748.  
  4749.  
  4750. PROC SAVEPROT;
  4751. BEGIN
  4752. #
  4753. ** SAVEPROT - SAVE COPY OF LINE IMAGE FOR EDITFIELD.
  4754. *
  4755. * SAVEPROT IS ONE OF THE MAJOR INTERFACES BY WHICH EDITING
  4756. * CODE CAN COMPLY WITH EDITFIELD RESTRICTIONS. SAVEPROT
  4757. * COPIES THE LINE IMAGE INTO PROTLIN AND TRUNCATES ORIGINAL.
  4758. *
  4759. * ENTRY LIN - INTERNAL LINE IMAGE.
  4760. * EDITFIELD - START COLUMN FOR PROTECTED FIELD.
  4761. *
  4762. * EXIT PROTLIN - COPY OF ORIGINAL LIN CONTENT.
  4763. * LIN - TRUNCATED AT EDITFIELD TO HIDE FIELD.
  4764. *
  4765. * MACROS SETCHAR.
  4766. *
  4767. * CALLS COPYLIN, TRIMPAD.
  4768. #
  4769. IF EDITFIELD GQ BUFCM1 THEN RETURN;
  4770. COPYLIN(LIN,PROTLIN);
  4771. SETCHAR(LINE,EDITFIELD,CENDLINE);
  4772. TRIMPAD;
  4773. END # OF SAVEPROT #
  4774.  
  4775. PROC MERGEPROT;
  4776. # TITLE MERGEPROT - MERGE MODIFIED LINE WITH PROTECTED FIELD. #
  4777.  
  4778. BEGIN # MERGEPROT #
  4779.  
  4780. #
  4781. ** MERGEPROT - MERGE MODIFIED LINE WITH PROTECTED FIELD.
  4782. *
  4783. * MERGEPROT IS ONE OF THE MAJOR INTERFACES WITH WHICH
  4784. * EDITING CODE CAN COMPLY WITH EDITFIELD RESTRICTIONS.
  4785. *
  4786. * PROC MERGEPROT
  4787. *
  4788. * ENTRY LIN - MODIFIED INTERNAL LINE IMAGE.
  4789. * PROTLIN - UNMODIFIED VERSION OF SAME LINE.
  4790. * EDITFIELD - SHOWS WHICH FIELDS TO MERGE.
  4791. *
  4792. * EXIT LIN - PARTIALLY DE-MODIFIED.
  4793. *
  4794. * MACROS GETCHAR, SETCHAR.
  4795. *
  4796. * CALLS EXTENDC, TRIMPAD.
  4797. #
  4798.  
  4799. ITEM TMP1 I; # TEMPORARY STORAGE #
  4800. ITEM TMP2 I; # TEMPORARY STORAGE #
  4801.  
  4802. IF EDITFIELD GQ BUFCM1 THEN RETURN;
  4803. IF LENGTH(PROTLIN) LQ EDITFIELD THEN RETURN;
  4804. EXTENDC(LIN,EDITFIELD);
  4805. FOR TMP1=EDITFIELD STEP 1 UNTIL BUFCHAR DO
  4806. BEGIN
  4807. GETCHAR(PROTLINE,TMP1,TMP2);
  4808. SETCHAR(LINE,TMP1,TMP2);
  4809. END
  4810. SETCHAR(LINE,BUFCHAR,CENDLINE);
  4811. TRIMPAD;
  4812.  
  4813. END # MERGEPROT #
  4814.  
  4815.  
  4816. PROC SETFIELD;
  4817. BEGIN
  4818. #
  4819. ** SETFIELD - ESTABLISH TAB-FIELD RESTRICTIONS.
  4820. *
  4821. * SETFIELD IS CALLED TO SET UP THOSE VARIABLES WHICH CAN
  4822. * CONTROL LIMITATIONS ON TEXT MANIPULATION BY TAB-FIELD
  4823. * COLUMNS. NOTE THAT ACTUAL COMPLIANCE WITH SUCH
  4824. * RESTRICTIONS IS LEFT TO THE ACTUAL MANIPULATORS.
  4825. *
  4826. * ENTRY FIELDNDX - SHOWS WHICH FIELD IF ANY.
  4827. * NUMWIDBLK - OFFSET TO IGNORE SEQUENCE NUMBERS.
  4828. *
  4829. * EXIT FIELDFLG - WHETHER RESTRICTIONS APPLICABLE.
  4830. * FIELDBGN, FIELDEND - FIELDNDX CONVERTED TO COLUMNS.
  4831. *
  4832. * CALLS TABFN.
  4833. #
  4834.  
  4835. ITEM TMP1 I; # TEMPORARY STORAGE #
  4836. ITEM TMP2 I; # TEMPORARY STORAGE #
  4837.  
  4838. IF FIELDNDX NQ 0 THEN
  4839. BEGIN
  4840. FIELDFLG=TRUE;
  4841. IF FIELDNDX GR 0 THEN
  4842. BEGIN # IF USING TAB FIELDS #
  4843. TMP1 = NUMWIDBLK+TABFN(FIELDNDX-1);
  4844. TMP2 = NUMWIDBLK+TABFN(FIELDNDX)-1;
  4845. END
  4846. ELSE
  4847. BEGIN # IF USING DIRECT COLUMNS #
  4848. TMP1 = INFLDBGN;
  4849. TMP2 = INFLDEND;
  4850. END
  4851. IF TMP2 LS TMP1 THEN TMP2 = BUFCM1;
  4852. IF BACKWARD THEN
  4853. BEGIN
  4854. IF NOT (FIRSTRANGE AND (FIELDBGN LS TMP2)) THEN FIELDBGN = TMP2;
  4855. FIELDEND = TMP1;
  4856. END
  4857. ELSE
  4858. BEGIN
  4859. IF NOT (FIRSTRANGE AND (FIELDBGN GR TMP1)) THEN FIELDBGN = TMP1;
  4860. FIELDEND = TMP2;
  4861. END
  4862. END
  4863. END # OF SETFIELD #
  4864.  
  4865.  
  4866. PROC SETFIRST;
  4867. BEGIN
  4868. #
  4869. ** SETFIRST - SET PARAMETERS FOR FIRST LINE OF RANGE.
  4870. *
  4871. * SETFIRST IS USED BY DORANGE TO INDICATE WHEN WE ARE
  4872. * PROCESSING THE FIRST LINE OF A RANGE, (BY CHRONOLOGY
  4873. * RATHER THAN POSITION), AND ALSO SETS UP THE VARIABLES
  4874. * WHICH NORMALLY CONTROL TAB FIELD LIMITATIONS SO AS TO
  4875. * LIMIT MANIPULATIONS TO OCCUR NO EARLIER THAN A CURSOR
  4876. * POSITION. THIS CONVERTS SOME OPERATIONS INTO CHARACTER-
  4877. * MODE IN PLACE OF RANGE MODE. NOTE THAT ACTUAL COMPLIANCE
  4878. * WITH FIELD LIMITATIONS IS LEFT TO THE MANIPULATORS.
  4879. *
  4880. * ENTRY CHRPTR1 - FIRST COLUMN OF STREAM.
  4881. *
  4882. * EXIT FINDCONTROL - BOTTOM BIT IS FORCED ON.
  4883. * FIELDFLG - FORCED TRUE.
  4884. * FIELDBGN, FIELDEND - BRACKET SECOND HALF OF LINE.
  4885. *
  4886. * CALLS MAX.
  4887. #
  4888. FIRSTRANGE=TRUE;
  4889. FINDCONTROL=FINDCONTROL LOR 1;
  4890. FIELDFLG=TRUE;
  4891. FIELDBGN=MAX(CHRPTR1,NUMWIDBLK);
  4892. IF NOT BACKWARD THEN FIELDEND=BUFCM1;
  4893. END
  4894.  
  4895.  
  4896. PROC SETLAST;
  4897. BEGIN
  4898. #
  4899. ** SETLAST - SET PARAMETERS FOR LAST LINE OF RANGE.
  4900. *
  4901. * SETLAST IS SIMILAR TO SETFIRST EXCEPT THAT IT INDICATES
  4902. * THE RANGE IS ALMOST DONE AND BRACKETS THE FIRST HALF
  4903. * INSTEAD OF THE SECOND HALF OF THE LINE FOR CHARACTER-
  4904. * STREAM ORIENTATION.
  4905. *
  4906. * ENTRY CHRPTR2 - LAST EDITABLE COLUMN OF STREAM.
  4907. *
  4908. * EXIT LASTRANGE - FORCED TRUE.
  4909. * FINDCONTROL - BOTTOM BIT FORCE ON.
  4910. * FIELDFLG - FORCED TRUE.
  4911. * FIELDEND - BRACKET END OF STREAM.
  4912. *
  4913. * CALLS MAX.
  4914. #
  4915. LASTRANGE=TRUE;
  4916. FINDCONTROL=FINDCONTROL LOR 1;
  4917. FIELDFLG=TRUE;
  4918. FIELDEND=MAX(CHRPTR2,NUMWIDBLK);
  4919. END
  4920. PAGE # EXEC ROUTINE #
  4921.  
  4922. PROC EXEC;
  4923. IOBEGIN(EXEC)
  4924. #
  4925. ** EXEC - FAN-OUT TO TEXT MANIPULATOR FOR ONE LINE OF RANGE.
  4926. *
  4927. * THE EXEC ROUTINE CONTAINS CHUNKS OF CODE THAT NEED TO BE
  4928. * EXECUTED ONCE PER LINE FOR THOSE COMMANDS THAT WORK ON
  4929. * RANGES OF LINES. THIS IS A MEDIUM-SIZED SUBSET OF ALL
  4930. * CMDS. THE COMMAND HANDLING ROUTINES IN PROCESS MUST SELECT
  4931. * THEIR BROTHER HERE IN EXEC BY SETTING EXECNDX TO THE RIGHT
  4932. * STATUS VALUE BEFORE CALLING EXEC. EXEC WILL DO A SWITCH
  4933. * GOTO ON THE BASIS OF EXECNDX.
  4934. *
  4935. * THE CASE HANDLERS IN EXEC ARE ALLOWED TO EXECUTE
  4936. * NON-REENTRANT CODE SEQUENCES FOR THE PURPOSE OF TEXT
  4937. * MANIPULATION. THESE SEQUENCES CAN USE GLOBAL STORAGE.
  4938. * TERMINAL OR FILE OPERATIONS HOWEVER MUST FOLLOW REENTRANT
  4939. * CODING PRINCIPLES.
  4940. *
  4941. * THE LINCTR VARIABLE IS THE CRUCIAL LINK BETWEEN DORANGE AND
  4942. * EXEC. IT IS THE COUNTER FOR USER LIMITS. THE OUTER LOGIC
  4943. * ALWAYS INCREMENTS IT AS A WISEST ASSUMPTION. THE FIND AND
  4944. * SUBSTITUTE COMMAND HANDLERS THEN MUST DECREMENT IT UPON
  4945. * FAILURE SO AS IT KEEP IT CONSTANT. NOTE THAT DORANGE KNOWS
  4946. * HOW MANY TIMES TO CALL US WITH REGARD TO THE NUMBER OF
  4947. * LINES IN THE RANGE.
  4948. *
  4949. * EXEC IS ALSO OBLIGATED TO CHECK FOR INTERRUPT CONDITIONS
  4950. * WHICH MUST TERINATE RANGE PROCESSING, AND TO SET LINCTR
  4951. * UPON INTERRUPTS TO SIGNAL SHUTDOWN TO DORANGE.
  4952. *
  4953. * ENTRY LIN - CURRENT INTERNAL LINE IMAGE.
  4954. * CURRENT, CURFILE, CURSPLIT - WHERE WE ARE IN FILE.
  4955. * FIELDNDX - DEFINES TAB-FIELD LIMITATIONS.
  4956. * FIELDFLG, FIELDBGN, FIELDEND - MAY HAVE FIELD LIMITS.
  4957. * CHARRANGE - MODE.
  4958. * FIRSTRANGE, LASTRANGE - WHETHER AT BOUNDS OF RANGE.
  4959. * FORCEFIELD - EXPLICIT FIELD CONSTRAINT IN SYNTAX.
  4960. * LINPTR1 - SAME AS CURRENT.
  4961. * LINPTR2 - ORIGINAL LINE ADDRESS FOR END OF RANGE.
  4962. * CHRPTR1, CHRPTR2 - CHARACTER BOUNDARIES IF ANY.
  4963. * USRBRK - USER INTERRUPT.
  4964. * LINCTR - COUNTER AGAINST LIMIT.
  4965. * LIMIT - LIMIT ON RANGE ITERATION.
  4966. * EXECNDX - WHICH CODE IN EXEC TO EXECUTE.
  4967. * LCOUNT - ACCURATE COUNT OF LINES PROCESSED.
  4968. * CANINTER - CONTROLS INTERRUPTABILITY OF COMMANDS.
  4969. * DONTPRINT - CONTROL PRINTOUT.
  4970. * SCREENMODE - ALSO CONTROLS PRINTOUT.
  4971. *
  4972. * EXIT LINCTR - INCREMENTED TOWARDS LIMIT.
  4973. * (NOT INCREMENTED FOR MISSED SEARCH)
  4974. * (LARGENUM FOR ANY TYPE OF FORCED SHUTDOWN)
  4975. * LCOUNT - INCREMENTED.
  4976. * FIELDFLG, FIELDBGN, FIELDEND - POSSIBLY DESTROYED.
  4977. * LIN - UPDATED AND TRANSMITTED INTO FILE.
  4978. * DONTPRINT - POSSIBLY DESTROYED IF INTERRUPTED.
  4979. * NEWCURSOR - CURSOR AFTER SEARCH.
  4980. * STRINGLEN - LENGTH OF SEARCHED STRING.
  4981. *
  4982. * MACROS GETCHAR, SETCHAR.
  4983. *
  4984. * CALLS SETCHRPTR(INTERNAL), DODELETE(INTERNAL),
  4985. * SETFIELD, TRIMPAD, MERGEPROT, REPX, DELX,
  4986. * CHKVICTIM(MULTI), CLEARQUE(MULTI),
  4987. * SAVEPROT, APPEND, XSHOW, XFRCMOUT, FINDER, NOPOP,
  4988. * GLOBALLOCATE, PUSH, DOMOD, DOCENTER, GLOBALCHANGE,
  4989. * SUBST, LENGTH.
  4990. *
  4991. * USES CHRPTR1, CHRPTR2.
  4992. #
  4993.  
  4994.  
  4995. # EXECSW MUST MATCH EXECST #
  4996.  
  4997. SWITCH EXECSW XXAPPEND, XXCENTER, XXCOPY, XXDELETE, XXLOCATE,
  4998. XXMODIFY, XXMOVE, XXREPLACE, XXTYPE;
  4999.  
  5000.  
  5001. # INTERNAL PROCEDURES #
  5002.  
  5003. PROC SETCHRPTR;
  5004. BEGIN
  5005. #
  5006. ** SETCHRPTR - SETUP CHARACTER POINTERS.
  5007. *
  5008. * SETCHRPTR IS AN INTERNAL ALGORITHM TO CONSOLIDATE CODE
  5009. * FREQUENTLY USED WITHIN THE EXEC ROUTINE. SETCHRPTR
  5010. * SETS UP THE CHRPTR1 AND CHRPTR2 VARIABLES BASED ON
  5011. * ANY FIELD RESTRICTIONS.
  5012. *
  5013. * ENTRY FIELDBGN, FIELDEND - POSSIBLY SETUP BY SETFIRST
  5014. * OR SETLAST.
  5015. * FORCEFIELD - WHETHER EXPLICIT FIELD SYNTAX.
  5016. * FIELDNDX - WHICH TAB FIELD.
  5017. * NUMWIDBLK - SETUP PER SEQUENCE MODE AND LINE CONTENT.
  5018. *
  5019. * EXIT FIELDBGN, FIELDEND - POSSIBLY SETUP BY SETFIELD.
  5020. * CHRPTR1, CHRPTR2 - POSSIBLY MATCH FIELDBGN, FIELDEND.
  5021. * FIELDFLG - POSSIBLY SETUP BY SETFIELD.
  5022. *
  5023. * CALLS SETFIELD.
  5024. #
  5025. SETFIELD;
  5026. IF FORCEFIELD AND FIELDNDX NQ 0 THEN
  5027. BEGIN
  5028. CHRPTR1=FIELDBGN;
  5029. CHRPTR2=FIELDEND;
  5030. END
  5031. END # OF SETCHRPTR #
  5032.  
  5033. PROC DODELETE;
  5034. IOBEGIN(DODELETE)
  5035. #
  5036. ** DODELETE - ACTUAL LINE/STRING REMOVAL.
  5037. *
  5038. * DODELETE DELETES AN ENTIRE LINE WHEN APPROPRIATE, AND
  5039. * REPLACES A LINE WITH A STRING DELETED OTHERWISE.
  5040. *
  5041. * DODELETE IS OBLIGATED TO EXECUTE INSTANTLY UNTIL ANY NEED
  5042. * FOR MERGEPROT IS DONE OR GONE.
  5043. *
  5044. * ENTRY LIN - INTERNAL LINE IMAGE.
  5045. * CURRENT, CURFILE, CURSPLIT - WHERE WE ARE.
  5046. * FORCEFIELD - WHETHER EXPLICIT SYNTAX.
  5047. * CHARRANGE - CHARACTER/LINE BOUNDARY MODE.
  5048. * FIRSTRANGE, LASTRANGE - WHETHER AT BOUNDS.
  5049. * FIELDBGN, FIELDEND - POSSIBLY SET BY SETFIRST
  5050. * OR SETLAST.
  5051. * FIELDNDX - WHICH TAB FIELD.
  5052. *
  5053. * EXIT LIN - UPDATED IF STRING EXTRACTION.
  5054. * FILE UPDATED.
  5055. * CURRENT - POSSIBLY DECREMENTED IF LINE DELETE.
  5056. * FIELDBGN, FIELDEND - POSSIBLY SET BY SETFIELD.
  5057. *
  5058. * MACROS GETCHAR, SETCHAR.
  5059. *
  5060. * CALLS SETFIELD, LENGTH, TRIMPAD, MERGEPROT, REPX, DELX.
  5061. #
  5062. ITEM TMP1, TMP2;
  5063. IF FORCEFIELD OR (CHARRANGE AND (FIRSTRANGE OR LASTRANGE)) THEN
  5064. BEGIN # REPLACE LINE, STRING DELETED #
  5065. SETFIELD;
  5066. IF FIELDEND GQ LENGTH(LIN) THEN SETCHAR(LINE,FIELDBGN,CENDLINE);
  5067. # START INSTANTANEOUS CALCULATION #
  5068. FOR TMP1=FIELDEND+1 STEP 1 UNTIL LENGTH(LIN) DO
  5069. BEGIN
  5070. GETCHAR(LINE,TMP1,TMP2);
  5071. SETCHAR(LINE,FIELDBGN+TMP1-(FIELDEND+1),TMP2);
  5072. END
  5073. # END INSTANTANEOUS CALCULATION #
  5074. IF NOT (CHARRANGE AND FIRSTRANGE) THEN TRIMPAD;
  5075. MERGEPROT;
  5076. REPX;
  5077. END
  5078. ELSE DELX; # DELETE WHOLE LINE #
  5079. # NOTE MERGEPROT NOT NEEDED FOR LINE DELETION #
  5080. IOEND # OF DODELETE #
  5081.  
  5082.  
  5083. # EXEC MAIN CODE STARTS HERE #
  5084.  
  5085. CONTROL IFEQ MULTI,1;
  5086.  
  5087. # CHECK FOR SMFEX CAUSING US GRIEF #
  5088. CHKVICTIM;
  5089.  
  5090. CONTROL FI;
  5091.  
  5092. IF USRBRK NQ 0 OR ESCAPE THEN
  5093. BEGIN
  5094. IF CANINTER THEN
  5095. BEGIN
  5096. LINCTR=LARGENUM;
  5097. IORET
  5098. END
  5099. DONTPRINT=TRUE;
  5100. END
  5101. CONTROL IFEQ MULTI,1;
  5102. CLEARQUE;
  5103. CONTROL FI;
  5104.  
  5105. LINCTR=LINCTR+1; # ASSUME INCR AGAINST LIMIT #
  5106. GOTO EXECSW[EXECNDX];
  5107. PAGE # EXEC COMMAND HANDLERS #
  5108.  
  5109.  
  5110. XXAPPEND: # A COMMAND #
  5111. SAVEPROT; # MUST EXECUTE INSTANTLY UNTIL MERGEPROT #
  5112. APPEND;
  5113. MERGEPROT;
  5114. XSHOW;
  5115. REPX;
  5116. GOTO EXECDONE;
  5117.  
  5118. CONTROL IFEQ SINGLE,1;
  5119.  
  5120. XXCOPY:
  5121. SETCHRPTR;
  5122. LCOUNT=LCOUNT+1; # ACCURATE WORK ACCOUNTING #
  5123. XFRCMOUT;
  5124. GOTO EXECDONE;
  5125.  
  5126. XXCENTER:
  5127. SAVEPROT;
  5128. DOCENTER;
  5129. TRIMPAD;
  5130. MERGEPROT;
  5131. XSHOW;
  5132. REPX;
  5133. GOTO EXECDONE;
  5134.  
  5135. CONTROL FI;
  5136.  
  5137. XXDELETE:
  5138. SAVEPROT; # MUST EXECUTE INSTANTLY UNTIL MERGEPROT #
  5139. SETCHRPTR;
  5140. LCOUNT=LCOUNT+1;
  5141. DODELETE; # THIS ACCOMODATES MERGEPROT #
  5142. GOTO EXECDONE;
  5143.  
  5144. XXLOCATE:
  5145. SETFIELD;
  5146. FOUND=FINDER(NEWCURSOR,STRINGLEN);
  5147. IF FOUND THEN
  5148. BEGIN
  5149. YSHOW;
  5150. GLOBALLOCATE;
  5151. CHECKWIDE;
  5152. NOPOP; # TO COME BACK HERE #
  5153. PUSH;
  5154. END
  5155. ELSE LINCTR=LINCTR-1;
  5156. GOTO EXECDONE;
  5157.  
  5158. XXMODIFY:
  5159. SAVEPROT; # MUST EXECUTE INSTANTLY UNTIL MERGEPROT #
  5160. DOMOD;
  5161. TRIMPAD;
  5162. MERGEPROT;
  5163. XSHOW;
  5164. REPX;
  5165. GLOBALCHANGE;
  5166. GOTO EXECDONE;
  5167.  
  5168. XXTYPE:
  5169. SAVEPROT; # MUST EXECUTE INSTANTLY UNTIL MERGEPROT #
  5170. MERGEPROT; # SO FIELD IS PRINTABLE #
  5171. XSHOW;
  5172. GOTO EXECDONE;
  5173.  
  5174. XXREPLACE:
  5175. SAVEPROT; # MUST EXECUTE INSTANTLY UNTIL MERGEPROT #
  5176. SETFIELD;
  5177. SUBST;
  5178. IF FOUND THEN
  5179. BEGIN
  5180. MERGEPROT;
  5181. YSHOW;
  5182. REPX;
  5183. GLOBALCHANGE;
  5184. CHECKWIDE;
  5185. NOPOP; # SET UP HERE AS ... #
  5186. PUSH; # ... PLACE TO COME BACK TO #
  5187. END
  5188. ELSE LINCTR=LINCTR-1;
  5189. GOTO EXECDONE;
  5190.  
  5191. CONTROL IFEQ SINGLE,1;
  5192.  
  5193. XXMOVE:
  5194. SAVEPROT; # MUST EXECUTE INSTANTLY UNTIL MERGEPROT #
  5195. SETCHRPTR;
  5196. LCOUNT=LCOUNT+1; # ACCURATE WORK ACCOUNTING #
  5197. XFRCMOUT;
  5198. DODELETE; # THIS ACCOMODATES MERGEPROT #
  5199. GOTO EXECDONE;
  5200.  
  5201. CONTROL FI;
  5202.  
  5203. CONTROL IFEQ MULTI,1;
  5204.  
  5205. XXCENTER: XXCOPY: XXMOVE: # DROP INTO EXECDONE #
  5206.  
  5207. CONTROL FI;
  5208.  
  5209. EXECDONE:
  5210.  
  5211.  
  5212. IOEND # OF EXEC #
  5213. PAGE # UTILITIES FOR EXEC-LIKE STUFF #
  5214.  
  5215. PROC GETESCAPE;
  5216. IOBEGIN(GETESCAPE)
  5217. #
  5218. ** GETESCAPE - DETERMINE IF INPUT DATA AT/NEAR END.
  5219. *
  5220. * GETESCAPE RECOGNIZES IMMEDIATE END OF INPUT DATA, WHICH
  5221. * IS A NULL INPUT, AND UPCOMING END OF INPUT DATA, WHICH IS
  5222. * A TRAILING SOFT-TAB CHARACTER ON A NON-NULL INPUT.
  5223. *
  5224. * ENTRY TTYLIN - INTERNAL LINE IMAGE OF TERMINAL INPUT.
  5225. * TXTINCMD - WHETHER TTYLIN EXTRACTED FROM COMMAND.
  5226. *
  5227. * EXIT ESCAPE - TRUE FOR IMMEDIATE END OF INPUT.
  5228. * NXTESCAPE - TRUE FOR UPCOMING ESCAPE.
  5229. * TTLIN - TRAILING TAB CONVERTED TO BLANK.
  5230. *
  5231. * MACROS GETCHAR, SETCHAR.
  5232. *
  5233. * CALLS LENGTH, TRIM.
  5234. #
  5235. ITEM TMP1, TMP2;
  5236. CONTROL IFEQ SINGLE,1; # IF NOT MULTI USER FSE #
  5237. IF NOT INTERACT AND NOT TXTINCMD THEN
  5238. BEGIN # IF BATCH MODE INSERTION #
  5239. TRIM(TTYLIN,0); # TRIM TRAILING BLANKS #
  5240. END
  5241. CONTROL FI; # END OF NOT MULTI USER FSE #
  5242. TMP2=LENGTH(TTYLIN);
  5243. IF TMP2 EQ 0 THEN ESCAPE=TRUE;
  5244. ELSE
  5245. BEGIN
  5246. GETCHAR(TTYLINE,TMP2-1,TMP1);
  5247. IF TMP1 EQ TABCHAR THEN
  5248. BEGIN
  5249. SETCHAR(TTYLINE,TMP2-1,CBLANK);
  5250. TRIM(TTYLIN,1);
  5251. IF LENGTH(TTYLIN) EQ 0 THEN ESCAPE=TRUE;
  5252. ELSE NXTESCAPE=TRUE;
  5253. END
  5254. END
  5255. IF TXTINCMD THEN NXTESCAPE=TRUE;
  5256.  
  5257. IOEND # OF GETESCAPE #
  5258.  
  5259.  
  5260. PROC DOTAB(OFFSETI,OFFSETO,OFFSETTAB);
  5261. BEGIN
  5262. #
  5263. ** DOTAB - EXPAND SOFT-TABS.
  5264. *
  5265. * DOTAB EXPANDS TABS WITHIN TTYLIN, USING TMPLIN AS A SCRATCH
  5266. * BUFFER. FOR THE BENEFIT OF NUMBERS THE CALLER HAS GIVEN US
  5267. * AN OFFSET TO WORK AGAINST.
  5268. *
  5269. * ENTRY TTYLIN - INTERNAL LINE IMAGE OF TEXT TO EXPAND.
  5270. * OFFSETI - OFFSET TO START LOOKING IN TTYLIN.
  5271. * OFFSETO - OFFSET TO START EXPANDING IN TTYLIN.
  5272. * OFFSETTAB - OFFSET FOR TABS.
  5273. * TABCHAR - SOFT-TAB CHARACTER VALUE.
  5274. * TABVECTOR - SETUP.
  5275. *
  5276. * EXIT TTYLIN - UPDATED.
  5277. *
  5278. * MACROS GETCHAR, SETCHAR.
  5279. *
  5280. * CALLS LENGTH, COPYLIN, TABFN, TRIM.
  5281. *
  5282. * USES TMPLIN.
  5283. #
  5284. ITEM OFFSETI,OFFSETO,OFFSETTAB;
  5285. ITEM TMP1, TMP2, TMP3, TMP4;
  5286.  
  5287. COPYLIN(TTYLIN,TMPLIN);
  5288. FOR TMP1=OFFSETI STEP 1 UNTIL OFFSETO-1
  5289. DO SETCHAR(TMPLINE,TMP1,CBLANK);
  5290. TMP2=OFFSETO;
  5291. FOR TMP1=OFFSETI STEP 1 WHILE TMP1 LS LENGTH(TTYLIN) AND
  5292. TMP2 LS BUFCHAR DO
  5293. BEGIN
  5294. GETCHAR(TTYLINE,TMP1,TMP3);
  5295. IF TMP3 NQ TABCHAR OR TABVCTWRD[1] EQ 0 THEN
  5296. BEGIN
  5297. SETCHAR(TMPLINE,TMP2,TMP3);
  5298. TMP2=TMP2+1;
  5299. END
  5300. ELSE # IT IS TAB #
  5301. BEGIN
  5302. TMP3=0;
  5303. FOR TMP4=1 STEP 1 UNTIL USERTABS DO
  5304. BEGIN
  5305. IF TMP3 EQ 0 AND TABFN(TMP4) GR (TMP2-OFFSETTAB)
  5306. THEN TMP3=TABFN(TMP4)-(TMP2-OFFSETTAB);
  5307. END
  5308. IF TMP3 EQ 0 THEN TMP3=1;
  5309. # TMP3=NUMBER OF BLANKS TO GENERATE #
  5310. FOR TMP4=1 STEP 1 WHILE TMP4 LQ TMP3 AND TMP2 LS BUFCHAR DO
  5311. BEGIN
  5312. SETCHAR(TMPLINE,TMP2,CBLANK);
  5313. TMP2=TMP2+1;
  5314. END
  5315. END
  5316. END # OF LOOP #
  5317. SETCHAR(TMPLINE,MIN(TMP2,BUFCHAR),CENDLINE);
  5318. COPYLIN(TMPLIN,TTYLIN);
  5319. TRIM(TTYLIN,MAX(OFFSETO,1));
  5320.  
  5321. END # OF DOTAB #
  5322. PAGE # EXEC-LIKE STUFF. EXECINS #
  5323.  
  5324. PROC EXECINS;
  5325. IOBEGIN(EXECINS)
  5326. #
  5327. ** EXECINS - PROCESS ONE ONE LINE OF LINE-MODE INPUT.
  5328. *
  5329. * THE INSERT COMMAND IS NOT IMPLEMENTED THRU DORANGE AND EXEC
  5330. * AS IT WORKS ON A LINE POSITION, NOT A RANGE OF LINES. THE
  5331. * PROCESS COMMAND HANDLER FOR INSERT WILL REPEATEDLY CALL
  5332. * EXECINS. EXECINS WORKS IN THE AREA OF ESCAPE SEQUENCING
  5333. * PLUS DRIVING OF PARSING OUT TEXT ON THE COMMAND LINE PLUS
  5334. * PROMPTING AND GENERATION OF LINE NUMBER TEXT. EXECINS IS
  5335. * ONLY RELEVANT TO LINE-MODE AND SHOULD NOT BE CALLED WHEN
  5336. * IN SCREEN-MODE.
  5337. *
  5338. * ENTRY NXTESCAPE - WHETHER UPCOMING END OF INPUT.
  5339. * TXTINCMD - WHETHER TEXT ALREADY IN TTYLIN FROM CMD.
  5340. * CURRENT, CURFILE - WHERE WE ARE IN FILE.
  5341. * NUMBERED[CURFILE] - CONTROL PROMPTING AND SEQUENCING.
  5342. * LINENO - SEQUENCE NUMBER FOR NEW LINE.
  5343. * NUMWIDBLK - STANDARD SEQUENCING OFFSET.
  5344. * BLANKS - WHETHER TO ADD BLANK AFTER SEQUENCE NUMBER.
  5345. * TOPF(CURFILE) - RELOCATION FACTOR AND BOUNDS.
  5346. * ASCII[CURFILE] - CONTROLS LOWERCASE SUPPRESSION.
  5347. *
  5348. * EXIT LIN - INPUT LINE READY TO GO INTO FILE.
  5349. * NXTESCAPE, ESCAPE - UPDATED.
  5350. *
  5351. * MACROS SETCHAR.
  5352. *
  5353. * CALLS PUSHTEMP, POPTEMP, TTLPAD, TTSTR, TTST, TTLIN, TTBRK,
  5354. * PROMPT, CONVIN, TRIM, SQUELCH, GETESCAPE, DOTAB,
  5355. * COPYLIN, SETLNUM, TRIMPAD, CHECKWIDE, CHKVICTIM(MULTI)
  5356. *
  5357. * USES TTYLIN, TMPLIN, TEMP(RESTORED), DUMB.
  5358. #
  5359. PUSHTEMP;
  5360.  
  5361. IF NXTESCAPE THEN
  5362. BEGIN
  5363. ESCAPE=TRUE;
  5364. GOTO EXINSDONE;
  5365. END
  5366. IF NOT TXTINCMD THEN
  5367. BEGIN
  5368. CONTROL IFEQ SINGLE,1;
  5369. IF NOT INTERACT THEN GOTO EXECINS2;
  5370. CONTROL FI;
  5371. IF NUMBERED[CURFILE] NQ 0 THEN
  5372. BEGIN
  5373. TTLPAD(LINENO,NUMWIDTH,"0");
  5374. TEMP=NUMWIDBLK;
  5375. IF B&lt;59,1>TEMP NQ 0 THEN TTSTR(BLANKWRD);
  5376. TEMP=BLANKS;
  5377. TTST(" ",TEMP);
  5378. TTLIN(CKWRD);
  5379. END
  5380. ELSE IF FLOAT THEN
  5381. BEGIN
  5382. TEMP=CURRENT-TOPF(CURFILE)+1;
  5383. IF TEMP GR 9999 THEN TTLPAD(TEMP,8," ");
  5384. ELSE TTLPAD(TEMP,4," ");
  5385. TTLIN(BCCKWRD);
  5386. END
  5387. ELSE TTBRK;
  5388. EXECINS2:
  5389. PROMPT(NULLWRD);
  5390. CONVIN(TTYLIN,2);
  5391. TRIM(TTYLIN,1);
  5392. IF ASCII[CURFILE] LQ 1 THEN SQUELCH(TTYLIN);
  5393. END
  5394. GETESCAPE; # DETERMINES UPCOMING ESCAPE #
  5395. IF ESCAPE THEN GOTO EXINSDONE;
  5396. DOTAB(0,NUMWIDBLK,NUMWIDBLK);
  5397. COPYLIN(TTYLIN,LIN);
  5398. IF NUMBERED[CURFILE] NQ 0 THEN
  5399. BEGIN
  5400. FOR DUMB=1 STEP 1 UNTIL NUMWIDTH DO SETCHAR(LINE,DUMB-1,CDIGIT0);
  5401. SETLNUM;
  5402. END
  5403. TRIMPAD;
  5404. CHECKWIDE;
  5405.  
  5406. EXINSDONE:
  5407. POPTEMP;
  5408.  
  5409. CONTROL IFEQ MULTI,1;
  5410. CHKVICTIM; # SEE IF SMFEX IN TROUBLE #
  5411. CONTROL FI;
  5412.  
  5413.  
  5414. IOEND # OF EXECINS #
  5415. PAGE # DORANGE ROUTINE #
  5416.  
  5417. PROC DORANGE;
  5418. IOBEGIN(DORANGE)
  5419. #
  5420. ** DORANGE - PROCESS RANGE OF LINES FOR COMMAND.
  5421. *
  5422. * DORANGE IS USED TO MOVE THRU THE FILE ONE LINE AT A TIME
  5423. * CALLING EXEC EACH TIME. WE ARE THUS USED ONLY AND ALWAYS
  5424. * BY THOSE PROCESS COMMAND HANDLERS WHO DEAL WITH RANGES OF
  5425. * LINES. REMEMBER EXEC SUPPLIES THE PER-LINE GOODIES. WE
  5426. * ASSUME THAT OUR PROCESS ROUTINE HAS ALREADY SET UP EXECNDX,
  5427. * WHICH WILL TELL EXEC WHICH COMMAND IS ALIVE. WE ASSUME
  5428. * THAT THE PROCESS ROUTINE EITHER KNOWS THE RANGE IMPLICITLY
  5429. * OR HAS CALLED SCANNER, THUS LINPTR1 AND LINPTR2 GIVE THE
  5430. * RANGE. EXEC WILL DEAL ALSO WITH LINCTR AND LCOUNT.
  5431. *
  5432. * ENTRY BACKWARD - DIRECTION OF RANGE.
  5433. * LINPTR1 - TOP ADDRESS OF RANGE.
  5434. * LINPTR2 - BOTTOM ADDRESS OF RANGE.
  5435. * CURFILE, CURSPLIT - CURRENT FILE.
  5436. * ELLIPSIS, WORDSEARCH, UPPERSEARCH - SEARCH MODES.
  5437. * FIELDNDX - WHETHER/WHICH TAB FIELD LIMIT.
  5438. * LIMIT - MAXIMUM ITERATIONS.
  5439. * TOPF(CURFILE), BOTF(CURFILE) - BOUNDS.
  5440. * FOUND - WHETHER SYNTAX GAVE VALID BOUNDS.
  5441. * PROCESSNDX - WHICH COMMAND.
  5442. * EXECNDX - WHICH EXEC PROCESSOR.
  5443. * NUMBERED[CURFILE] - SEQUENCING MODE.
  5444. *
  5445. * EXIT LINPTR1, LINPTR2 - DESTROYED.
  5446. * LASTPROCESS - INDICATES TYPE OF COMMAND EXECUTED.
  5447. * NEWCURSOR - ZEROED.
  5448. *
  5449. * CALLS EXECONE(INTERNAL), GETLNUM, SETFIRST, SETLAST,
  5450. * EXEC, VOLUNTEER(MULTI), HALT, POSZ, MIN, FWDZ,
  5451. * BAKZ, MAX.
  5452. *
  5453. * USES LINPTR1, LINENO, WIDTHFOUND, FIELDFLG, FIELDBGN,
  5454. * FIELDEND, FINDCONTROL, LINPTR2, FIRSTRANGE, LASTRANGE,
  5455. * DORNGCTR, LCOUNT, LINCTR, YCURSOR, DELETEDONE,
  5456. * REGLINE[RNGTOPREG], REGLINE[RNGBOTREG], DELETCTL.
  5457. #
  5458.  
  5459. PROC EXECONE(FIRST,LAST);
  5460. IOBEGIN(EXECONE)
  5461. #
  5462. ** EXECONE - EXECUTE COMMAND PROCESSOR FOR ONE LINE.
  5463. *
  5464. * EXECONE IS AN INTERNAL ALGORITHM OF DORANGE WHICH
  5465. * EXISTS TO CONSOLIDATE CODE. INTERFACE TO EXEC ROUTINE.
  5466. *
  5467. * ENTRY FIRST - LINE ADDRESS FOR FIRST LINE OF RANGE.
  5468. * LAST - LINE ADDRESS FOR LAST LINE OF RANGE.
  5469. * (FIRST, LAST ARE IN CHRONOLOGICAL ORDER)
  5470. * CURRENT, CURFILE, CURSPLIT - LINE TO PROCESS.
  5471. * LIN - TEXT OF LINE TO PROCESS.
  5472. * NUMBERED[CURFILE] - MODE.
  5473. *
  5474. * EXIT CONDITIONS AS LEFT BY EXEC ROUTINE.
  5475. *
  5476. * USES FIELDFLG, FIELDBGN, FIELDEND, NUMWIDBLK, DELETEDONE.
  5477. *
  5478. * CALLS EXEC, SETFIRST, SETLAST, GETLNUM.
  5479. *
  5480. * NOTE THIS ROUTINE IS REENTRANT AND HAS PARAMETERS. IT
  5481. * MUST EXECUTE NON-REENTRANTLY UNTIL PARAMETER
  5482. * ARE COMPLETE AND CANNOT ALTER THE PARAMETERS.
  5483. #
  5484. ITEM FIRST, LAST;
  5485. DELETEDONE=FALSE;
  5486. IF NUMBERED[CURFILE] NQ 0 THEN
  5487. BEGIN
  5488. GETLNUM;
  5489. NUMWIDBLK=WIDTHFOUND+BLANKS;
  5490. END
  5491. FIELDFLG=FALSE;
  5492. FIELDBGN=NUMWIDBLK;
  5493. IF BACKWARD THEN FIELDBGN=BUFCM1;
  5494. FIELDEND=BUFCM1;
  5495. IF BACKWARD THEN FIELDEND=NUMWIDBLK;
  5496. FINDCONTROL=FINDCONTROL LAN 2;
  5497. FIRSTRANGE=FALSE;
  5498. LASTRANGE=FALSE;
  5499. IF CURRENT EQ FIRST THEN SETFIRST;
  5500. IF CURRENT EQ LAST THEN SETLAST;
  5501. # END PARAMETERS #
  5502. EXEC;
  5503. LINPTR1=CURRENT;
  5504. CONTROL IFEQ MULTI,1;
  5505. IF MOD(DORNGCTR,VOLLINES) EQ 0 THEN VOLUNTEER;
  5506. CONTROL FI;
  5507. IOEND # OF EXECONE #
  5508.  
  5509.  
  5510. # MAIN CODE OF DORANGE STARTS HERE #
  5511.  
  5512. LCOUNT=0; # DEFAULT WORK ACCOMPLISHED #
  5513. LINCTR=0;
  5514. LASTPROCESS=PROCESSNDX;
  5515.  
  5516. YCURSOR=-1; # TO RE-ADDRESS CURSOR #
  5517. NEWCURSOR=0;
  5518.  
  5519. FINDCONTROL=0; # SET TEXT SEARCH OPTIONS #
  5520. IF ELLIPSIS OR WORDSEARCH OR UPPERSEARCH
  5521. OR BACKWARD OR FIELDNDX NQ 0 THEN FINDCONTROL=2;
  5522.  
  5523. IF BACKWARD THEN
  5524. BEGIN
  5525. LINPTR1 = = LINPTR2;
  5526. CHRPTR1 = = CHRPTR2;
  5527. END
  5528.  
  5529. IF TOPF(CURFILE) EQ BOTF(CURFILE)-1 THEN
  5530. BEGIN
  5531. HALT("EMPTY FILE$");
  5532. END
  5533. ELSE IF NOT FOUND THEN
  5534. BEGIN
  5535. HALT("OUT OF BOUNDS$");
  5536. END
  5537. IF NOT FOUND THEN IORET # IF HALT CALLED #
  5538.  
  5539. POSZ(LINPTR1); # POSITION START OF RANGE #
  5540. DELETEDONE=TRUE; # TO TRICK FIRST PASS #
  5541.  
  5542. IF LINPTR1 LQ LINPTR2 THEN
  5543. BEGIN
  5544. IF EXECNDX NQ EXECST"LOCATE" AND EXECNDX NQ EXECST"REPLACE"
  5545. THEN LINPTR2=MIN(LINPTR2,LINPTR1+LIMIT-1);
  5546. DELETCTL=1;
  5547. REGLINE[RNGTOPREG]=LINPTR1-1;
  5548. REGLINE[RNGBOTREG]=LINPTR2+1;
  5549. FOR DORNGCTR=1 STEP 1 WHILE LINPTR1 GR REGLINE[RNGTOPREG] AND
  5550. LINPTR1 LS REGLINE[RNGBOTREG] AND LINCTR LS LIMIT DO
  5551. BEGIN
  5552. IF NOT DELETEDONE THEN
  5553. BEGIN
  5554. LINPTR1=LINPTR1+1;
  5555. IF LINPTR1 LS REGLINE[RNGBOTREG] THEN FWDZ;
  5556. ELSE TEST;
  5557. END
  5558. ELSE IF DELETCTL EQ 0 THEN
  5559. BEGIN
  5560. LINCTR=LARGENUM;
  5561. TEST;
  5562. END
  5563. EXECONE(REGLINE[RNGTOPREG]+1,REGLINE[RNGBOTREG]-1);
  5564. END
  5565. IF DELETEDONE AND DELETCTL EQ 1 THEN BAKZ;
  5566. END
  5567. ELSE
  5568. BEGIN
  5569. IF EXECNDX NQ EXECST"LOCATE" AND EXECNDX NQ EXECST"REPLACE"
  5570. THEN LINPTR1=MAX(LINPTR1,LINPTR2-LIMIT+1);
  5571. DELETCTL=0;
  5572. REGLINE[RNGTOPREG]=LINPTR2-1;
  5573. REGLINE[RNGBOTREG]=LINPTR1+1;
  5574. FOR DORNGCTR=1 STEP 1 WHILE LINPTR1 GR REGLINE[RNGTOPREG] AND
  5575. LINPTR1 LS REGLINE[RNGBOTREG] AND LINCTR LS LIMIT DO
  5576. BEGIN
  5577. IF NOT DELETEDONE THEN
  5578. BEGIN
  5579. LINPTR1=LINPTR1-1;
  5580. IF LINPTR1 GR REGLINE[RNGTOPREG] THEN BAKZ;
  5581. ELSE TEST;
  5582. END
  5583. EXECONE(REGLINE[RNGBOTREG]-1,REGLINE[RNGTOPREG]+1);
  5584. END
  5585. END
  5586.  
  5587. IOEND # OF DORANGE #
  5588. PAGE # PROGRAM INTERPRETATION CONTROL #
  5589.  
  5590.  
  5591. CONTROL IFEQ SINGLE,1;
  5592.  
  5593.  
  5594. FUNC COMPARLIN(TEXTLIN,KEYWORD,ABBREV) B;
  5595. BEGIN
  5596. #
  5597. ** COMPARLIN - COMPARE INTERNAL LINE TO DISPLAY KEYWORD.
  5598. *
  5599. * COMPARLIN COMPARES A LINE IMAGE (INTERNAL CHARACTER SET)
  5600. * TO A KEYWORD (DISPLAY CODE). THE KEYWORD IS VARIABLE IN
  5601. * LENGTH UP TO TEN CHARACTERS. THE LINE MUST EXACTLY
  5602. * EQUAL THE KEYWORD IN LENGTH AND CONTENT, EXCEPT THAT THE
  5603. * CASE OF LETTERS DOES NOT MATTER.
  5604. *
  5605. * ENTRY TEXTLIN, KEYWORD - WHAT WE COMPARE.
  5606. * ABBREV - WHETHER ABBREVIATIONS ARE PERMISSIBLE.
  5607. *
  5608. * EXIT COMPARLIN - RESULT OF COMPARISON.
  5609. *
  5610. * CALLS LENGTH, DSPLCOD.
  5611. #
  5612. ARRAY TEXTLIN[0:99]; ITEM TEXTLINE;
  5613. ITEM KEYWORD;
  5614. ITEM ABBREV B;
  5615.  
  5616. ITEM TMP1, TMP2, TMP3, TMP4, TMP5, TMP6, TMP7, TMP8, BOOL B;
  5617.  
  5618. PROC CHECKWORD(LEN);
  5619. BEGIN
  5620. ITEM LEN;
  5621. # ENTRY - TMP1=KEYWORD POSITION (ALREADY SCANNED) #
  5622. # TMP2=TEXTLINE POSITION (NEEDS SCAN) #
  5623. # TMP3=LENGTH OF WORD - NOT USED HERE #
  5624. # LEN=HOW MANY CHARACTERS TO CHECK #
  5625. # EXIT - BOOL=RESULT OF COMPARE #
  5626. # TMP4=POSITION AT WHICH TEXTLINE HAD THE WORD #
  5627. # TMP5=LENGTH PARAMETER #
  5628. BOOL=FALSE;
  5629. TMP4=TMP2;
  5630. GETCHAR(TEXTLINE,TMP4,TMP5);
  5631. WHYLE TMP4 LS LENGTH(TEXTLIN) AND TMP5 EQ CBLANK DO
  5632. BEGIN # FIND START OF WORD #
  5633. TMP4=TMP4+1;
  5634. GETCHAR(TEXTLINE,TMP4,TMP5);
  5635. END
  5636. IF TMP4 GQ LENGTH(TEXTLIN) THEN RETURN; # NO WORDS AVAIL #
  5637. TMP5=TMP4+1;
  5638. GETCHAR(TEXTLINE,TMP5,TMP6);
  5639. WHYLE TMP6 NQ CBLANK AND TMP6 NQ CENDLINE DO
  5640. BEGIN # LOOK FOR END OF WORD #
  5641. TMP5=TMP5+1;
  5642. GETCHAR(TEXTLINE,TMP5,TMP6);
  5643. END
  5644. TMP5=TMP5-TMP4; # LENGTH OF WORD #
  5645. IF TMP5 GQ LEN THEN # WORD MIGHT MATCH #
  5646. BEGIN
  5647. FOR TMP6=0 STEP 1 UNTIL LEN-1 DO
  5648. BEGIN
  5649. GETCHAR(TEXTLINE,TMP4+TMP6,TMP7);
  5650. DSPLCOD(TMP7);
  5651. TMP8=C&lt;TMP1+TMP6,1>KEYWORD;
  5652. IF TMP7 NQ TMP8 THEN RETURN;
  5653. END
  5654. TMP5=LEN;
  5655. BOOL=TRUE;
  5656. END
  5657. END # OF CHECKWORD #
  5658.  
  5659.  
  5660. # MAIN COMPARLIN CODE STARTS HERE #
  5661.  
  5662. COMPARLIN=FALSE;
  5663.  
  5664. IF ABBREV THEN
  5665. BEGIN
  5666. TMP1=0; # KEYWORD POSITION #
  5667. TMP2=0; # TEXTLINE POSITION #
  5668. BOOL=FALSE;
  5669. WHYLE TMP1 LQ 9 DO
  5670. BEGIN
  5671. IF C&lt;TMP1,1>KEYWORD EQ " " OR C&lt;TMP1,1>KEYWORD EQ 0
  5672. THEN TMP1=TMP1+1; # KEEP LOOKING FOR WORD #
  5673. ELSE # WORD FOUND #
  5674. BEGIN
  5675. TMP3=TMP1+1; # END OF WORD #
  5676. WHYLE TMP3 LQ 9 AND C&lt;TMP3,1>KEYWORD NQ " "
  5677. AND C&lt;TMP3,1>KEYWORD NQ 0 DO TMP3=TMP3+1;
  5678. TMP3=TMP3-TMP1; # LENGTH OF WORD #
  5679. CHECKWORD(TMP3); # TEST ALL POSSIBLE ABBREV-S #
  5680. IF (NOT BOOL) AND (TMP3 GR 3) THEN CHECKWORD(3);
  5681. IF (NOT BOOL) AND (TMP3 GR 1) THEN CHECKWORD(1);
  5682. IF BOOL THEN # PREPARE TO CHECK NEXT WORD #
  5683. BEGIN
  5684. TMP1=TMP1+TMP3;
  5685. TMP2=TMP4+TMP5;
  5686. END
  5687. ELSE TMP1=10; # IMMEDIATE FAILURE #
  5688. END
  5689. END
  5690. IF BOOL THEN
  5691. BEGIN
  5692. GETCHAR(TEXTLINE,TMP2,TMP5);
  5693. WHYLE TMP5 EQ CBLANK DO # LOOK FOR EOL OR SURPLUS TEXT #
  5694. BEGIN
  5695. TMP2=TMP2+1;
  5696. GETCHAR(TEXTLINE,TMP2,TMP5);
  5697. END
  5698. IF TMP5 EQ CENDLINE THEN COMPARLIN=TRUE;
  5699. END
  5700. END
  5701. ELSE
  5702. BEGIN
  5703. TMP1=9;
  5704. BOOL=FALSE;
  5705. FOR TMP2=9 STEP -1 WHILE TMP2 GQ 0 AND NOT BOOL DO
  5706. BEGIN
  5707. IF C&lt;TMP2,1>KEYWORD EQ " " OR C&lt;TMP2,1>KEYWORD EQ 0
  5708. THEN TMP1=TMP2;
  5709. ELSE BOOL=TRUE;
  5710. END
  5711. IF TMP1 EQ LENGTH(TEXTLIN) THEN
  5712. BEGIN
  5713. FOR TMP2=0 STEP 1 UNTIL TMP1-1 DO
  5714. BEGIN
  5715. GETCHAR(TEXTLINE,TMP2,TMP3);
  5716. DSPLCOD(TMP3);
  5717. TMP4=C&lt;TMP2,1>KEYWORD;
  5718. IF TMP3 NQ TMP4 THEN RETURN;
  5719. END
  5720. COMPARLIN=TRUE;
  5721. END
  5722. END
  5723. END # OF COMPARLIN #
  5724.  
  5725.  
  5726. PROC GETPROCNXT;
  5727. BEGIN
  5728. #
  5729. ** GETPROCNXT - GET NEXT COMMAND LINE FROM PROCEDURE.
  5730. *
  5731. * ENTRY CURP(PROCCTL) - PREVIOUS PROCEDURE ADDRESS.
  5732. * BOTP(PROCCTL) - BOUNDS ON PROC FILE.
  5733. * PROCACTIVE - SHOULD BE TRUE.
  5734. *
  5735. * EXIT CMDLIN - NEW COMMAND LINE IF NOT END OF PROC.
  5736. * CURP(PROCCTL) - INCREMENTED.
  5737. * PROCACTIVE - FORCED FALSE IF END OF PROC.
  5738. * SCANPOS, TOKENPOS, KEYWDTYPE - RE-INITIALIZED.
  5739. *
  5740. * CALLS CLEARPROC, COMPARLIN, PUSH, POP, STARTCMD.
  5741. *
  5742. * USES P<LINEBUF> (RESTORED TO LOC(LIN)).
  5743. #
  5744. CURP(PROCCTL)=CURP(PROCCTL)+1;
  5745. IF CURP(PROCCTL) GQ BOTP(PROCCTL) THEN CLEARPROC;
  5746. ELSE
  5747. BEGIN
  5748. PUSH;
  5749. P&lt;LINEBUF>=LOC(CMDLIN);
  5750. POSZ(CURP(PROCCTL));
  5751. P&lt;LINEBUF>=LOC(LIN);
  5752. POP;
  5753. STARTCMD;
  5754. IF COMPARLIN(CMDLIN,EORCON,FALSE) THEN CLEARPROC;
  5755. IF COMPARLIN(CMDLIN,EOFCON,FALSE) THEN CLEARPROC;
  5756. EXPANDAT=0;
  5757. EXPANDCMDS;
  5758. END
  5759. END # OF GETPROCNXT #
  5760.  
  5761.  
  5762. PROC CLEARPROC;
  5763. BEGIN
  5764. #
  5765. ** CLEARPROC - GET OUT OF PROCEDURE EXECUTION MODE.
  5766. *
  5767. * EXIT PROCACTIVE - FALSE.
  5768. * CMDLIN - NULL.
  5769. *
  5770. * CALLS STARTCMD.
  5771. #
  5772. PROCACTIVE=FALSE;
  5773. CMDLINE[0]=NULLIN;
  5774. STARTCMD;
  5775. END # OF CLEARPROC #
  5776. CONTROL FI;
  5777. PAGE # SINGLE/MULTI CONNECTION #
  5778.  
  5779.  
  5780. CONTROL IFEQ SINGLE,1;
  5781.  
  5782. CONTROL IFEQ NEVERMULTI,1;
  5783. PROC CONNECT; BEGIN END
  5784. PROC PRECONNECT; BEGIN END
  5785. PROC POSTCONNECT; BEGIN END
  5786. CONTROL FI;
  5787.  
  5788. CONTROL IFEQ NEVERMULTI,0;
  5789.  
  5790.  
  5791. PROC PRECONNECT;
  5792. BEGIN
  5793. #
  5794. ** PRECONNECT - FIRST STEP IN CONNECTING TO MULTI-USER EDITOR.
  5795. *
  5796. * PRECONNECT DETERMINES WHETHER CONNECTION SHOULD BE ATTEMPTED.
  5797. * IF CONNECTION SHOULD PROCEED, PRECONNECT SIGNALS THIS
  5798. * WITH THE CONNECTED FLAG AND CHECKPOINTS THE WORKFILE.
  5799. * THE WORKFILE CARRIES THE SMFINCTL FLAG SO WE CAN TELL
  5800. * WHETHER SMFEX REACHES A NORMAL END OF SESSION, AS OPPOSED
  5801. * TO A RECOVERY SITUATION.
  5802. *
  5803. * ENTRY SINGLEONLY - WHETHER CONNECTION SHOULD PROCEED.
  5804. *
  5805. * EXIT CONNECTED - WHETHER CONNECTION SHOULD PROCEED.
  5806. * SMFINCTL - SET INTO WORKFILE IF CONNECTED.
  5807. * CMDLIN - NULLED OUT IF CONNECTED.
  5808. * WORKFILE CHECKPOINTED IF CONNECTED.
  5809. *
  5810. * CALLS CHECKIO, VDTEOO, TTSYNC, VDTCLO.
  5811. #
  5812. IF NOT SINGLEONLY THEN
  5813. BEGIN
  5814. CONNECTED=TRUE;
  5815. SMFINCTL=TRUE; # SO WE WILL KNOW IF RCVCRY #
  5816. IF SCREENMODE THEN VDTEOO;
  5817. ELSE TTSYNC;
  5818. VDTCLO(1);
  5819. CHECKIO; # DE-INTERLOCK FILE #
  5820. END
  5821. END # OF PRECONNECT #
  5822.  
  5823.  
  5824. PROC CONNECT;
  5825. BEGIN
  5826. #
  5827. ** CONNECT - ACTUAL ATTEMPT TO CONNECT TO MULTI.
  5828. *
  5829. * CONNECT ACTUALLY ATTEMPTS TO CONNECT TO THE MULTI-USER
  5830. * EDITING SUBSYSTEM, SMFEX. CONNECT SHOULD BE CALLED ONLY
  5831. * IF PRECONNECT RETURNED A POSITIVE RESULT. CONNECT FIRST
  5832. * FLUSHES ANY PENDING TERMINAL OUTPUT.
  5833. *
  5834. * ENTRY SCREENMODE - CONTROL MANNER OF OUTPUT FLUSH.
  5835. * FETFNT - NEGATIVE FIELD LENGTH ADDR OF WORKFILE.
  5836. * CONNECTED - SHOULD BE TRUE.
  5837. *
  5838. * EXIT CONNECTED - FORCED FALSE IF ATTEMPT FAILED.
  5839. *
  5840. * CALLS DISSJ, POSZ, RESUMIO, SYSREQ(TLX).
  5841. #
  5842. ARRAY XFRVECTOR;
  5843. BEGIN
  5844. ITEM XFRWORD;
  5845. ITEM XFRFNTR U(0,0,12)=[0];
  5846. ITEM XFRFNTS U(0,12,12)=[0];
  5847. ITEM XFRSSID U(0,24,12)=[SMFSSID];
  5848. ITEM XFRFILL U(0,36,12)=[0];
  5849. ITEM XFRSTAT U(0,48,11)=[0];
  5850. ITEM XFRCOMP U(0,59,1)=[0];
  5851. END
  5852.  
  5853. XFRFNTS=FETFNT;
  5854. XFRCOMP=0;
  5855. DISSJ(3); # ENABLE SSJ= #
  5856. SYSREQ("TLX",1,LOC(XFRWORD),TLXFUNC*64);
  5857. DISSJ(2); # DISABLE SSJ= #
  5858. IF XFRSTAT NQ 0 THEN
  5859. BEGIN
  5860. RESUMIO; # RE-INTERLOCK FILE #
  5861. POSZ(SAVECURL);
  5862. CONNECTED=FALSE; # INDICATE NO CONNECT OCCURRED #
  5863. SINGLEONLY=TRUE;
  5864. END
  5865. END # OF CONNECT #
  5866.  
  5867.  
  5868. PROC POSTCONNECT;
  5869. # TITLE POSTCONNECT - VERIFY REVIVAL OF SINGLE-USER EDITOR. #
  5870.  
  5871. BEGIN # POSTCONNECT #
  5872.  
  5873. #
  5874. ** POSTCONNECT - VERIFY REVIVAL OF SINGLE-USER EDITOR.
  5875. *
  5876. * POSTCONNECT REVIVES THE SINGLE-USER EDITOR AFTER AN
  5877. * ATTEMPT TO CONNECT TO THE MULTI-USER VERSION OF THE
  5878. * FULL SCREEN EDITOR. IF THE CONNECTION ATTEMPT WAS NOT
  5879. * SUCCESSFUL, THEN POSTCONNECT SERVES ONLY TO INDICATE
  5880. * THAT NO FUTURE CONNECTIONS SHOULD BE ATTEMPTED. FOR A
  5881. * NORMAL CONNECTION, POSTCONNECT RESUMES WORKFILE CONTENT
  5882. * INTO WORK STORAGE AND INITIALIZES THE SYNTAX SCANNER TO
  5883. * USE THE COMMAND STRING RETURNED BY SMFEX.
  5884. *
  5885. * PROC POSTCONNECT
  5886. *
  5887. * EXIT CONNECTED - FALSE.
  5888. * PAINTAGAIN - FORCED TRUE IF NO CONNECTION.
  5889. * SINGLEONLY - FORCED TRUE IF NO CONNECTION.
  5890. * SCANPOS - SET ACCORDING TO START OF COMMAND.
  5891. * ENTIRE DATA SEGMENT AND ARRAY SEGMENT - PER SMFEX.
  5892. *
  5893. * CALLS FATAL, PAINTALL, POSZ, RESUMIO, STARTCMD.
  5894. #
  5895.  
  5896. RESUMIO; # GET SMF RESULT AND INTERLOCK #
  5897. IF NOT IORESUMED THEN
  5898. BEGIN
  5899. FATAL(" WORKFILE IS NOT IN A RESUMEABLE STATE.$");
  5900. END
  5901. CONNECTED=FALSE;
  5902. SCANPOS=CMDMARKER; # LOOK BACK TO CMD START #
  5903. BUILDCIO=0;
  5904. IF FORCENULL OR SMFINCTL THEN
  5905. BEGIN
  5906. FORCENULL=FALSE;
  5907. SMFINCTL=FALSE;
  5908. SINGLEONLY=TRUE;
  5909. CMDLINE[0]=NULLIN;
  5910. ERRSTRING="SYSTEM INTERRUPT, PROCEED NOW$";
  5911. STARTCMD;
  5912. PAINTALL;
  5913. PAINTAGAIN=TRUE; # SET PAINT AGAIN FLAG #
  5914. END
  5915. POSZ(SAVECURL);
  5916.  
  5917. END # POSTCONNECT #
  5918.  
  5919. CONTROL FI;
  5920. CONTROL FI;
  5921. PAGE # UTILITIES ONLY USED BY PROCESS #
  5922.  
  5923.  
  5924. PROC ERRJUMP(STR);
  5925. BEGIN
  5926. #
  5927. ** ERRJUMP - ISSUE ERROR MESSAGE AND JUMP TO FRESH COMMANDS.
  5928. *
  5929. * ERRJUMP PROCESSES ERROR MESSAGES FOR SYNTAX ERRORS IN
  5930. * COMMAND PROCESSORS. ERRJUMP THEN IGNORES THE SUBROUTINE
  5931. * CALLING CHAIN AND BRANCHES DIRECTLY TO THE MAIN COMMAND
  5932. * SEQUENCING LOOP. THUS, ERRJUMP CAN ONLY BE CALLED BY
  5933. * ROUTINES WHICH WERE THEMSELVES CALLED BY THE MAIN COMMAND
  5934. * SEQUENCING LOOP. NOTE THAT IN THE MULTI-USER VERSION OF
  5935. * THE EDITOR, THE CODE AT LABEL "PRERROR" WILL BE EXPECTED
  5936. * TO RESET ALL STRUCTURES HAVING TO DO WITH REENTRANT
  5937. * SUBROUTINE CALLING CHAINS.
  5938. *
  5939. * ENTRY STR - MESSAGE TO BE PRINTED.
  5940. * SCREENMODE - MODE.
  5941. * TOKENPOS - WHERE ERROR WAS DETECTED.
  5942. * COMMANDROW - SETUP.
  5943. * PROCACTIVE - MODE.
  5944. * CURP(PROCCTL) - WHERE WE ARE IN PROC IF ANY.
  5945. * CURPROCNAM - NAME OF CURRENT PROC.
  5946. * USRSPLTSZ - SETUP.
  5947. * CMDLIN - BAD COMMAND TEXT.
  5948. *
  5949. * EXIT VIA LABEL "PRERROR".
  5950. * ERRSTRING - COPY OF THE MESSAGE.
  5951. * ERRCURSOR, YCURSOR - POINT TO SYNTAX ERROR.
  5952. * SCREEN FORMATTED TO DISPLAY SOURCE OF ERROR.
  5953. * CMDLIN - NULLED OUT UNDER CERTAIN CONDITIONS.
  5954. * CURFILE, CURSPLIT - MAY BE OPENED INTO PROC.
  5955. *
  5956. * CALLS OPENFILE, POSZ, SETUPSCREEN, TTBRK, TTLIN, TTSTR,
  5957. * CONVOUT, VDTWTC.
  5958. *
  5959. * USES TMPLIN, FILNUM, GETPARM, CHARPARM, CURF(2),
  5960. * CURFILE, CURSPLIT, CURRENT, LIN, LINCTR.
  5961. #
  5962. ITEM STR C(40);
  5963. XREF LABEL PRERROR;
  5964. ERRSTRING=STR;
  5965. ERRCURSOR=TOKENPOS;
  5966. IF SCREENMODE THEN
  5967. BEGIN
  5968. IF TOKENPOS GQ 0 THEN YCURSOR=COMMANDROW;
  5969. CONTROL IFEQ SINGLE,1;
  5970. IF PROCACTIVE THEN
  5971. BEGIN
  5972. READNAM=CURPROCNAM;
  5973. FILNUM=2;
  5974. GETPARM=0;
  5975. CHARPARM=0;
  5976. OPENFILE;
  5977. CURF(2)=CURP(PROCCTL);
  5978. POSZ(CURF(2));
  5979. CURFILE=2;
  5980. CURSPLIT=2;
  5981. SETUPSCREEN(1,2,USRSPLTSZ);
  5982. YCURSOR=LTOY(CURRENT,2);
  5983. CMDLINE[0]=NULLIN;
  5984. END
  5985. CONTROL FI;
  5986. END
  5987. ELSE # LINE MODE #
  5988. BEGIN
  5989. CONTROL IFEQ SINGLE,1;
  5990. IF PROCACTIVE THEN
  5991. BEGIN
  5992. IF INTERACT THEN
  5993. BEGIN # IF INTERACTIVE PROCEDURE ERROR #
  5994. TTBRK;
  5995. TTLIN("ERROR IN THIS PROCEDURE LINE: $");
  5996. TTSTR(" $");
  5997. TTSYNC;
  5998. CONVOUT(CMDLIN,2);
  5999. VDTWTC(TMPLIN);
  6000. END
  6001. END
  6002. CONTROL FI;
  6003. CMDLINE[0]=NULLIN;
  6004. IF C&lt;0,2>ERRSTRING NQ " $" THEN
  6005. BEGIN
  6006. TTBRK;
  6007. FOR LINCTR=1 STEP 1 UNTIL TOKENPOS+3 DO TTSTR(BLANKWRD);
  6008. TTSTR("!$");
  6009. TTBRK;
  6010. CONTROL IFEQ SINGLE,1;
  6011. IF NOT INTERACT AND PROCACTIVE THEN
  6012. BEGIN # IF BATCH PROCEDURE ERROR #
  6013. TTLIN(" ERROR IN PROCEDURE LINE ABOVE WAS: $");
  6014. END
  6015. CONTROL FI;
  6016. END
  6017. END
  6018. GOTO PRERROR;
  6019. END # OF ERRJUMP #
  6020.  
  6021.  
  6022. PROC VFYLOCK;
  6023. BEGIN
  6024. #
  6025. ** VFYLOCK - VERIFY PERMISSION TO CHANGE CURRENT FILE.
  6026. *
  6027. * ENTRY CURFILE - CURRENT FILE.
  6028. * LOCKED[CURFILE] - TRUE IF READ-ONLY FILE.
  6029. *
  6030. * EXIT VIA ERRJUMP IF NOT VALIDATED.
  6031. #
  6032. IF LOCKED[CURFILE] NQ 0 THEN
  6033. BEGIN
  6034. ERRJUMP("CANNOT CHANGE READ-ONLY FILE$");
  6035. END
  6036. END # OF VFYLOCK #
  6037. PAGE # FILE ASSIGNMENT HISTORY #
  6038.  
  6039.  
  6040. PROC PUSHBACK;
  6041. BEGIN
  6042. #
  6043. ** PUSHBACK - PUSH CURRENT FILES AND SPLITS ONTO BACKSTACK.
  6044. *
  6045. * ENTRY FILENAM[1-2] CONTAIN CURRENT OPEN FILES.
  6046. * NUMROWS[2] HAS SPLITSIZE.
  6047. *
  6048. * EXIT BACKIN (AND MAYBE BACKOUT) INCREMENTED.
  6049. * BACKSTACK[BACKIN] CONTAINS FILES,SPLITS.
  6050. *
  6051. * CALLS INCR(INTERNAL).
  6052. #
  6053.  
  6054. PROC INCR(I);
  6055. BEGIN
  6056. # INCR - INCREMENT BACK POINTER #
  6057. ITEM I;
  6058. I=I+1;
  6059. IF I GR BACKMAX THEN I=0;
  6060. END # OF INCR #
  6061.  
  6062.  
  6063. INCR(BACKIN);
  6064. BACKFIL1[BACKIN]=FDLF(1);
  6065. BACKFIL2[BACKIN]=FDLF(2);
  6066. BACKSPL2[BACKIN]=SPLITFILE[2];
  6067. BACKSPLN[BACKIN]=NUMROWS[2];
  6068. IF BACKIN EQ BACKOUT THEN INCR(BACKOUT);
  6069.  
  6070. END # OF PUSHBACK #
  6071.  
  6072.  
  6073. FUNC SAMEBACK B;
  6074. BEGIN
  6075. #
  6076. ** SAMEBACK - TEST WHETHER FILES/SPLITS CHANGED.
  6077. *
  6078. * SAMEBACK ALLOWS THE CALLER TO KNOW WHETHER THE FILE
  6079. * BRACKETS HAVE CHANGED IN FILE CHOICE OR IN SPLIT
  6080. * DISPLAY DIMENSIONS, SINCE THE LAST CALL TO PUSHBACK.
  6081. *
  6082. * ENTRY FILENAM[1-2], SPLITFILE[2], NUMROWS[2] - SETUP.
  6083. * BACKIN - AS LEFT BY PUSHBACK.
  6084. * BACKSTACK[BACKIN] - AS LEFT BY PUSHBACK.
  6085. *
  6086. * EXIT SAMEBACK - RESULT OF COMPARISON.
  6087. #
  6088. SAMEBACK=TRUE;
  6089. IF BACKFIL1[BACKIN] NQ FDLF(1)
  6090. OR BACKFIL2[BACKIN] NQ FDLF(2)
  6091. OR BACKSPL2[BACKIN] NQ SPLITFILE[2]
  6092. OR BACKSPLN[BACKIN] NQ NUMROWS[2] THEN SAMEBACK=FALSE;
  6093. END # OF SAMEBACK #
  6094.  
  6095.  
  6096. PROC DECRBACK;
  6097. BEGIN
  6098. #
  6099. ** DECRBACK - DECREMENT FILE SELECTION QUEUE.
  6100. *
  6101. * DECRBACK BACKS UP THE CIRCULAR QUEUE OF FILE SELECTIONS.
  6102. *
  6103. * ENTRY BACKIN - POINTER TO BE BACKED AROUND CIRCLE.
  6104. *
  6105. * EXIT BACKIN - DECREMENTED OR RECIRCULATED.
  6106. #
  6107. IF BACKIN NQ BACKOUT THEN
  6108. BEGIN
  6109. BACKIN=BACKIN-1;
  6110. IF BACKIN LS 0 THEN BACKIN=BACKMAX;
  6111. END
  6112. END # OF DECRBACK #
  6113.  
  6114. PROC RESTSAVPOS;
  6115. IOBEGIN(RESTSAVPOS)
  6116. #
  6117. ** RESTSAVPOS - RESTORE SAVED POSITION.
  6118. *
  6119. * RESTSAVPOS ACCOMPLISHES THE FILE SWITCHING OF THE
  6120. * BACK DIRECTIVE EXCHANGE OPERATION.
  6121. * IT IS CALLED TO SET UP THE FILE POSITION IN EFFECT
  6122. * WHEN THE LAST BACK OR DATA DIRECTIVE WAS EXECUTED.
  6123. *
  6124. * ENTRY FILNUM - INDICATES WHICH SPLIT IS BEING ACTIVATED.
  6125. * BKSPLIT2[BACKIND] - INDICATES SINGLE FILE IS ACTIVE.
  6126. * CURSPLIT - RECENT HISTORY OF FILE SELECTION.
  6127. * REGSTCLIN(BCKCURLIN) - REGISTER STACK LINE POINTER.
  6128. *
  6129. * EXIT DESIGNATED FILE OPENED AND POSSIBLY POINTING
  6130. * TO THE EXACT WORKING LINE.
  6131. *
  6132. * CALLS OPENFILE, POSZ, SCANFDL.
  6133. *
  6134. * USES CHARPARM, CURF(FILNUM), CURRENT, GETPARM,
  6135. * LINCTR, READNAM.
  6136. #
  6137.  
  6138. CHARPARM = 0;
  6139. GETPARM = 0;
  6140. IF (FILNUM EQ 1) THEN
  6141. POSZ(BKFDLFF1[BACKIND]);
  6142. ELSE
  6143. POSZ(BKFDLFF2[BACKIND]);
  6144. SCANFDL(READNAM); # RETRIEVE FILE NAME FROM FDL #
  6145. OPENFILE; # ACCESS THE FILE #
  6146.  
  6147. IOEND # OF RESTSAVPOS #
  6148.  
  6149. PROC EXCHSAVPOS;
  6150.  
  6151. IOBEGIN(EXCHSAVPOS)
  6152. #
  6153. ** EXCHSAVPOS - EXCHANGE CURRENT POSITION WITH SAVED POSITION.
  6154. * EXCHSAVPOS COMPRISES THE FUNCTIONAL OPERATION OF THE
  6155. * BACK DIRECTIVE EXCHANGE OPERATION.
  6156. * IT IS CALLED BY THE BACK DIRECTIVE TO ACCOMPLISH THE
  6157. * SWITCH BETWEEN THE CURRENT POSITION ON THE SCREEN
  6158. * WITH THE POSITION IN EFFECT AFTER THE MOST RECENT BACK
  6159. * OR EDIT DIRECTIVE.
  6160. * EXCHSAVPOS FIRST SAVES THE CURRENT FILE(S), SPLIT LOGIC,
  6161. * ACTIVE LINE, AND CURSOR POSITION IN TEMPORARY STORAGE.
  6162. * THE PREVIOUSLY STORED POSITION IS THEN RECALLED, AND THE
  6163. * TEMPORARY VALUES ARE THEN SAVED IN PERMANENT STORAGE.
  6164. *
  6165. * EXIT BACKSTORE ARRAY CONTAINS NEW POSITION.
  6166. * FILE(S) AND SCREEN UPDATED TO REFLECT PREVIOUSLY
  6167. * STORED POSITION.
  6168. *
  6169. * CALLS POP, PUSH, RESTSAVPOS.
  6170. *
  6171. * USES BACKSTORE, CURSPLIT, FILNUM, LINPTR1, LINPTR2,
  6172. * NEWCURSOR, REGSTCLIN, TEMPCURLIN, YCURSOR.
  6173. *
  6174. #
  6175. LINPTR1 = 0;
  6176. LINPTR2 = 0;
  6177.  
  6178. # PLACE CURRENT SCREEN POSITION INTO TEMPORARY STORAGE. #
  6179.  
  6180. PUSH;
  6181. BKFDLFF1[TEMPIND] = FDLF(1);
  6182. BKFDLFF2[TEMPIND] = FDLF(2);
  6183. BKSPLIT2[TEMPIND] = SPLITFILE[2];
  6184. BKNROWS1[TEMPIND] = NUMROWS[1];
  6185. BKNROWS2[TEMPIND] = NUMROWS[2];
  6186. BKWHCHSP[TEMPIND] = CURSPLIT;
  6187. IF ( CURSPLIT EQ 1 ) THEN
  6188. TEMPCURLIN = CURF(1);
  6189. ELSE
  6190. TEMPCURLIN = CURF(2);
  6191. BKCURSOR[TEMPIND] = CURCURSOR;
  6192. POP;
  6193.  
  6194. # RETRIEVE STORED POSITION. #
  6195.  
  6196. CURSPLIT = BKWHCHSP[BACKIND];
  6197. IF (BKSPLIT2[BACKIND] EQ 0) THEN # SINGLE FILE, NO SPLIT #
  6198. BEGIN
  6199. FILNUM = 1;
  6200. RESTSAVPOS; # RESTORE SINGLE FILE #
  6201. END
  6202. ELSE
  6203. BEGIN # SPLIT FILES #
  6204. IF (CURSPLIT NQ 1) THEN
  6205. BEGIN # TOP FIRST, THEN BOTTOM #
  6206. FILNUM = 1;
  6207. RESTSAVPOS;
  6208. FILNUM = 2;
  6209. RESTSAVPOS; # RESTORE SPLIT FILE #
  6210. END
  6211. ELSE
  6212. BEGIN # BOTTOM FIRST, THEN TOP #
  6213. FILNUM = 2;
  6214. RESTSAVPOS; # RESTORE SPLIT FILE #
  6215. FILNUM = 1;
  6216. RESTSAVPOS; # RESTORE TOP FILE #
  6217. END
  6218. END
  6219. LINPTR1 = BKSPLIT2[BACKIND];
  6220. LINPTR2 = BKNROWS2[BACKIND];
  6221. YCURSOR = -1;
  6222. NEWCURSOR = BKCURSOR[BACKIND];
  6223.  
  6224. # MOVE CURRENT POSITION FROM TEMPORARY TO PERMANENT STORAGE. #
  6225.  
  6226. BKFDLFF1[BACKIND] = BKFDLFF1[TEMPIND];
  6227. BKFDLFF2[BACKIND] = BKFDLFF2[TEMPIND];
  6228. BKSPLIT2[BACKIND] = BKSPLIT2[TEMPIND];
  6229. BKNROWS1[BACKIND] = BKNROWS1[TEMPIND];
  6230. BKNROWS2[BACKIND] = BKNROWS2[TEMPIND];
  6231. BKWHCHSP[BACKIND] = BKWHCHSP[TEMPIND];
  6232. REGSTCLIN(BCKCURLIN) = TEMPCURLIN;
  6233. BKCURSOR[BACKIND] = BKCURSOR[TEMPIND];
  6234.  
  6235. IOEND # OF EXCHSAVPOS #
  6236.  
  6237. PROC STORCURPOS;
  6238.  
  6239. IOBEGIN(STORCURPOS)
  6240. #
  6241. ** STORCURPOS - STORE CURRENT POSITION.
  6242. *
  6243. * STORCURPOS PLACES THE CURRENT SCREEN AND FILE POSITIONS
  6244. * INTO PERMANENT STORAGE, FOR LATER RECALL BY THE BACK
  6245. * DIRECTIVE. A FLAG IS SET TO INDICATE THAT THE STORAGE
  6246. * HAS TAKEN PLACE.
  6247. *
  6248. * EXIT CURRENT FILE(S) AND SCREEN POSITION STORED IN
  6249. * BACKSTORE.
  6250. *
  6251. * CALLS POP, PUSH.
  6252. *
  6253. * USES BACKSTORE[BACKIND], REGSTCLIN.
  6254. *
  6255. #
  6256.  
  6257. # STORE CURRENT POSITION FOR LATER RECALL BY BACK DIRECTIVE.#
  6258.  
  6259. PUSH;
  6260. BKFDLFF1[BACKIND] = FDLF(1);
  6261. BKFDLFF2[BACKIND] = FDLF(2);
  6262. BKSPLIT2[BACKIND] = SPLITFILE[2];
  6263. BKNROWS1[BACKIND] = NUMROWS[1];
  6264. BKNROWS2[BACKIND] = NUMROWS[2];
  6265. BKWHCHSP[BACKIND] = CURSPLIT;
  6266. IF ( CURSPLIT EQ 1 ) THEN
  6267. REGSTCLIN(BCKCURLIN) = CURF(1);
  6268. ELSE
  6269. REGSTCLIN(BCKCURLIN) = CURF(2);
  6270. BKCURSOR[BACKIND] = CURCURSOR;
  6271. POP;
  6272.  
  6273. IOEND # OF STORCURPOS #
  6274.  
  6275.  
  6276. PROC DOBACK;
  6277. IOBEGIN(DOBACK)
  6278. #
  6279. ** DOBACK - REVERT TO EARLIER FILE SELECTION.
  6280. *
  6281. * DOBACK CONSTITUTES THE ESSENTIAL FUNCTION OF THE BACK
  6282. * COMMAND, WHICH IS TO CHANGE THE EDITORS SELECTION OF
  6283. * ONE OR TWO OPEN FILE BRACKETS TO THE SELECTION IN
  6284. * EFFECT ONE CHRONOLOGICAL UNIT EARLIER.
  6285. *
  6286. * ENTRY BACKIN, BACKOUT - CIRCULAR POINTERS FOR QUEUE.
  6287. * BACKSTACK - RECENT HISTORY OF FILE SELECTION.
  6288. *
  6289. * EXIT ONE OR BOTH FILE BRACKETS OPENED.
  6290. * BACKIN - CIRCULARLY DECREMENTED.
  6291. * LINPTR1, LINPTR2 - INDICATE SCREEN FORMATTING.
  6292. *
  6293. * CALLS PADNAME, OPENFILE, DECRBACK, SCANFDL.
  6294. *
  6295. * USES READNAM, FILNUM, CHARPARM, GETPARM.
  6296. #
  6297. LINPTR1=0;
  6298. LINPTR2=0;
  6299. DECRBACK;
  6300. IF BACKIN NQ BACKOUT THEN
  6301. BEGIN
  6302. POSZ(BACKFIL1[BACKIN]);
  6303. SCANFDL(READNAM);
  6304. FILNUM=1;
  6305. CHARPARM=0;
  6306. GETPARM=0;
  6307. OPENFILE;
  6308. IF BACKSPL2[BACKIN] NQ 0 THEN
  6309. BEGIN
  6310. POSZ(BACKFIL2[BACKIN]);
  6311. SCANFDL(READNAM);
  6312. FILNUM=2;
  6313. OPENFILE;
  6314. END
  6315. LINPTR1=BACKSPL2[BACKIN];
  6316. LINPTR2=BACKSPLN[BACKIN];
  6317. DECRBACK;
  6318. END
  6319. IOEND # OF DOBACK #
  6320.  
  6321.  
  6322. PROC MAKENONTRIV;
  6323. IOBEGIN(MAKENONTRIV)
  6324. #
  6325. * MAKENONTRIV - MAKE FILE SELECTION NON-TRIVIAL.
  6326. *
  6327. * MAKENONTRIV IS RESPONSIBLE TO TRY TO AVOID SHOWING THE
  6328. * THE USER ANY DISCARDED FILE IMAGES, WHICH HAVE FILE NAMES
  6329. * OF ZZZNULL. THIS IS DONE BY CHECKING FOR THAT RESERVED
  6330. * FILE NAME, AND WHEN IT APPEARS, THE ALGORITHM ATTEMPTS TO
  6331. * SELECT A BETTER FILE USING THE "LAST NON-TRIVIAL FILE CLOSED"
  6332. * INFORMATION WHICH WAS MAINTAINED BY THE CLOSEFILE ROUTINE.
  6333. *
  6334. * ENTRY FILENAM[1-2] - CURRENT FILE NAMES.
  6335. * FILEFILE[2 - WHETHER SECOND FILE BRACKET ACTIVE.
  6336. * NONTRIVFILE[ALL] - RECENT VALID FILES.
  6337. *
  6338. * EXIT ONE OR BOTH FILE IMAGES POSSIBLY RE-OPENED.
  6339. *
  6340. * CALLS OPENFILE, SCANFDL, PICKFILE(INTERNAL), POSZ.
  6341. *
  6342. * USES READNAM, FILNUM, GETPARM, CHARPARM, LINENO.
  6343. #
  6344.  
  6345. PROC PICKFILE;
  6346. IOBEGIN(PICKFILE)
  6347. #
  6348. * PICKFILE - INTERNAL ALGORITHM FOR MAKENONTRIV.
  6349. *
  6350. * NOTE SEE HEADER DOCUMENTATION FOR MAKENONTRIV.
  6351. #
  6352. POSZ(LINENO);
  6353. SCANFDL(READNAM);
  6354. GETPARM=0;
  6355. CHARPARM=0;
  6356. OPENFILE;
  6357. IF FILNUM EQ CURFILE AND NOT SCREENMODE THEN
  6358. BEGIN
  6359. CONTROL IFEQ SINGLE,1;
  6360. IF NOT INTERACT THEN TTSTR(" $");
  6361. CONTROL FI;
  6362. TTSTR("EDIT: $");
  6363. TTLFN(FILENAM[FILNUM]);
  6364. TTBRK;
  6365. END
  6366. IOEND # OF PICKFILE #
  6367.  
  6368.  
  6369. # MAKENONTRIV MAIN ALGORITHM STARTS HERE #
  6370.  
  6371. PUSHTEMP;
  6372. IF SPLITFILE[2] NQ 0 AND FILENAM[2] EQ "ZZZNULL" THEN
  6373. BEGIN
  6374. FILNUM=2;
  6375. LINENO=FDLF(2);
  6376. IF FILENAM[1] NQ "ZZZNULL" THEN LINENO=FDLF(1);
  6377. ELSE
  6378. BEGIN
  6379. FOR TEMP=4 STEP -1 UNTIL 1 DO
  6380. BEGIN
  6381. IF NONTRIVFILE[2,TEMP] NQ 0 THEN LINENO=NONTRIVFILE[2,TEMP];
  6382. END
  6383. END
  6384. PICKFILE;
  6385. END
  6386. IF FILENAM[1] EQ "ZZZNULL" THEN
  6387. BEGIN
  6388. FILNUM=1;
  6389. LINENO=FDLF(1);
  6390. IF SPLITFILE[2] NQ 0 AND FILENAM[2] NQ "ZZZNULL"
  6391. THEN LINENO=FDLF(2);
  6392. ELSE
  6393. BEGIN
  6394. FOR TEMP=4 STEP -1 UNTIL 1 DO
  6395. BEGIN
  6396. IF NONTRIVFILE[1,TEMP] NQ 0 THEN LINENO=NONTRIVFILE[1,TEMP];
  6397. END
  6398. END
  6399. PICKFILE;
  6400. END
  6401. POPTEMP;
  6402. IOEND # OF MAKENONTRIV #
  6403. PAGE # GLOBAL PROMPTING #
  6404.  
  6405.  
  6406. PROC CHECKGLOBAL;
  6407. BEGIN
  6408. #
  6409. ** CHECKGLOBAL - SEE IF GLOBAL SEARCH/CHANGE IN EFFECT.
  6410. *
  6411. * CHECKGLOBAL TESTS WHETHER THE PROMPTING FLAG SHOULD BE SET
  6412. * FOR GLOBAL LOCATE/CHANGE MENU PROMPTS. THE DECISION
  6413. * REQUIRES SCREEN MODE, LARGE LIMIT IN THE COMMAND RANGE,
  6414. * LACK OF QUIET MODE, LACK OF COMMAND PROCEDURE, AT LEAST ONE
  6415. * RANGE BOUNDARY OFF-SCREEN.
  6416. *
  6417. * ENTRY LIMIT, SCREENMODE, DONTPRINT - MODES.
  6418. * LINPTR1, LINPTR2 - RANGE BOUNDS.
  6419. * CURSPLIT, TOPS(CURSPLIT), BOTS(CURSPLIT) - BOUNDS.
  6420. *
  6421. * EXIT PROMPTING - FORCED TRUE IF RIGHT CONDITIONS.
  6422. * ROWSUSED - FORCED ZERO SAME CONDITIONS.
  6423. #
  6424. IF LIMIT GR 1
  6425. AND SCREENMODE
  6426. AND ( NOT DONTPRINT )
  6427. AND ( LINPTR1 LQ TOPS(CURSPLIT)
  6428. OR LINPTR1 GQ BOTS(CURSPLIT)
  6429. OR LINPTR2 LQ TOPS(CURSPLIT)
  6430. OR LINPTR2 GQ BOTS(CURSPLIT)
  6431. OR (LINPTR1 EQ TOPF(CURFILE)+1 AND LINPTR2 EQ BOTF(CURFILE)-1) )
  6432. THEN
  6433. BEGIN
  6434. PROMPTING=TRUE;
  6435. ROWSUSED=0;
  6436. END
  6437. END # OF CHECKGLOBAL #
  6438.  
  6439.  
  6440. PROC LASTGLOBAL;
  6441. IOBEGIN(LASTGLOBAL)
  6442. #
  6443. ** LASTGLOBAL - DETERMINE IF LAST ITERATION OF CHANGE.
  6444. *
  6445. * LASTGLOBAL DETERMINES WHETHER A RECENTLY COMPLETED
  6446. * ALTER OR REPLACE COMMAND NEEDS ONE LAST GLOBAL CHANGE
  6447. * MENU DISPLAY.
  6448. *
  6449. * ENTRY PROMPTING - WHETHER IN GLOBVAL DISPLAY MODE.
  6450. * ROWSUSED - HOW MANY MENU ITEMS PENDING USER PROMPT.
  6451. *
  6452. * EXIT LINCTR - POSSIBLY LARGENUM.
  6453. * CMDLIN - POSSIBLY CONTAINS UNDO COMMAND.
  6454. *
  6455. * CALLS GLOBALCHANGE.
  6456. #
  6457. IF PROMPTING THEN
  6458. BEGIN
  6459. LINCTR=LARGENUM; # FOR FINAL PROMPT #
  6460. IF ROWSUSED NQ 0 THEN GLOBALCHANGE;
  6461. END
  6462. IOEND # OF LASTGLOBAL #
  6463.  
  6464.  
  6465. PROC ASKUSER(STR1,STR2);
  6466. IOBEGIN(ASKUSER);
  6467. #
  6468. ** ASKUSER - ASK QUESTION EITHER SCREEN OR LINE.
  6469. *
  6470. * ASKUSER IS ABLE TO INQUIRE OF THE USER FOR EXTRA INSTRUCTIONS
  6471. * USING EITHER THE SCREEN DISPLAY OR BY PROMPTING ON A LINE
  6472. * MODE TERMINAL.
  6473. *
  6474. * ENTRY STR1 - PROMPT STRING FOR SCREEN DEVICE.
  6475. * STR2 - PROMPT STRING FOR LINE DEVICE.
  6476. * SCREENMODE - WHICH MODE IS IN EFFECT.
  6477. * COMMANDROW - WHERE TO PUT STR1.
  6478. * CURFILE, ASCII[CURFILE] - LOWERCASE SUPPRESSION.
  6479. *
  6480. * EXIT TTYLIN - USER'S REPLY.
  6481. * PROMPTING - FORCED FALSE ON RETURN.
  6482. * ERRSTRING - FORCED BLANK ON RETURN.
  6483. * ROWPAINT[COMMANDROW] - FORCED TRUE.
  6484. * FOUND - FALSE FOR FUNCTION KEY COMMAND OVERRIDE.
  6485. * ESCAPE - TRUE FOR FUNCTION OVERRIDE.
  6486. * CMDLIN - IF OVERRIDE, FUNCTION COMMAND.
  6487. * SCANPOS, TOKENPOS - ZEROED FOR OVERRIDE.
  6488. *
  6489. * CALLS COPYLIN, PUSH, PAINTSCREEN, DOSCREEN, POP, STARTCMD,
  6490. * EXCHWD, TTSTR, PROMPT, CONVIN, TRIM, SQUELCH,
  6491. * PUSHTEMP, POPTEMP.
  6492. *
  6493. * USES TEMP, TMPLIN, XCURSOR, YCURSOR.
  6494. #
  6495. ITEM STR1 C(80);
  6496. ITEM STR2 C(10);
  6497. CONTROL IFEQ SINGLE,1;
  6498. ARRAY CMDTEMP[0:BUFWID]; # SAVE COMMAND LINE #
  6499. BEGIN
  6500. ITEM CMDLINSAVE = [BUFWIDP1(NULLIN)];
  6501. END
  6502. CONTROL FI;
  6503.  
  6504. IF SCREENMODE THEN
  6505. BEGIN
  6506. CONTROL IFEQ SINGLE,1;
  6507. COPYLIN(CMDLIN,CMDTEMP); # SAVE #
  6508. CONTROL FI;
  6509. CONTROL IFEQ MULTI,1;
  6510. COPYLIN(CMDLIN,TTYLIN); # SAVE #
  6511. CONTROL FI;
  6512. CMDLINE[0]=NULLIN;
  6513. PUSH;
  6514. PUSHTEMP;
  6515. TEMP=CURCURSOR;
  6516. IF ERRSTRING NQ " $" AND ERRSTRING NQ STR1 THEN
  6517. BEGIN # IF UNIQUE ERRSTRING PRESENT #
  6518. XCURSOR = 0; # MERGE WITH PROMPT #
  6519. YCURSOR = 0;
  6520. WHYLE C&lt;XCURSOR,1>ERRSTRING NQ "$" DO XCURSOR = XCURSOR + 1;
  6521. C&lt;XCURSOR,2>ERRSTRING = ", ";
  6522. XCURSOR = XCURSOR + 2;
  6523. WHYLE XCURSOR LQ 77 AND C&lt;YCURSOR,1>STR1 NQ "$" DO
  6524. BEGIN
  6525. C&lt;XCURSOR,1>ERRSTRING = C&lt;YCURSOR,1>STR1;
  6526. XCURSOR = XCURSOR + 1;
  6527. YCURSOR = YCURSOR + 1;
  6528. END
  6529. C&lt;XCURSOR,1>ERRSTRING = "$";
  6530. END
  6531. ELSE
  6532. BEGIN # NO UNIQUE ERRSTRING YET #
  6533. ERRSTRING = STR1; # SET TO PROMPT #
  6534. END
  6535. XCURSOR=0;
  6536. YCURSOR=COMMANDROW;
  6537. PROMPTING=TRUE; # RESTRICT KEYBOARD TRICKS #
  6538. PAINTSCREEN;
  6539. DOSCREEN;
  6540. PROMPTING=FALSE;
  6541. ROWPAINT[COMMANDROW]=TRUE;
  6542. CURCURSOR=TEMP;
  6543. POPTEMP;
  6544. POP;
  6545. IF ESCAPE THEN
  6546. BEGIN
  6547. MOVEWD(BUFWIDP1,CMDLIN,TTYLIN);
  6548. STARTCMD;
  6549. END
  6550. CONTROL IFEQ SINGLE,1;
  6551. ELSE
  6552. BEGIN # RESTORE #
  6553. COPYLIN(CMDLIN,TTYLIN);
  6554. COPYLIN(CMDTEMP,CMDLIN);
  6555. END
  6556. CONTROL FI;
  6557. CONTROL IFEQ MULTI,1;
  6558. ELSE EXCHWD(BUFWIDP1,CMDLIN,TTYLIN); # RESTORE #
  6559. CONTROL FI;
  6560. END
  6561. ELSE
  6562. BEGIN
  6563. ERRSTRING=STR2;
  6564. TTSTR(STR1);
  6565. PROMPT(ERRSTRING);
  6566. CONVIN(TTYLIN,2);
  6567. TRIM(TTYLIN,1);
  6568. END
  6569. IF ASCII[CURFILE] LQ 1 THEN SQUELCH(TTYLIN);
  6570. ERRSTRING=" $";
  6571. IOEND # OF ASKUSER #
  6572. PAGE # PROCESS ROUTINE #
  6573.  
  6574. PROC PROCESS;
  6575. IOBEGIN(PROCESS)
  6576. #
  6577. ** PROCESS - STEADY-STATE MAIN PROCESS OF EDITOR.
  6578. *
  6579. * PROCESS PROVIDES THE MAIN LOOP FOR EDITOR EXECUTION IN THE
  6580. * STEADY STATE, (I.E. AFTER INITIALIZE AND BEFORE
  6581. * TERMINATE), AND DRIVES THE SCANNING AND EXECUTION OF EACH
  6582. * OF THE COMMANDS. THE MAIN LOOP OF PROCESS IS BROKEN IN THE
  6583. * FOLLOWING LABELED SECTIONS --
  6584. *
  6585. * "PRCLEAR" - THIS SECTION DRIVES INTERACTION WITH THE
  6586. * TERMINAL TO OBTAIN NEW COMMANDS. SINCE PRCLEAR MAY BE
  6587. * ACTIVATED BEFORE THE PREVIOUS COMMAND SEQUENCE CLEANLY
  6588. * TERMINATED, (I.E. AFTER TERMINAL INTERRUPT OR SYNTAX
  6589. * ERROR), LOGIC IS PROVIDED TO CLEAN UP ANY CLUTTER. THE
  6590. * FETCHING OF COMMANDS MAY OCCUR VIA GETPROCNXT, GETCMD,
  6591. * DOSCREEN, OR VIA CONNECTION FROM THE SINGLE-USER EDITOR TO
  6592. * THE MULTI-USER EDITOR.
  6593. *
  6594. * GETPROCNXT AND GETCMD SIMPLY OBTAIN ONE LINE OF COMMAND
  6595. * TEXT FROM EITHER AN ACTIVE EDITOR PROCEDURE OR FROM A
  6596. * LINE-MODE TERMINAL. DOSCREEN OBTAIN COMMANDS FROM A SCREEN
  6597. * TERMINAL, AND MAY PERFORM ANY FILE MANIPULATIONS OFF THE
  6598. * KEYBOARD BEFORE IDENTIFYING A COMMAND STRING. BEFORE
  6599. * CALLING DOSCREEN, PRCLEAR MUST CALL PAINTSCREEN TO BRING
  6600. * THE SCREEN DISPLAY UP TO DATE WITH RESULTS OF THE PREVIOUS
  6601. * COMMAND SEQUENCE. CONNECTION TO MULTI MAY CAUSE ANY AMOUNT
  6602. * OF EDITING TO BE DONE BEFORE THE MULTI-USER EDITOR RETURNS
  6603. * A COMMAND STRING WHICH IT DOES NOT KNOW HOW TO EXECUTE.
  6604. *
  6605. * "PRNEXT" CONTINUES AFTER PRCLEAR BY INITIALIZING THE SYNTAX
  6606. * SCANNER TO THE BEGINNING OF A STRING OF SEVERAL COMMANDS.
  6607. * THE PROCESS ROUTINE IS ALLOWED TO SKIP PRCLEAR AND START
  6608. * WITH THE PRNEXT SECTION SHOULD A COMMAND STRING BE
  6609. * AVAILABLE AS A RESULT OF EDITOR INITIALIZATION.
  6610. *
  6611. * "PRMORE" CONTINUES SYNTAX SCAN FOR EACH COMMAND VERB.
  6612. * PRMORE RE-DEFAULTS A NUMBER OF EDITOR VARIABLES RELATED TO
  6613. * SYNTAX OPTIONS THEN IDENTIFIES THE COMMAND VERB AND FANS
  6614. * OUT TO THE APPROPRIATE PROCESSING LABEL. THERE IS ONE
  6615. * PROCESSING LABEL FOR EACH COMMAND VERB (LABELS "PPXXXX")
  6616. * PLUS A NUMBER OF PROCESSING LABELS FOR QUASI COMMANDS.
  6617. * (LABELS "QQXXXX")
  6618. *
  6619. * "PREND" IS THE RETURN POINT FOR COMMANDS THAT COMPLETE
  6620. * NORMALLY. IT SIMPLY DETERMINES WHETHER TO GO TO PRMORE FOR
  6621. * EXECUTION OF ADDITIONAL COMMAND VERBS FROM THE SAME COMMAND
  6622. * STRING, OR TO GO TO PRCLEAR TO RESET THE TERMINAL AND
  6623. * PROMPT FOR MORE COMMANDS.
  6624. *
  6625. * "PRERROR" IS THE RETURN POINT FOR COMMANDS THAT CANNOT
  6626. * COMPLETE THEIR NORMAL FUNCTION DUE TO A USER'S ERROR. FOR
  6627. * THE MULTI-USER VERSION OF THE EDITOR, PRERROR MUST
  6628. * RE-DEFAULT THE SUBROUTINE CALLING LINKAGE TO KEEP
  6629. * REENTRANCY WORKING CORRECTLY.
  6630. *
  6631. * THERE IS ONLY ONE MECHANISM TO RETURN OUT OF THE PROCESS
  6632. * ROUTINE - THE "QQEXIT" LABELED SECTION.
  6633. *
  6634. * ENTRY WHEN PROCESS IS ENTERED, ALL THAT IS EXPECTED IS
  6635. * THERE IS A VALID WORKFILE WITH A FILE DIRECTORY
  6636. * BRACKET, ONE OR MORE FILE IMAGE BRACKETS, AND AN
  6637. * AUDIT TRAIL BRACKET. THE RELOCATION VECTOR MUST
  6638. * CONTAIN VALID BRACKET POINTERS FOR THESE SECTIONS.
  6639. * THE INPUT AND OUTPUT FILES MUST BE READY TO BE USED.
  6640. *
  6641. * EXIT WHEN PROCESS COMPLETES, ALL COMMANDS HAVE BEEN
  6642. * PROCESSED IN THE CASE OF THE SINGLE-USER VERSION, OR
  6643. * CMDLIN CONTAINS AN UNEXECUTABLE COMMAND IN THE CASE
  6644. * OF THE MULTI-USER VERSION. AFTER PROCESS COMPLETES,
  6645. * THE MULTI-USER VERSION IS EXPECTED TO CHECKPOINT AND
  6646. * RE-TRANSFER THE WORKFILE. THE SINGLE-USER VERSION
  6647. * IS EXPECTED TO RE-BUILD FILES ACCORDING TO THE
  6648. * ATTRIBUTES IN THE FILE DIRECTORY.
  6649. #
  6650. XDEF LABEL PRERROR;
  6651. CONTROL IFEQ MULTI,1;
  6652. XDEF LABEL QQSINGLE;
  6653. CONTROL FI;
  6654.  
  6655. SWITCH PROCESSSW
  6656. PPALTER,
  6657. PPBACK,
  6658. PPCOPY,
  6659. PPDELETE,
  6660. PPDATA,
  6661. PPEDIT,
  6662. PPFSE,
  6663. PPGET,
  6664. PPHELP,
  6665. PPINSERT,
  6666. PPLOCATE,
  6667. PPMOVE,
  6668. PPPRINT,
  6669. PPQUIT,
  6670. PPREPLACE,
  6671. PPSET,
  6672. PPTEACH,
  6673. PPUNDO,
  6674. PPVIEW;
  6675. PAGE # OUTER LOGIC OF PROCESS #
  6676.  
  6677.  
  6678. ORIGSTKPTR=STACKPTR;
  6679. STARTCMD;
  6680. GOTO PRNEXT; # CTL CARD HAS 1ST CMD #
  6681.  
  6682. PRCLEAR: # NEW INTERACTION #
  6683. CURF(CURFILE)=MIN(MAX(CURRENT,TOPF(CURFILE)),BOTF(CURFILE));
  6684. IF USRBRK NQ 0 THEN
  6685. BEGIN
  6686. USRBRK=0;
  6687. TTINIT;
  6688. VDTFLS; # THROW AWAY INCOMPLETE I/O #
  6689. VDTDRN;
  6690. CONTROL IFEQ MULTI,1;
  6691. CLEARINT; # CLEAR SMFEX INTRPT, REQUE #
  6692. CONTROL FI;
  6693. CONTROL IFEQ SINGLE,1;
  6694. IF PROCACTIVE THEN CLEARPROC;
  6695. CONTROL FI;
  6696. CMDLINE[0]=LINECMD; # SET LINE #
  6697. CMDLINE[1]=NULLIN;
  6698. STARTCMD;
  6699. GOTO PRNEXT;
  6700. END
  6701. FORWARD=FALSE;
  6702. BACKWARD=FALSE;
  6703. PROMPTING=FALSE;
  6704.  
  6705. NUMWIDBLK=NUMWIDTH+BLANKS;
  6706. IF NUMBERED[CURFILE] EQ 0 THEN NUMWIDBLK=0;
  6707.  
  6708. CONTROL IFEQ SINGLE,1;
  6709.  
  6710. # NOTE - MUST TEST VDTAPS BEFORE PROCACTIVE. IF VDTAPS, JUMP #
  6711. # FORWARD TO AVOID PROCACTIVE TEST. #
  6712. IF NOT APSTRREAD[0] THEN
  6713. BEGIN # IF APPLICATION STRING NOT READ #
  6714. VDTAPS("FSEKEYS",CMDLIN,LINPTR1,LINPTR2);
  6715. IF LINPTR2 EQ 0 THEN # GOT A COMMAND #
  6716. BEGIN
  6717. IF LINPTR1 LQ BUFCM1 THEN
  6718. BEGIN # IF TDU STRING IS SMALL ENOUGH #
  6719. FOR LINPTR3=0 STEP 1 UNTIL LINPTR1-1 DO
  6720. BEGIN # TRANSLATE COMMAND #
  6721. GETCHAR(CMDLINE,LINPTR3,LINPTR2);
  6722. LINPTR2=XLTXPINT[LINPTR2];
  6723. SETCHAR(CMDLINE,LINPTR3,LINPTR2);
  6724. END
  6725. SETCHAR(CMDLINE,LINPTR1,CENDLINE);
  6726. END
  6727. ELSE
  6728. BEGIN # TDU FSEKEYS STRING IS TOO LONG #
  6729. CMDLINE[0]=NULLIN; # NULL COMMAND #
  6730. ERRSTRING = "FSEKEYS IN TDU DEFINITION TOO LONG$";
  6731. END
  6732. STARTCMD;
  6733. GOTO PRNEXT;
  6734. END
  6735. ELSE # END OF COMMANDS #
  6736. BEGIN
  6737. IF SCREENMODE THEN APSTRREAD[0] = TRUE;
  6738. END
  6739. END
  6740.  
  6741. # NOTE - MUST TEST PROCACTIVE BEFORE CTLCDCMD. IF PROCACTIVE, #
  6742. # JUMP FORWARD TO AVOID CTLCDCMD TEST. SINCE GETPROCNXT MIGHT #
  6743. # TURN PROCACTIVE OFF, THE CODE CANNOT USE IF/ELSE LOGIC BUT #
  6744. # MUST TEST THE FLAG TWICE. #
  6745. IF PROCACTIVE THEN GETPROCNXT; # MUST TEST TWICE #
  6746. IF PROCACTIVE THEN GOTO PRNEXT; # CANNOT USE "ELSE" #
  6747.  
  6748. # NOTE - MUST TEST CTLCDCMD BEFORE READING A COMMAND BUFFER FROM #
  6749. # THE TERMINAL. IF CTLCDCMD, JUMP FORWARD TO AVOID TERMINAL IO. #
  6750. IF CTLCDCMD THEN # FETCH CTL CARD CMDS #
  6751. BEGIN
  6752. P&lt;FROM>=CCDR;
  6753. MOVEWD(8,FROM,TMPLIN);
  6754. CONVIN(CMDLIN,1);
  6755. LINPTR3=-1;
  6756. FOR LINPTR1=0 STEP 1 WHILE LINPTR3 LS 0 DO
  6757. BEGIN
  6758. GETCHAR(CMDLINE,LINPTR1,LINPTR2);
  6759. IF LINPTR2 EQ CPERIOD OR LINPTR2 EQ CRPAREN
  6760. THEN LINPTR3=LINPTR1+1;
  6761. IF LINPTR2 EQ CENDLINE THEN LINPTR3=LINPTR1;
  6762. END
  6763. FOR LINPTR1=LINPTR3 STEP 1 UNTIL LENGTH(CMDLIN) DO
  6764. BEGIN
  6765. GETCHAR(CMDLINE,LINPTR1,LINPTR2);
  6766. SETCHAR(CMDLINE,LINPTR1-LINPTR3,LINPTR2);
  6767. END
  6768. CTLCDCMD=FALSE; # ASSURE NO FURTHER USAGE #
  6769. STARTCMD;
  6770. IF LENGTH(CMDLIN) NQ 0 THEN GOTO PRNEXT;
  6771. END
  6772. CONTROL FI;
  6773.  
  6774. AUDITCHECK; # SINCE THIS IS NEW TRANSACTION CYCLE #
  6775.  
  6776. IF CURFILE EQ 2 AND SPLITFILE[2] EQ 0 THEN
  6777. BEGIN # MUST GET CURRENT FILE INTO BRACKET 1 #
  6778. CURF(2)=MIN(MAX(CURRENT,TOPF(2)),BOTF(2));
  6779. READNAM=PADNAME(FILENAM[2]);
  6780. FILNUM=1;
  6781. CHARPARM=0;
  6782. GETPARM=0;
  6783. OPENFILE;
  6784. END
  6785.  
  6786. MAKENONTRIV; # MAKE FILE SELECT NONTRIVIAL #
  6787. IF ERRCURSOR LS 0 THEN CMDLINE[0]=NULLIN;
  6788. IF SCREENMODE THEN
  6789. BEGIN
  6790. IF FORCEDHOME THEN # IF HOME REQUESTED #
  6791. BEGIN
  6792. FORCEDHOME=FALSE;
  6793. XCURSOR=0;
  6794. YCURSOR=COMMANDROW;
  6795. END
  6796. PAINTSCREEN;
  6797. IF PAINTAGAIN THEN # IF SCREEN SHOULD BE PAINTED #
  6798. BEGIN
  6799. PAINTALL; # SET PAINT SCREEN BITS #
  6800. PAINTAGAIN=FALSE; # RESET PAINT FLAG #
  6801. END
  6802. END
  6803. ELSE
  6804. BEGIN # LINE MODE #
  6805. IF ERRSTRING NQ " $" THEN
  6806. BEGIN # IF MESSAGE TO OUTPUT #
  6807. CONTROL IFEQ SINGLE,1;
  6808. IF NOT INTERACT THEN TTSTR(" $");
  6809. CONTROL FI;
  6810. TTLIN(ERRSTRING);
  6811. END
  6812. END
  6813. IF ERRSTRING NQ " $" THEN
  6814. BEGIN # IF MESSAGE TO CLEAR #
  6815. ROWPAINT[RESPONSEROW] = TRUE;
  6816. ERRSTRING = " $";
  6817. END
  6818. ERRCURSOR=-1;
  6819.  
  6820. STARTCMD;
  6821.  
  6822. CONTROL IFEQ SINGLE,1;
  6823. IF LENGTH(CMDLIN) EQ 0 THEN PRECONNECT;
  6824. IF CONNECTED THEN CONNECT; # MUST TEST TWICE #
  6825. IF CONNECTED THEN POSTCONNECT; # CANNOT USE *ELSE* HERE #
  6826. ELSE # BUT MUST USE *ELSE* HERE #
  6827. BEGIN
  6828. PUSH;
  6829. IF NULLINPUT THEN
  6830. BEGIN
  6831. CMDLINE[0]=NULLIN;
  6832. GOTO QQEXIT;
  6833. END
  6834. IF SCREENMODE THEN DOSCREEN;
  6835. ELSE GETCMD;
  6836. NOPOP;
  6837. END
  6838. IF EXPANDAT GQ 0 THEN EXPANDCMDS;
  6839. CONTROL FI;
  6840. CONTROL IFEQ MULTI,1;
  6841. PUSH;
  6842. IF SCREENMODE THEN DOSCREEN;
  6843. ELSE GETCMD;
  6844. NOPOP;
  6845. IF EXPANDAT GQ 0 THEN EXPANDCMDS;
  6846. CONTROL FI;
  6847.  
  6848. PRNEXT: # DROP THRU OR SKIP AT START #
  6849. CONTROL IFEQ SINGLE,1;
  6850. IF NOT (ECHOOFF OR INTERACT) THEN
  6851. BEGIN # IF NOT INTERACTIVE #
  6852. IF LENGTH(CMDLIN) NQ 0 THEN
  6853. BEGIN # IF COMMAND, ECHO #
  6854. TTSTR(" $");
  6855. SCRNPT3 = LENGTH(CMDLIN);
  6856. FOR SCRNPT5 = 0 STEP 1 UNTIL SCRNPT3 - 1 DO
  6857. BEGIN
  6858. GETCHAR(CMDLINE,SCRNPT5,SCRNPT4);
  6859. SCRNPT4 = XLTINTDSP[SCRNPT4];
  6860. TTCHR(SCRNPT4);
  6861. END
  6862. TTBRK;
  6863. END
  6864. END
  6865. CONTROL FI;
  6866. KEYWDTYPE=1;
  6867. TOKEN;
  6868.  
  6869. PRMORE: # CONTINUE MULTI-CMD LINE #
  6870. CONTROL IFEQ MULTI,1;
  6871. CHKVICTIM; # IN CASE SMFEX PROBLEM #
  6872. RSTKSAVE=RSTKPTR; # IN CASE SYNTAX ERROR #
  6873. OLDCURFIL=CURFILE; # IN CASE CHANGE OF FILE ... #
  6874. OLDFDLF1=FDLF(1); # ... SELECTION IN SWITCH ... #
  6875. OLDFDLF2=FDLF(2); # ... MULTI TO SINGLE. #
  6876. CONTROL FI;
  6877. DATAPTR=-1; # ASSURE CLEAN DATA STACK #
  6878. CMDMARKER=TOKENPOS; # REMEMBER BEFORE PREFICES #
  6879. DELETCTL=0;
  6880. NONDEFAULT=FALSE;
  6881. TXTINCMD=FALSE;
  6882. BACKWARD=FALSE;
  6883. FORWARD=FALSE;
  6884. CHARRANGE=FALSE;
  6885. NUMWIDBLK=NUMWIDTH+BLANKS;
  6886. IF NUMBERED[CURFILE] EQ 0 THEN NUMWIDBLK=0;
  6887. DONTPRINT=FALSE;
  6888. FOUND=TRUE;
  6889. LIMIT=-1;
  6890. WHICHLIN=1;
  6891. WHICHSTR=0;
  6892. FILNUM=0;
  6893. CURF(CURFILE)=MIN(MAX(CURRENT,TOPF(CURFILE)),BOTF(CURFILE));
  6894. NEWCURSOR=CURCURSOR;
  6895. ESCAPE=FALSE;
  6896. NXTESCAPE=FALSE;
  6897. THISEXTEND=0;
  6898. CMDWASDLTE[0] = FALSE;
  6899. FORCEAUTOP[0] = FALSE;
  6900. FORCEAUTOR[0] = FALSE;
  6901. IF USRBRK NQ 0 THEN GOTO PRCLEAR;
  6902. CANINTER=TRUE;
  6903. PUSH; # REMEMBER CURRENT #
  6904. PUSHBACK;
  6905. CONTROL IFEQ MULTI,1;
  6906. IF FORCESINGLE THEN
  6907. BEGIN
  6908. FORCESINGLE=FALSE;
  6909. TOKEN;
  6910. GOTO QQSINGLE;
  6911. END
  6912. CONTROL FI;
  6913.  
  6914. PROCESSNDX=-1; # DEFAULT IS BAD CMD #
  6915. IF NOT SYNTAXCHAR[TOKENCHAR] THEN
  6916. BEGIN
  6917. IF TOKENCHAR EQ CSEMCOLON
  6918. AND NOT SCREENMODE THEN TTLIN(" $");
  6919. GOTO PREND2;
  6920. END
  6921. IF TOKENCHAR EQ CSLASH THEN GOTO QQNOS;
  6922. ELSE IF TOKENCHAR EQ CPERIOD THEN GOTO QQWORD;
  6923. ELSE IF TOKENCHAR EQ CMINUS THEN GOTO QQXECUTE;
  6924. ELSE IF TOKENTYPE EQ TYPST"LETTER" THEN PROCESSNDX=KEYWDNDX;
  6925. IF PROCESSNDX EQ -1 THEN ERRJUMP("UNKNOWN DIRECTIVE$");
  6926. TOKEN;
  6927.  
  6928. GOTO PROCESSSW[PROCESSNDX];
  6929.  
  6930. PREND: # RESUME HERE AFTER COMMAND #
  6931. PAGELAST=FALSE;
  6932. PREND1: # RESUME HERE AFTER VIEW COMMAND #
  6933. OLDLINPTR=CURRENT;
  6934. OLDCURSOR=NEWCURSOR;
  6935. CURCURSOR=NEWCURSOR;
  6936. XCURSOR=NEWCURSOR-XSHIFT[CURSPLIT];
  6937. YCURSOR=-1;
  6938. PREND2: # RESUME HERE FOR NULL CMD LINE, PROC CALL #
  6939. CONTROL IFEQ SINGLE,1;
  6940. IF NOT INTERACT AND PROCACTIVE AND ERRSTRING NQ " $" THEN
  6941. BEGIN # IF BATCH PROCEDURE ERRSTRING #
  6942. TTSTR(" $");
  6943. TTLIN(ERRSTRING);
  6944. ERRSTRING = " $";
  6945. END
  6946. CONTROL FI;
  6947. IF KILLMARKS THEN
  6948. BEGIN
  6949. KILLMARKS=FALSE;
  6950. PAINTMARKS(3);
  6951. NUMMARKS=0;
  6952. END
  6953. NOPOP; # COMMAND DID POS #
  6954. IF SAMEBACK THEN DECRBACK;
  6955. IF ESCAPE THEN GOTO PRNEXT;
  6956. IF NOT FOUND THEN GOTO PRCLEAR;
  6957. KEYWDTYPE=1;
  6958. TOKEN;
  6959. IF TOKENTYPE EQ TYPST"EOL" THEN GOTO PRCLEAR;
  6960. GOTO PRMORE;
  6961.  
  6962. PRERROR: # RESUME HERE AFTER ERROR #
  6963. CONTROL IFEQ MULTI,1;
  6964. RSTKPTR=RSTKSAVE; # SINCE ERROR COULD BE NESTED #
  6965. CONTROL FI;
  6966. CONTROL IFEQ SINGLE,1;
  6967. IF PROCACTIVE THEN CLEARPROC;
  6968. CONTROL FI;
  6969. POP; # RESTORES CURRENT #
  6970. IF SAMEBACK THEN DECRBACK;
  6971. CONTROL IFEQ SINGLE,1;
  6972. IF NOT INTERACT THEN
  6973. BEGIN
  6974. TTSTR(" $");
  6975. TTLIN(ERRSTRING);
  6976. MORTAL(" BATCH JOBS MUST BE ERROR FREE.$");
  6977. END
  6978. CONTROL FI;
  6979. GOTO PRCLEAR;
  6980. PAGE # PROCESS COMMAND HANDLERS #
  6981.  
  6982.  
  6983. PPALTER:
  6984. TTYLINE[0]=NULLIN;
  6985. WHICHSTR=1;
  6986. EXECNDX=EXECST"MODIFY";
  6987. SCANNER;
  6988. VFYLOCK;
  6989. IF EXECNDX EQ EXECST"APPEND" THEN GOTO QQAPPEND;
  6990. IF NOT TXTINCMD THEN
  6991. BEGIN
  6992. IF SCREENMODE THEN ASKUSER("ALTER WHAT ?$",CKWRD);
  6993. ELSE GETMOD;
  6994. END
  6995. CONTROL IFEQ MULTI,1;
  6996. IF SCREENMODE THEN
  6997. BEGIN # IF SCREEN MODE #
  6998. CONTROL FI;
  6999. CONTROL IFEQ SINGLE,1;
  7000. IF SCREENMODE OR NOT INTERACT THEN
  7001. BEGIN # IF SCREEN OR BATCH MODE #
  7002. CONTROL FI;
  7003. DOTAB(0,XSHIFT[CURSPLIT],0);
  7004. END
  7005. ELSE
  7006. BEGIN # INTERACTIVE LINE MODE #
  7007. DOTAB(0,0,0);
  7008. END
  7009. CHECKGLOBAL;
  7010. DORANGE;
  7011. LASTGLOBAL;
  7012. GOTO PREND;
  7013.  
  7014.  
  7015. PPBACK:
  7016. SCNEOC;
  7017. IF DATAKEYPRS[0] THEN
  7018. BEGIN
  7019. SCNEOC;
  7020. EXCHSAVPOS; # EXCHANGE WITH STORED SCREEN #
  7021. SETUPSCREEN(1,LINPTR1,LINPTR2);
  7022. END
  7023. ELSE
  7024. BEGIN
  7025. ERRSTRING = "NO FILE DATA STORED WITH 'DATA'$";
  7026. END
  7027. GOTO PREND;
  7028.  
  7029.  
  7030. PPCOPY:
  7031. FILCMDNDX=FILCMDST"COPY";
  7032. EXECNDX=EXECST"COPY";
  7033. PPCOPY2:
  7034. NEWCURSOR=0;
  7035. CONTROL IFEQ SINGLE,1;
  7036. SNGLMOV;
  7037. CONTROL FI;
  7038. CONTROL IFEQ MULTI,1;
  7039. MULTMOV;
  7040. CONTROL FI;
  7041. GOTO PREND;
  7042.  
  7043.  
  7044. PPDELETE:
  7045. CMDWASDLTE[0] = TRUE;
  7046. SCANNER;
  7047. VFYLOCK;
  7048. IF SCANBLOCK THEN GOTO QQCLOSE;
  7049. IF SCANWORD THEN GOTO QQSQUEEZE;
  7050. IF NOT (SCREENMODE OR DONTPRINT) THEN
  7051. BEGIN
  7052. EXECNDX=EXECST"TYPE";
  7053. DORANGE;
  7054. IF NOT FOUND THEN GOTO PREND;
  7055. LINPTR1=REGLINE[RNGTOPREG]+1;
  7056. LINPTR2=REGLINE[RNGBOTREG]-1;
  7057. END
  7058. EXECNDX=EXECST"DELETE";
  7059. DORANGE;
  7060. IF CHARRANGE THEN
  7061. BEGIN
  7062. SPLICE;
  7063. NEWCURSOR=CHRPTR3;
  7064. END
  7065. IF CURRENT LQ TOPF(CURFILE) THEN FWDZ; # IF FIRST LINE DELETED #
  7066. GOTO PREND;
  7067.  
  7068. PPDATA:
  7069. SCNEOC; # SCAN TO END OF COMMAND #
  7070. STORCURPOS; # STORE CURRENT POSITION #
  7071. DATAKEYPRS[0] = TRUE; # SET FLAG REFERENCE BY BACK #
  7072. ERRSTRING = "FILE DATA STORED FOR USE WITH 'BACK'$";
  7073. GOTO PREND;
  7074.  
  7075. PPEDIT:
  7076. SCNEOC; # SCAN TO END OF COMMAND #
  7077. IF SPLITFILE[2] NQ 0 THEN
  7078. BEGIN # IF IN SPLIT SCREEN MODE #
  7079. SETUPSCREEN(1,0,0); # EDIT THE TOP SPLIT ONLY #
  7080. CURFILE = 1;
  7081. POSZ(CURF(1));
  7082. END
  7083. ELSE
  7084. BEGIN # NOT IN SPLIT SCREEN MODE #
  7085. IF INITFILE[1] EQ 0 THEN
  7086. BEGIN # IF CURRENT FILE NOT FIRST #
  7087. PUSH;
  7088. POSZ(TOPC(FILECTL)+1);
  7089. SCNFDINIT = 0;
  7090. WHYLE SCNFDINIT EQ 0 AND CURRENT NQ BOTC(FILECTL) DO
  7091. BEGIN
  7092. SCANFDL(LINPTR1);
  7093. FWDZ;
  7094. END
  7095. POP;
  7096. FILNUM = 1;
  7097. CLOSEFILE; # CLOSE CURRENT FILE #
  7098. READNAM = C&lt;0,7>LINPTR1; # OPEN INITIAL FILE #
  7099. CHARPARM = 0;
  7100. GETPARM = 0;
  7101. FILNUM = 1;
  7102. OPENFILE;
  7103. ERRSTRING = "EDITING INITIAL FILE$";
  7104. END
  7105. ELSE # CURRENT FILE IS INITIAL #
  7106. BEGIN
  7107. ERRSTRING = "CURRENT FILE IS INITIAL FILE$";
  7108. END
  7109. END
  7110. GOTO PREND;
  7111.  
  7112. PPFSE:
  7113. SCNFILOPT;
  7114. SCNEOC;
  7115. OPENFILE;
  7116. IF FILNUM EQ 2 THEN SETUPSCREEN(1,2,USRSPLTSZ);
  7117. ELSE SETUPSCREEN(1,0,0);
  7118. NEWCURSOR=0;
  7119. GOTO PREND;
  7120.  
  7121.  
  7122. PPGET:
  7123. SCNEQNAM(READNAM);
  7124. SCNEOC;
  7125. IF C&lt;0,1>READNAM EQ "S" THEN GOTO QQSTATUS; # "GET STATUS" #
  7126. IF C&lt;0,1>READNAM EQ "A" THEN GOTO QQPSCALE; # "GET ALIGN" #
  7127. CONTROL IFEQ MULTI,1;
  7128. CONTROL IFEQ METERING,1;
  7129. IF C&lt;0,1>READNAM EQ "D" THEN # "GET DATA" #
  7130. BEGIN
  7131. FOR LINPTR1=LOC(BGNSTATS) STEP 1 UNTIL LOC(ENDSTATS) DO
  7132. BEGIN
  7133. FOR LINPTR2=0 STEP 1 UNTIL 19 DO
  7134. BEGIN
  7135. SETCHAR(LINE,LINPTR2,CDIGIT0+B&lt;LINPTR2*3,3>MEM[LINPTR1]);
  7136. END
  7137. SETCHAR(LINE,20,CENDLINE);
  7138. INSX;
  7139. END
  7140. END
  7141. CONTROL FI;
  7142. CONTROL FI;
  7143. GOTO PREND;
  7144.  
  7145.  
  7146. PPHELP:
  7147. CONTROL IFEQ MULTI,1;
  7148. GOTO QQSINGLE;
  7149. CONTROL FI;
  7150. CONTROL IFEQ SINGLE,1;
  7151. HELPCMD;
  7152. NEWCURSOR=0;
  7153. GOTO PREND;
  7154. CONTROL FI;
  7155.  
  7156.  
  7157. PPINSERT:
  7158. TTYLINE[0]=NULLIN;
  7159. LIMIT=-2;
  7160. WHICHSTR=1;
  7161. WHICHLIN=4;
  7162. SCANNER;
  7163. VFYLOCK;
  7164. IF FORWARD THEN LINPTR3=LINPTR3+1;
  7165. ELSE IF BACKWARD THEN LINPTR3=LINPTR3-1;
  7166. WINDOPOS(LINPTR3,FILPTR3);
  7167. IF NOT FOUND THEN
  7168. BEGIN
  7169. HALT("OUT OF BOUNDS$");
  7170. GOTO PREND;
  7171. END
  7172. IF SCANBLOCK THEN GOTO QQOPEN;
  7173. IF SCANWORD THEN GOTO QQSTRETCH;
  7174. IF NOT TXTINCMD AND SCREENMODE THEN
  7175. BEGIN
  7176. ASKUSER("INSERT WHAT ?$",CKWRD);
  7177. IF NOT FOUND THEN GOTO PREND;
  7178. TXTINCMD=TRUE;
  7179. END
  7180.  
  7181. POSZ(LINPTR3); # TARGET FOR INSERTION #
  7182. CURFILE=FILPTR3;
  7183. LIMIT=1; # INDICATE ONE LINE MUST FIT #
  7184. FITNUM;
  7185.  
  7186. LINCTR=0;
  7187. WHYLE NOT ESCAPE DO
  7188. BEGIN
  7189. IF NUMBERED[CURFILE] NQ 0 THEN
  7190. BEGIN
  7191. LINENO=LINENO+INCR;
  7192. IF LINENO GQ LINNUM2 OR LINENO GR NINES THEN
  7193. BEGIN
  7194. ESCAPE=TRUE;
  7195. TEST; # THIS KILLS LOOP #
  7196. END
  7197. END
  7198. EXECINS; # PROCESSES ESCAPE, READS TTY #
  7199. IF ESCAPE THEN TEST; # AND KILL LOOP #
  7200. INSX; # FINALLY GOT A LINE #
  7201. LINCTR=LINCTR+1;
  7202. END # OF EVERYTHING LOOP #
  7203. NEWCURSOR=0;
  7204. ESCAPE=FALSE;
  7205. GOTO PREND;
  7206.  
  7207.  
  7208. PPLOCATE:
  7209. EXECNDX=EXECST"LOCATE";
  7210. WHICHSTR=2;
  7211. PPLOCATE2:
  7212. SCANNER;
  7213. IF EXECNDX EQ EXECST"REPLACE" THEN VFYLOCK;
  7214.  
  7215. IF SCANWORD THEN WORDSEARCH=TRUE;
  7216. IF SCANUPPER THEN UPPERSEARCH=TRUE;
  7217. IF LIMIT EQ 1 THEN SUBSTONCE=TRUE;
  7218. ELSE SUBSTONCE=FALSE;
  7219.  
  7220. IF LOCSTRLEN1 EQ 0 THEN # NEED STRING #
  7221. BEGIN
  7222. ASKUSER("LOCATE WHAT?$",CKWRD);
  7223. IF LENGTH(TTYLIN) GR 0 THEN MOVEWD(STRWID,TTYLIN,LOCSTRING1);
  7224. SETCHAR(LOCSTR1,80,CENDLINE); # ASSURE TERMINATED #
  7225. LOCSTRLEN1=LENGTH(LOCSTRING1);
  7226. ELLIPSIS=FALSE;
  7227. END
  7228. CHECKGLOBAL;
  7229.  
  7230. PUSH; # REMEMBER WHERE WE ARE #
  7231. FOUNDOTHER=FOUND; # REMEMBER WHETHER IN BOUNDS #
  7232. DORANGE;
  7233. FOUND=FOUNDOTHER;
  7234. IF FOUND AND (LINCTR EQ 0 OR (LINCTR LS LIMIT AND LIMIT LS LARGENUM))
  7235. THEN
  7236. BEGIN # IF IN BOUNDS BUT TOO FEW HITS #
  7237. IF SCHSTRSPEC AND SCREENMODE AND NOT PROCACTIVE THEN
  7238. BEGIN # IF NEED TO PRESERVE COMMAND LINE #
  7239. POP;
  7240. ERRJUMP("NOT FOUND$");
  7241. END
  7242. HALT("NOT FOUND$");
  7243. END
  7244. IF EXECNDX EQ EXECST"REPLACE" THEN LASTGLOBAL;
  7245. IF PROMPTING AND EXECNDX EQ EXECST"LOCATE" THEN
  7246. BEGIN
  7247. LINCTR=LARGENUM; # FOR FINAL PROMPT #
  7248. IF ROWSUSED NQ 0 THEN # FORCE FINAL PROMPT #
  7249. BEGIN
  7250. POP; # GET TO LAST FOUND LINE #
  7251. PUSH; # SAME STACK DEPTH #
  7252. GLOBALLOCATE;
  7253. NOPOP; # HOLD THIS POSITION #
  7254. PUSH; # GET THIS LINE ONTO STACK #
  7255. END
  7256. END
  7257. POP; # GO TO LAST LINE FOUND, OR OLD CURRENT IF NONE FOUND #
  7258. IF PROMPTING THEN NEWCURSOR=0;
  7259. GOTO PREND;
  7260.  
  7261.  
  7262. PPMOVE:
  7263. FILCMDNDX=FILCMDST"MOVE";
  7264. EXECNDX=EXECST"MOVE";
  7265. GOTO PPCOPY2;
  7266.  
  7267.  
  7268. PPPRINT:
  7269. EXECNDX=EXECST"TYPE";
  7270. SCANNER;
  7271. LASTPROCESS=PROCESSNDX;
  7272. IF SCREENMODE AND LIMIT EQ 1 THEN POSZ(LINPTR1);
  7273. ELSE DORANGE;
  7274. NEWCURSOR=CHRPTR1;
  7275. GOTO PREND;
  7276.  
  7277.  
  7278. PPQUIT:
  7279. GOTO QQEXIT;
  7280.  
  7281.  
  7282. PPREPLACE:
  7283. EXECNDX=EXECST"REPLACE";
  7284. WHICHSTR=3;
  7285. GOTO PPLOCATE2;
  7286.  
  7287.  
  7288. PPSET:
  7289. SCANSET;
  7290. GOTO PREND;
  7291.  
  7292.  
  7293. PPTEACH:
  7294. GOTO PPHELP;
  7295.  
  7296.  
  7297. PPUNDO:
  7298. CONTROL IFEQ MULTI,1;
  7299. GOTO QQSINGLE;
  7300. CONTROL FI;
  7301. CONTROL IFEQ SINGLE,1;
  7302. UNDOCMD;
  7303. GOTO PREND;
  7304. CONTROL FI;
  7305.  
  7306.  
  7307. PPVIEW:
  7308. WHICHLIN=3;
  7309. SCANNER;
  7310. LINCTR=LINPTR3; # SELECT CENTER LINE #
  7311.  
  7312. IF SCREENMODE THEN
  7313. BEGIN
  7314. IF SCANHOME THEN # SPECIAL - ONLY MOVE CURSOR #
  7315. BEGIN
  7316. FORCEDHOME=TRUE; # PUT CURSOR AT HOME POSITION #
  7317. GOTO PREND2;
  7318. END
  7319. IF FORWARD THEN
  7320. BEGIN
  7321. TOPS(CURSPLIT)=LINCTR-1;
  7322. END
  7323. ELSE IF BACKWARD THEN
  7324. BEGIN
  7325. TOPS(CURSPLIT)=LINCTR-NUMROWS[CURSPLIT];
  7326. END
  7327. ELSE
  7328. BEGIN
  7329. TOPS(CURSPLIT)=LINCTR-(NUMROWS[CURSPLIT]/2)-1;
  7330. END
  7331. SETTOPS(CURSPLIT);
  7332. SETBOTS(CURSPLIT);
  7333. IF FORWARD OR BACKWARD THEN
  7334. BEGIN
  7335. LINCTR=TOPS(CURSPLIT)+(NUMROWS[CURSPLIT]/2+1);
  7336. END
  7337. LINCTR=MAX(LINCTR,TOPF(CURFILE)+1);
  7338. LINCTR=MIN(LINCTR,BOTF(CURFILE)-1);
  7339. POSZ(LINCTR);
  7340. END
  7341. ELSE
  7342. BEGIN
  7343. MAKEPAGE(GROUPSIZ,CURFILE);
  7344. BACKWARD=FALSE;
  7345. LIMIT=LARGENUM;
  7346. EXECNDX=EXECST"TYPE";
  7347. DORANGE;
  7348. END
  7349. PAGELAST=TRUE;
  7350. GOTO PREND1;
  7351. PAGE # ADDITIONAL PROCESSORS #
  7352.  
  7353.  
  7354. QQABORT:
  7355. TOKEN;
  7356. SCNEOC;
  7357. CONTROL IFEQ MULTI,1;
  7358. GOTO QQSINGLE;
  7359. CONTROL FI;
  7360. CONTROL IFEQ SINGLE,1;
  7361. IF SCREENMODE THEN CLEARSCREEN;
  7362. EVICT(FET,1); # ASSURE NO RESUMED EDIT #
  7363. ABORT;
  7364. CONTROL FI;
  7365.  
  7366.  
  7367. QQAPPEND:
  7368. IF NOT TXTINCMD THEN ASKUSER("APPEND WHAT?$",CKWRD);
  7369. DORANGE;
  7370. GOTO PREND;
  7371.  
  7372.  
  7373. QQCLOSE:
  7374. POSZ(LINPTR1);
  7375. IF LINPTR1 LQ TOPF(CURFILE) THEN FWDZ;
  7376. WHYLE CURRENT LS BOTF(CURFILE) AND NOTEXT DO
  7377. BEGIN
  7378. DELETCTL=1;
  7379. DELX;
  7380. POSZ(CURRENT);
  7381. END
  7382. NEWCURSOR=0;
  7383. GOTO PREND;
  7384.  
  7385.  
  7386. QQEXIT:
  7387. EXITFLAGS=0;
  7388. WHYLE TOKENTYPE EQ TYPST"LETTER" DO
  7389. BEGIN
  7390. KEYWDNDX=-1;
  7391. KEYWDTYPE=9;
  7392. SCANPOS=TOKENPOS;
  7393. TOKEN;
  7394. IF TOKENSYM EQ "UNDO" THEN GOTO QQABORT;
  7395. ELSE IF KEYWDNDX EQ KEYST"QPRO" THEN GOTO QQQUITPROC;
  7396. ELSE IF KEYWDNDX EQ KEYST"QREP" THEN EXITSAVE=TRUE;
  7397. ELSE IF KEYWDNDX EQ KEYST"QQUI" THEN DONTPRINT=TRUE;
  7398. ELSE ERRJUMP("PARAMETER NOT VALID FOR THIS DIRECTIVE$");
  7399. TOKEN;
  7400. END
  7401. IF TOKENTYPE NQ TYPST"DELIMIT" THEN SCNEOC;
  7402. QQNOS:
  7403. TOKEN;
  7404. KEYWDTYPE=0;
  7405. SCANPOS=TOKENPOS;
  7406. TOKEN;
  7407. EXITCMD=TRUE;
  7408. CONTROL IFEQ SINGLE,1;
  7409. IF SCREENMODE THEN
  7410. BEGIN
  7411. CLEARSCREEN;
  7412. END
  7413. IF TOKENTYPE NQ TYPST"EOL" THEN # USER WANTS EXCST #
  7414. BEGIN
  7415. TTYLINE[0]=NULLIN; # COPY CONTROL STATEMENT #
  7416. LINPTR2=0;
  7417. LINNUM1=0;
  7418. FOR LINPTR1=TOKENPOS STEP 1 UNTIL LENGTH(CMDLIN) DO
  7419. BEGIN
  7420. GETCHAR(CMDLINE,LINPTR1,LINCTR);
  7421. SETCHAR(TTYLINE,LINPTR2,LINCTR);
  7422. LINPTR2=LINPTR2+1;
  7423. IF LINCTR EQ CPERIOD OR LINCTR EQ CRPAREN THEN LINNUM1=1;
  7424. IF LINCTR NQ CBLANK AND LINCTR NQ CENDLINE THEN EXITEXCST=TRUE;
  7425. END
  7426. IF LINNUM1 EQ 0 THEN # NEEDS PUNCTUATION HELP #
  7427. BEGIN
  7428. SETCHAR(TTYLINE,LINPTR2-1,CPERIOD);
  7429. SETCHAR(TTYLINE,LINPTR2,CENDLINE);
  7430. END
  7431. END
  7432. PROCACTIVE=FALSE;
  7433. CONTROL FI;
  7434. CONTROL IFEQ MULTI,1;
  7435. IF TOKENTYPE NQ TYPST"EOL" THEN EXITCMD=FALSE;
  7436. QQSINGLE:
  7437. IF CURFILE NQ OLDCURFIL OR FDLF(1) NQ OLDFDLF1
  7438. OR FDLF(2) NQ OLDFDLF2 THEN
  7439. BEGIN
  7440. # RESTORE FILE SELECTION IN EFFECT AT START OF COMMAND #
  7441. # SINCE COMMAND WILL BE RESTARTED IN SINGLE. #
  7442. PUSH;
  7443. POSZ(OLDFDLF1);
  7444. SCANFDL(READNAM);
  7445. FILNUM=1;
  7446. GETPARM=0;
  7447. CHARPARM=0;
  7448. OPENFILE;
  7449. IF OLDFDLF2 NQ 0 THEN
  7450. BEGIN
  7451. POSZ(OLDFDLF2);
  7452. SCANFDL(READNAM);
  7453. FILNUM=2;
  7454. GETPARM=0;
  7455. CHARPARM=0;
  7456. OPENFILE;
  7457. END
  7458. POP;
  7459. CURFILE=OLDCURFIL;
  7460. END
  7461. CONTROL FI;
  7462. STACKPTR=ORIGSTKPTR; # UNDOES PUSH IN PROCESS MAIN LOOP #
  7463. IORET # THIS IS ONLY RETURN FROM PROCESS #
  7464.  
  7465.  
  7466. QQOPEN:
  7467. POSZ(LINPTR3);
  7468. IF LIMIT NQ -2 THEN LINCTR=MIN(100,LIMIT);
  7469. ELSE
  7470. BEGIN
  7471. LINCTR=GROUPSIZ;
  7472. IF SCREENMODE THEN
  7473. BEGIN
  7474. LINCTR=NUMROWS[CURSPLIT]-4;
  7475. LINPTR1=CURRENT-2;
  7476. IF NUMROWS[CURSPLIT] LQ 8 THEN
  7477. BEGIN
  7478. LINCTR=LINCTR+2;
  7479. LINPTR1=CURRENT-1;
  7480. END
  7481. IF NUMROWS[CURSPLIT] LQ 2 THEN
  7482. BEGIN
  7483. LINCTR=1;
  7484. LINPTR1=CURRENT;
  7485. END
  7486. TOPS(CURSPLIT)=LINPTR1;
  7487. SETTOPS(CURSPLIT);
  7488. SETBOTS(CURSPLIT);
  7489. END
  7490. END
  7491. FOR LINPTR2=1 STEP 1 UNTIL LINCTR DO
  7492. BEGIN
  7493. LINE[0]=NULLIN;
  7494. INSX;
  7495. END;
  7496. POSZ(CURRENT-LINCTR+1);
  7497. NEWCURSOR=0;
  7498. GOTO PREND;
  7499.  
  7500.  
  7501. QQPSCALE:
  7502. SCNEOC;
  7503. IF SCREENMODE THEN
  7504. BEGIN
  7505. ROWCOLUM[LTOY(CURRENT,CURSPLIT)]=TRUE;
  7506. ROWPAINT[LTOY(CURRENT,CURSPLIT)]=TRUE;
  7507. GOTO PREND;
  7508. END
  7509. IF NUMBERED[CURFILE] NQ 0 THEN LINPTR1=NUMWIDBLK;
  7510. ELSE IF FLOAT THEN LINPTR1=5;
  7511. ELSE LINPTR1=0;
  7512. TTST(" ",LINPTR1);
  7513. FOR LINCTR=1 STEP 1 UNTIL WIDTH DO
  7514. BEGIN
  7515. LINNUM2=MOD(LINCTR,10);
  7516. TTDEC(LINNUM2);
  7517. END
  7518. TTBRK;
  7519. GOTO PREND;
  7520.  
  7521.  
  7522. QQQUITPROC:
  7523. CONTROL IFEQ SINGLE,1;
  7524. TOKEN;
  7525. IF NOT SYNTAXCHAR[TOKENCHAR] THEN CLEARPROC;
  7526. SCANNER;
  7527. SCNEOC;
  7528. IF BACKWARD OR NOT FOUND THEN CLEARPROC;
  7529. CONTROL FI;
  7530. GOTO PREND;
  7531.  
  7532.  
  7533. QQSQUEEZE:
  7534. POSZ(LINPTR1);
  7535. SQUEEZE;
  7536. REPX;
  7537. GOTO PREND;
  7538.  
  7539.  
  7540. QQSTATUS:
  7541. CONTROL IFEQ MULTI,1;
  7542. GOTO QQSINGLE;
  7543. CONTROL FI;
  7544. CONTROL IFEQ SINGLE,1;
  7545. GETSTATUS;
  7546. GOTO PREND;
  7547. CONTROL FI;
  7548.  
  7549.  
  7550. QQSTRETCH:
  7551. POSZ(LINPTR3);
  7552. STRETCH;
  7553. REPX;
  7554. GOTO PREND;
  7555.  
  7556.  
  7557. QQWORD:
  7558. TOKEN;
  7559. SCANPOS=TOKENPOS; # RESTART SCAN ON SUBCOMMAND #
  7560. KEYWDTYPE=6;
  7561. TOKEN;
  7562. KEYWDTYPE=0;
  7563. IF KEYWDNDX LS 0 THEN
  7564. BEGIN
  7565. ERRJUMP("PARAMETER NOT VALID FOR THIS DIRECTIVE$");
  7566. END
  7567. IF KEYWDNDX EQ KEYST"WINC" THEN
  7568. BEGIN
  7569. VFYLOCK;
  7570. TOKEN;
  7571. SETCHAR(TTYLINE,0,CBLANK);
  7572. SETCHAR(TTYLINE,1,CENDLINE);
  7573. IF TOKENTYPE EQ TYPST"DELIMIT" THEN
  7574. BEGIN
  7575. WHICHSTR=1;
  7576. SCANSTR;
  7577. END
  7578. SCNEOC;
  7579. SAVEPROT;
  7580. RSHIFT(LIN,CURCURSOR,LENGTH(TTYLIN)); # MAKE ROOM #
  7581. FOR LINPTR1=0 STEP 1 UNTIL LENGTH(TTYLIN)-1 DO
  7582. BEGIN # INSERT STRING #
  7583. GETCHAR(TTYLINE,LINPTR1,LINPTR2);
  7584. SETCHAR(LINE,CURCURSOR+LINPTR1,LINPTR2);
  7585. END
  7586. MERGEPROT;
  7587. REPX;
  7588. GOTO PREND;
  7589. END
  7590. ELSE IF KEYWDNDX EQ KEYST"WDLC" THEN
  7591. BEGIN
  7592. VFYLOCK;
  7593. TOKEN;
  7594. SCNEOC;
  7595. SAVEPROT;
  7596. LSHIFT(LIN,CURCURSOR+1,1);
  7597. MERGEPROT;
  7598. REPX;
  7599. GOTO PREND;
  7600. END
  7601. ELSE IF KEYWDNDX EQ KEYST"WEND" THEN
  7602. BEGIN
  7603. TOKEN;
  7604. SCNEOC;
  7605. NEWCURSOR=LENGTH(LIN);
  7606. IF NEWCURSOR GR USRNUMCOL+XSHIFT[CURSPLIT]
  7607. THEN ERRSTRING="END OF LINE BEYOND EDGE OF SCREEN$";
  7608. GOTO PREND;
  7609. END
  7610. ELSE IF KEYWDNDX EQ KEYST"WPOS" THEN
  7611. BEGIN
  7612. KEYWDTYPE=2;
  7613. TOKEN;
  7614. LINPTR1=CURCURSOR;
  7615. IF TOKENTYPE EQ TYPST"DIGIT" THEN
  7616. BEGIN
  7617. SCNEQVAL;
  7618. LINPTR1=LINPTR1-1;
  7619. END
  7620. IF KEYWDNDX EQ KEYST"XPRM" OR KEYWDNDX EQ KEYST"YPRM"
  7621. OR KEYWDNDX EQ KEYST"ZPRM" THEN
  7622. BEGIN
  7623. # NOTE - CODE ASSUMES X, Y, Z ARE CONSECUTIVE IN TABLES #
  7624. LINPTR1=XYZCHAR[KEYWDNDX-KEYST"XPRM"];
  7625. TOKEN;
  7626. END
  7627. LINPTR2=0;
  7628. IF TOKENTYPE EQ TYPST"PLUS" THEN LINPTR2=1;
  7629. ELSE IF TOKENTYPE EQ TYPST"MINUS" THEN LINPTR2=-1;
  7630. LINPTR3=1;
  7631. IF LINPTR2 NQ 0 THEN
  7632. BEGIN
  7633. TOKEN;
  7634. IF TOKENTYPE EQ TYPST"DIGIT" THEN
  7635. BEGIN
  7636. LINPTR3=TOKENVAL;
  7637. TOKEN;
  7638. END
  7639. LINPTR1=LINPTR1+LINPTR2*LINPTR3;
  7640. END
  7641. NEWCURSOR=MAX(LINPTR1,0);
  7642. IF NEWCURSOR GR BUFCM1 THEN
  7643. BEGIN # IF BEYOND MAXIMUM LINE LENGTH #
  7644. NEWCURSOR = BUFCM1;
  7645. ERRSTRING = "POSITION REQUESTED EXCEEDS MAXIMUM LINE LENGTH$";
  7646. END
  7647. SCNEOC;
  7648. GOTO PREND;
  7649. END
  7650. ELSE IF KEYWDNDX EQ KEYST"WJOI" THEN
  7651. BEGIN
  7652. TOKEN; # ADVANCE TO NEXT SYNTAX #
  7653. WHICHLIN=3;
  7654. CHARRANGE=TRUE;
  7655. SCANNER;
  7656. VFYLOCK;
  7657. IF NOT FOUND THEN GOTO PREND; # OUT OF BOUNDS #
  7658. POSZ(LINPTR3);
  7659. CURFILE=FILPTR3;
  7660. DOJOIN(1);
  7661. GOTO PREND;
  7662. END
  7663. ELSE IF KEYWDNDX EQ KEYST"WSPL" THEN
  7664. BEGIN
  7665. TOKEN; # ADVANCE TO NEXT SYNTAX #
  7666. WHICHLIN=3;
  7667. CHARRANGE=TRUE;
  7668. SCANNER;
  7669. VFYLOCK;
  7670. IF NOT FOUND THEN GOTO PREND; # OUT OF BOUNDS #
  7671. POSZ(LINPTR3);
  7672. CURFILE=FILPTR3;
  7673. DOSPLIT(2);
  7674. IF SCREENMODE AND CURRENT EQ BOTS(CURSPLIT) THEN
  7675. FORCEAUTOP[0] = TRUE;
  7676. NEWCURSOR=0;
  7677. GOTO PREND;
  7678. END
  7679. CONTROL IFEQ MULTI,1;
  7680. GOTO QQSINGLE;
  7681. CONTROL FI;
  7682. CONTROL IFEQ SINGLE,1;
  7683. WORDCMD;
  7684. GOTO PREND;
  7685. CONTROL FI;
  7686.  
  7687.  
  7688. QQXECUTE:
  7689. TOKEN;
  7690. CONTROL IFEQ MULTI,1;
  7691. GOTO QQSINGLE;
  7692. CONTROL FI;
  7693. CONTROL IFEQ SINGLE,1;
  7694. SCNEQNAM(PROCREC); # RECORD NAME #
  7695. PARMPTR=SCNNAMPTR; # REMEMBER WHERE PARMS START #
  7696. READNAM=PROCNAM; # DEFAULT PROC FILE #
  7697. IF TOKENCHAR EQ CLPAREN THEN # USER HAS FILE NAME #
  7698. BEGIN
  7699. SCNFILE(READNAM);
  7700. PARMPTR=SCNNAMPTR;
  7701. END
  7702. CURPROCNAM=READNAM;
  7703. IF NOT PROCACTIVE THEN
  7704. BEGIN
  7705. EXPANDAT=PARMPTR;
  7706. EXPANDCMDS; # EXPAND PARAMETER REFERENCES #
  7707. END
  7708. COPYLIN(CMDLIN,PARMLIN); # SAVE FOR PARAMETER REFERENCES #
  7709.  
  7710. IF READNAM EQ "0" THEN GOTO PREND; # IF NO FILE #
  7711.  
  7712. IF PROCACTIVE THEN # DETERMINE IF LOOPING #
  7713. BEGIN
  7714. IF PROCREC EQ OLDPROCREC AND READNAM EQ OLDPROCFIL THEN
  7715. BEGIN # LOOPING ON SAME PROC #
  7716. CURP(PROCCTL)=TOPP(PROCCTL);
  7717. GOTO QQXECUTE2; # CAN BYPASS FILE SEARCH #
  7718. END
  7719. END
  7720.  
  7721. OLDPROCREC=PROCREC; # SAVE FOR POSSIBLE LOOP #
  7722. OLDPROCFIL=READNAM;
  7723.  
  7724. PUSH; # SAVE FILE/LINE WHILE OPENING..#
  7725. CURFILE=2; # ..PROCEDURE FILE, .. #
  7726. POSZ(CURF(2)); # FOR CURRENT FILE AND FILE 2 #
  7727. PUSH;
  7728. PUSHBACK; # SAVE FILE CHOICES ALSO #
  7729. FILNUM=2; # ACCESS THE FILE #
  7730. CHARPARM=0;
  7731. GETPARM=1;
  7732. OPENFILE;
  7733. LINENO=1; # 1=NEED RECORDNAME, 2=NEED EOR, 0=FOUND #
  7734. POSZ(TOPF(2)+1);
  7735. WHYLE CURRENT LS BOTF(2) AND LINENO NQ 0 AND USRBRK EQ 0 DO
  7736. BEGIN
  7737. TRIMPAD;
  7738. IF LINENO EQ 1 THEN
  7739. BEGIN
  7740. IF COMPARLIN(LIN,PROCREC,FALSE) THEN LINENO=0;
  7741. ELSE IF COMPARLIN(LIN," ",FALSE) THEN LINENO=1;
  7742. ELSE LINENO=2;
  7743. END
  7744. IF LINENO EQ 2 THEN
  7745. BEGIN
  7746. IF COMPARLIN(LIN,"QUIT PROC",TRUE) THEN LINENO=1;
  7747. ELSE IF COMPARLIN(LIN,EORCON,FALSE) THEN LINENO=1;
  7748. ELSE IF COMPARLIN(LIN,EOFCON,FALSE) THEN LINENO=1;
  7749. END
  7750. IF LINENO NQ 0 THEN FWDZ;
  7751. END
  7752. IF LINENO NQ 0 AND PROCREC NQ "STARTUP" AND NOT PROCACTIVE THEN
  7753. BEGIN # IF ERROR DISPLAY NEEDED #
  7754. IF SCREENMODE THEN
  7755. BEGIN # IF NEED TO PRESERVE COMMAND #
  7756. DOBACK;
  7757. POP;
  7758. CURF(CURFILE)=CURRENT;
  7759. POP;
  7760. ERRJUMP("PROCEDURE NOT FOUND$");
  7761. END
  7762. HALT("PROCEDURE NOT FOUND$");
  7763. END
  7764. TOPP(PROCCTL)=CURRENT;
  7765. CURP(PROCCTL)=CURRENT;
  7766. BOTP(PROCCTL)=BOTF(2);
  7767. PROCACTIVE=TRUE;
  7768. DOBACK;
  7769. POP; # RESTORE CURRENT FILE/LINE #
  7770. CURF(CURFILE)=CURRENT;
  7771. POP;
  7772. QQXECUTE2:
  7773. CMDLINE[0]=NULLIN;
  7774. STARTCMD;
  7775. GOTO PREND2;
  7776. CONTROL FI;
  7777.  
  7778.  
  7779.  
  7780. IOEND # OF PROCESS, FINALLY #
  7781. PAGE # EDTINIT, EDTTERM - MAIN PGM #
  7782.  
  7783.  
  7784. PROC EDTINIT;
  7785. IOBEGIN(EDTINIT)
  7786.  
  7787. CONTROL IFEQ MULTI,1;
  7788. RESUMIO; # GETS DATA SEGMENT, CHECKS FILE #
  7789. IF NOT IORESUMED THEN
  7790. BEGIN
  7791. FATAL(" PREVIOUS VERSION OF WORKFILE.$");
  7792. END
  7793. POSZ(SAVECURL);
  7794. CONTROL IFEQ METERING,1;
  7795. BGNMETER;
  7796. CONTROL FI;
  7797. CONTROL FI;
  7798.  
  7799. IOEND # OF EDTINIT #
  7800.  
  7801.  
  7802. PROC EDTTERM;
  7803. IOBEGIN(EDTTERM)
  7804.  
  7805.  
  7806. CONTROL IFEQ MULTI,1;
  7807. SMFINCTL=FALSE; # SHOW NORMAL NOT RCVRY #
  7808. USRBRK=0;
  7809. CHECKIO; # CHECKPOINTS EDIT #
  7810. # NOTE WE ROLLIN SINGLE-USER JOB TO DO FILREBUILD #
  7811. CONTROL FI;
  7812.  
  7813. CONTROL IFEQ SINGLE,1;
  7814. PAUSEIO; # FOR OTHER OVL'S BUFFERS #
  7815. CONTROL FI;
  7816.  
  7817. IOEND # OF EDTTERM #
  7818.  
  7819.  
  7820. END TERM