Google
 

Trailing-Edge - PDP-10 Archives - mit_emacs_170_teco_1220 - emacs/purify.emacs
There are no other files named purify.emacs in the archive.
!* -*-TECO-*-!

!* EMACS "Purifier" and "Compressor".  The compressor takes
a file of macros such as this one and deletes comments and spaces.
It also performs a few syntactic transformations described in
EMACS;CONV >, and separates out the documentation.
The Purifier turns a compressed file in the buffer into a
file that can be :EJ'ed!

!~FILENAME~:! !Macros for editing and debugging TECO macros,
and for maintaining libraries and dump files.!
PURIFY
!& Compress Buffer:! !S Compress a file of macros, in the buffer.
Removes spaces and comments, and makes the documentation
and directory strings.!

[a[b[c 0ua fsruntimuc
@:ib` %a,-1*qc+(fsruntimuc qc)= `
:ib				    !* For now, turn off runtime printout!
mb
    [0 [1 [2 [3 [4 [5 [6 [7 [8 [9 f[ s string
    J @F
R
    :F:FB*DOCOND*"L		    !* Omit docond stuff at front from compression.!
      S{END:} L .F[VB'
!*** First, an error check:  make sure that there are no CRLF-FF-CRLFs!
!*** without a following macro name.  If there is one, it will screw up!
!*** the alignment of the numbers and the names in the dispatch table.!
!*** Also, blank macros will lose so check for them.!
    J <:S

;                                  !* Found a page break;!
       < @f_	
k	    !* Kill any extra whitespace,!
	 2f=!*:@;	    !* Kill comment if any.!
         .,(c s! .)k >
       
,1a-
"e		    !* If another ^L follows, kill the blank page.!
         -k 2r !<!>'
       1A#!+( 2S! -1A#:)"N     !* Otherwise, there should be a macro name here.!
	  :I* FMT	MACRO_NAME_MISSING fs err'
       s!
 1a-
"E :I* FMT	MACRO_BODY_EMPTY fs err'
       >
mb
!*** Parse macros, build the ~DIRECTORY~ in a buffer in Q9!
!*** Build the documentation in a buffer in Q7!
    FSBCONSU9 FSBCONSU7  Q..OU8 [..O
    J <:S:!; .U2                 !* Q2 IS AFTER FIRST NAME OF MACRO!
      :L 0F:FB:! 2C	    !* Find end of last macro name on line.!
      2F~_!"N :I* Bad_macro_documentation_beginningFS ERR'
      .+1U3			    !* Q3 GETS ADDR OF START OF DOCUMENTATION!
      2C S! :@F"N !"!
        :I* Macro_documentation_doesn't_end_at_end_of_line FS ERR'
      Q3,.FX4                       !* TRANSFER DOCUMENTATION INTO Q4!
      Q2J 0L .,(Q3J L .)X5          !* GET ALL NAMES IN Q5!
      Q9U..O G5 Q7U..O              !* PUT THEM INTO THE ~DIRECTORY~ STRING!
      ZJ I

                                   !* AT END OF DOCUMENTATION BUFFER MAKE CRLF-FF-CRLF!
      .(G5)J                        !* FOLLOWED BY A COPY OF THE NAMES.!
      <  :S!;
         I~DOC~_ S:!>  :k       !* PUT ~DOC~ INTO EACH NAME!
      ZJ .(G4)J  .,(S! .)K         !* THEN GET DOCUMENTATION, KILL THRU LEADING EXCL!
      S -D                         !* DELETE TRAILING EXCL.!
      Q8U..O Q3J
      >                             !* REPEAT FOR NEXT MACRO!
mb
!*** IN THE DOCUMENTATION, CONVERT ^^ TO AN EXCLAMATION MARK!
    q7u..o j0S <:S; !>
!*** Build the actual ~DIRECTORY~ string along with the documentation.!
    ZJ I

!~DIRECTORY~:!		    !* INSERT CRLF-FF-CRLF-EXCL-~DIRECTORY~-EXCL!
    .U0 G9                          !* GET THE CONTENTS - A LOT OF MACRO-NAMES!
    Q0J .U4
    < .U0 :S!; Q0,.K               !* KILL ALL UP TO THE NEXT NAME!
      I
                                   !* PUT CRLF BETWEEN NAMES!
      S:! -2D>                   !* MOVE PAST THIS NAME!
    .,ZK                            !* FLUSH ALL THAT FOLLOWS THAT LAST NAME!
    I

    Q4J  < :S~; 0KK>               !* Throw away names containing ~!
mb
!*** DELETE COMMENTS AND SPACES, AND CONVERT _S TO SPACES!
    Q8U..O
    J<:S!*;
        .-2,( S! .)K		    !* COMMENTS DISAPPEAR!
	@-F_	K>	    !* along with spaces and tabs before them.!
mb
    J<.-Z; @F_	K L>	    !* Delete spaces and tabs at fronts of lines.!
mb
    J 0S_ <:S;
        -1A-"N -D'>             !* SPACES DISAPPEAR!
mb
    J<:S	;		    !* Tabs disappear.!
        -1A-"N -D'>
mb
    J0S_
    <:S; -1A-"N .-1F_' >    !* _ REPLACED BY SPACE!
mb
    J0S

   <:S; -2D 2R>		    !* FLUSH DUPLICATE CRLFS!
mb
    J2F=
 "E 2D'			    !* DELETE ANY LEADING CRLF!
    fq7"n zj-2f=
"e -2d''			    !* IF FILE ENDS AND DOC STARTS WITH CRLF, FLUSH ONE OF THEM!
!*** NOW UN-COMPRESS THE MACRO NAMES BY REPLACING EACH NAME WITH!
!*** THE ORIGINAL STRING WHICH WAS COPIED INTO Q9!
    q9u..o j q8u..o j
    < :S:!;			    !* FIND NEXT MACRO NAME.!
	.(-2S!.,)K		    !* KILL IT.!
	Q9U..O :S:!;		    !* FIND NEXT COPIED MACRO NAME IN Q9!
	.(-2S!.,)X1 fq1c	    !* USE IT TO REPLACE THE COMPRESSED NAME WE KILLED!
	Q8U..O G1 >
!*** PUT THE DOCUMENTATION INTO THE MAIN BUFFER AND KIL THE OTHERS.!
    q8u..o zj g7 q7fs b kill Q9 FS BKILL 
!& Purify BARE File:! !S Purify the file BARE of names of bare TECO ^R functions.
This file is purified so as to make the definitions of those names
appear to be the bare TECO functions.!
    J @I`
      [0 +8+FQ(+4)[1	    !* Q0 string arg, Q1 FO table.!
      0FO1 0 F"G (		    !* If found, get string in file!
       )+Q1U0 FQ0-3"G Q0'	    !* If string is more than 3 chars, return it.!
         F0 @FS ^R Init'   !* Else use as name of character, get initial TECO defn.!
      +FQ()+4U1		    !* Lost, get pointer to next file!
      FQ1"L 0'		    !* No more files =) return 0 *!
      ,Q1:M(Q1+4(]1 ]0))	    !* Else pass rqs to next file *!
      `
    1:m(m.m &_Purify_Buffer)
!& Purify Buffer:! !S Convert macros in buffer to :EJ'able format.
Assumes compression has been done already, if desired.
Nonzero numeric arg means leave out the ~INVERT~ macro
and the loader macro.  The caller should already have put in
an ~INVERT~ macro if desired, and inserted the loader macro
at the front of the buffer, leaving point after it.!

[a[b[c 0ua fsruntimuc
@:ib` %a,-1*qc+(fsruntimuc qc)= `
:ib				    !* For now, turn off runtime printout!
    [0 [1 [2 [3 [4 [5 [6 [7 [8 [9 f[ s string
mb
"e
!*** Now put an ~INVERT~ macro in the file.!
!*** The ~INVERT~ macro is the inverse of the loader macro:  given!
!*** <object> and <ptr to file>, it returns the name of the object as a string!
    zj -2f=
 "e -2d'			    !* Dont make a duplicate CRLF at end of bfr!
    zj @i|

!~INVERT~:!
+8+fq(+4)[2 0[3			!* 2: FO table!
					!* 3: index into table!
< %3,-q2f2u3 q3&1@; q3"l 0' >	!* search FO table, exit if even,!
					!* return 0 if not found!
f[BBind q3-1*5,q3*5g2 q:..o(0)+q2	!* get string pointer from pure!
|					!* string, and return!

!*** NOW PUT A COPY OF THE LOADER AT THE FRONT OF THE FILE!
    J @I`
    [0 +8+FQ(+4)[1	    !* Q0 string arg, Q1 FO table.!
    0FO1 0 F"G +Q1 '	    !* If found, get value, relocate and return.!
	+FQ()+4U1		    !* Lost, get pointer to next file!
        FQ1"L 0'                  !* No more files =) return 0 *!
        ,Q1:M(Q1+4(]1 ]0))        !* Else pass rqs to next file *!
	`
mb
    '

!*** END OF SECTION INHIBITED BY NUMERIC ARGUMENT TO & PURIFY BUFFER.!
    .+8u1 q1+4/5*5+1-q1,32i	    !* Follow loader with padding making table!
				    !* eventually come out on word boundary!
    .+4u5 j 177.i q5&177.i q5/200.&177.i q5/40000.&177.i q5j
					!* add loader string header!
					!* 5: start of table!

!*** now, for each macro, convert it into a string,!
!*** and accumulate in buffer in Q9 the data for the table, in ascii: !
!*** For each name, the first line is the name, and the second!
!*** Has the two numbers that will go in the table eventually.!
    0u6 0u7				!* 6: function strings length!
					!* 7: no. of functions!
    q..ou8 f[BBind [..o q..ou9 q8u..o	!* 8: source buffer,!
					!* 9: auxillary buffer!
    <	.-z; .u3 :x2 q9u..o .( g2 )j	!* put function names in Q9!
					!* 3: start of function!
	:fb:!"l
	  0l
	  < 1a-32"e d'
	    1a-!"n 0;'
	    d .(s:!	    !* Put a CRLF after this function name,!
   .u2)j Q2-.+2u2		    !* and Q2 gets length plus 4.!
	    177.i q2&177.i q2/200.&177.i q2/40000.&177.i
				    !* Add string header before the name.!
	    l q6+q2u6 q3-q5\ i	    !* After the name, put a line containing address of defn.!
   %7w				    !* 7: count number of names defined.!
	    .-z;>
	  q8u..o :k'		    !* Back to source buffer; kill line with fn names, if any.!
	"#  .,zk q8u..o i	    !* If none, assume line wasn't there, and make blank one.!
 2r'
	z-2-2u4 :s

"l .-3-2-2u4'			    !* Q4 points at end of function.  -2 matches CRLF!
 "# zj 0@f"n :i*No_CRLF_at_end_of_COMPRS_file fs err''
	q3j 2d			    !* deleted here, which used to follow function names.!
				    !* Another -2 is for CRLF at end before ^L, which will go.!
	q4-.+4u4 177.i q4&177.i q4/200.&177.i q4/40000.&177.i
	q4-4c			    !* Skip to end of function.!
	2d .-z"n 3d' >		    !* Delete page boundary if not at eof.!
				    !* Delete terminal CRLF in any case.!

    q5j q7*10+5+4u4 177.i q4&177.i q4/200.&177.i q4/40000.&177.i
					!* insert table string header!
    q4-4,0i				!* make space for table!
    .u4 q6,0i .-q5u6			!* make space for function names!
					!* 4: name table!
					!* 6: offset of no.s in auxiliary!
					!* buffer!
mb
!*** Now pad whole file to even # of K, and make the header for the whole file.!
    q8u..o
    Z+4+(2000.*5)-1/2000./5U2	    !* SIZE OF FILE, IN K.!
    Q2*2000.*5U2                    !* ULTIMATE SIZE OF FILE, IN CHARS.!
    J 177.I Q2&177.I		    !* THEN FIX THE HEADER, TURNING!
    Q2/200.&177.I Q2/40000.&177.I   !* THE FILE INTO ONE BIG STRING.!
    ZJ Q2-(Z-B),0I		    !* FILL FILE OUT TO A K BOUNDARY!
    q4+4u4 q5+4u5		    !* Relocate pointers to tables.!
    1f?				    !* Flush gap now or else would destroy low bits!
mb
!*** Now sort the ascii table-precursor in q9!
    q9u..o
    1f[^p case
     4c  l  l 
    f] ^p case
mb
!*** Now put the numbers in the table precursor into the space allocated!
    q5+4/5u1			    !* Get word addr of table data (skip table headers)!
    q1*5-q5-4"n @feDSI fsErr'	    !* We supposedly made table data!
				    !* start on word boundry.!
    2u:8(q1)			    !* Start the table with a 2 (# wds per entry).!
    j < .-z; .(4cl),.-2x2 q4:f82	!* add name string!
	q4-q5u:8(%1) q4+fq2u4	    !* Put name address in table.!
	\+q6u:8(%1) l>		    !* Get function address, relocate,!
				    !* and add to table!

    q8u..o j 			    !* The end!
!& Compress Var List:! !S Compress a varlist file such as EMACS;VARS >.
Turns it into a standard COMPRS file containing one definition,
for && Variable Name List, whose value contains pure strings,
one for each of the lines present in the source file.!
    et_comprs eihpef
    
!& Compress File:! !S Compress file of macros.
Input file taken as string argument.  Output is written
in file with FN2 of COMPRS.  If the COMPRS file already
exists and is more recent, the operation is skipped
(however an explicit numerical argument forces compilation anyway).!
    [0 :i0			    !* Read filename argument!
    f[ d file -1f[ Fnam Syntax    !* Be sure FN2 defaults to greater than !
    fs uread"n e[  fn e]'	    !* Dont clobber filenames or files!
    fs uwrite"n e\  fn e^'
    0[1				    !* Now get date of COMPRS file (0 if no file)!
    et 0  1:< er  COMPRS fs if cdateu1 >
    er 0
    ff"e fs if cdate-q1"L '' !* If no numeric arg, and COMPRS file more recent, all done!
    1:< ed _COMPRS>		    !* Otherwise, delete the old COMPRS file.!
	    !* On Twenex, multiple versions would pile up.!
    FT Compressing_file_0

    f[ b bind @y		    !* Else read in and hack the source file!

    15f~! *_Varlist_File(
       m(m.m &_Compress_Buffer)
    )"e				    !* For special Varlist files,!
      jl			    !* Go to first variable name.!
      iVar_List_Name_Body

      < .-z;			    !* Make each variable name be its own page,!
        1a-
"e i
		    !* Putting an empty macro after the last one.!

  0;'
        i
			    !* with no macro name in front of it,!
 l>'				    !* So each one will become a separate string.!

    et  COMPRS ei hp ef 
!TCompile:! !C Compile macro to be tried out.
Compile (compress) the buffer or the current page
as an EMACS function definition, and define the
function name(s) at the front.
The compiled definition is also returned as a value.!

    f[vb f[vz .[1  fn q1j	    !* preserve bounds and point!
    < -:s

; 2F=
"E fkc 0;'> .fsvb		    !* Find start of this macro.!
    :s

: fsz-.fsvz			    !* Find end of this macro.!
    q..O[0 f[bbind g0		    !* COPY THE BUFFER!
    J
    < @f
	k	    !* Flush whitespace at beginning.!
      2f=! *:@;		    !* If there is a comment at the beginning,!
      2s! b,.k >		    !* Flush it.!
    < :s:!; >		    !* Find end of last macro name.!
    .[3 [4 [5 [6
    Q3-B"G
      2F~_!"N :I* Bad_macro_documentation_beginningFS ERR'
      2C S! :@F"N !"!
        :I* Macro_documentation_doesn't_end_at_end_of_line FS ERR'
      Q3+2,.-1X5		    !* Save away macro documentation.!
      Q3,.+2K			    !* Kill it too.!
      < .,b:fb:!;		    !* Find end of next function name (going backwards)!
        .u4 -s!		    !* Find start of it.!
	.+1,q4X4
	1,m.m_~DOC~_4u6	    !* Unless macro already ha correct doc string,!
	:f=56"n
	q5m.vMM_~DOC~_4'	    !* define the doc string.!
	>'
    b,Q3fx3			    !* Save macro names in Q3 for storing in later.!
    j i

!*** DELETE COMMENTS AND SPACES, AND CONVERT _S TO SPACES!
    J<:S!*;
        .-2,( S! .)K               !* COMMENTS DISAPPEAR!
	@-F_	K>	    !* along with the spaces and tabs before them.!
    J<.-Z; @F	_K	    !* Delete spaces and tabs at fronts of lines.!
           L>
    J 0S_ <:S;
        -1A-"N -D'>		    !* SPACES DISAPPEAR!
    J<:S	;
        0,-1A-"N -D'>	    !* Tabs disappear.!
    J<:S_;
        0,-1A-"N .-1F_' >      !* _ REPLACED BY SPACE!
    J<:S

; -2D 2R>			    !* FLUSH DUPLICATE CRLFS!
    ZJ -2F=
"E -2A-"N -2D''		    !* FLUSH ANY CRLF AT THE END.!
    2,ZFX*[4			    !* Get compressed macro in Q4.!
    HK G3 J			    !* Get back the macro's names.!
    < :S!; 0,.K :S:!; -2D	    !* Find next name,!
      B,.FX3 Q4M.V MM_3 >	    !* define it.!
    Q4			    !* Return the definition.!


!* 
** Local Modes:
** Compile Command: M(M.M Generate Library)EMACS;[PRFY] >EMACS1;PURIFYEMACS1;CCL
** End:
*!