Advertisement
Guest User

Untitled

a guest
Feb 3rd, 2012
110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lisp 4.55 KB | None | 0 0
  1. ;;; ppindent.el --- Indents C preprocessor directives
  2.  
  3. ;; Copyright (C) 2007 Free Software Foundation, Inc.
  4.  
  5. ;; Author: Craig McDaniel <craigmcd@gmail.com>
  6. ;; Keywords: languages, c
  7. ;; Maintainer: Craig McDaniel <craigmcd@gmail.com>
  8.  
  9. ;; This file is free software; you can redistribute it and/or modify
  10. ;; it under the terms of the GNU General Public License as published by
  11. ;; the Free Software Foundation; either version 2, or (at your option)
  12. ;; any later version.
  13.  
  14. ;; This file is distributed in the hope that it will be useful,
  15. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. ;; GNU General Public License for more details.
  18.  
  19. ;; You should have received a copy of the GNU General Public License
  20. ;; along with GNU Emacs; see the file COPYING. If not, write to
  21. ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  22. ;; Boston, MA 02111-1307, USA.
  23.  
  24. ;;; Commentary:
  25.  
  26. ;; PPINDENT indents C-preprocessor statements depending on the current
  27. ;; #if..., #el.., #endif level. It only modifies lines with "#" as the
  28. ;; first non-blank character and therefore does not conflict with the
  29. ;; normal C indentation. Unlike a true indent, it inserts the
  30. ;; requisite number of spaces after, rather than before the "#"
  31. ;; character. This type of preprocesor indent is commonly used to
  32. ;; provide the most compatibility with different C-compilers.
  33. ;;
  34. ;; Example:
  35.  
  36. ;;        #ifdef WOO
  37. ;;        ....
  38. ;;        #if defined(X) && !defined(Y)
  39. ;;        #ifdef Q8
  40. ;;        ...
  41. ;;        #else
  42. ;;        ...
  43. ;;        ....
  44. ;;        #elif defined (Z)
  45. ;;        ....
  46. ;;        #endif
  47. ;;        #endif
  48. ;;        #endif
  49.          
  50. ;; After "M-x ppindent-c" becomes:
  51.          
  52. ;;        #ifdef WOO
  53. ;;        ....
  54. ;;        #  if defined(X) && !defined(Y)
  55. ;;        #    ifdef Q8
  56. ;;        ...
  57. ;;        #    else
  58. ;;        ...
  59. ;;        ....
  60. ;;        #    elif defined (Z)
  61. ;;        ....
  62. ;;        #    endif
  63. ;;        #  endif
  64. ;;        #endif
  65.  
  66. ;; Two functions are provided: PPINDENT-C indents as described
  67. ;; above. PPINDENT-H does not indent the first level, assuming that
  68. ;; .h/.hpp files use an #ifdef guard around the entire file.
  69.  
  70. ;; You can customize PPINDENT-INCREMENT if you want to use something
  71. ;; other than 2 spaces for the indent.
  72.  
  73. ;;; History:
  74.  
  75. ;; 2007-01-19 WCM Initial version
  76.  
  77. ;;; Code:
  78.  
  79. (provide 'ppindent)
  80.  
  81. (defgroup pp-indent nil
  82.   "Indent C preproccessor directives."
  83.   :group 'c)
  84.  
  85. (defcustom ppindent-increment 2
  86.   "Number of spaces per indention level.
  87.  
  88. Used in C pre-processor indent functions ppindent-c and ppindent-h"
  89.   :type 'number
  90.   :group 'pp-indent)
  91.  
  92. (defun starts-withp (str prefix)
  93.   "str starts with prefix"
  94.   (eql (compare-strings prefix nil nil str nil (length prefix)) t))
  95.  
  96. (defun my-make-string (length init)
  97.   "just like make-string, but makes an empty string if length is negative"
  98.   (when (minusp length)
  99.     (setf length 0))
  100.   (make-string length init))
  101.  
  102. (defun ppindent-aux (start)
  103.   (let ((cnt start))
  104.     (goto-char (point-min))
  105.     (while (re-search-forward "^[ \t]*#[ \t]*\\(.*\\)" nil t)
  106.       (cond ((starts-withp (match-string-no-properties 1) "if")
  107.              (replace-match (concat (my-make-string cnt ?\s) "#\\1"))
  108.              (incf cnt ppindent-increment))
  109.             ((starts-withp (match-string-no-properties 1) "el")
  110.              (when (< (- cnt ppindent-increment) start)
  111.                (throw 'err `(,(line-number-at-pos) "Unmatched #else or #elif")))
  112.              (replace-match (concat (my-make-string
  113.                                          (- cnt ppindent-increment)
  114.                                          ?\s) "#\\1")))
  115.             ((starts-withp (match-string-no-properties 1) "endif")
  116.              (when (< (- cnt ppindent-increment) start)
  117.                (throw 'err `(,(line-number-at-pos) "Unmatched #endif")))
  118.              (decf cnt ppindent-increment)
  119.              (replace-match (concat (my-make-string cnt ?\s) "#\\1")))
  120.             (t
  121.              (replace-match (concat (my-make-string cnt ?\s) "#\\1")))))))
  122.  
  123. (defun ppindent-buffer (start)
  124.   (let ((result (catch 'err (save-excursion (ppindent-aux start)))))
  125.     (when result
  126.       (goto-line (car result))
  127.       (error "Error: %s" (cadr result)))))
  128.  
  129. (defun ppindent-c ()
  130.   "Indent all C pre-processor statements"
  131.   (interactive)
  132.   (ppindent-buffer 0))
  133.  
  134. (defun ppindent-h ()
  135.   "Indent C pre-processor statements, keeping first level #ifdef unindented"
  136.   (interactive)
  137.   (ppindent-buffer (- ppindent-increment)))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement