home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / languages / elisp / misc / fort-clean.el < prev    next >
Encoding:
Text File  |  1992-11-23  |  18.6 KB  |  533 lines

  1. ;;;   fort-clean.el - code for cleaning and stylizing FORTRAN subprograms
  2. ;;;   Copyright (C) 1992 Free Software Foundation, Inc.
  3. ;;;
  4. ;;;   This program is free software; you can redistribute it and/or modify
  5. ;;;   it under the terms of the GNU General Public License as published by
  6. ;;;   the Free Software Foundation; either version 1, or (at your option)
  7. ;;;   any later version.
  8. ;;;
  9. ;;;   This program is distributed in the hope that it will be useful,
  10. ;;;   but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ;;;   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. ;;;   GNU General Public License for more details.
  13. ;;;
  14. ;;;   You should have received a copy of the GNU General Public License
  15. ;;;   along with this program; if not, write to the Free Software
  16. ;;;   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18. ;;;   Title:  fortran clean
  19. ;;;
  20. ;;;   Description:  cleans around operators and logicals in a FORTRAN 
  21. ;;;                 subprogram or all subprograms in a buffer. Filling and
  22. ;;;                 indenting of the resulting FORTRAN code are *not*
  23. ;;;                 attempted. The buffer can be toggle-read-only, fort-clean
  24. ;;;                 will still work.
  25. ;;;
  26. ;;;   Created:  Thu May 28 10:59:30 1992
  27. ;;;   Author:   Lawrence R. Dodd
  28. ;;;             <dodd@mycenae.cchem.berkeley.edu>
  29. ;;;             <dodd@roebling.poly.edu>
  30. ;;;   
  31. ;;;   Bug Reports, Comments, Suggestions, Smart Remarks: 
  32. ;;;         dodd@roebling.poly.edu 
  33. ;;;         also M-x fortran-clean-submit-report
  34. ;;;
  35. ;;;   $LastEditDate:     "Sat Nov 14 14:00:27 1992"$
  36. ;;;   $Date: 1992/11/14 19:04:31 $
  37. ;;;
  38. ;;;   $Author: dodd $
  39. ;;;   $Id: fort-clean.el,v 3.41 1992/11/14 19:04:31 dodd Exp $
  40. ;;;   $Source: /home/dodd/lisp/RCS/fort-clean.el,v $ 
  41. ;;;   $Revision: 3.41 $ 
  42.  
  43. ;;;   INSTALLATION: 
  44. ;;; 
  45. ;;;     o  save as fort-clean.el in the GNU emacs load-path.
  46. ;;;  
  47. ;;;     o  stick:
  48. ;;;
  49. ;;;      ;; autoload fortran-clean
  50. ;;; 
  51. ;;;        (autoload 'fortran-clean "fort-clean"
  52. ;;;           "Code for cleaning and stylizing FORTRAN code in the 
  53. ;;;      current subprogram." t)
  54. ;;;      
  55. ;;;      ;; autoload fortran-clean-buffer
  56. ;;; 
  57. ;;;        (autoload 'fortran-clean-buffer "fort-clean"
  58. ;;;           "Code for cleaning and stylizing FORTRAN code in all the 
  59. ;;;      subprograms of the current buffer." t)
  60. ;;;
  61. ;;;        inside your .emacs, or more preferably inside fortran-mode-hook:
  62. ;;;
  63. ;;;        (setq fortran-mode-hook 
  64. ;;;           '(lambda () 
  65. ;;;                    .
  66. ;;;                    . other stuff
  67. ;;;                    .
  68. ;;;              ;; autoload fortran-clean
  69. ;;; 
  70. ;;;                (autoload 'fortran-clean "fort-clean"
  71. ;;;               "Code for cleaning and stylizing FORTRAN code in the 
  72. ;;;              current subprogram." t)
  73. ;;;      
  74. ;;;              ;; autoload fortran-clean-buffer
  75. ;;; 
  76. ;;;                (autoload 'fortran-clean-buffer "fort-clean"
  77. ;;;               "Code for cleaning and stylizing FORTRAN code in all the 
  78. ;;;              subprograms of the current buffer." t)))
  79.  
  80. ;;;   USAGE INSTRUCTIONS: 
  81. ;;; 
  82. ;;;     o type `M-x fortran-clean' to clean the current subprogram
  83. ;;;     o type `M-x fortran-clean-buffer' to clean the current all subprograms 
  84. ;;;       in the current buffer
  85.  
  86. ;;;   KNOWN BUGS: 
  87. ;;; 
  88. ;;;     o  will NOT fill properly -- statements may exceed the 72 column 
  89. ;;;     afterwards
  90. ;;; 
  91. ;;;     o  will NOT make 'if (a .eq. b  ) b = d' into 'if (a .eq. b) b = d' 
  92. ;;;     because there is no `then' at the end
  93. ;;;   
  94. ;;;     o  will NOT make (file ='foobar') into (file = 'foobar') because of 
  95. ;;;     the fortran-clean-inside-re check
  96. ;;;
  97. ;;;     o  definition of fortran-subprogram can be fragile and as a result 
  98. ;;;     sometimes fortran-clean fails 
  99. ;;; 
  100. ;;;     o  if more than on fortran-clean-statement replacement is done on one
  101. ;;;     line then the last match is not replaced.  WHY?  if
  102. ;;;     fortran-clean-statement is run again it cleans up properly. this has
  103. ;;;     something to do with where the point is left after a replace-match is
  104. ;;;     performed. it is placed at the end of the replacement string so I have
  105. ;;;     fortran-statement-replace-regexp step back a single space.
  106.  
  107. ;;;   SEE ALSO:
  108. ;;;
  109. ;;;     /hallc1.cebaf.gov:/emacs for the most recent version of fortran-mode
  110. ;;;     and also for Ralph Finch's fortran-beautifier stored in
  111. ;;;     fortran-misc.el
  112.  
  113. ;; LCD Archive Entry:
  114. ;; fort-clean|Lawrence R. Dodd|dodd@roebling.poly.edu|
  115. ;; Code for cleaning and stylizing fortran code|
  116. ;; 92-11-14|3.41|~/misc/fort-clean.el.Z|
  117.  
  118. (defconst fortran-clean-version "$Revision: 3.41 $"
  119.   "$Id: fort-clean.el,v 3.41 1992/11/14 19:04:31 dodd Exp $")
  120.  
  121.  
  122. ;;; ** define some useful regular expressions
  123.  
  124. (defvar fortran-relational-regexp
  125.       "\\.lt\\.\\|\\.le\\.\\|\\.eq\\.\\|\\.ne\\.\\|\\.gt\\.\\|\\.ge\\."
  126.       "Regular expression that will match relational expressions in a fortran
  127. program.")
  128.  
  129. (defvar fortran-logical-regexp
  130.       "\\.and\\.\\|\\.or\\.\\|\\.neqv\\.\\|\\.xor\\.\\|\\.eqv\\.\\|\\.not\\."
  131.       "Regular expression that will match logical expressions in a fortran
  132. program.")
  133.  
  134. (defvar fortran-log-rel-regexp
  135.       (concat "\\(" fortran-logical-regexp "\\|" fortran-relational-regexp
  136.               "\\)")
  137.       "Regular expression that will match both relational and logical
  138. expressions in a fortran program.")
  139.  
  140. (defvar fortran-prefix-char "\\([a-z0-9A-Z()=]\\)"
  141.   "Standard prefix character regular expression.")
  142.  
  143. (defvar fortran-suffix-char "\\([(a-z0-9A-Z]\\)"
  144.   "Standard suffix character regular expression.")
  145.  
  146.  
  147. ;;; ** clean all in buffer
  148.  
  149. (defun fortran-clean-buffer ()
  150.   "Cleans around equal signs, minus signs, plus signs, as well as in and
  151. around if-then-elseif constructs, read statements, and write statements for
  152. all fortran subprograms within buffer. Works only on lines that do not contain
  153. a comment character in the zeroth column."
  154.   (interactive)
  155.   (let (originally_locked)
  156.  
  157.     ;; if the buffer is set to read only, unlock it and set a flag
  158.     (if buffer-read-only
  159.     (progn (toggle-read-only)
  160.            (setq originally_locked t))
  161.       (setq originally_locked nil))
  162.  
  163.     (save-excursion
  164.       ;; go to top of the buffer
  165.       (goto-char (point-min))
  166.  
  167.       ;; loop through all the subprograms in this buffer. The `while' loop
  168.       ;; uses as its `CONDITION' the first half of the funtion
  169.       ;; end-of-subprogram from fortran.el. The value returned by
  170.       ;; `re-search-forward' is used to abort the iteration. This was done
  171.       ;; because `end-of-subprogram' does not return `nil' if there are no
  172.       ;; more subprograms in the current buffer and the `while' loop would
  173.       ;; iterate endlessly (I know because it happened to me).
  174.  
  175.       (while (progn 
  176.            (let ((case-fold-search t))
  177.          (beginning-of-line 2)
  178.          (re-search-forward "^[ \t0-9]*end\\b[ \t]*[^ \t=(a-z]" nil 'move)))
  179.     ;; another subprogram exists, move into position
  180.     (goto-char (match-beginning 0))
  181.     (forward-line 1)
  182.     ;; fire!
  183.     (fortran-clean-subprogram)))
  184.  
  185.     (message "cleaning buffer...done")
  186.  
  187.     ;; if the buffer was originally locked, relock it
  188.     (if originally_locked (toggle-read-only))
  189.     )
  190.   )
  191.  
  192.  
  193.  
  194. ;;; ** clean all
  195.  
  196. (defun fortran-clean ()
  197.   "Cleans around equal signs, minus signs, plus signs, as well as in and around
  198. if-then-elseif constructs, read statements, and write statements in a fortran
  199. subprogram. Works only on lines that do not contain a comment character in the
  200. zeroth column."
  201.   (interactive)
  202.   (let (originally_locked)
  203.  
  204.     ;; if the buffer is set to read only, unlock it and set a flag
  205.     (if buffer-read-only
  206.     (progn (toggle-read-only)
  207.            (setq originally_locked t))
  208.       (setq originally_locked nil))
  209.  
  210.     (fortran-clean-subprogram)
  211.  
  212.     ;; if the buffer was originally locked, relock it
  213.     (if originally_locked (toggle-read-only))
  214.     )
  215.   )
  216.  
  217.  
  218.  
  219. ;;; ** clean subprogram
  220.  
  221. (defun fortran-clean-subprogram ()
  222.   "This function cleans the current subprogram and is either called once by
  223. fortran-clean or called as many times as needed by fortran-clean-buffer."
  224.     (message "cleaning subprogram...=")
  225.     (fortran-clean-equal-sign)
  226.     (message "cleaning subprogram...=,-")
  227.     (fortran-clean-minus-sign)
  228.     (message "cleaning subprogram...=,-,+")
  229.     (fortran-clean-plus-sign)
  230.     (message "cleaning subprogram...=,-,+,if")
  231.     (fortran-clean-statements)
  232.     (message "cleaning subprogram...fixing...")
  233.     (fortran-clean-exponential)
  234.     (fortran-clean-for-clean)
  235.     (message "cleaning subprogram...done."))
  236.  
  237.  
  238. ;;; ** clean the equal signs
  239.  
  240. (defun fortran-clean-equal-sign ()
  241.   "Places single space before and after all equal signs in fortran statements
  242. but not in fortran comment lines. Removes tabs surrounding plus signs. Will
  243. not put a space after a equal sign if it is followed by a minus sign. Will not
  244. put space around equal sign unless it is preceded or followed by an
  245. alphanumeric character or parenthesis. Example: '= -a' will result not '= -
  246. a'"
  247.  
  248.   ;; NOT ENOUGH SPACE
  249.   ;; replace 'a=-b-c' with 'a =-b-c'
  250.   (fortran-statement-replace-regexp "\\([a-z0-9A-Z)]\\)=" "\\1 =")
  251.   ;; replace 'a = -b-c' with 'a = -b-c'
  252.   (fortran-statement-replace-regexp "\\([^=]\\)=\\([(a-z0-9A-Z---]\\)"
  253.                     "\\1= \\2")
  254.   ;; TOO MUCH SPACE
  255.   (fortran-statement-replace-regexp " [ \t]+=" " =")
  256.   (fortran-statement-replace-regexp "\t[ \t]+=" " =")
  257.   (fortran-statement-replace-regexp "= [ \t]+" "= ")
  258.   (fortran-statement-replace-regexp "=\t[ \t]+" "= ")
  259.   )
  260.  
  261. ;;; ** clean the minus signs
  262.  
  263. (defun fortran-clean-minus-sign ()
  264.   "Places single space before and after all minus signs in fortran statements
  265. but not in fortran comment lines. Removes tabs surrounding minus signs. Will
  266. not put a space after a minus sign if it is preceded by an equal sign or by a
  267. relational or logical expression. Example: '= -a' will result not '= - a'"
  268.  
  269.   ;; NOT ENOUGH SPACE
  270.   ;; replace 'a=b -c' with 'a=b - c'
  271.   (fortran-statement-replace-regexp
  272.    (concat "\\([^---=.]\\)-" fortran-suffix-char) "\\1- \\2")
  273.   ;; replace 'a=b-c' with 'a=b -c'
  274.   (fortran-statement-replace-regexp
  275.    (concat fortran-prefix-char "-\\([^---]\\)") "\\1 -\\2")
  276.  
  277.   ;; TOO MUCH SPACE
  278.   (fortran-statement-replace-regexp " [ \t]+-" " -")
  279.   (fortran-statement-replace-regexp "\t[ \t]+-" " -")
  280.   (fortran-statement-replace-regexp "- [ \t]+" "- ")
  281.   (fortran-statement-replace-regexp "-\t[ \t]+" "- ")
  282.   )
  283.  
  284.  
  285. ;;; ** clean the plus signs
  286.  
  287. (defun fortran-clean-plus-sign ()
  288.   "Places single space before and after all plus signs in fortran statements
  289. but not in fortran comment lines. Removes tabs surrounding plus signs. Will
  290. not put a space after a plus sign if it is preceded by an equal sign or by a
  291. relational or logical expression. Example: '= +a' will result not '= + a'"
  292.  
  293.   ;; NOT ENOUGH SPACE
  294.   ;; replace 'a=b +c' with 'a=b + c'
  295.   (fortran-statement-replace-regexp
  296.    (concat "\\([^+=.]\\)\\+" fortran-suffix-char) "\\1\\+ \\2")
  297.   ;; replace 'a=b+c' with 'a=b +c'
  298.   (fortran-statement-replace-regexp
  299.    (concat fortran-prefix-char "\\+\\([^+]\\)") "\\1 \\+\\2")
  300.  
  301.   ;; TOO MUCH SPACE
  302.   (fortran-statement-replace-regexp " [ \t]+\\+" " \\+")
  303.   (fortran-statement-replace-regexp "\t[ \t]+\\+" " \\+")
  304.   (fortran-statement-replace-regexp "\\+ [ \t]+" "\\+ ")
  305.   (fortran-statement-replace-regexp "\\+\t[ \t]+" "\\+ ")
  306.   )
  307.  
  308.  
  309. ;;; ** clean the if-then-elseif constructs, read, and write statements
  310.  
  311. (defun fortran-clean-statements ()
  312.   "Places a single space after an 'if', before a 'then', around relational
  313. and logical expressions, and around 'read' and 'write' statements."
  314.  
  315.   ;;; replace 'if   ( a)' with 'if (a)'
  316.   (fortran-statement-replace-regexp "\\(^  +if\\)[ \t]*([ \t]*" "\\1 (")
  317.   ;;; replace 'else if   ( a)' with 'else if (a)'
  318.   (fortran-statement-replace-regexp "\\(^  +else[ \t]*if\\)[ \t]*([ \t]*" "\\1 (")
  319.   ;;; replace '(a)  then' with (a) then
  320.   (fortran-statement-replace-regexp ")[ \t]*then$" ") then")
  321.   ;;; replace '(a ) then' with '(a) then'
  322.   (fortran-statement-replace-regexp "[ \t]*) then$" ") then")
  323.   ;;; replace 'a.gt.' with 'a .gt.'
  324.   (fortran-statement-replace-regexp
  325.    (concat "[ \t]*" fortran-log-rel-regexp) " \\1")
  326.   ;;; replace 'a.gt.' with 'a .gt.' (REPEAT) this is a patch! why does this 
  327.   ;;; screw up? KLUDGE!
  328.   (fortran-statement-replace-regexp
  329.    (concat "[ \t]*" fortran-log-rel-regexp) " \\1")
  330.   ;;; replace '.gt.b' with '.gt. b'
  331.   (fortran-statement-replace-regexp
  332.    (concat fortran-log-rel-regexp "[ \t]*") "\\1 ")
  333.   ;;; replace 'read   ( a)' with 'read (a)'
  334.   (fortran-statement-replace-regexp "\\(^  +read\\)[ \t]*([ \t]*" "\\1 (")
  335.   ;;; replace 'write   ( a)' with 'write (a)'
  336.   (fortran-statement-replace-regexp "\\(^  +write\\)[ \t]*([ \t]*" "\\1 (")
  337.     )
  338.  
  339. ;;; ** clean exponential constants
  340.  
  341. (defun fortran-clean-exponential ()
  342.   "Removes spaces found in exponential constants. For example, we want to
  343. replace occurrences of '1.0D - 9' with '1.0D-9'"
  344.  
  345.   ;; exponential notation: 
  346.   ;;   OPTIONAL integer(s), OPTIONAL decimal point, OPTIONAL integer(s), 
  347.   ;;   one letter (e,d, or q), OPTIONAL sign (+ or -), integer(s)
  348.   (fortran-statement-replace-regexp
  349.    "\\([0-9=+---/*(, ]\\.?[0-9]*[edqEDQ]\\) \\([+---]\\) \\([0-9]\\)"
  350.    "\\1\\2\\3")
  351.   )
  352.  
  353. ;;; ** clean fortran-clean
  354.  
  355. (defun fortran-clean-for-clean ()
  356.   "Cleans up after fortran-clean. Corrects some substitutions made by the
  357. previous routines that are not desired and that are hard to avoid."
  358.  
  359.   ;; CORRECTION SEARCH-AND-REPLACES
  360.  
  361.   ;; replace 'a   = -  b -c' with 'a = -b - c'
  362.   (fortran-statement-replace-regexp
  363.    (concat "\\([a-z0-9A-Z) ]=\\) \\([+---]\\) " fortran-suffix-char)
  364.    "\\1 \\2\\3")
  365.  
  366.   ;; replace '( - a - c)' with '( -a - c)'
  367.   (fortran-statement-replace-regexp
  368.    (concat "( \\([+---]\\) " fortran-suffix-char)
  369.    "( \\1\\2")
  370.  
  371.   ;; replace ',- a' with ', -a'
  372.   (fortran-statement-replace-regexp
  373.    (concat ",[ \t]*\\([+---]\\) " fortran-suffix-char)
  374.    ", \\1\\2")
  375.  
  376.   ;; replace '.and. - a .lt. - c' with '.and. -a .lt. -c'
  377.   (fortran-statement-replace-regexp
  378.    (concat fortran-log-rel-regexp " \\([+---]\\) " fortran-suffix-char)
  379.    "\\1 \\2\\3")
  380.  
  381.   )
  382.  
  383.  
  384. ;;; ** general search and replace routine for non-comment fortran statements
  385.  
  386. (defun fortran-statement-replace-regexp (regstring replacement)
  387.   "Replaces REGSTRING with REPLACEMENT for in fortran statements, excluding
  388. comment lines and anything between (single or double) quote marks, within a
  389. fortran subprogram. We define a fortran statement as anything without a \"C\"
  390. in the zeroth column. In this way, comments, FORMAT statements, filenames, and
  391. character strings should be uneffected. Also will not search and replace
  392. following \"!\" comment characters."
  393.   (interactive
  394.    "sReplace regexp: \nsReplace regexp %s in fortran statement with: \n")
  395. ;;; 
  396. ;;; logic: 
  397. ;;;   o do a regular expression forward search for 'regstring'
  398. ;;;   o when a match is found go to the beginning of the line 
  399. ;;;   o if there is not a comment character at the beginning of the line then 
  400. ;;;     search and replace in that line 'regstring' with 'replacement' 
  401. ;;;      oo search in the current line up to the first ! that is not in 
  402. ;;;         quotes or the end of line if there are no non-quoted !'s
  403. ;;;      oo only replace if string is not between quotes
  404. ;;;      oo after each replacement move back one character to avoid endless 
  405. ;;;         looping
  406. ;;;   o go forward one line
  407. ;;; 
  408.   (save-excursion
  409.     (beginning-of-fortran-subprogram)
  410.     (let
  411.     ;; VARLIST
  412.  
  413.     ((eop
  414.       (save-excursion (end-of-fortran-subprogram) (end-of-line) (point))))
  415.  
  416.       ;; BODY
  417.  
  418.       ;; search for regstring from the current point to the end of the 
  419.       ;; subprogram
  420.       (while (and (< (point) eop) (re-search-forward regstring eop t))
  421.         (beginning-of-line) ; regstring found - go to beginning of line
  422.         ;; if there is a blank or tab in the first column then search and 
  423.     ;; replace the rest of the current line
  424.         (if (not (looking-at "[cC*]")) ; not comment?
  425.             (progn
  426.               (let*
  427.           ;; VARLIST
  428.  
  429.           ( 
  430.            ;; end of line
  431.            (eol (save-excursion (end-of-line) (point)))
  432.            
  433.            ;; final point of search/replace
  434.            (finalpt
  435.             (save-excursion
  436.               
  437.               ;; go to beginning of line
  438.               (beginning-of-line)
  439.               
  440.               ;; search forward from bol to eol for a "!" that does
  441.               ;; not reside in a set of single or double quotes. if a
  442.               ;; "!"  is *not* found, then search-forward will leave
  443.               ;; the point at eol.
  444.               
  445.               (while (and (search-forward "!" eol 0)
  446.                   (or (fortran-clean-inside-re "'" "'")
  447.                       (fortran-clean-inside-re "\"" "\""))
  448.                   ))
  449.               
  450.               ;; get value of point
  451.               (point)
  452.               
  453.               ) ; end excursion 
  454.             ) ; finalpt defined
  455.            
  456.            ) ; end of VARLIST
  457.         
  458.         ;; BODY
  459.  
  460.                 (while (re-search-forward regstring finalpt t)
  461.  
  462.           ;; if we are not inside a single or double quote then 
  463.           ;; replace `regstring' with `replacement' 
  464.           ;; (the `unwind-protect' contruct from section in Elisp 
  465.           ;; Reference Manual on saving match data)
  466.  
  467.           (if (let ((data (match-data)))
  468.             (unwind-protect
  469.                 (not (or (fortran-clean-inside-re "'" "'")
  470.                      (fortran-clean-inside-re "\"" "\"")
  471.                      (first-non-continuation-char regstring)))
  472.               (store-match-data data)))
  473.               (progn (replace-match replacement) (backward-char))
  474.             ) ; end of if
  475.  
  476.           ) ; end of while
  477.         ) ; end of inner let
  478.           
  479.           ) ; end of if-then FORM
  480.       ) ; end of if
  481.     (forward-line 1) ; go to beginning of next line
  482.     ) ; end while
  483.       )   ; end of outer let
  484.     )     ; end save-excusion
  485.   )
  486.  
  487. (defun first-non-continuation-char (regstring)
  488.   "Returns t if REGSTRING is the first string in a continuation fortran line."
  489.   (save-excursion
  490.     (beginning-of-line)
  491.     (looking-at (concat "^     [^ ]" regstring))))
  492.  
  493.  
  494. ;; this page is provided for reports.
  495. ;; adopted from Barry A. Warsaw's c++-mode.el
  496.  
  497. (defvar fortran-mailer 'mail
  498.   "*Mail package to use to generate report mail buffer.")
  499.  
  500. (defconst fortran-clean-help-address "dodd@roebling.poly.edu"
  501.   "Address accepting submission of reports.")
  502.  
  503. (defun fortran-clean-submit-report ()
  504.   "Submit via mail a report using the mailer in fortran-mailer."
  505.   (interactive)
  506.   (funcall fortran-mailer)
  507.   (insert fortran-clean-help-address)
  508.   (if (re-search-forward "^subject:[ \t]+" (point-max) 'move)
  509.       (insert "Report on fortran-clean.el " fortran-clean-version))
  510.   (if (not (re-search-forward mail-header-separator (point-max) 'move))
  511.       (progn (goto-char (point-max))
  512.          (insert "\n" mail-header-separator "\n")
  513.          (goto-char (point-max)))
  514.     (forward-line 1))
  515.   (set-mark (point))            ;user should see mark change
  516.   (insert "\n\n")
  517.   (insert (emacs-version) "\n")
  518.   (insert "fort-clean.el " fortran-clean-version)
  519.   (exchange-point-and-mark))
  520.  
  521.  
  522. ;;; Based on code from Ralph Finch's fortran-beautifier (rfinch@water.ca.gov)
  523.  
  524. (defun fortran-clean-inside-re (start-re end-re)
  525.   "Returns t if inside a starting regexp and an ending regexp
  526. on the same line."
  527.   (and (save-excursion
  528.      (re-search-backward start-re
  529.                  (save-excursion (beginning-of-line) (point)) t))
  530.        (save-excursion
  531.      (re-search-forward end-re
  532.                 (save-excursion (end-of-line) (point)) t))))
  533.