FSEMAIN 
PROC FSEMAIN; 
BEGIN 
  
# 
***       FSEMAIN -- FILE-BUILD/CTL-CRACK OVERLAY 
* 
*         COPYRIGHT CONTROL DATA SYSTEMS INC.  1992.
* 
*         FSEMAIN PERFORMS CONTROL CARD SCANNING, INITIALIZTION 
*         OF THE EDITOR AND WORKFILE, RESUMPTION OF PREVIOUS WORK 
*         FILES, AND INITIAL/FINAL COPYING OF FILES.  IF THE EDITOR 
*         IS CONVERTED TO AN OVERLAY STRUCTURE AT A FUTURE DATE,
*         THIS MODULE WOULD BE A CANDIDATE FOR AN OVERLAY.  THIS
*         MODULE EXISTS ONLY IN THE SINGLE-USER VERSION OF THE
*         EDITOR, SO IT IS PROGRAMMED NON-REENTRANTLY.
# 
  
  DEF LISTCON #0#;
  
CONTROL EJECT;                 # UNIVERSAL DECLARES # 
*IFCALL SINGLE,COMFSGL
*IFCALL ONLY,COMFONL
*IFCALL MULTI,COMFMLT 
*CALL COMFFSE 
  
                             # EXTERNALS         #
  
XDEF PROC BLDINIT;
XDEF PROC BLDTERM;
  
XREF
  BEGIN 
*CALL COMFXFL 
*CALL COMFXFO 
*CALL COMFXTI 
*CALL COMFXVT 
*CALL COMFXSB 
*CALL COMFXWK 
  END 
  
XREF                         # FSELIB  SUPPORT   #
  BEGIN 
  FUNC LENGTH;
  PROC DISSJ;                        # DISABLE/ENABLE SSJ= #
  PROC MOVEWD;
  PROC FLDLEN;
  PROC DISTCON; 
  PROC SETNAD;
  PROC VDTGSL;
  PROC SETAUC;                       # APPLICATION UNIT CHARGE #
  PROC VDTGTN;
  END 
  
XREF                                 # SRVLIB SUPPORT # 
  BEGIN 
  PROC REWIND;
  PROC WRITEC;
  PROC WRITEF;
  PROC WRITER;
  PROC READC; 
  PROC MESSAGE; 
  PROC ENDRUN;
  PROC ABORT; 
  PROC EXCST; 
  PROC TSTATUS; 
  PROC GETJO; 
  PROC RECALL;
  PROC READ;
  PROC RETERN;
  PROC RTIME; 
  PROC DEFINE;
  PROC PURGE; 
  PROC GETSS; 
  PROC PF;
  END 
  
XREF                         # BUFFER MAPPING    #
  BEGIN 
  ARRAY WORKBUF;; 
  ARRAY BUILDBF;; 
  ITEM MAXADDR; 
  END 
  
  
*CALL COMFDS1 
*CALL COMFVD2 
*CALL COMFDS2 
*CALL COMFTAB 
*CALL COMSPFM 
PAGE                                 # COMMAND BUFFER MANIPULATION #
  
  
PROC SETCMD(STR,LEN,OFFSET);
  BEGIN 
  ITEM STR C(40); 
  ITEM LEN, OFFSET; 
  ITEM TMP1, TMP2;
  TMP2=0; 
  FOR TMP1=1 STEP 1 UNTIL LEN DO
    BEGIN 
    C<9,1>TMP2=C<TMP1-1,1>STR;
    IF TMP2 EQ 0 THEN C<9,1>TMP2=" "; 
    SETCHAR(CMDLINE,OFFSET+TMP1-1,TMP2);
    END 
  END                                # OF SETCMD #
PAGE                         # INITIAL FILE CONSTRUCTION   #
  
  
PROC FILBUILD;
  BEGIN 
# 
**        FILBUILD - READ FIRST SOURCE FILE INTO WORKFILE.
* 
*         FILBUILD PERFORMS INITIAL FILE COPYING AND CERTAIN OTHER
*         TASKS TO INITIALIZE THE EDITOR.  FILBUILD IS CALLED IF
*         THERE IS A FILE SPECIFIED BY THE CONTROL STATEMENT OR IF
*         THERE WAS NO FILE AND NO RESUMABLE WORKFILE IMAGE.  IN THE
*         LATTER CASE, FILBUILD ATTEMPTS TO IDENTIFY A PRIMARY FILE 
*         AS THE FILE TO EDIT.
* 
*         IN ADDITION TO COPYING THE FIRST SOURCE FILE OF THE EDIT
*         SESSION, FILBUILD ALSO INITIALIZES THE WORKFILE MANAGER,
*         SETS THE CHARACTER SET FOR LINE-MODE TERMINAL 
*         COMMUNICATIONS, READS IN THE DEFAULT PROCEDURE FILE, AND
*         INITIALIZES THE RELOCATION VECTOR TO BRACKET THE SOURCE 
*         FILE AND A NEW, EMPTY AUDIT TRAIL IMAGE.
* 
*         ENTRY  FILENAM[1] - NAME OF FILE TO EDIT OR BLANK.
*                CHARPARM - FILE CHARACTER SET SPECIFICATION. 
*                GETPARM - PERMANENT FILE ACCESS REQUEST. 
*                ALLASCII - WHETHER DEFAULT CHARACTER SET IS 6/12.
* 
*         EXIT   FILENAM[1] - NAME OF PRIMARY FILE IF NEEDED. 
*                BUILDCIO - CIO COUNT FOR FILE COPY.
*                TOPC(), BOTC() - BRACKET FILE DIRECTORY. 
*                TOPF(), BOTF() - BRACKET FILE IMAGES.
*                TOPA(), BOTA(), CURA() - BRACKET AUDIT TRAIL.
*                TOPK(), BOTK() - BRACKET FUNCTION KEY STRINGS. 
* 
*         CALLS  MAKEFET, FATAL, VFYFILE, INITIO, SETCSET,
*                INSY, ADDFILE, TTSTR, TTLFN, TTBRK, TTLIN, PUSH, 
*                OPENFILE, POP. 
* 
*         USES   FILNUM, READNAM, CURFILE, CHARPARM, GETPARM. 
# 
  ITEM TMP1;
  
  INITIO; 
  ONWAYINBLK=BLANKS;
  SETCSET(TRUE);
  
  TOPK(FKEYS)=PALAST[0];             # FUNCTION KEYS ARE 1ST BRACKET #
  LINE[0]=NULLIN; 
  FOR TMP1=1 STEP 1 UNTIL NUMFKEYS DO 
    BEGIN 
    INSY;                            # INSERT BLANK LINE FOR EACH KEY # 
    END 
  BOTK(FKEYS)=PALAST[0];             # FKEY BRACKET NEVER CHANGE SIZE # 
  TOPC(FILECTL)=PALAST[0];           # FILE DIRECTORY IS 2ND BRACKET #
  LINE[0]=NULLIN; 
  INSY; 
  BOTC(FILECTL)=PALAST[0];
  INSY;                              # AUDIT NEEDS EXTRA SEPARATOR #
  TOPA(AUDITCTL)=PALAST[0];          # AUDIT MUST BE LAST BRACKET # 
  CURA(AUDITCTL)=PALAST[0]; 
  INSY; 
  BOTA(AUDITCTL)=PALAST[0]; 
  
  FILNUM=1;                    # ADD FIRST FILE BRACKET      #
  READNAM=FILENAM[1]; 
  FILENAM[1]=" "; 
  SCNFDINIT = 1;                     # INDICATE INITIAL FILE #
  ADDFILE;                     # BUILD FIRST FILE  #
  IF NOT INTERACT THEN
    BEGIN 
    TTLIN("1$");                     # CARRIAGE CONTROL # 
    TTSTR(" $");                     # MOVE EDIT/CREATE # 
    END 
  IF BOTF(1) GR TOPF(1)+1 THEN
    BEGIN                            # IF NON-EMPTY FILE #
    TTSTR("EDIT:     $"); 
    END 
  ELSE
    BEGIN                            # NEW FILE # 
    TTSTR("CREATE:   $"); 
    END 
  TTLFN(READNAM); 
  IF LOCKED[1] NQ 0 THEN TTSTR(" (READ-ONLY FILE) $");
  TTBRK;
  IF NUMBERED[1] NQ 0 THEN TTLIN("SEQUENCE NUMBERED FILE$");
  
  CURFILE=1;
  PUSH;                        # HOLD POSITION WHILE INIT PROCS # 
  FILNUM=2; 
  GETPARM=1;
  IF PROCNAM NQ READNAM THEN
    BEGIN                      # IF PROCEDURE FILE IS NOT EDIT FILE # 
    CHARPARM=2;                # FORCE PROCEDURE FILE TO ASCII MODE # 
    READNAM=PROCNAM;
    END 
  OPENFILE; 
  POP;
  
  CONTROL IFEQ METERING,1;
    BUILDCIO=CIOCOUNT;
  CONTROL FI; 
  
  END                          # OF FILBUILD       #
  
  
PROC RESUMEFILES; 
  BEGIN 
# 
**        RESUMEFILES - ATTEMPT TO RESUME PREVIOUS SESSION. 
* 
*         RESUMEFILES ATTEMPTS TO RESUME SOME PREVIOUS EDIT SESSION 
*         FROM A LEFT-OVER WORKFILE.  THIS MAY BE POSSIBLE BECAUSE
*         WORKFILES CONTAIN NOT ONLY ALL TEXT OF ALL FILES, BUT ALSO
*         BINARY DATA IMAGES FOR ALL EDITOR DATA. 
* 
*         THE CALLER DECIDES WHETHER TO CALL RESUMEFILES ON THE BASIS 
*         OF CONTROL STATEMENT SYNTAX.  IF RESUMEFILES IS NOT 
*         SUCCESSFUL, THEN IT CLEARS THE TRYRESUME FLAG AS A SIGNAL 
*         TO THE CALLER THAT FILBUILD SHOULD BE CALLED. 
* 
*         IF RESUMPTION OCCURS, THEN RESUMEFILES RE-INITIALIZES SOME
*         OF THE DATA READ UP FROM THE WORKFILE.  THE TERMINAL IS 
*         RECONFIGURED (FOR SCREEN MODE) BY CALLING VDTSTM/STD AND
*         COPYTABS.  THE COMMAND BUFFER IS CLEARED.  THE MULTI-USER 
*         CONNECTION STATUS IS CLEARED.  THE INTERNAL FILE DIRECTORY
*         IS SEARCHED AND EACH FILE IS RE-VERIFIED FOR PERMISSIONS. 
*         IF THE LAST EXIT WAS A *QUIT REPLACE*, EACH FILE IS FLAGGED 
*         AS UNALTERED.  THE LAST CURRENT LINE SELECTION IS RESTORED. 
* 
*         ENTRY  TRYRESUME - PRESUMED TRUE. 
* 
*         EXIT   TRYRESUME - FORCED FALSE IF NO RESUMPTION OCCURRED.
*                ALL DATA REDEFINED IF RESUMPTION OCCURRED. 
* 
*         MACROS SETCHAR. 
* 
*         CALLS  COPYTABS, FWDZ, POSZ, REPY, RESUMIO, SCANFDL, SETCSET, 
*                TTSYNC, VDTSTD, VDTSTM, VFYFILE, WRITEABLE.
# 
  
  ITEM TMP1      I;                  # TEMPORARY STORAGE #
  ITEM TMP2      I;                  # TEMPORARY STORAGE #
  
  RESUMIO;
  IF IORESUMED THEN          # THERE IS OLD EDIT #
    BEGIN 
    #  RESUMED EDIT ACCEPTABLE -- FINAL SETUP FOLLOWS  #
    # OVERRIDE SOME RESTORED DATA # 
    CONNECTED=FALSE;
    FOR TMP1=0 STEP 1 UNTIL 10 DO SETCHAR(CMDLINE,TMP1,CBLANK); 
    SETCHAR(CMDLINE,11,CENDLINE); 
    IF INTERACT THEN
      BEGIN 
      VDTGSL(TMP1,TMP2);             # GET SCREEN/LINE MODE # 
      IF TMP2 NQ 0 THEN SETCMD("SET SCREEN",10,0);
      ELSE SETCMD("SET LINE",8,0);
      END 
    SETCSET(TRUE);
    POSZ(TOPC(FILECTL)+1);
    WHYLE CURRENT LS BOTC(FILECTL) DO  # CHECK ALL FILES IN SESSION  #
      BEGIN                   # UPDATE LOCKED, CHANGED      # 
      SCANFDL(READNAM); 
      VFYFILE(READNAM,-1);
      IF NOT WRITEABLE(READNAM) THEN
        BEGIN 
        SETCHAR(LINE,8,CDIGIT0+1);
        IF CURRENT EQ FDLF(1) THEN LOCKED[1]=1; 
        IF CURRENT EQ FDLF(2) THEN LOCKED[2]=1; 
        END 
      IF EXITSAVE THEN SETCHAR(LINE,10,CDIGIT0);
      REPY;                  # UPDATE FILE DESCRIPTOR      #
      FWDZ;                  # NEXT FILE DESCRIPTOR        #
      END 
    IF EXITSAVE THEN
      BEGIN                    # IF REPLACED ON EXIT #
      CHANGED[1]=0; 
      CHANGED[2]=0; 
      END 
    EXITFLAGS=0;
    POSZ(SAVECURL); 
    END 
  ELSE TRYRESUME=FALSE; 
  END                         # OF RESUMEFILES    # 
PAGE                         # FINAL FILE RECONSTRUCTION   #
  
  
PROC FILEWRITE; 
  BEGIN 
# 
**        FILEWRITE - COPY ONE INTERNAL FILE IMAGE TO LOCAL FILE. 
* 
*         ENTRY  FILEFET - INITIALIZED FOR EXTERNAL FILE. 
*                TOPF(1), BOTF(1) - BRACKET INTERNAL FILE IMAGE.
* 
*         EXIT   FILEFET - EOR WRITTEN, REWOUND.
* 
*         CALLS  REWIND, POSZ, FWDZ, CONVOUT, WRITER, WRITEF, 
*                WRITEC.
* 
*         USES   LIN, TMPLIN, CURRENT.
# 
  DEF  AVERAGE    #500#;             # AVERAGE FILE SIZE #
  DEF  TWOANAHALF #2500#;            # TWO AND A HALF SECONDS # 
  ITEM COUNTER    I;                 # LINE COUNTER # 
  ITEM SAMPLE     I;                 # LINE SAMPLE RATE # 
  ITEM STARTTIME  I;                 # REAL TIME CLOCK (START) #
  ITEM CHECKTIME  I;                 # REAL TIME CLOCK (CHECK) #
  IF DONTPRINT OR NOT INTERACT THEN 
    BEGIN                            # IF NO MESSAGE SHOULD BE SENT # 
    COUNTER = 0;
    END 
  ELSE
    BEGIN                            # MESSAGE MAY BE SENT #
    COUNTER = 1;
    SAMPLE = AVERAGE; 
    RTIME(STARTTIME); 
    STARTTIME = B<24,36>STARTTIME;
    END 
  REWIND(FILEFET,1);
  POSZ(TOPF(1));
  WHYLE CURRENT LS BOTF(1)-1 DO 
    BEGIN 
    FWDZ; 
    CONVOUT(LIN,1); 
    IF TMPLINE[0] EQ EORCON THEN WRITER(FILEFET,1); 
    ELSE IF TMPLINE[0] EQ EOFCON THEN WRITEF(FILEFET,1);
    ELSE
      BEGIN 
      CONVOUT(LIN,ASCII[1]);
      WRITEC(FILEFET,TMPLIN); 
      IF COUNTER NQ 0 THEN
        BEGIN                        # IF MESSAGE STILL TO ISSUE #
        COUNTER = COUNTER + 1;
        IF COUNTER GR SAMPLE THEN 
          BEGIN                      # IF SAMPLE SIZE REACHED # 
          RTIME(CHECKTIME); 
          CHECKTIME = B<24,36>CHECKTIME - STARTTIME;
          IF CHECKTIME GR TWOANAHALF THEN 
            BEGIN                    # IF ENOUGH TIME HAS PASSED #
            TTLIN(" (REBUILDING) $"); 
            TTSTR("              $"); 
            COUNTER = 0;             # ONE MESSAGE IS ENOUGH #
            VDTCLO(COUNTER);         # FLUSH OUTPUT, NO RECALL #
            END 
          ELSE
            BEGIN                    # COMPUTE PROBABLE SAMPLE COUNT #
            SAMPLE = (SAMPLE*TWOANAHALF)/CHECKTIME; 
            END 
          END 
        END 
      END 
    END 
  WRITER(FILEFET,1);
  REWIND(FILEFET,1);
  END 
  
  
PROC FILREBUILD;
  BEGIN 
# 
**        FILREBUILD - REBUILD ALL SOURCE FILES.
* 
*         FILREBUILD IS CALLED AT THE END OF AN EDIT SESSION.  IT 
*         GOES THRU THE DIRECTORY OF INTERNAL FILE IMAGES.  FOR EVERY 
*         ALTERED FILE, THE LOCAL FILE IS RECONSTRUCTED OUT OF THE
*         EDITOR'S INTERNAL FILE IMAGE.  IF THE REPLACE OPTION WAS
*         SELECTED, THEN FILREBUILD ALSO ASSURES THAT PERMANENT FILES 
*         ARE BUILT.  IF THE REPLACE OPTION WAS IGNORED, THEN 
*         FILREBUILD PERFORMS A RETURN MACRO TO ASSURE THAT THE FILE
*         WRITTEN IS A PURELY LOCAL FILE, AND NOT A PRE-ATTACHED
*         PERMANENT FILE. 
* 
*         FOR ALL FILES (EVEN THOSE UNALTERED OR READ-ONLY
*         RESTRICTED) FILREBUILD PRINTS OUT A STATUS MESSAGE.  THE
*         STATUS MESSAGES, HOWEVER, ARE SUPPRESSED IF THE USER
*         SELECTED THE QUIET OPTION.
* 
*         FILREBUILD CLOSES OUT BOTH BRACKETS, AS NEEDED, AND CLEARS
*         THE COMMAND BUFFER, THEN CHECKPOINTS THE WORKFILE.  IT
*         IS ABSOLUTELY ESSENTIAL THAT NEITHER FILREBUILD NOR THE 
*         CALLER NOR ANY OTHER ROUTINE PERFORM ANY DESTRUCTIVE
*         WORKFILE ACCESSES ONCE CHECKIO HAS BEEN CALLED, OTHERWISE 
*         THE USER MAY PERCEIVE A CONFUSING FILE SELECTION SHOULD THE 
*         WORKFILE BE RESUMED INTO A LATER EDIT SESSION.
* 
*         ENTRY  DONTPRINT - QUIET OPTION.
*                EXITSAVE - REPLACE OPTION. 
*                FILE DIRECTORY - DESCRIBES ALL INTERNAL IMAGES.
* 
*         EXIT   FILE WRITTEN, POSSIBLY SAVED.
* 
*         CALLS  PADNAME, CLOSEFILE, CHECKIO, POSZ, SCANFDL, PUSH,
*                OPENFILE, TTSTR, TTLFN, MAKEFET, ASSGNFILE,
*                LOCALFILE, RETERN, FILEWRITE, REPLACE, ATTACH, 
*                TTBRK, POP, FWDZ.
* 
*         USES   FILNUM, FILENAM[1], FILENAM[2], READNAM, CURRENT,
*                LIN, CHARPARM, GETPARM, CHANGED[1], LOCKED[1], 
*                ASCII[1], PFMFET.
# 
  ITEM TMP1, TMP2;
  ITEM NOTCHANGED B;                 # NOT CHANGED FLAG # 
  
  CMDLINE[0]=NULLIN;
  IF EXITSAVE THEN
    BEGIN                            # IF QUIT WITH REPLACE REQUESTED # 
    TMP1=CURFILE; 
    IF FILENAM[TMP1] EQ "FSEHELP" 
      AND CHANGED[TMP1] EQ 0 THEN TMP1=3 LXR TMP1;
    END 
  ELSE TMP1=0;
  FOR FILNUM=1 STEP 1 UNTIL 2 DO
    BEGIN 
    IF PADNAME(FILENAM[FILNUM]) NQ " " THEN 
      BEGIN                          # IF A FILE IN THIS SPLIT #
      IF FILNUM EQ TMP1 THEN
        BEGIN                        # IF CURRENT FILE TO BE REPLACED # 
        IF FILENAM[FILNUM] NQ "FSTEACH" THEN CHANGED[FILNUM]=1; 
        END 
      CLOSEFILE;
      END 
    END 
  CHECKIO;   # ABSOLUTELY MUST NOT CHANGE WORKFILE AFTER THIS # 
  
  NOTCHANGED=FALSE;                  # RESET NOT CHANGED FLAG # 
  IF NOT EXITQUIT THEN
    BEGIN 
    FILENAM[2]=" "; 
    POSZ(TOPC(FILECTL)+1);
    WHYLE CURRENT LS BOTC(FILECTL) DO 
      BEGIN 
      SCANFDL(READNAM); 
      IF READNAM NQ "ZZZNULL" THEN
        BEGIN 
        PUSH; 
        FILENAM[1]=" "; 
        FILNUM=1; 
        CHARPARM=0; 
        GETPARM=0;
        OPENFILE; 
        IF ZEROCOLASK THEN ZEROCOLIN = FALSE;  # DO NOT "ASK" TWICE # 
        IF ZEROCOLIN AND INTERACT AND CHANGED[1] NQ 0 
          AND FILENAM[1] NQ "FSEPROC" THEN
          BEGIN                      # IF MESSAGE TO SEND # 
          ZEROCOLIN = FALSE;         # ONCE IS ENOUGH # 
          TTLIN("                                        $"); 
          TTLIN("WARNING:  ONE OR MORE OF YOUR ASCII FILES $"); 
          TTLIN("CONTAINED CHARACTERS CODED IN THE DISPLAY $"); 
          TTLIN("CODE FORMAT OF OCTAL 00 (:) RATHER THAN $"); 
          TTLIN("THE ASCII FORMAT OF OCTAL 7404 (@AD).   $"); 
  ASKAGAIN:                          # ASK UNTIL Y OR N # 
          TTLIN("                                        $"); 
          TTLIN("ENTER ...                               $"); 
          TTLIN 
          ("YES     DISPLAY(:) AND ASCII(@AD) CHANGED TO DISPLAY(:)$"); 
          TTLIN 
          ("NO      DISPLAY(:) AND ASCII(@AD) CHANGED TO ASCII(@AD)$"); 
          PROMPT(QCCKWRD);
          CONVIN(CMDLIN,2); 
          GETCHAR(CMDLINE,0,TMP1);
          TMP1 = XLTINTDSP[TMP1]; 
          IF TMP1 NQ CLETTERY AND TMP1 NQ CLETTERN THEN GOTO ASKAGAIN;
          IF TMP1 EQ CLETTERY THEN ZEROCOLOUT = TRUE; 
          END 
        IF NOT DONTPRINT THEN 
          BEGIN 
          IF NOT INTERACT THEN TTSTR(" $"); 
          TTSTR("FILE: $"); 
          TTLFN(FILENAM[1]);
          IF LOCKED[1] NQ 0 THEN
            BEGIN 
            TTSTR(" (READ-ONLY) $");
            END 
          ELSE
            BEGIN 
            IF CHANGED[1] EQ 0 THEN TTSTR(" (NO CHANGES)$");
            END 
          IF EXITSAVE AND CHANGED[1] EQ 0 THEN
            BEGIN                    # IF QUIT REPLACE OPTION # 
            TTSTR(" (NOT REPLACED)$");
            END 
          END 
        IF CHANGED[1] NQ 0 AND LOCKED[1] EQ 0 THEN
          BEGIN 
          MAKEFET(FILEFET,FILENAM[1],FILEBUF,DSKSIZ); 
          # REWRITE LOCAL OR PREATTACHED FILE # 
          FILEWRITE;
          IF EXITSAVE AND LOCALFILE(READNAM) THEN 
            BEGIN                    # IF FILE TO BE MADE PERMANENT # 
            # FILE NEEDS TO BE MADE PERMANENT - TRY INDIRECT FIRST #
            PF("REPLACE",READNAM,READNAM,"RC",PFMERROR,"EM",PFMMSG, 
              "EL","40",0); 
            IF PFMERROR EQ FNF THEN 
              BEGIN                  # IF NOT INDIRECT TRY ATTACH # 
              PF("ATTACH",READNAM,READNAM,"RC",PFMERROR,"M","W",
                "NA","YES","SR","NF","EM",PFMMSG,"EL","40",0);
              FILEWRITE;
              END 
            ELSE
              BEGIN 
              IF PFMERROR EQ FTL THEN 
                BEGIN                # IF FILE TOO LONG # 
                # SAVE FIRST ERROR, RETURN LOCAL FILE, TRY DEFINE # 
                PFMMS2=PFMMSG;
                RETERN(FILEFET,1);
                PF("DEFINE",READNAM,READNAM,"RC",PFMERROR,
                  "EM",PFMMSG,"EL","40",0); 
                FILEWRITE;
                IF PFMERROR NQ 0 THEN 
                  BEGIN              # IF DEFINE FAILED # 
                  PFMMSG=PFMMS2;     # REPLACE ERROR MESSAGE #
                  END 
                END 
              END 
            IF PFMERROR NQ 0 THEN 
              BEGIN                  # IF FILE NOT MADE PERMANENT # 
              TMP1=39;
              WHYLE C<TMP1,1>PFMMSG EQ " " DO TMP1=TMP1-1;
              C<0,1>PFMMSG="("; 
              C<TMP1,2>PFMMSG=")$"; 
              IF DONTPRINT THEN 
                BEGIN                # IF QUIET OPTION, OVERRIDE #
                IF NOT INTERACT THEN TTSTR(" $"); 
                TTSTR("FILE: $"); 
                TTLFN(FILENAM[1]);
                END 
              TTLIN(" (LOCAL - COULD NOT BE SAVED)$");
              TTSTR("               $");
              TTSTR(PFMMSG);
              NOTCHANGED=TRUE;       # SET NOT CHANGED FLAG # 
              IF DONTPRINT THEN TTBRK;
              END 
            ELSE
              BEGIN                  # IF FILE WAS MADE PERMANENT # 
              IF NOT DONTPRINT THEN TTSTR(" (PERMANENT)$"); 
              END 
            END 
          ELSE                       # IF NOT TO BE MADE PERMANENT #
            BEGIN 
            IF NOT DONTPRINT THEN 
              BEGIN                  # IF NOT QUIET OPTION #
              IF LOCALFILE(READNAM) THEN TTSTR(" (LOCAL)$");
              ELSE IF FILINFFT EQ 2 THEN TTSTR(" (QUEUED)$"); 
              ELSE TTSTR(" (PERMANENT)$");
              END 
            END 
          END 
        IF NOT DONTPRINT THEN TTBRK;
        POP;
        END 
      FWDZ; 
      END 
    ZEROCOLOUT=FALSE; 
    END 
  
    IF NOTCHANGED AND INTERACT THEN  # IF FILE NOT CHANGED #
      BEGIN 
      TTLIN("                                        $"); 
      TTLIN("WARNING:  ONE OR MORE OF YOUR FILES $"); 
      TTLIN("COULD NOT BE SAVED.                 $"); 
      TTLIN("                                        $"); 
      TTLIN("ENTER ...  CARRIAGE RETURN TO CONTINUE. $"); 
      PROMPT(QCCKWRD);
      END 
  
  END                          # OF FILREBUILD     #
PAGE                         # INITIATION ROUTINE          #
  
  
PROC CRACKCTL;
  BEGIN 
# 
**        CRACKCTL - CRACK CONTROL STATEMENT. 
* 
*         ENTRY  RA+2, RA+3, ETC - PARAMETERS, EITHER FORMAT. 
*                FILENAM[1] - BLANK.
*                INPTNAM, OUTPNAM, PROCNAM, WORKNAM, - DEFAULTS.
*                GETPARM, CHARPARM, ECHOOFF - DEFAULTS. 
* 
*         EXIT   TRYRESUME - WHETHER RESUMPTION SHOULD BE TRIED.
*                FILENAM[1] - FILLED IN IF SUPPLIED.
*                INPTNAM - CHANGED IF SUPPLIED. 
*                OUTPNAM - CHANGED IF SUPPLIED. 
*                PROCNAM - CHANGED IF SUPPLIED. 
*                WORKNAM - CHANGED IF SUPPLIED. 
*                GETPARM - 2 IF "GET" PARAMETER SPECIFIED.
*                CHARPARM - 1, 2, OR 3 IF SPECIFIED.
*                ECHOOFF - TRUE IF *E=NO* SPECIFIED, FALSE IF *E=YES*.
* 
*         CALLS  PADNAME, MATCHKEY. 
* 
*         USES   TOKENSYM, KEYWDNDX, KEYWDTYPE, TOKENLEN. 
# 
  
  # PARMKEYS AND PARMSW MUST MATCH #
  DEF MAXPARMS #8#; 
  ARRAY PARMKEYS [0:MAXPARMS]; ITEM PARMKEY C(0,0,7) = [ "*NULL*",
    "FN", "I", "L", "IP", "CS", "OP", "WF", "E" ];
  SWITCH KEYPARMSW PSDFLT, PSFILE, PSINP, PSLST, PSPROC,
                   PSCHAR, PSOP, PSWORK, PSECHO;
  SWITCH POSPARMSW PSOP, PSFILE, PSOP, PSINP, PSLST, PSPROC, PSWORK,
                   PSECHO;
  ITEM TMP1, TMP2, TMP3, TMP4, QUIT B, KEYPARM, POSPARM;
  
  TRYRESUME=TRUE; 
  KEYPARM=0;
  POSPARM=0;
  FOR TMP1=2 STEP 1 UNTIL 1+B<42,18>MEM[O"64"] DO 
    BEGIN                            # UNTIL PARAMETERS EXHAUSTED # 
    TOKENSYM=PADNAME(MEM[TMP1]);
    IF B<42,18>MEM[TMP1] EQ 2 OR B<42,18>MEM[TMP1] EQ O"54" THEN
      BEGIN                          # KEYWORD ASSIGNMENT # 
      IF KEYPARM NQ 0 THEN
        BEGIN                        # IF BAD ASSIGNMENT #
        MORTAL(" UNRECOGNIZED FSE COMMAND SYNTAX.$"); 
        END 
      FOR TMP2=0 STEP 1 UNTIL MAXPARMS DO 
        BEGIN                        # SEARCH FOR MATCH # 
        IF TOKENSYM EQ PARMKEY[TMP2] THEN KEYPARM=TMP2; 
        END 
      IF KEYPARM EQ 0 THEN
        BEGIN                        # NO MATCH FOUND # 
        ERRSTRING = " UNKNOWN FSE OPTION : "; 
        C<22,7>ERRSTRING = C<0,7>TOKENSYM;
        C<29,1>ERRSTRING = "$"; 
        MORTAL(ERRSTRING);
        END 
      END 
    ELSE
      BEGIN                          # PARAMETER #
      IF KEYPARM NQ 0 THEN GOTO KEYPARMSW[KEYPARM]; 
      POSPARM=POSPARM+1;
      IF POSPARM GR MAXPARMS - 1 THEN 
        BEGIN                        # IF TOO MANY PARAMETERS # 
        MORTAL(" TOO MANY FSE COMMAND PARAMETERS.$"); 
        END 
      TMP2 = B<42,18>MEM[TMP1]; 
      IF TMP2 NQ 0 AND TMP2 NQ 1 AND TMP2 NQ 2 AND TMP2 NQ O"17" THEN 
        BEGIN                        # IF BAD SYNTAX #
        MORTAL(" UNRECOGNIZED FSE COMMAND SYNTAX.$"); 
        END 
      IF B<0,42>MEM[TMP1] NQ 0 THEN GOTO POSPARMSW[POSPARM];
      GOTO NEXTPARM;
  
PSFILE: 
      FILENAM[1]=C<0,7>MEM[TMP1]; 
      TRYRESUME=FALSE;
      GOTO NEXTPARM;
  
PSINP:  
      INPTNAM=C<0,7>MEM[TMP1];
      GOTO NEXTPARM;
  
PSLST:  
      OUTPNAM=C<0,7>MEM[TMP1];
      GOTO NEXTPARM;
  
PSPROC: 
      PROCNAM=C<0,7>MEM[TMP1];
      GOTO NEXTPARM;
  
PSWORK: 
      WORKNAM=C<0,7>MEM[TMP1];
      GOTO NEXTPARM;
  
PSECHO: 
      FOR TOKENLEN=7 STEP -1 WHILE TOKENLEN GR 0 DO 
        BEGIN 
        IF C<TOKENLEN-1,1>TOKENSYM NQ " " THEN GOTO PSECH2; 
        END 
PSECH2: 
      KEYWDNDX=-1;
      KEYWDTYPE=3;
      MATCHKEY(TMP2); 
      IF KEYWDNDX EQ KEYST"STNO" THEN ECHOOFF=TRUE; 
      ELSE IF KEYWDNDX EQ KEYST"SYES" THEN ECHOOFF=FALSE; 
      ELSE MORTAL(" UNKNOWN FSE COMMAND OPTION.$"); 
      GOTO NEXTPARM;
  
PSDFLT:  PSCHAR:  PSOP: 
      FOR TOKENLEN=7 STEP -1 WHILE TOKENLEN GR 0 DO 
        BEGIN 
        IF C<TOKENLEN-1,1>TOKENSYM NQ " " THEN GOTO PSOP2;
        END 
PSOP2:  
      KEYWDNDX=-1;
      KEYWDTYPE=4;
      MATCHKEY(TMP2); 
      IF KEYWDNDX EQ KEYST"XGET" THEN GETPARM=2;
      ELSE IF KEYWDNDX EQ KEYST"XDIS" OR KEYWDNDX EQ KEYST"XNOR"
        THEN CHARPARM=1;
      ELSE IF KEYWDNDX EQ KEYST"XASC" THEN CHARPARM=2;
      ELSE IF KEYWDNDX EQ KEYST"XASC8" OR KEYWDNDX EQ KEYST"XA8"
        THEN CHARPARM=3;
      ELSE MORTAL(" UNKNOWN FSE COMMAND OPTION.$"); 
      TOKENSYM=C<TMP2,10-TMP2>TOKENSYM; 
      TOKENLEN=TOKENLEN-TMP2; 
      IF TOKENLEN GR 0 THEN GOTO PSOP2; 
  
NEXTPARM: 
      KEYPARM=0;
  
      END 
    END 
  
  END                         # OF CRACKCTL       # 
  
  
PROC BLDINIT; 
  BEGIN 
# 
**        BLDINIT - INITIALIZE EDIT SESSION.
* 
*         ENTRY  EVERYTHING DEFAULTED.
* 
*         EXIT   OLD SESSION RESUMED OR NEW SESSION STARTED.
*                ERRSTRING - ANNOUNCEMENT OF THE DAY. 
*                P<CORE> - ZERO.
*                NUMMODE - CONTROLS EMPTY FILE SEQUENCE ASSUMPTION. 
*                P<FET,OBF,READLST,BFPRU,DISK,FILEBUF> - INIT.
*                CONTROL STATEMENT SCANNED. 
*                FILENAM[1] - FIRST FILE TO EDIT. 
*                INPTNAM, OUTPNAM, WORKNAM, PROCNAM - FILE NAMES. 
*                IORESUMED - TRUE.
*                NULLINPUT - WHETHER THERE IS ANY INPUT FILE. 
*                INTERACT - WHETHER TRUE INTERACTIVE SESSION. 
*                ALLASCII - WHETHER DISPLAY CODE OR 6/12 ASCII DEFAULT. 
*                TTYINPUT - WHETHER INPUT IS FROM A TERMINAL. 
*                WORKFILE ACCESS VALIDATED. 
*                DEFAULT PROCEDURE FILE ACCESSED IF NEEDED. 
*                SINGLEONLY - WHETHER TO SUPPRESS MULTI-USER. 
*                CMDLIN - CLEARED OR BUILT-IN FIRST COMMAND.
*                SCANPOS, TOKENPOS - SET TO START SYNTAX SCAN.
*                SMALLFIELD - TRUE, AND FIELD LENGTH REDUCED. 
*                USER BREAKS DISABLED IF INTERACT.
* 
*         MACROS SETCHAR. 
* 
*         CALLS  GETSS, GETJO, CRACKCTL, TSTATUS, TTEQUIP,
*                VDTOPN, TTINIT, WRITEABLE, FATAL, VFYFILE, 
*                ASSGNFILE, MAKEFET, GET, READ, LOCALFILE,
*                RESUMEFILES, FILBUILD, PAUSEIO, FLDLEN, STARTCMD,
*                DISTCON. 
* 
*         USES   PFMFET, CHARPARM, GETPARM, DSKSIZ, SETCMD(INTERNAL). 
# 
  ITEM TMP1, TMP2, TMP3;
  
  ERRSTRING="NOS FULL SCREEN EDITOR$";
  P<CORE>=0;
  IF B<00,01>MEM[CSMR] EQ 0 THEN     # IF SYSTEM CHARACTER SET = 63 # 
    BEGIN 
    XLTINTXP[O"00"]=O"4045";         # COLON = PERCENT #
    XLTINTXP[O"63"]=O"4072";         # PERCENT = COLON #
    XLTDSPXP[O"00"]=O"4045";         # COLON = PERCENT #
    XLTDSPXP[O"63"]=O"4072";         # PERCENT = COLON #
    XLTDSPINT[O"00"]=O"0063";        # COLON = PERCENT #
    XLTDSPINT[O"63"]=O"0000";        # PERCENT = COLON #
    XLTXPINT[O"45"]=O"0000";         # PERCENT = COLON #
    XLTXPINT[O"72"]=O"0063";         # COLON = PERCENT #
    XLTINTDSP[O"00"]=O"0055";        # COLON = BLANK #
    END 
  NUMMODE=NUMST"INTERPRET"; 
  GETSS(TMP1);
  GETJO(ORIGIN);
  IF TMP1 EQ BASIC THEN NUMMODE=NUMST"PREFER";
  IF TMP1 EQ FORTRAN OR TMP1 EQ FTNTS THEN
    BEGIN 
    NUMMODE=NUMST"PREFER";
    BLANKS=0; 
    END 
  P<FET>=LOC(SNGLFET);
  P<OBF>=LOC(SNGLOBF);
  P<READLST>=LOC(SNGLLST);
  P<BFPRU>=LOC(SNGLPRU);
  P<DISK>=LOC(WORKBUF); 
  P<FILEBUF>=LOC(BUILDBF);
  LINE[0]=NULLIN; 
  CMDLINE[0]=NULLIN;
  TTYLINE[0]=NULLIN;
  CRACKCTL; 
  
  IF OUTPNAM EQ DEFOUTNAM AND FILENAM[1] EQ DEFOUTNAM 
    THEN B<0,42>OUTPNAM=0;
  IF OUTPNAM EQ NULLNAM THEN B<0,42>OUTPNAM=0;
  IF INPTNAM EQ NULLNAM THEN
    BEGIN 
    B<0,42>INPTNAM=0; 
    NULLINPUT=TRUE; 
    END 
  IF FILENAM[1] EQ NULLNAM
    OR (GETPARM EQ 3 AND NOT TRYRESUME) THEN TRYRESUME=TRUE;
  
  INTERACT=FALSE; 
  IF ORIGIN EQ TXOT THEN
    BEGIN 
    INTERACT=TRUE;
    TSTATUS(TSTATAREA); 
    FORMERASCII=CURRENTASC; 
    ALLASCII=INITASCII; 
    END 
  TTYINPUT=INTERACT AND TTEQUIP(INPTNAM); 
  TTYOUTPUT=INTERACT AND TTEQUIP(OUTPNAM);
  INTERACT=INTERACT AND TTYINPUT AND TTYOUTPUT; 
  VDTOPN; 
  TTINIT; 
  IF NOT (WRITEABLE(WORKNAM) AND WRITEABLE("ZZZMOVE"))
    THEN MORTAL(" WORKFILE MUST BE WRITABLE.$");
  IF FILENAM[1] NQ " " THEN VFYFILE(FILENAM[1],-1); 
  
  IF NOT ASSGNFILE(PROCNAM) THEN
    BEGIN 
    PF("GET",PROCNAM,PROCNAM,"RC",PFMERROR,0);
    IF PROCNAM EQ "FSEPROC" AND PFMERROR NQ 0 THEN
      BEGIN 
  PF("GET",PROCNAM,PROCNAM,"RC",PFMERROR,"UN",HELPUSERNUM,"PN","0",0);
      END 
    IF PFMERROR NQ 0 THEN 
      BEGIN 
      MAKEFET(PFMFET,PROCNAM,UTILBUF,MINIBUFSIZ); 
      READ(PFMFET,1);       # ASSIGN NULL FILE #
      END 
    END 
  
  DSKSIZ=INIDSKSIZ;            # NOW BUILD OR RESUME         #
  
  # NOTE RESUMEFILES WILL CLEAR TRYRESUME IF UNABLE, THUS IT #
  # IS NECESSARY TO INTERROGATE TRYRESUME AGAIN AFTERWARDS #
  IF TRYRESUME THEN RESUMEFILES;
  IF NOT TRYRESUME THEN 
    BEGIN                    # NO RESUME ATTEMPT OR ATTEMPT FAILED #
    IF FILENAM[1] EQ " " AND INTERACT THEN
      BEGIN 
      TTSTR("WHICH FILE$"); 
      PROMPT(QCCKWRD);
      CONVIN(TTYLIN,2); 
      TRIM(TTYLIN,0); 
      TMP3=0; 
      FOR TMP1=0 STEP 1 UNTIL LENGTH(TTYLIN)-1 DO 
        BEGIN 
        GETCHAR(TTYLINE,TMP1,TMP2); 
        # CODE ASSUMES INTERNAL CHARSET EQUALS DISPLAY CODE # 
        CONTROL IFNQ CLETTERA,1; DEFERROR; CONTROL FI;
        CONTROL IFNQ CDIGIT0,O"33"; DEFERROR; CONTROL FI; 
        IF TMP2 GQ CLOWERA AND TMP2 LQ CLOWERZ
          THEN TMP2=TMP2-CLOWERA+CLETTERA;
        IF NOT DELIMITER[TMP2] AND TMP3 LQ 6 THEN 
          BEGIN 
          C<TMP3,1>FILENAM[1]=C<9,1>TMP2; 
          TMP3=TMP3+1;
          END 
        ELSE IF TMP2 NQ CBLANK THEN MORTAL("INVALID FILE NAME$"); 
        END 
      VFYFILE(FILENAM[1],-1); 
      END 
    IF FILENAM[1] EQ " " THEN 
      BEGIN 
      MORTAL(" NO FILE NAME ON FSE COMMAND.$"); 
      END 
    FILBUILD; 
    FOR TMP1=0 STEP 1 UNTIL 20 DO SETCHAR(CMDLINE,TMP1,CBLANK); 
    SETCHAR(CMDLINE,21,CENDLINE); 
    IF INTERACT THEN
      BEGIN                          # IF INTERACTIVE # 
      VDTGSL(TMP1,TMP2);             # GET SCREEN/LINE MODE # 
      IF TMP2 NQ 0 THEN              # SCREEN MODE #
        BEGIN 
        SETCMD("SET SCREEN",10,0);   # CONSTRUCT SETSCREEN COMMAND #
        SETCMD(";",1,10); 
        END 
      ELSE                           # PUT OUT HEADER MESSAGE # 
        BEGIN 
        TTLIN(ERRSTRING); 
        ERRSTRING=" $"; 
        END 
      SETCMD("-STARTUP",8,12);       # ADD "-STARTUP" COMMAND # 
      END 
    ELSE
      BEGIN                          # BATCH MODE # 
      TTSTR(" $");                   # PUT OUT SHIFTED HEADER MESSAGE # 
      TTLIN(ERRSTRING); 
      ERRSTRING=" $"; 
      SETCMD("-STARTUP",8,0);        # "-STARTUP" COMMAND # 
      END 
    FLOAT = TRUE;                    # CLEAR *SET NUMBERS NONE* # 
    END 
  
  PAUSEIO;                   # TO ACCEPT NEW DSKSIZ        #
  DSKSIZ=DISKSIZE;
  FLDLEN(LOC(WORKBUF)+DSKSIZ+4);
  SMALLFIELD=TRUE;
  STARTCMD; 
  IF INTERACT THEN DISTCON(USRBRK); 
  
  WORKORG = WORKNAM;                 # SAVE FOR USE IN &Z MICRO # 
  IF NOT LOCALFILE(WORKNAM) THEN SINGLEONLY=TRUE; 
  
  IF PALAST[0] GR MAXLMULTI   OR   (NOT INTERACT)   OR
    B<41,1>MEM[LWPR] EQ 0   OR   TSTATUSTN GR MAXCONNECT
    THEN SINGLEONLY=TRUE; 
  
  END                          # OF BLDINIT       # 
PAGE                         # TERMINATION ROUTINE         #
  
PROC BLDTERM; 
  BEGIN 
# 
**        BLDTERM - TERMINATE EDIT SESSION. 
* 
*         ENTRY  PAUSEIO MUST HAVE BEEN CALLED TO IDLE WORKIO.
*                EXITEXCST, TTYLIN - USER'S CONTROL STATEMENT.
* 
*         EXIT   ALL FILES REWRITTEN AS APPROPRIATE.
*                FIELD LENGTH ENLARGED. 
*                WORKFILE HAS NO-AUTO-DROP STATUS.
*                TERMINAL OUTPUT DRAINED FROM BUFFERS.
*                IAF CHARACTER SET RESTORED.
*                B-DISPLAY MESSAGE CLEARED. 
*                USER-SPECIFIED CONTROL STATEMENT INVOKED.
* 
*         CALLS  CONVOUT, DISSJ, ENDRUN, EXCST, FILREBUILD, FLDLEN, 
*                MESSAGE, SETCSET, SETNAD, TTSYNC, VDTCLO.
* 
*         USES   TMPLIN.
# 
  IF ACCTPRU NQ 0 THEN               # ACCOUNT FOR MULTI USER WORK #
    BEGIN 
    DISSJ(3);                        # ENABLE SSJ= #
    SETAUC(ACCTCIO,ACCTPRU,ACCTOUT);  # COMPUTE AND APPLY CHARGES # 
    DISSJ(2);                        # DISABLE SSJ= # 
  
    # CLEAR ACCUMULATORS IN CASE THIS SESSION IS RESUMED. # 
  
    ACCTPRU=0;
    ACCTCIO=0;
    ACCTTRANS=0;
    ACCTOUT=0;
    END 
  DSKSIZ=INIDSKSIZ; 
  FLDLEN(LOC(MAXADDR)+4); 
  SMALLFIELD=FALSE; 
  FILREBUILD;                # CANNOT ALTER WORKFILE AFTER THIS      #
  SETNAD(FET);
  TTSYNC; 
  VDTCLO(0);
  SETCSET(FORMERASCII); 
  MESSAGE(0,1,1); 
  IF EXITEXCST THEN 
    BEGIN 
    CONVOUT(TTYLIN,1);
    EXCST(TMPLIN);
    END 
  ELSE ENDRUN;
  
  END                          # OF BLDTERM       # 
  
  
END TERM
