SECTION "EDITMAIN"

GET "LIBHDR"

STATIC   $(   SETTCB=TRUE; NOTCB='0'; SETCPU=TRUE; DATING=FALSE    $)


 //    THIS PROGRAM IS DESIGNED SPECIFICALLY TO EDIT THE SOURCE
 //    OF THE BCPL MACHINE-CODE LIBRARY.   IT TAKES INPUT FROM
 //    DD-NAME "FROM", AND WRITES OUTPUT TO DD-NAME "TO".

 //    THE FOLLOWING OPTIONS ARE AVAILABLE :-

 //          '360'         SOURCE FOR O.S. ON SYSTEM/360
 //          '370'         SOURCE FOR O.S. ON SYSTEM/370
 //          'STANDARD'    NO O.S. CONTROL BLOCK REFERENCE, 360
 //          'CMS'         NO O.S. CONTROL BLOCK REFERENCE, 370

 //    ANY SOURCE OUTPUT BY SOME RUN OF THIS PROGRAM WILL PRODUCE
 //    THE SAME OUTPUT ON A SUBSEQUENT RUN.

 //          'DATE'        PERFORM ONLY DATE EDITING

 //    THIS OPTION IS AVAILABLE FOR USE WITH PRIVATE MACHINE-CODE
 //    MODULES, AND WILL REPLACE ANY RECORD HAVING THE CHARACTERS
 //    '  *UNDATED*' STARTING AT COLUMN 17, OVERWRITING WITH THE
 //    CURRENT DATE.   WHEN THE 'MODULE' MACRO HAS BEEN CALLED TO
 //    ESTABLISH THE STANDARD BCPL HEADER FORMAT IT IS OF COURSE
 //    NECESSARY TO EDIT THE OBJECT MODULE ; USE THE PROGRAM
 //    'DATEMOD' TO CARRY THIS OUT.

 //    OPTIONS 'STANDARD', 'CMS' AND 'DATE' ARE RECOGNISED BY THE
 //    FIRST CHARACTER ONLY.


LET  START(P)  BE

    $(S   LET  V = VEC 100
          AND  S = DATE()

          LET  INDCB = FINDINPUT("FROM")
          AND  OUTDCB = FINDOUTPUT("TO")

          LET  CH = GETBYTE(P, 1)

          SWITCHON  CH  INTO

            $(  DEFAULT:   WRITETOLOG("INVALID OPTION, *'370*' ASSUMED")
                           P := "370"

                CASE '3':  ENDCASE

                CASE 'S':  NOTCB, P := '1', "360"
                           ENDCASE

                CASE 'C':  NOTCB, P := '1', "370"
                           ENDCASE

                CASE 'D':  DATING := TRUE                 $)


       //   THE OPTIONS ARE NOW SET AND WE CAN PROCEED TO HANDLE
       //   THE SOURCE.   DDNAMES "TO" AND "FROM" ARE REQUIRED, AND
       //   WE VERIFY THEIR EXISTENCE BEFORE PROCEEDING.

          IF  INDCB=0    DO  $(  WRITETOLOG("NO *"FROM*" DD-NAME")
                                 STOP(20)    $)

          IF  OUTDCB=0   DO  $(  WRITETOLOG("NO *"TO*" DD-NAME")
                                 STOP(20)    $)

          SELECTINPUT(INDCB);  SELECTOUTPUT(OUTDCB)


       //   THE WORK IS DONE USING RECORD I/O.   SIGNIFICANT
       //   TOKENS ARE IDENTIFIED BY LOOKING FOR HEXADECIMAL
       //   VALUES AT THE RELEVANT PLACES IN THE INPUT RECORD.
       //   BE CAREFUL NOT TO INTRODUCE NEW SOURCE RECORDS THAT
       //   WILL DEFEAT THE LOGIC OF THE SEARCH.


     $(   LET  N = READREC(V)

          UNTIL  N=-1  DO

     $(1  LET WORD1 = V!0 ;        IF DATING GOTO SETDATE


       //   FIRST CHECK FOR THE 'SET' DIRECTIVES THAT CONTROL
       //   THE CPU TYPE AND CONTROL BLOCK REFERENCES.

          IF  (WORD1=#X50C3D7E4) & SETCPU  DO     //    '&CPU'
             FOR I = 1 TO 3  DO PUTBYTE(V, I+18, GETBYTE(P, I))

          IF  (WORD1=#X50D5D6E3) & SETTCB  DO     //    '&NOTCB'
                 PUTBYTE(V, 20, NOTCB)


       SETDATE:

       //   WHEN GENERATING BINARY WE WISH TO INCLUDE THE DATE OF
       //   ASSEMBLY IN STANDARD FORM AS A BCPL STRING.   TO DO
       //   THIS SCAN FOR THE CHARACTERS  '  *UNDATED*' .   NOTE
       //   THAT THIS WILL ONLY PLANT THE CURRENT DATE IN AN UNDATED
       //   VERSION OF THE LIBRARY ; THE FIRST EDIT RUN SHOULD
       //   THEREFORE ALWAYS BE FROM SUCH AN UNDATED FORM.

          IF  N>24  DO
              IF  (V!4=#X7D40405C) & (V!5=#XE4D5C4C1) & (V!6=#XE3C5C45C)
                  DO  FOR I = 1 TO GETBYTE(S,0)
                       DO  PUTBYTE(V, I+16, GETBYTE(S,I))

          WRITEREC(V, N);    N := READREC(V)    $)1   $)S
