[net.sources] Super C+ mode for Emacs

ray@othervax.UUCP (10/17/84)

		C+MODE INSTALLATION INSTRUCTIONS

Use "sh" to unbundle this distribution file after the cut line below.  You
should then have the following files:

	c+.doc			;documentation of the C+ mode
	c+mode.ml		;the main C+ mode program
	c-layout.ml		;the C+ parameterisation file
	reindent-c.ml		;auxilliary C+ routine
	beautify-c.ml		;auxilliary C+ routine

The files should be copied into a suitable maclib directory, whose pathname
should be edited into the (setq lib-dir "....") statement at line 13 in
c+mode.ml.

In addition two other lines may require editing:

(setq comment-check 1)	   line 15, file c+mode.ml, should be edited
			   according to whether your Emacs has the fix to
			   the backward-paren bug in which parenthesis
			   inside comments are not ignored, and '\\' and
			   single quotes etc. screw things up.

(setq xemacs-key "^X^C")   line 28, file beautify-c.ml, should be edited if
			   exit-emacs is not bound to ^X^C.


Read the c+.doc and c-layout.ml files, and edit c-layout.ml to reflect your
required house or personal style.

c-layout.ml can be copied into ~/maclib/c-layout.ml of any user wishing to
have his own pet format.

To default automatically to C+ mode for C programs, your .emacs_pro file
should contain lines in the form:-

	 	(autoload "c+mode" "...../maclib/c+mode.ml")
		(auto-execute "c+mode" "*.c")
		(auto-execute "c+mode" "*.h")

I am currently in the process of changing employers to one with a VAX but
not on the net (horrors).  Mail sent to the below net address will still
reach me, but I will not be able to reply until I get the other site onto
the net (shortly).

PLEASE SEND YOUR COMMENTS - POSITIVE AND NEGATIVE.  I will respond whenever I
can, however for the time being treat all 'bugs' as features!

Best of luck to everyone, over 50 requests were received, so there is an
obvious gap which I hope C+ adequately fills.


Ray Dunn.  Montreal.

Current net address:	...decvax!linus!philabs!micomvax!othervax!ray

CanadaPost address:	Ray Dunn
			62 Midland Avenue
			Beaconsfield.
			Quebec.
			H9W 4P1

Telephone:		(514) 694 4605


------CUT------CUT------CUT------CUT------CUT------CUT------CUT------
:  To unbundle, "sh" this file -- DO NOT use csh
:  Modified SHAR archive format.  Archive created Tue Oct 16 19:50:31 EDT 1984
echo x - c+.doc
sed 's/^X//' > c+.doc <<'+ END-OF-FILE 'c+.doc
X			  C+MODE
X			  ------
X		EMACS EDITOR MODE FOR C PROGRAMS
X		--------------------------------
X
XINTRODUCTION
X------------
X
XThe C+ Emacs mode is a powerful assistant when inputting and editing C
Xprograms.  It is easily configured to suit your own pet layout format (or
Xthe one imposed on you), and automatically inserts line feeds and
Xindentations where specified.
X
XUnlike existing C modes, the indentation algorithm produces a correct
Xindentation dependant upon the preceding lines of code.  In most cases when
XC+ indents to an un-expected position, it means that you have a syntax error
Xon an earlier line!
X
XTogether with optional automatic action on all the various parenthesis
Xcharacters and other syntactically meaningful characters like ';', ':', ',',
Xand '/*', the main functions of the package are provided on the TAB,
XESC-TAB, RETURN and LINEFEED keys.  In addition several other features and
Xkey bindings are used as described below.
X
XAll the special character actions are inhibited if typed within quotes (both
X'"' and ''') and also within comments (see later).
X
XTo default automatically to C+ mode for C programs, your .emacs_pro file
Xshould contain lines in the form:-
X
X	 	(autoload "c+mode" "...../maclib/c+mode.ml")
X		(auto-execute "c+mode" "*.c")
X		(auto-execute "c+mode" "*.h")
X
X
XAs implemented in Mlisp, C+ can not be said to be super fast, however if
Xconfigured in a semi-automatic mode (i.e. using ESC-TAB for re-indenting)
Xspeed is adequate on our 11-70 while the load remains below 12.  It was
Xintended to re-implement C+ in C as an extension to Emacs itself,
Xunfortunately, as Emacs is written in such a way that the Mlisp standard
Xfunctions can not easily be called from within Emacs (they assume they are
Xgetting their arguments from Mlisp), it has proved to be not a trivial task
X(..flame..flame..).  
X
X
X
XPARAMETERISATION
X----------------
X
XAll the features of the mode (both user-interface and program format) are
Xprofilable to personal taste.  Some of these profiling features are described
Xbelow, the rest in the file c-layout.ml which should also be digested.
X
XThe c-layout.ml file in the Emacs Mlisp library defines the default values
Xfor all variables which control the mode's actions.
X
Xc-layout.ml can be copied into ~/maclib/c-layout.ml of any user wishing to
Xhave his own pet format.
X
XA serious attempt has been made to make the parameters as general as
Xpossible to please most of the people most of the time, however experience
Xdictates that you may be forced into a slightly different style if you want
Xto take advantage of all the C+ features.
X
XAll possible combinations of all the variables have not been tested, nor are
Xall necessarily sensible.
X
X
X
XINDENTATION - SOME NOTES
X------------------------
X
XWhen using C+ you need never worry again about tabbing and spacing to the
Xcorrect indent position, nor cursoring right over existing indents!
X
XThe value of the variable c-unit-indent determines the number of spaces per
Xindent depth.  Tab characters are used whenever possible in the indentation.
XBecause skipping over the indent is handled automatically, there is no real
Xadvantage in having indents as a multiple of 8 characters, indeed except for
Xthose of you (note: not "us") to whom an 8 character indent is cast in
Xstone, there are significant advantages in readability when each indent is
X3, 4 or 5 characters wide.
X
XWhen a blank line is indented, the indentation may not be suitable for the
Xcontents about to be typed (e.g. a protruding label, an else clause, a
Xpre-processor statement). DONT PANIC (qv HHGTTG), this will automatically be
Xcorrected when the line is input and terminated, or may manually be
Xcorrected using ESC-TAB.
X
XThe indentation algorithm assumes all lines preceding it in the current
Xprocedure are indented correctly.  A line incorrectly indented may cause
Xsubsequent lines to be indented incorrectly also.
X
X"Non-standard" indentations can not be handled correctly by the program, in
Xparticular, the practice of indenting declaration lines thus:
X
X	    register int x,
X		         y,
X			 z;
X
Xis unfortunately not supported.
X
XThe use of pre-processor macros may upset the indentation algorithm,
Xparticularly if lines which syntactically are terminated by a semi-colon, do
Xnot contain them because of the use of macros.
X
XOther than parenthesis and line terminating conditions, the only syntax
Xwords recognised and used by C+ for the computation of indents, are 'if',
X'else' ('elseif' is allowed) and '#' preprocessor definition lines (always
Xkept at the left margin).
X
XIn general more than one statement should not be placed on a single line
X(except simple semi-colon terminated statements), otherwise C+ may become
XC-.
X
XThe use of parenthesis and unmached quotes inside comments, and '\\', will
Xconfuse C+ unless your version of Emacs has the fix to this bug (in
Xbackward-paren & forward-paren).  The comment-check flag at line 15 of file
Xc+mode.ml should be set according to whether your Emacs has this bug or not.
XIf set this flag only makes C+ mode skip over certain comment situations,
X'\\' is not corrected for.  A full correction at this level would be too
Xcpu time consuming.
X
XNOT ONLY ARE SMALL PROCEDURES GOOD PROGRAMMING PRACTICE, BUT ALSO MAKE FOR
XMORE EFFICIENT C+ INDENT CALCULATION.
X
X
X
XKEY BINDINGS AND COMMANDS
X-------------------------
X
XThe (*) denotes the default settings of the variables in the package as
Xdistributed.
X
XC+MODE	  Extended command which enters the C+ mode for the current buffer.
X	  To default automatically to C+ mode for C programs, your .emacs_pro
X	  file should contain lines in the form:-
X	 	(autoload "c+mode" ".....maclib/c+mode.ml")
X		(auto-execute "c+mode" "*.c")
X		(auto-execute "c+mode" "*.h")
X	  
X
XTAB	  Action is controlled by variables re-indent-on-tab
X					    skip-indent-on-tab.
X
X	  re-indent-on-tab = 1
X
X	    When dot is at the start of a line, TAB computes the correct
X	    indent for the line, adjusts the line if necessary, and leaves
X	    dot at the indent position.
X
X     (*)  re-indent-on-tab = 0 & skip-indent-on-tab = 1
X
X	    When dot is at the start of a line, TAB causes dot to be moved
X	    to the EXISTING indent position (i.e. normally to the first
X	    non-white-space character).
X
X	  In either of the above cases:-
X
X	    If the first non-white-space character on the line is a '{' or
X	    '}', a subsequent TAB or ESC-TAB will move dot to after the
X	    parenthesis to the next correct indent position.
X
X	    A TAB in any other situation acts normally, i.e. inserts a tab
X	    character.
X
X	    IF DOT IS AT THE BEGINNING OF A BLANK LINE, TAB ALWAYS ACTS AS
X	    IF RE-INDENT-ON-TAB = 1
X
X	  re-indent-on-tab = 0 & skip-indent-on-tab = 0
X
X	    No special action is taken on TAB, ESC-TAB must be used for
X	    re-indenting.
X
X
XESC-TAB	  Re-computes the indent for the current line, and adjusts the line
X	  if necessary. 
X
X	  If dot is at the beginning of the line, it is left as for TAB
X	  (including the insertion of an indent in blank lines), otherwise
X	  dot is left unchanged.
X
X
XRETURN	  Action is controlled by the variables newline-on-cr 
X					        indent-on-newline
X
X     (*)  newline-on-cr = 1
X
X	    A newline is always inserted after CR is pressed (in the
X	    traditional Emacs way).
X
X	  newline-on-cr = 0
X
X	    A newline is not inserted unless at the end of the buffer, or an
X	    insert-space has been created by opening up at least two blank
X	    lines using the LINEFEED key.  Thus if several lines have to be
X	    inserted in existing text, LINEFEED key should be hit twice, now
X	    as the insertion is typed, the following text will continue to
X	    drop down to make room for the insertion.  When the insertion is
X	    complete, the extra blank line should be deleted.
X
X	  In both cases, dot is left at the start of the line if
X	  indent-on-newline = 0, at the computed indent position if
X	  indent-on-newline = 1.
X
X	  With indent-on-newline = 0, use ESC-TAB to indent.
X
X
XLINEFEED  Action is controlled by the variable indent-on-newline
X
X	  The LINEFEED key is used to open up space for the insertion of one
X	  or more lines.  Any characters to the right of dot are moved to
X	  the next line and dot REMAINS IN THE CURRENT LINE.
X
X	  If indent-on-newline = 1, then the characters moved to the next
X	  line will be re-indented, and if dot is anywhere prior to the first
X	  non-white-space character in the line, it will be moved to the
X	  correct indent position ready for insertion of the new line.
X
X
X{ and }	  Action controlled by the variables newline-before-{
X					     nextline-after-{
X					     spaces-before-{ 
X					     spaces-after-{
X					     newline-before-} 
X					     nextline-after-} 
X					     spaces-before-} 
X					     spaces-after-}
X
X	  The c-layout.ml file describes the values of the above variables
X	  in detail.  When the '{' or '}' is typed, newlines and spaces are
X	  inserted as required to meet the layout specifications.
X
X	  It is neither necessary nor desirable to adjust dot to the
X	  accurate position of the required parenthesis prior to typing it,
X	  as its position will be recalculated anyway.  Thus, e.g. the
X	  parenthesis may be typed at the start of a line without moving to
X	  the correct indent position.  It will be positioned correctly by
X	  the program.
X
X	  When '}' is typed, the corresponding open parenthesis position is
X	  displayed.
X
X
X(	  Action controlled by the variable spaces-before-bracket
X
X	  If the character preceding the '(' is a letter, then
X	  spaces-before-bracket spaces are inserted prior to the bracket.
X
X	  Even if spaces-before-bracket = 0, one space is still always
X	  inserted if the bracket is immediately preceded by 'if', 'for',
X	  'switch' or 'while'.
X
X	  The variable indent-on-bracket controls how the mode will indent
X	  subsequent lines within such an open bracket.
X
X
X) & ]	  Show the position of their corresponding open brackets.
X
X
XESC-}
XESC-)
XESC-]	  Close off ALL outstanding open brackets of their type!  Gosh!
X
X
X;	  Action controlled by variables nextline-after-semicolon
X					 spaces-after-semicolon
X
X	  nextline-after-semicolon = 1
X
X	    Whenever ';' is type, dot is moved to the start of the next
X	    line,, a newline is inserted if newline-after-nextline = 1, and
X	    dot is left at the recomputed indent position if
X	    indent-on-newline = 1.
X
X	    If the ';' is typed within an open '(' on the same line (e.g. in
X	    a for statement), the cursor is not moved to the next line.
X
X	  Otherwise
X
X	    spaces-after-semicolon spaces are inserted.
X
X
X,	  Action controlled by variable spaces-after-comma
X
X	  Spaces-after-comma spaces are inserted following a comma.
X
X
X:	  Action controlled by variables label-protrusion
X					 case-protrusion
X					 newline-after-label
X
X	  If the typed ':' produces a label (immediately preceded by an
X	  alpha-numeric string i.e. with no interveneing white-space), or a
X	  case specifier (case ...:), the statement is dedented by the
X	  specified amount (hard to the left margin if a large negative
X	  protrusion is specified), and dot moved to the next line etc under
X	  the control of newline-after-label, newline-on-nextline and
X	  indent-on-newline.
X
X
XESC right arrow
X	  Bound to forward-paren
X
XESC left arrow
X	  Bound to backward-paren
X
XESC-J	  Runs the standard indent program on the procedure enclosing dot, qv
X	  existing c modes.
X
XESC-I	  Reindents the procedure enclosing dot using the C+ indentation
X	  algorithm.  This does not re-format the procedure, only reindents
X	  it line by line.
X
XESC-C	  Manual switch between Comment mode and C+ mode.  Should be used
X	  when dot is moved into an existing comment for editing.
X
X/*	  Enters comment mode automatically.
X
X	  In this mode, all the above actions are inhibited, and the
X	  variables	comment-column
X			comment-start-string
X			comment-prefix-string
X			comment-end-string
X			nextline-after-comment
X	  control the action (see their descriptions in c-layout.ml).
X
X	  Automatic overflow from one line to the next is provided, with a
X	  prefix string being inserted.
X
X	  TAB may still be used to get dot from the start of a line to the
X	  first non-white-space character.
X
X	  Comment mode is exited and C+ mode re-entered automatically when
X	  '*/' is typed, or manually by typing ESC-C.
X
X	  Nested comments cannot be handled (shame..shame).
X
X
XBEAUTIFY-C
X	  This extended command re-formats the WHOLE BUFFER, using the C+
X	  formatting parameters, including the nextline-after-... variables
X	  which must be specifically set for your requirements.
X
X	  The variable values you use for interactive use are not
X	  necessarily those you want for Beautify.  E.g. you may want
X	  nextline-after-} = 0 for interactive use so you can insert
X	  comments after your parenthesis, but if you run Beautify with this
X	  it will not insert newlines after }'s!  If
X	  nextline-after-semicolon = 0 then lots of statements will be put
X	  on each line!.
X
X	  The file b-layout.ml may be created in your own maclib directory,
X	  being a copy of the c-layout.ml file but with the parameters set
X	  up for Beautify.  This will be loaded, if it exists, whenever
X	  Beautify is called, the c-layout being restored on exit.
X
X	  This process is SLOW (spelled g-o-f-o-r-l-u-n-c-h), but it should be
X	  a rarely used feature (i.e. once only on a file not in your pet
X	  format).  It is not guaranteed to get the format perfect under all
X	  circumstances, but should leave the file so that only a few manual
X	  fix-ups are required.  Flames will not be accepted!
X
+ END-OF-FILE c+.doc
echo '-rw-r--r-- 1 ray       13453 Oct 16 16:41 c+.doc    (as sent)'
chmod u=rw,g=r,o=r c+.doc
ls -l c+.doc
echo x - c+mode.ml
sed 's/^X//' > c+mode.ml <<'+ END-OF-FILE 'c+mode.ml
X; Copyright (c) Raymond D. Dunn. Montreal. 1984.  All rights reserved.
X; This software or any part therof may not be sold, or otherwise disposed of
X; for gain, whether by itself, or in combination with any other software or
X; computer product of any description, without the express written consent of
X; the author.
X
X; Extra powerful 'C+' mode - does all indenting automatically for you and
X; formats on comments, brackets, comma, semi-colon etc. according to user
X; specified parameters.
X
X(declare-global lib-dir comment-check)
X
X(setq lib-dir "~ray/maclib")	;defines the path to your C+ mlisp library
X
X(setq comment-check 1)		;set this to 1 if your emacs does NOT have the
X 				;fix to the backward-paren bug in which
X 				;parenthesis inside comments are not ignored,
X 				;and \\ and single quotes etc. screw things up.
X 				;This will not fix the problem completely, but
X 				;alleviates it somewhat.
X
X(declare-global indent-options in-comment-mode beautify-mode indent-val
X                pre-{-str  post-{-str  {-str  }-str
X		non-bol-{-str  non-bol-}-str
X		label-protrusion  case-protrusion
X		comment-start-string comment-prefix-string quoted-prefix-string
X		comment-end-string  nextline-after-comment
X		c-unit-indent  spaces-pre-{  spaces-post-{  {-posn
X		indent-from-{  comma-string  semicolon-string max-space-string
X		spaces-before-bracket  indent-within-bracket
X		newline-before-}  nextline-after-}
X		spaces-before-} spaces-after-}
X		newline-before-{  nextline-after-{
X		spaces-before-{  spaces-after-{  spaces-after-semicolon
X		nextline-after-semicolon  nextline-after-label
X		spaces-after-comma  re-indent-on-tab  skip-indent-on-tab
X		indent-on-newline newline-on-cr newline-on-nextline
X)
X
X(defun
X  (init-c-vars		;define working variables from parameterisation
X    (setq max-space-string "              ")
X    (setq spaces-pre-{ (if newline-before-{  spaces-before-{  0))
X    (setq spaces-post-{ (- c-unit-indent (+ spaces-pre-{ 1)))
X
X    (setq pre-{-str (substr max-space-string 1 spaces-pre-{))
X    (setq post-{-str (substr max-space-string 1 spaces-post-{))
X    
X    (setq {-str (concat pre-{-str "{" post-{-str))
X
X    (setq }-str 
X      (concat "}"
X	(if nextline-after-}
X	    "" 
X	    (substr max-space-string 1 spaces-after-}))))
X    
X    (setq non-bol-{-str
X      (concat
X	(substr max-space-string 1 spaces-before-{)
X	"{"
X	(if nextline-after-{
X	    ""
X	    (substr max-space-string 1 spaces-after-{))))
X
X    (setq non-bol-}-str
X      (concat
X	(substr max-space-string 1 spaces-before-})
X	"}"
X	(if nextline-after-}
X	    ""
X	;else
X	    (substr max-space-string 1 spaces-after-})
X	)))
X
X    (setq semicolon-string
X      (concat ";" (substr max-space-string 1 spaces-after-semicolon)))
X      
X    (setq comma-string
X      (concat "," (substr max-space-string 1 spaces-after-comma)))
X
X    (setq quoted-prefix-string (concat "[ \t]*" (quote comment-prefix-string)))
X    (setq indent-from-{  (+ 1 spaces-post-{))
X    (setq beautify-mode 0)
X  )
X)
X
X(declare-global if-line-match     paren-if-match      non-prog-line-match
X                else-line-match   elseif-line-match   if-elseif-line-match
X		pre-proc-line-match
X                label-line-match  case-line-match     comment-line-match
X		exclusion-line-match paren-label-line-match)
X
X;Note:  The use of variables for these match strings is to make the code more
X;	readable, however mlisp procedures are significantly slower when given
X;	a string valued variable rather than a string constant (presumably cos
X;	in the former, a copy of the string is made). It may be wise to replace
X;	these variables by their values.
X
X(setq if-line-match "[ \t]*if[^a-zA-Z0-9_]")
X(setq paren-if-match "{[ \t]*if[^a-zA-Z0-9_]")
X(setq else-line-match
X    "[ \t]*else[^a-zA-Z0-9_]\\|[ \t]*elseif[^a-zA-Z0-9_]\\|[ \t]*else\\'\\|[ \t]*elseif\\'")
X(setq elseif-line-match
X    "[ \t]*else[ \t]*if[^a-zA-Z0-9_]\\|[ \t]*else[ \t]*if\\'")
X(setq if-elseif-line-match
X    "[ \t]*if[^a-zA-Z0-9_]\\|[ \t]*else[ \t]*if[^a-zA-Z0-9_]\\|[ \t]*else[ \t]*if\\'")
X(setq label-line-match
X    "[ \t]*[a-zA-Z_][a-zA-Z0-9_]*:\\|[ \t]*case[^a-zA-Z0-9_][^:]*:")
X(setq paren-label-line-match
X    "[{ \t]*[a-zA-Z_][a-zA-Z0-9_]*:\\|[{ \t]*case[^a-zA-Z0-9_][^:]*:")
X(setq case-line-match
X    "[ \t]*case[^a-zA-Z0-9_].[^:]*:\\|[ \t]*default:")
X(setq comment-line-match "[ \t]*/\\*")
X(setq pre-proc-line-match "[ \t]*#")
X(setq non-prog-line-match
X    (concat
X      comment-line-match "\\|" label-line-match "\\|" pre-proc-line-match))
X(setq exclusion-line-match
X    (concat
X      label-line-match "\\|" else-line-match "\\|" pre-proc-line-match))
X
X(defun
X  (c-{
X    (if (not-literally-inserted '{')
X	(progn
X	  (delete-white-space)
X	  (if (bolp)
X	      (progn 
X		(insert-character '{')
X		(indent-c-line)
X		(re-search-forward "[ \t{]*")
X		(conditional-newline nextline-after-{ newline-on-nextline)
X	      )
X	  ;else not at bol
X	      (progn
X		(if newline-before-{
X		    (progn 
X		      (newline)
X		      (c-{)
X		    )
X		;else
X		    (progn
X		      (insert-string non-bol-{-str)
X		      (conditional-newline
X			nextline-after-{ newline-on-nextline)
X		    )
X		)
X	      )
X	  )
X	)
X    )
X  )
X
X  (c-}		;this is complicated by its interaction with c-close-all
X                ;which must be able to recover from one too many c-}
X    (if (not-literally-inserted '}')
X	(progn
X	  (delete-white-space)
X	  (if (bolp)
X	      (progn
X		(insert-character '}')
X		(save-excursion (indent-c-line))
X		(if (! nextline-after-})
X		    (insert-string (substr max-space-string 1 spaces-after-})))
X		(conditional-newline nextline-after-} newline-on-nextline)
X		(display-match {-posn 1 (interactive))
X	      )
X	  ;else not at bol
X	      (progn
X		(if (| (! newline-before-})
X		       (save-excursion
X			 (re-search-reverse "{\\|^")
X			 (looking-at "{")))
X		    (progn 
X		      (insert-character '}')
X		      (save-excursion
X			(backward-paren)
X			(setq {-posn (dot)))
X		      (delete-previous-character)
X		      (insert-string non-bol-}-str)
X		      (conditional-newline
X			nextline-after-} newline-on-nextline)
X		      (display-match {-posn 1 (interactive))
X		    )
X		;else
X		    (progn
X		      (newline)
X		      (c-})
X		    )
X		)
X	      )
X	  )
X	)
X    )
X  )
X  
X  (c-colon
X    (if (not-literally-inserted ':')
X	(progn
X	  (insert-character ':')
X	  (if (save-excursion
X		(beginning-of-line)
X		(looking-at paren-label-line-match)
X	      )
X	  ;then
X	      (conditional-newline nextline-after-label newline-on-nextline)
X	  )
X	)
X    )
X  )
X
X  (c-cr
X    (conditional-newline 1 newline-on-cr)
X  )
X
X  (c-nl
X    (if (| (bolp)
X	   (save-excursion
X	     (re-search-reverse "^[ \t]*\\=\\|$\\|'")
X	     (!(looking-at "\n"))))
X    ;then
X	(progn posn
X	  (setq posn (current-column))
X	  (beginning-of-line)
X	  (newline)
X	  (backward-character)
X	  (to-col posn)
X	)
X    ;elseif
X	(looking-at "[ \t]*$")
X	(save-excursion 
X	  (newline)
X	  (if indent-on-newline (indent-c-line))
X	)
X    ;else
X	(progn
X	  (conditional-newline 1 newline-on-cr)
X	  (previous-line)
X	  (beginning-of-line)
X	  (if (looking-at "[ \t]*{[ \t]*$")
X	      (progn
X		(end-of-line)
X		(delete-white-space)
X		(insert-string post-{-str)
X	      )
X	  ;else
X	      (end-of-line)
X	  )
X	)
X    )
X  )
X
X  (c-tab
X    (if (bolp)
X	(progn
X	  (if (| re-indent-on-tab (looking-at "[ \t]*$"))    
X	      (indent-c-line)
X	  ;else
X	      (dot-after-current-indent)
X	  )
X	  (if (& (bolp)(looking-at "[ \t]*[{}]")) ;zero indent pathologl case
X		  (re-search-forward "[ \t]*[{}][ \t]*")
X	  )
X	)
X    ;elseif
X	(looking-at "[ \t]*[{}]")
X	(re-search-forward "[ \t]*[{}][ \t]*")
X    ;else
X	(insert-character '\t')
X    )
X  )
X
X  (c-esc-tab
X    (if (bolp)
X	(progn
X	  (indent-c-line)
X	  (if (& (bolp)(looking-at "[ \t]*[{}]")) ;zero indent pathologl case
X	      (re-search-forward "[ \t]*[{}][ \t]*")
X	  )
X	)
X    ;elseif
X	(looking-at "[ \t]*[{}]")
X	(progn 
X	  (indent-c-line)
X	  (re-search-forward "[ \t]*[{}][ \t]*")
X	)
X    ;else
X	(save-excursion (indent-c-line))
X    )
X  )
X
X  (dot-after-current-indent
X    (re-search-forward "[^ \t]")
X    (backward-character)
X    (if (& (!(bolp))
X	   (& (looking-at "[{}]") (& newline-before-{ spaces-before-{)))
X	(to-posn (- (current-column) spaces-before-{))
X    )
X  )
X    
X  (to-posn posn
X    (setq posn (arg 1))
X    (if (> posn 0)
X	(while (> (current-column) posn) (backward-character))
X    )
X    (if (< (current-column) posn) (to-col posn))
X  )
X  
X  (c-cmnt-tab
X    (if (& (bolp)(!= 1 left-margin))
X	(if (| re-indent-on-tab (looking-at "[ \t]*$"))
X	    (indent-c-line)
X	;else
X	    (dot-after-current-indent)
X	)
X    ;else
X	(insert-character '\t')
X    )
X  )
X    
X  (c-comma
X    (if (not-literally-inserted ',')
X	(insert-string comma-string)
X    )
X  )
X
X  (c-bracket
X    (if (not-literally-inserted '(')
X	(if (& (! (|(bolp)(bobp)))
X	       (| (save-excursion
X		    (backward-character)
X		    (& spaces-before-bracket (looking-at "[a-zA-Z0-9_]"))
X		  )
X		  (save-excursion
X		    (re-search-reverse "[^a-zA-Z0-9_]\\|\\`")
X		    (forward-character)
X		    (looking-at "if\\|elseif\\|for\\|while\\|switch")
X		  )))
X	;then
X	    (progn 
X	      (insert-string
X		(substr max-space-string 1
X		  (if spaces-before-bracket spaces-before-bracket 1)))
X	      (insert-character '(')
X	    )
X	;else
X	    (insert-character '(')
X	)
X    )
X  )
X  
X  (c-close-bracket
X    (if (not-literally-inserted ')')
X	(progn
X	  (if (& (>= indent-within-bracket 0)
X		 (save-excursion 
X		   (re-search-reverse "[^ \t]\\|^")
X		   (bolp)))
X	      (progn
X		(delete-white-space)
X		(insert-character ')')
X		(indent-c-line)
X		(forward-character)
X	      )
X	  ;else	
X	      (insert-character ')')
X	  )
X	  (save-excursion (display-match 0 0 (interactive)))
X	)
X    )
X  )
X
X  (c-]
X     (if (not-literally-inserted ']')
X	 (progn
X	   (insert-character ']')
X	   (save-excursion (display-match 0 0 (interactive)))
X	 )
X     )
X  )
X  
X  (c-close-all char nextline-after-}
X    (setq char (last-key-struck))
X    (if (not-literally-inserted char)
X	(progn 
X	  (if (= char '}') (c-})
X	      (= char ')') (c-close-bracket)
X	      		   (c-])
X	  )
X	  (setq nextline-after-} 1)
X	  (while (!(error-occured 
X		     (if (= char '}') (c-})
X			 (= char ')') (c-close-bracket)
X			 (c-]))))
X	  )
X	  (delete-previous-character)
X	)
X    )
X  )
X     
X  (aux-c-close
X    (insert-character char)
X    (save-excursion 
X      (if (& (! (error-occured (backward-paren)))
X	     (looking-at "{\\|(\\|\\["))
X	  (progn 
X	    (setq count (+ count 1))
X	    (aux-c-close)
X	  )
X      )
X    )
X    (delete-previous-character)
X  )
X
X  (display-match cur-dot
X    (if (& (arg 3)(! beautify-mode))
X	(progn
X	  (if (arg 2) (sit-for 0))
X	  (setq cur-dot (dot))
X	  (if (!(dot-is-visible)) (sit-for 0))
X	  (if (arg 1)
X	      (goto-character (arg 1))
X	  ;else
X	      (backward-paren)
X	  )
X	  (if (dot-is-visible)
X	      (progn 
X		(sit-for 5)
X		(goto-character cur-dot)
X	      )
X	  ;else
X	      (progn
X		(beginning-of-line)
X		(set-mark)
X		(end-of-line)
X		(message (region-to-string))
X		(goto-character cur-dot)
X		(sit-for 0)
X	      )
X	  )
X	)
X    )
X  )
X
X  (c-semicolon
X    (if (not-literally-inserted ';')
X	(if (| (! nextline-after-semicolon)
X	       (save-excursion
X		 (& (!(error-occured (backward-balanced-paren-line)))
X		    (looking-at "("))
X	       ))
X	    (insert-string semicolon-string)
X	;else
X	    (progn 
X	      (insert-character ';')
X	      (conditional-newline
X		nextline-after-semicolon newline-on-nextline)
X	    )
X	)
X    )
X  )
X
X  (conditional-newline
X    (save-excursion
X      (beginning-of-line)
X      (if (looking-at exclusion-line-match)
X	  (indent-c-line)
X      )
X    )
X    (if (arg 1)
X	(progn
X	  (if (arg 2)
X	      (newline)
X	  ;else
X	      (progn 
X		(if (& (looking-at "[ \t]*$") (!(eobp)))
X		    (progn
X		      (next-line)
X		      (beginning-of-line)
X		    )
X		;else
X		    (newline)
X		)
X		(if (& (!(eobp))
X		       (| (looking-at "[ \t]*$")
X			  (& in-comment-mode
X			     (looking-at
X			       (concat quoted-prefix-string "[ \t]*$")))))
X		    (progn
X		      (newline)
X		      (backward-character)
X		    )
X		)
X	      )
X	  )
X	  (if indent-on-newline (indent-c-line))
X	)
X    )
X  )
X
X  (c-*
X    (if (not-literally-inserted '*')
X	(if (= (preceding-char) '/')
X	    (progn
X	      (if (looking-at "[ \t][ \t]*$")  (delete-white-space))
X	      (delete-previous-character)
X	      (if comment-column  (move-to-comment-column))
X	      (save-excursion (insert-string comment-start-string))
X	      (comment-mode)
X	    )
X	;else
X	    (insert-character '*')
X	)
X    )
X    in-comment-mode
X  )
X
X  (c-/					;only active in comment mode
X     (if (= (preceding-char) '*')
X	 (progn
X	   (if (save-excursion
X		 (beginning-of-line)
X		 (looking-at
X		   (concat quoted-prefix-string "\\*$")))
X	       (progn
X		 (provide-prefix-argument
X		   (+ 1 (length prefix-string))
X		   (delete-previous-character))
X		 (to-col left-margin)
X		 (insert-string comment-end-string)
X	       )
X	   ;else
X	       (progn
X		 (delete-previous-character)
X		 (if beautify-mode
X		     (progn (delete-white-space)(to-col left-margin)))
X		 (insert-string comment-end-string)
X	       )
X	   )
X	   (setq in-comment-mode 0)
X	   (conditional-newline nextline-after-comment newline-on-nextline)
X	   (reenter-c+mode 1)
X	 )
X     ;else
X	 (insert-character '/')
X     )
X     (! in-comment-mode)
X  )
X
X  (not-literally-inserted
X    (if (in-c-literal)
X	(progn
X	  (insert-character (arg 1))
X	  0
X	)
X    ;else
X	1
X    )
X  )
X 
X  (in-c-literal srch  ;hack hack hack
X    (if (bolp)
X	0
X    ;elseif
X	(= 92 (preceding-char))
X	1
X    ;else
X	(save-excursion 
X	  (re-search-reverse "['\"]\\|^")
X	  (if (= 92 (preceding-char)) ;cant [^\\] cos pathalogical bobp case
X	      (progn 
X		(backward-character)
X		(in-c-literal)
X	      )
X	  ;elseif
X	      (looking-at "['\"]")
X	      (progn 
X		(setq srch (following-char))
X		(c-str-match)
X	      )
X	  ;else
X	      0
X	  )
X	)
X    )
X  )
X	
X  (c-str-match
X    (if (bolp)
X	1
X    ;else
X	(progn 
X	  (re-search-reverse "['\"]\\|^")
X	  (if (= 92 (preceding-char))
X	      (c-str-match)
X	  ;elseif
X	      (= srch (following-char))
X	      (in-c-literal)
X	  ;else
X	      (c-str-match)
X	  )
X	)
X    )
X  )
X
X  (indent-c-line
X    (if in-comment-mode
X	(progn
X	  (if (looking-at quoted-prefix-string)
X	      (progn
X		(re-search-forward quoted-prefix-string)
X		(region-around-match 0)
X		(erase-region)
X	      )
X	  ;else
X	      (delete-white-space)
X	  )
X	  (to-col left-margin)
X	  (insert-string prefix-string)
X	)
X    ;else
X	(progn not-incr
X	  (beginning-of-line)
X	  (if (looking-at "[ \t]*/\\*")
X	      (progn 
X		(search-forward "/")
X		(backward-character)
X	      )
X	  ;else
X	      (progn
X		(compute-new-indent)
X		(delete-white-space)
X		(if (looking-at "{")
X		    (progn
X		      (delete-next-character)
X		      (delete-white-space)
X		      (to-col (if not-incr
X				  indent-val
X				  (- indent-val c-unit-indent)))
X		      (save-excursion (insert-string {-str))
X		    )
X		;elseif
X		    (looking-at "}")
X		    (progn
X		      (to-col (- indent-val c-unit-indent))
X		      (save-excursion (insert-string pre-{-str))
X		    )
X		;elseif
X		    (looking-at ")")
X		    (to-col (- indent-val indent-within-bracket))
X		;elseif
X		    (looking-at label-line-match)
X		    (to-col (+ indent-val
X			       (if (looking-at case-line-match)
X				   case-protrusion
X				   label-protrusion)))
X		;else
X		    (to-col indent-val)
X		)
X	      )
X	  )
X	)
X    )
X  )
X  
X  (compute-new-indent paren-found
X    ;searches back to line which defines the indent value
X    ;of the current line & sets indent-val
X    (save-excursion 
X      (if (looking-at "[)}]")
X	  (progn
X	    (forward-character)
X	    (rev-to-paren)
X	    (setq paren-found (following-char))
X	    (setq not-incr 1)
X	    (setq indent-val (this-lines-indent))
X	  )
X      ;elseif
X	  (looking-at else-line-match)
X	  (progn
X	    (rev-to-if-line)
X	    (setq indent-val (this-lines-indent))
X	  )
X      ;elseif
X	  (| (looking-at pre-proc-line-match)
X	     (error-occured (find-indent-defn)))
X	  (setq indent-val 1)
X      )
X    )
X  )
X
X  (rev-to-if-line
X    (rev-prog-line)
X    (if paren-found
X	(if (!(looking-at paren-if-match))
X	    (progn 
X	      (send-string-to-terminal "")
X	      (message "No matching \"if\"!")(sit-for 5)
X	    )
X	)
X    ;elseif
X	(!(looking-at if-elseif-line-match))
X	(progn 
X	  (if (looking-at else-line-match)
X	      (rev-to-if-line)
X	  )
X	  (rev-to-if-line)
X	)
X    )
X  )
X  
X  (find-indent-defn cur-indent cc
X    (rev-prog-line)
X    (if (!= 1 (setq indent-val (this-lines-indent)))
X	(if (setq not-incr paren-found)
X	    (if (! (| (= paren-found '(') (not-ind-incr)))
X		(progn 
X		  (setq indent-val (+ indent-val c-unit-indent))
X		  (setq not-incr 0)
X		)
X	    )
X	;else
X	    (if (| (= ',' (setq not-incr (not-ind-incr))) (= '}' not-incr))
X		(progn 
X		  (setq indent-val (this-lines-indent))
X		  0
X		)
X	    ;elseif
X		not-incr
X		(while
X		  (progn
X		    (rev-prog-line)
X		    (if (looking-at else-line-match)
X			(progn 
X			  (setq indent-val (this-lines-indent))
X			  (rev-to-if-line)
X			)
X		    )
X		    (if paren-found
X			(progn 
X			  (setq indent-val (this-lines-indent))
X			  0
X			)
X		    ;elseif
X			(| (& (setq cc (not-ind-incr)) (!= ',' cc))
X			  (< indent-val (setq cur-indent (this-lines-indent))))
X			0
X		    ;else
X			(setq indent-val cur-indent) ;always non-zero
X		    )
X		  )
X		)
X	    ;else
X		(progn
X		  (rev-prog-line)
X		  (if (| (= paren-found '{')
X			 (| (not-ind-incr)
X			    (< (this-lines-indent) indent-val)))
X		      (setq indent-val (+ indent-val c-unit-indent))
X		  )
X		)
X	    )
X	)
X    )
X  )
X
X  (rev-to-paren
X    (setq paren-found (preceding-char))
X    (backward-paren)
X    (if (!(looking-at "{\\|(\\|\\["))
X	(error-message "No matching open parenthesis"))
X    (setq {-posn (dot))
X    (re-search-reverse "^\\|/\\*\\|\\*/")
X    (if (looking-at "/\\*") ;ignore within comments - emacs doesnt handle this
X	(progn
X	  (save-excursion
X	    (insert-character paren-found)
X	    (rev-to-paren)
X	  )
X	  (delete-next-character)
X	)
X    )
X    (goto-character {-posn)
X  )
X
X  (rev-prog-line
X    (backward-character)
X    (if (backward-balanced-paren-line)
X	(setq paren-found (following-char))
X    ;elseif
X	(looking-at non-prog-line-match)
X	(rev-prog-line)
X    ;else
X	(setq paren-found 0)
X    )
X    (if (& comment-check (is-in-comment))
X	(rev-prog-line)
X    )
X  )
X  
X  (is-in-comment	;checks only if comment starts  or ends in current line
X    (| (save-excursion  ; and dot is in the comment
X	 (error-occurred (re-search-reverse "/\\*\\|\\*/\\|^"))
X	 (looking-at "/\\*")
X       )
X       (save-excursion
X	 (error-occurred
X	   (re-search-forward "/\\*\\|\\*/\\|\n")
X	   (backward-character)
X	   (backward-character))
X	 (looking-at "\\*/")
X       )
X    )
X  )
X
X  (this-lines-indent
X    (if paren-found
X	(if (| (= paren-found '{')
X	       (< indent-within-bracket 0))
X	    (if (bolp)
X		(+ 1 c-unit-indent)
X	    ;elseif "{" is the first non-space char on line
X		(save-excursion
X		  (re-search-reverse "[^ \t]\\|^")
X		  (looking-at "[ \t][ \t]*{"))
X		(+ (current-indent) indent-from-{)
X	    ;else "{" was preceded by non-space-characters so:
X		(progn paren-found not-incr indent-val
X		  (newline)
X		  (save-excursion
X		    (rev-prog-line)
X		    (setq indent-val (this-lines-indent))
X		  )
X		  (delete-previous-character)
X		  (+ indent-val c-unit-indent)
X		)
X	    )
X	;else paren-found = '(' so:
X	    (+ indent-within-bracket (current-column))
X	)
X    ;else paren not found
X	(save-excursion 
X	  (beginning-of-line)
X	  (if (looking-at "[ \t]*[{}]")
X	      (- (current-indent) spaces-pre-{)
X	  ;else first non space char is not "{" so:
X	      (current-indent)
X	  )
X	)
X    )
X  )
X
X  (not-ind-incr		;called only after rev-prog-line
X    (save-excursion
X      (if paren-found
X	  (if (= paren-found '(')
X	      0
X	  ;elseif
X	      (looking-at
X		"{[ \t]*/\\*\\|{[ \t]*$\\|{[ \t]*[a-zA-Z][a-zA-Z_]*:\\|[ \t]*case.*:")
X	      1
X	  ;else
X	      (progn
X		(forward-character)
X		(if (looking-at "[ \t]$")
X		    1
X		    (test-if-not-to-incr)
X		)
X	      )
X	  )
X      ;else
X	  (test-if-not-to-incr)
X      )
X    )
X  )
X
X  (test-if-not-to-incr
X    (if (bolp)
X	(progn
X	  (re-search-forward "/\\*\\|$")
X	  (aux-fnim)
X	)
X    ;elseif
X	(looking-at label-line-match)
X	':'
X    ;else
X	(progn no-incr	;note: searching does not respect narrow-region!!
X	  (newline)
X	  (save-excursion 
X	    (re-search-forward "/\\*\\|$")
X	    (setq no-incr (aux-fnim)))
X	  (delete-previous-character)
X	  no-incr
X	)
X    )
X  )
X  
X  (aux-fnim
X    (re-search-reverse "[^ \t]\\|^")
X    (if (| (looking-at "[;,{}(]") (bolp))
X	(following-char)
X    ;else
X	(progn
X	  (backward-character)
X	  (if (looking-at "/\\*")
X	      (aux-fnim)
X	  ;elseif
X	      (looking-at "\\*/")
X	      (progn
X		(re-search-reverse "/\\*\\|^")
X		(aux-fnim)
X	      )
X	  ;else
X	      (progn no-incr
X		(forward-character)
X		(forward-character)
X		(if (setq no-incr (backward-balanced-paren-line))
X		    (progn
X		      (if (error-occured (forward-paren))
X			  0
X		      ;else
X			  (progn
X			    (beginning-of-line)
X			    (not-ind-incr)
X			  )
X		      )
X		    )
X		;else
X		    0
X		)
X	      )
X	  )
X	)
X    )
X  )
X)
X
X(autoload "reformat-c-proc" (concat lib-dir "/reindent-c.ml"))
X(autoload "reindent-c-proc" (concat lib-dir "/reindent-c.ml"))
X(autoload "beautify-c" (concat lib-dir "/beautify-c.ml"))
X
X(defun 
X  (c-mode-switch
X    (if in-comment-mode
X	(reenter-c+mode 1)
X    ;else
X	(comment-mode)
X    )
X  )
X
X  (c-mode
X    (c+mode)
X  )
X  
X  (c+mode
X    (if (file-exists "~/maclib/c-layout.ml")
X	(load "~/maclib/c-layout.ml")
X	(load (concat libdir "/c-layout.ml"))
X    )
X    (init-c-vars)
X    (use-syntax-table "C")
X    (modify-syntax-entry "()   (")
X    (modify-syntax-entry ")(   )")
X    (modify-syntax-entry "(}   {")
X    (modify-syntax-entry "){   }")
X    (modify-syntax-entry "(]   [")
X    (modify-syntax-entry ")[   ]")
X    (modify-syntax-entry "w { */")
X    (modify-syntax-entry "w  }/*")
X    (modify-syntax-entry "\"    '")
X    (modify-syntax-entry "\"    \"")
X    (modify-syntax-entry "\\    \\")
X    (modify-syntax-entry "w    -+!$%^&=_~:?*<>|a-zA-Z0-9")
X    (reenter-c+mode 0)
X  )
X
X  (reenter-c+mode
X    (setq right-margin 1000)
X    (setq left-margin 1)
X    (remove-all-local-bindings)
X    (local-bind-to-key "c-{" "{")
X    (local-bind-to-key "c-}" "}")
X    (local-bind-to-key "c-colon" ":")
X    (local-bind-to-key "c-nl" 10)
X    (local-bind-to-key "c-cr" 13)
X    (local-bind-to-key
X      (if (| re-indent-on-tab skip-indent-on-tab)
X	  "c-tab" "self-insert")
X      "\t")
X    (local-bind-to-key "c-esc-tab" "\t")
X    (local-bind-to-key "c-]" "]")
X    (local-bind-to-key "c-close-bracket" ")")
X    (local-bind-to-key "c-bracket" "(")
X    (local-bind-to-key
X      (if spaces-after-comma "c-comma" "self-insert") ",")
X    (local-bind-to-key
X      (if (| nextline-after-semicolon spaces-after-semicolon)
X	  "c-semicolon" "self-insert")
X      ";")
X    (local-bind-to-key "c-*" "*")
X
X    (local-bind-to-key "c-close-all" ")")
X    (local-bind-to-key "c-close-all" "}")
X    (local-bind-to-key "c-close-all" "]")
X
X    (local-bind-to-key "forward-paren" "[C")
X    (local-bind-to-key "forward-paren" "Ov")
X    (local-bind-to-key "backward-paren" "[D")
X    (local-bind-to-key "backward-paren" "Ot")
X    
X    (local-bind-to-key "reformat-c-proc" "j")
X    (local-bind-to-key "reindent-c-proc" "i")
X
X    (local-bind-to-key "c-mode-switch" "c")
X    (local-bind-to-key "c-mode-switch" "C")
X
X    (setq in-comment-mode 0)
X    (if (! beautify-mode)
X	(progn
X	  (setq mode-string "C+")
X	  (if (arg 1)  (message "now in c+ mode"))
X	)
X    )
X    (novalue)
X  )
X  
X  (comment-mode
X    (if (looking-at "[ \t]*/\\*")
X	(progn
X	  (re-search-forward "[ \t]*")
X	  (setq left-margin (current-column))
X	  (if (looking-at (quote comment-start-string))
X	      (re-search-forward comment-start-string)
X	  ;else
X	      (search-forward "/*")
X	  )
X	)
X    ;else
X	(save-excursion 
X	  (if (| (error-occured (re-search-reverse "/\\*\\|\\*/\\|\\`"))
X		 (!(looking-at "/\\*")))
X	      (error-message "You're not in a comment!")
X	  ;else
X	      (setq left-margin (current-column))
X	  )
X	)
X    )
X    (setq right-margin (- (window-width) 2))
X    (setq prefix-string comment-prefix-string)
X    (remove-all-local-bindings)
X    (local-bind-to-key "c-mode-switch" "c")
X    (local-bind-to-key "c-mode-switch" "C")
X    (local-bind-to-key "c-cmnt-tab" "\t")
X    (local-bind-to-key "c-/" "/")
X    (local-bind-to-key "c-cr" 13)
X    (local-bind-to-key "c-nl" 10)
X    
X    (setq in-comment-mode 1)
X    (if (! beautify-mode)
X	(progn
X	  (setq mode-string "comment")
X	  (message "now in comment-mode")
X	)
X    )
X  )
X)
X
+ END-OF-FILE c+mode.ml
echo '-rw-r--r-- 1 ray       24208 Oct 16 17:22 c+mode.ml    (as sent)'
chmod u=rw,g=r,o=r c+mode.ml
ls -l c+mode.ml
echo x - c-layout.ml
sed 's/^X//' > c-layout.ml <<'+ END-OF-FILE 'c-layout.ml
X; Formatting and user-interface parameters for C+ mode and beautify-c.
X;
X; A copy of this file may be personally defined in the file
X;	~/maclib/c-layout.ml
X; which will be automatically loaded whenever c-plus mode is entered, and
X; another copy in the file
X;	~/maclib/b-layout.ml
X; which will be automatically loaded whenever beautify-c is called
X
X; SEE THE DOCUMENTATION IN THE FILE c+mode.doc
X
X; If the c-layout file is edited after c+mode is entered, it must be
X; written back then the c+mode command executed to re-initialise the
X; working variables.
X;
X; Iff a personal c-layout file does NOT exist, then parameters may be changed
X; interactively. c+mode must then be executed again to re-initialise the
X; working variables.
X
X(setq re-indent-on-tab		0)	;=1 pressing the tab key when dot is
X 					;   at the beginning-of-line will
X 					;   cause the current lines indent to
X 					;   be RE-COMPUTED, and dot left at
X 					;   that indent posn. (most convenient
X 					;   setting except if you require to
X 					;   periodically break the indentation
X 					;   rules, but also most cpu-consuming)
X 					;=0 skip-indent-on-tab controls
X 					;   tab key action
X
X(setq skip-indent-on-tab	1)	;ONLY RELEVANT IF re-indent-on-tab = 0
X 					;=1 pressing the tab key when dot is
X 					;   at the beginning-of-line will
X 					;   cause dot to be moved to after the
X 					;   EXISTING indent (i.e. normally to
X 					;   the first non-space/tab character)
X 					;   unless the line is empty, in which
X 					;   case dot is moved to the computed
X 					;   indent position
X 					;=0 no special action is taken on tab,
X 					;   ESC-tab must be used for re-
X 					;   indenting
X
X 					;NOTE: when dot is not at the beginning
X 					;      of line or preceding "{", tab
X 					;      has its normal (self-insert)
X 					;      meaning
X
X
X(setq indent-on-newline		0)	;=1 dot is moved to the computed
X 					;   indent position on the next line
X 					;   after CR is pressed, and after the
X 					;   CR created by any of the
X 					;   "nextline-after-..." flags defined
X 					;   below. (most convenient but most
X 					;   cpu-consuming setting)
X 					;=0 dot is always left at the start
X 					;   of the line in the above situations
X
X(setq newline-on-cr		1)	;=1 a newline is always inserted after
X 					;   CR is pressed (in the traditional
X 					;   Emacs way)
X 					;   (indented if indent-on-newline=1).
X 					;=0 newlines are not inserted unless
X 					;   an insert-space is created (see
X 					;   documentation)
X(setq newline-on-nextline	0)	;=1 a newline is always inserted when
X 					;   dot is moved to the next line with
X 					;   "nextline-after-..." flags defined
X 					;    below
X 					;   (indented if indent-on-newline=1).
X 					;=0 newlines are not inserted unless
X 					;   an insert gap is created (see
X 					;   documentation)
X
X(setq c-unit-indent		4) 	;# of spaces for each indent level
X 					;   (spaces are coverted to tabs where
X					;    possible)
X
X(setq indent-within-bracket     1)	;# of spaces to indent on new lines
X 					; within an open '(' bracket.
X 					;normally = 1 so next line will indent
X 					; to first character of bracketted
X 					; expression, e.g.
X 					; 	nextthing (first parameter,
X					;       	   second parameter);
X 					;if given any negative value then such
X 					; lines will indent as a normal indent
X 					; using c-unit-indent
X 					; e.g. if c-unit-indent = 4 then
X 					;	nextthing (first parameter,
X					;	    second parameter);
X
X(setq newline-before-{ 		0)	;=1 an indented newline is inserted
X 					;   before each '{'
X 					;=0 "spaces-before-{" spaces are
X 					;   inserted before each '{'
X(setq nextline-after-{ 		1)	;=1 an indented newline is inserted
X 					;   after each '{'
X 					;   dot is left either at the start of
X 					;   the line or at the re-computed
X 					;   indent position according to the
X 					;   value of indent-on-newline
X 					;=0 "spaces-after-{" spaces are
X 					;   inserted after each '{'
X
X(setq spaces-before-{           1)	;# of spaces to insert before '{'
X 					;if newline-before-{ = 1 then indent
X 					;will look like e.g. (as we all agree
X 					;it should be!!!!)
X 					;	if (........)
X 					;        {  a = 5;
X 					; 	    b = 6;
X 					;
X 					;if newline-before-{ = 0 and '{' is
X 					; the first significant character on
X 					; the line, no spaces are inserted
X(setq spaces-after-{            1)	;# of spaces to insert after '{'
X 					; only relevant if newline-before-{ &
X 					; nextline-after-{ are both zero
X
X(setq newline-before-} 		1)	;=1 an indented newline is inserted
X 					;   before each '}' unless the
X 					;   matching '{' is on the same line
X 					;   in which case "spaces-before-}"
X 					;   spaces are inserted before '}'
X 					;=0 "spaces-before-}" spaces are
X 					;   inserted before each '}'
X(setq nextline-after-} 		1)	;=1 an indented newline is inserted
X 					;   after each '}'
X 					;   dot is left either at the start of
X 					;   the line or at the re-computed
X 					;   indent position according to the
X 					;   value of indent-on-newline
X 					;=0 "spaces-after-}" spaces are
X 					;   inserted after each '}'
X(setq spaces-before-}           1)	;# of spaces to insert before '}'
X 					;if newline-before-} = 1 only inserted
X 					; if the matching '{' is on the same
X 					; line
X(setq spaces-after-}            1)	;# of spaces to insert after '}'
X 					; not relevant if nextline-after-} = 1
X
X(setq spaces-before-bracket	1)	;# of spaces to insert before each '('
X 					; typed in a procedure call or defn
X 					; i.e. no space adjustment is made if
X 					; '(' is preceded by a non-alphanumeric
X 					;even if zero, will ensure at least one
X					; space is inserted after "if", "for",
X					; "while" and "switch"
X
X(setq spaces-after-comma	1)	;# of spaces to insert after each ','
X 					; typed
X
X(setq label-protrusion 	       -2)	;number of spaces to indent labels from
X 					; current indent position. Normally
X 					; negative so labels protrude left.
X 					;if large negative number then labels
X 					; will be justified hard left on line
X(setq case-protrusion	       -2) 	;same as preceding for 'case....:'
X 					; lines
X 					;Note: The label or case is recognized
X  					; and the "protrusion" executed when
X 					; the ":" is typed
X
X(setq nextline-after-label	1)	;=1 a newline is inserted when the ':'
X 					;   following a label or case is typed
X 					;   dot is left either at the start of
X 					;   the line or at the re-computed
X 					;   indent position according to the
X 					;   value of indent-on-newline
X 					;Warning: if statements are typed on
X 					; the same line as a label, the indent-
X 					; ing procedure may not work properly
X 					; To be recognised as such only spaces
X 					; or tabs can precede a label or case,
X 					; and NO SPACE must appear between the
X 					; label and the colon
X
X(setq nextline-after-semicolon	1)	;=1 a newline is inserted after each
X 					;   ';' is typed unless within an open
X 					;   '(' on the same line.
X 					;   dot is left either at the start of
X 					;   the line or at the re-computed
X 					;   indent position according to the
X 					;   value of indent-on-newline
X 					;=0 spaces-after-semicolon spaces are
X					;   inserted after each ';'
X(setq spaces-after-semicolon	2)	;# of spaces to insert after any ';'
X 					; unless a newline is inserted
X
X(setq comment-column	        0)	;column position to automatically start
X 					; comments when '/*' typed
X 					;if = 0 or '/*' typed at start of line,
X 					; or at a position greater than
X 					; comment-column, then the comment
X 					; starts at the current dot position
X
X(setq comment-start-string  "/* ")	;comment start string
X 					; - must include "/*" but could have a
X 					;   trailing space for example
X(setq comment-prefix-string  "   ")	;the string which prefixes subsequent
X 					;   lines of a comment
X 					; - would normally be the same length
X 					;   as the comment-start-string to
X 					;   ensure lines line up
X(setq comment-end-string     " */")	;comment end string
X 					; - must include "*/" but could have a
X 					;   leading space for example
X(setq nextline-after-comment	1)	;=1 a newline is inserted after the
X 					;   closing "*/"
X 					;   dot is left either at the start of
X 					;   the line or at the re-computed
X 					;   indent position according to the
X 					;   value of indent-on-newline
X
X(setq indent-options "-l80 -i4 -ndj -d1 -bl")
X 					;parameters for ESC-J formatter
X
+ END-OF-FILE c-layout.ml
echo '-rw-r--r-- 1 ray        8439 Oct 16 15:51 c-layout.ml    (as sent)'
chmod u=rw,g=r,o=r c-layout.ml
ls -l c-layout.ml
echo x - reindent-c.ml
sed 's/^X//' > reindent-c.ml <<'+ END-OF-FILE 'reindent-c.ml
X; Copyright (c) Raymond D. Dunn. Montreal. 1984.  All rights reserved.
X; This software or any part therof may not be sold, or otherwise disposed of
X; for gain, whether by itself, or in combination with any other software or
X; computer product of any description, without the express written consent of
X; the author.
X
X; Routines to re-format or re-indent C procedures
X
X; Dot should be placed within the procedure to be processed
X
X; reformat-c-proc (ESC-J) uses the standard indent program
X; reindent-c-proc (ESC-I) applies the C+ indent algorithm
X;
X; To have your file reformatted use beautify-c
X
X(defun
X  (reformat-c-proc
X    (process-c-proc (filter-region (concat "indent -st " indent-options)))
X  )
X
X  (reindent-c-proc
X    (process-c-proc
X      (progn
X	(while (!(eobp))
X	  (if (looking-at "[ \t]*$")
X	      (next-line)
X	  ;else
X	      (if (| (looking-at "[ \t]*/\\*")
X		     (progn 
X		       (save-excursion (indent-c-line))
X		       (sit-for 0)
X		       (error-occured (re-search-forward "/\\*\\|\n"))
X		       (! (bolp))))
X		  (error-occured 
X		    (search-forward "*/")
X		    (next-line)
X		  )
X	      )
X	  )
X	  (beginning-of-line)
X	  (if (! (dot-is-visible)) (line-to-top-of-window))
X	)
X      )
X    )
X  )
X
X  (process-c-proc
X    (save-excursion
X      (previous-line)
X      (while
X	(progn 
X	  (forward-paren)
X	  (if (& (= '}' (preceding-char))
X		 (<= (current-indent) (+ spaces-before-{ 1))) 0 1)
X	)
X      )
X      (set-mark)
X      (backward-paren)
X      (beginning-of-line)
X      (newline)
X      (backward-character)
X      (exchange-dot-and-mark)
X      (end-of-line)
X      (newline)
X      (narrow-region)
X      (beginning-of-file)
X      (forward-character)
X      (error-occured (arg 1))
X      (beginning-of-file)(delete-next-character)
X      (end-of-file)(delete-previous-character)
X      (widen-region)
X    )
X    (message "Done!")
X  )
X)
X
X
+ END-OF-FILE reindent-c.ml
echo '-rw-r--r-- 1 ray        1843 Oct 16 15:51 reindent-c.ml    (as sent)'
chmod u=rw,g=r,o=r reindent-c.ml
ls -l reindent-c.ml
echo x - beautify-c.ml
sed 's/^X//' > beautify-c.ml <<'+ END-OF-FILE 'beautify-c.ml
X; Copyright (c) Raymond D. Dunn. Montreal. 1984.  All rights reserved.
X; This software or any part therof may not be sold, or otherwise disposed of
X; for gain, whether by itself, or in combination with any other software or
X; computer product of any description, without the express written consent of
X; the author.
X
X; C program re-formatter for use with c-plus-mode.
X; C+ mode must be loaded and active, and its parameters are used for the
X; beautification, INCLUDING THE nextline-after-... VARIABLES WHICH MUST BE
X; SPECIFICALLY SET FOR YOUR REQUIREMENTS (e.g. if nextline-after-semicolon=0
X; then lots of statements will be put on each line!).
X
X; This program is SLOW, but it should be a rarely used feature (i.e. once only
X; on a file not in your pet format).
X; It is not guaranteed to get the format perfect under all circumstances, but
X; should leave the file so that only a few manual fix-ups are reqd
X
X; Uses recursive-edit and assumes ^x^c is defined as exit-emacs. If it is not,
X; edit (setq xemacs-key "..") line below.
X; This is used in the comment handling routine (see at end of file).  Had some
X; problems with this - e.g. sometimes still comments cause beautify to abort
X; if some undefined recursive state has been got into prior to entering
X; beautify 
X
X(declare-global c-get-posn c-put-posn c-curbuf c-char cur-b-ind reqd-b-cr
X 		xemacs-key)
X
X(setq xemacs-key "")
X
X(defun		;there now follows a Fortran program! (hack....hack!)
X  (beautify-c beautify-mode
X    (get-tty-string "Re-formats whole buffer! OK? (^G to abort) ")
X    (message "OK...")(sit-for 0)
X    (if (file-exists "~/maclib/b-layout.ml") (load "~/maclib/b-layout.ml"))
X    (init-c-vars)
X    (reenter-c+mode 0)
X    (setq c-curbuf (current-buffer-name))
X    (end-of-file)
X    (if (!(bolp)) (newline))
X    (beginning-of-file)
X    (sit-for 0)
X    (newline)
X    (newline)
X    (backward-character)
X    (setq c-put-posn (dot))
X    (forward-character)
X    (setq c-get-posn (dot))
X    (setq beautify-mode 
X      (setq newline-on-cr
X	(setq newline-on-nextline 1)))
X    (setq indent-on-newline 0)
X    (setq indent-val 1)
X    (nxt-get-char 0 0)
X    (while (!= c-char -1)
X      (progn
X	(goto-character c-put-posn)(backward-character)
X	(if (= c-char '\n')
X	    (progn reqdbcr
X	      (setq reqdbcr (bolp))
X	      (newline)
X	      (ind-get-char 0 1)
X	      (setq reqd-b-cr reqdbcr)
X	    )
X	;elseif
X	    (not-literally-inserted c-char)
X	    (progn
X	      (if (= c-char ';')
X		  (if (save-excursion 
X			(goto-character c-get-posn)
X			(looking-at "[ \t]*/\\*"))
X		      (progn
X			(insert-character ';')
X			(nxt-get-char 0 0)
X		      )
X		  ;else
X		      (progn 
X			(error-occured (c-semicolon))
X			(if (& nextline-after-semicolon (!(bolp)))
X			    (nxt-get-char 0 1)
X			    (ind-get-char 1 1)
X			)
X		      )
X		  )
X	      ;elseif
X		  (= c-char ',')
X		  (progn 
X		    (error-occured (c-comma))
X		    (nxt-get-char 0 1)
X		  )
X	      ;elseif
X		  (= c-char '(')
X		  (progn 
X		    (if (& (! (| (bolp)(bobp)))
X			   (save-excursion 
X			     (re-search-reverse "[^ \t]\\|\\`")
X			     (looking-at "[a-zA-Z0-9_]")))
X		    ;then
X			(delete-white-space)
X		    )
X		    (error-occured (c-bracket))
X		    (nxt-get-char 0 0)
X		  )
X	      ;elseif
X		  (= c-char ')')
X		  (progn 
X		    (error-occured (c-close-bracket))
X		    (nxt-get-char 0 0)
X		  )
X	      ;elseif
X		  (= c-char '{')
X		  (progn
X		    (if (& newline-before-{ (!(bolp)))
X			(save-excursion (error-occured (indent-c-line))))
X		    (if (!= 1 indent-val)
X			(backup-to-prev-line newline-before-{))
X		    (error-occured (c-{))
X		    (ind-get-char 1 1)
X		  )
X	      ;elseif
X		  (= c-char '}')
X		  (progn
X		    (if (& newline-before-{ (!(bolp)))
X			(save-excursion (error-occured (indent-c-line))))
X		    (backup-to-prev-line newline-before-})
X		    (error-occured (c-}))
X		    (ind-get-char 1 1)
X		  )
X	      ;elseif
X		  (= c-char ':')
X		  (progn 
X		    (error-occured (c-colon))
X		    (if (bolp)
X		       (ind-get-char 1 1)
X		       (nxt-get-char 0 0)
X		    )
X		  )
X	      ;elseif
X		  (= c-char '/')
X		  (progn
X		    (goto-character c-get-posn)
X		    (if (& (looking-at "*") (!(in-c-literal)))
X			(error-occured
X			  (goto-character c-put-posn)(backward-character)
X			  (indent-c-line)
X			  (cmnt-beaut)
X			  (nxt-get-char
X			    nextline-after-comment nextline-after-comment)
X			) 
X		    ;else
X			(progn
X			  (goto-character c-put-posn)
X			  (backward-character)
X			  (insert-character '/')
X			  (nxt-get-char 0 0)
X			)
X		    )
X		  )
X	      ;else if not one of the above
X		  (nxt-get-char 0 0)
X	      )
X	    )
X	;else literally inserted
X	    (nxt-get-char 0 0)
X	)
X      )
X    ) ;while
X    (delete-previous-character)(delete-previous-character)
X    (c+mode)
X    (setq beautify-mode 0)
X    (beginning-of-file)
X    (send-string-to-terminal "")
X    (message "Done!")
X  )
X
X  (ind-get-char
X    (if (setq reqd-b-cr (bolp))
X	(progn 
X	  (save-excursion
X	    (backward-character)
X	    (if (!(bolp))
X		(error-occured (indent-c-line)))
X	  )
X	  (forward-character)
X	  (set-mark)
X	  (goto-character c-get-posn)
X	  (erase-region)
X	  (backward-character)
X	  (if (!(dot-is-visible))
X	      (line-to-top-of-window)
X	  )
X	  (sit-for 0)
X	)
X    )
X    (nxt-get-char (arg 1)(arg 2))
X  )
X  
X  (nxt-get-char
X    (goto-character c-get-posn)
X    (if (& (looking-at "[ \t]") (arg 2))
X	(progn
X	  (re-search-forward "[^ \t]")
X	  (backward-character)
X	)
X    )
X    (if (eolp)
X	(if (eobp)
X	    (setq c-char -1)
X	;else
X	    (progn 
X	      (forward-character)
X	      (setq c-get-posn (dot))
X	      (if (& (arg 1)(! (looking-at non-prog-line-match)))
X		  (nxt-get-char 0 1)
X	      ;else
X		  (setq c-char '\n')
X	      )
X	    )
X	)
X    ;else
X	(progn str
X	  (set-mark)
X	  (re-search-forward "[\n{}(),;:/]")
X	  (setq c-char (preceding-char))
X	  (setq c-get-posn (dot))
X	  (backward-character)
X	  (setq str (region-to-string))
X	  (goto-character c-put-posn)(backward-character)
X	  (insert-string str)
X	)
X    )
X  )
X  
X  (backup-to-prev-line
X    (if (& (!(| reqd-b-cr (arg 1)))
X	   (& (bolp)
X	      (save-excursion 
X		(goto-character c-get-posn)
X		(re-search-reverse "^[ \t]*[{}]\\=\\|$\\|'")
X		(! (looking-at "\n")))))
X    ;then
X	(progn
X	  (delete-white-space)
X	  (if (bolp) (delete-previous-character))
X	)
X    )
X  )
X
X  (cmnt-beaut cmnt-posn cmnt-str khold c-text-posn
X    (goto-character c-get-posn)
X    (setq cmnt-posn (- (current-column) 1))
X    (goto-character c-put-posn)(backward-character)
X    (if (= 1 cmnt-posn)
X	(progn
X	  (beginning-of-line)
X	  (if (looking-at "[ \t]*$")
X	      (delete-white-space)
X	  ;else
X	      (progn
X		(end-of-line)
X		(newline)
X	      )
X	  )
X	)
X    ;elseif
X	comment-column
X	(progn 
X	  (delete-white-space)
X	  (insert-character ' ')
X	)
X    ;elseif
X	(> (current-column) cmnt-posn)
X	(progn
X	  (delete-white-space)
X	  (to-col cmnt-posn)
X	)
X    )
X    (insert-character '/')
X    (c-*)
X    (goto-character c-get-posn)
X    (forward-character)
X    (re-search-forward "[ \t]*")
X    (setq c-text-posn (current-column))
X    (setq c-get-posn (dot))
X    (while in-comment-mode
X      (goto-character c-get-posn)
X      (if (bolp)
X	  (progn 
X	    (if (looking-at "[ \t]")
X		(progn 
X		  (re-search-forward "[ \t]*")
X		  (if (> (current-column) c-text-posn)
X		      (to-posn c-text-posn)
X		  )
X		)
X	    )
X	    (if (looking-at quoted-prefix-string)
X	      (re-search-forward quoted-prefix-string)
X	    )
X	  )
X      )
X      (set-mark)
X      (re-search-forward "\\*/\\|\n\\|................")
X      (setq c-get-posn (dot))
X      (setq cmnt-str (region-to-string))
X      (goto-character c-put-posn)(backward-character)
X      (push-back-string (concat cmnt-str xemacs-key))
X      (recursive-edit)
X    )
X  )
X)
X
X
+ END-OF-FILE beautify-c.ml
echo '-rw-r--r-- 1 ray        7585 Oct 16 17:04 beautify-c.ml    (as sent)'
chmod u=rw,g=r,o=r beautify-c.ml
ls -l beautify-c.ml
exit 0