Paste number 53428: selinux-te-mode.el

Paste number 53428: selinux-te-mode.el
Pasted by: abbe
1 year, 6 days ago
#emacs
Paste contents:
Raw Source | XML | Display As
;; SELinux TE File mode
;; Author: Ashish Shukla <gmail.com!wahjava>

(defvar selinux-te-mode-hook nil)

(add-to-list 'auto-mode-alist '("\\.te\\'" . selinux-te-mode))
;; %token ALIAS
;; %token ALLOW
;; %token ATTRIBUTE
;; %token AUDITALLOW
;; %token AUDITDENY
;; %token BOOL
;; %token CATEGORY
;; %token CLASS
;; %token CLONE
;; %token COMMON
;; %token CONSTRAIN
;; %token DOMINANCE
;; %token DOM DOMBY INCOMP
;; %token DONTAUDIT
;; %token ELSE
;; %token FSCON PORTCON NETIFCON NODECON
;; %token FSUSEXATTR FSUSETASK FSUSETRANS
;; %token GENFSCON
;; %token IF
;; %token INHERITS
;; %token LEVEL
;; %token MODULE VERSION_IDENTIFIER
;; %token MLSCONSTRAIN
;; %token MLSVALIDATETRANS
;; %token NEVERALLOW
;; %token OPTIONAL
;; %token PATH
;; %token RANGE
;; %token REQUIRE
;; %token ROLE
;; %token ROLES
;; %token ROLE_TRANSITION
;; %token RANGE_TRANSITION
;; %token SAMEUSER
;; %token SENSITIVITY
;; %token SID
;; %token SOURCE
;; %token TARGET
;; %token TYPE
;; %token TYPEALIAS
;; %token TYPEATTRIBUTE
;; %token TYPES
;; %token TYPE_TRANSITION
;; %token TYPE_MEMBER
;; %token TYPE_CHANGE
;; %token USER
;; %token U1 U2 U3 R1 R2 R3 T1 T2 T3 L1 L2 H1 H2
;; %token VALIDATETRANS

;; %token NOT AND OR XOR
;; %token CTRUE CFALSE
;; %token IDENTIFIER
;; %token USER_IDENTIFIER
;; %token NUMBER
;; %token EQUALS
;; %token NOTEQUAL
;; %token IPV6_ADDR

(defconst selinux-te-font-lock-keywords-1
  (list
   '("\\<\\(?:a\\(?:l\\(?:ias\\|low\\)\\|ttribute\\|udit\\(?:allow\\|deny\\)\\)\\|bool\\|c\\(?:ategory\\|l\\(?:ass\\|one\\)\\|o\\(?:mmon\\|nstrain\\)\\)\\|do\\(?:m\\(?:by\\|inance\\|\\)\\|ntaudit\\)\\|else\\|fs\\(?:con\\|_use_\\(?:xattr\\|task\\|trans\\)\\)\\|genfscon\\|i\\(?:f\\|n\\(?:herits\\|comp\\)\\)\\|level\\|m\\(?:odule\\|ls\\(?:constrain\\|validatetrans\\)\\)\\|n\\(?:e\\(?:tifcon\\|verallow\\)\\|odecon\\)\\|optional\\|p\\(?:ath\\|ortcon\\)\\|r\\(?:ange\\(?:_transition\\|\\)\\|equire\\|ole\\(?:s\\|_transition\\|\\)\\)\\|s\\(?:e\\(?:lf\\|nsitivity\\)\\|id\\|ource\\)\\|t\\(?:arget\\|ype\\(?:a\\(?:lias\\|ttribute\\)\\|s\\|_\\(?:transition\\|member\\|change\\)\\|\\)\\)\\|u\\(?:ser\\|1\\|2\\|3\\)\\|r\\(?:1\\|2\\|3\\)\\|t\\(?:1\\|2\\|3\\)\\|l\\(?:1\\|2\\)\\|h\\(?:1\\|2\\)\\|validatetrans\\)\\>" . font-lock-keyword-face)
   '("\\<\\(?:f\\(?:d\\|ile\\(?:system\\|\\)\\)\\|\\(?:\\(?:blk\\|chr\\|fifo\\|lnk\\|sock\\)_\\)file\\|d\\(?:ir\\|bus\\|rawable\\)\\|\\(?:\\(key\\|\\(?:netlink\\(?:_route\\|_firewall\\|_tcpdiag\\|_nflog\\|_xfrm\\|_selinux\\|_audit\\|_ip6fw\\|_dnrt\\|_kobject_uevent\\)?\\)\\|packet\\|\\(?:rawi\\|tc\\|ud\\)p\\|unix_\\(?:dgram\\|stream\\)\\|appletalk\\)_\\)?socket\\|ipc\\|msgq\\|s\\(?:e\\|h\\)m\\|capability\\|msg\\|n\\(?:etif\\|ode\\|scd\\)\\|p\\(?:ro\\(cess\\|perty\\)\\|a\\(?:x\\|sswd\\)\\)\\|s\\(?:ecurity\\|ystem\\)\\|x\\(?:client\\|input\\|server\\|extension\\)\\|font\\|c\\(?:olormap\\|ursor\\)\\)\\>" . font-lock-builtin-face)
   '("\\(\\w*\\))" . font-lock-variable-name-face)
)

  "Default font-lock-keywords for `selinux-te-mode'."
)


(defvar selinux-te-mode-syntax-table
  (let ((st (make-syntax-table)))
    (modify-syntax-entry ?{ "(}" st)
    (modify-syntax-entry ?} "){" st)
    (modify-syntax-entry ?# "<\n" st)
    (modify-syntax-entry ?\n ">#" st)
    (modify-syntax-entry ?_ "w" st)
    (modify-syntax-entry ?- "w" st)
    (modify-syntax-entry ?\; "." st) st
)

  "Syntax table used in `selinux-te-mode'."
)


(defun selinux-te-indent-line()
  "Indents SELinux TE Line"
  (interactive)
  (beginning-of-line)
  (let (cur-indent (indented nil))
      
    ;; if at beginning of buffer, then indent to column 0
    (if (bobp)
        (progn (setq cur-indent 0) (setq indented t))

      (progn
        (save-excursion

          ;; now indentation depends on what previous line, so move back
          (forward-line -1)
            
          ;; if its something like, (require|common|class|option) word {, then
          (if (looking-at "^[ \t]*\\(require\\|common\\|optional\\|class\\)[ \t]*[\w_]*{[ \t]*$")

              ;; indent-by current tab-width
              (progn
                (setq cur-indent (+ (current-indentation) tab-width))
                (setq indented t)
)

              
            ;; else if its some other style, like in "allow { httpd_t ftpd_t", then
            (if (looking-at "^.*{[^}]*$")
                (progn
                  ;; indent to the column no. of '{' + 1
                  (setq cur-indent (progn (search-forward "{") (+ (current-column) 1)))
                  (setq indented t)
)


              ;; else use current-indentation
              (progn
                (setq cur-indent (current-indentation))
                (setq indented   t)
                
)

              
)

            
)

          
)

          
        ;; now, we're back at current line, see if current line has '}', then we might need to de-indent.
        (if (looking-at "^[ \t]*}")
            (save-excursion
              ;; move to the point where it all started, i.e. the line containing '{'
              ;; so start moving upwards, unless we find that line
              ;; this block of code also keeps track of matching of braces
              (let ((brace-nesting-count 0) (reached-start nil))

                (while (or (> brace-nesting-count 0) (not reached-start))
                  (if (looking-at "^.*}")
                      (setq brace-nesting-count (+ brace-nesting-count 1))
                    (if (looking-at "^.*{")
                        (setq brace-nesting-count (- brace-nesting-count 1))
                      
)

                    
)


                  (forward-line -1)
                  (setq reached-start (bobp))
                  (if (= brace-nesting-count 0) (progn (forward-line 1)
                                                       (setq reached-start t)
)
)

                  
)

                
)

                  
              ;; now we're at that line, so see, if its some 'require|common|optional|class' block,
              ;; if it is, then
              (if (looking-at "^[ \t]*\\(require\\|common\\|optional\\|class\\)[ \t]*[\w_]*{[ \t]*$")

                  ;;  set the indentation to the current-indentation.
                  (setq cur-indent (current-indentation))

                ;; else, if its some other style, then indent to the column no. of '{'
                (progn
                  (setq cur-indent (progn (search-forward "{") (- (current-column) 1)))
                  (setq indented t)
                  
)

                
)

              
)

          
)

        
)

      
)

      
    (if indented (indent-line-to cur-indent))
    
)

  
)

            


(defun selinux-te-mode()
  "Major mode for selinux .te files"
  (interactive)
  (kill-all-local-variables)
   
  (make-local-variable 'font-lock-defaults)
  (make-local-variable 'comment-start)
  (make-local-variable 'indent-line-function)

  (setq major-mode 'selinux-te-mode
        mode-name "SELinux Type Enforcement"
        font-lock-defaults '(selinux-te-font-lock-keywords-1 nil)
        comment-start "#"
        indent-line-function 'selinux-te-indent-line
        
)


  (set-syntax-table selinux-te-mode-syntax-table)
  (run-mode-hooks 'selinux-te-mode-hook)
  
)


(provide 'selinux-te-mode)

This paste has no annotations.

Colorize as:
Show Line Numbers

Lisppaste pastes can be made by anyone at any time. Imagine a fearsomely comprehensive disclaimer of liability. Now fear, comprehensively.