Paste number 53428: selinux-te-mode.el

Paste number 53428: selinux-te-mode.el
Pasted by: abbe
When:1 year, 6 months ago
Share:Tweet this! | http://paste.lisp.org/+1584
Channel:#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.