snmp-mode.el 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697
  1. ;;; snmp-mode.el --- SNMP & SNMPv2 MIB major mode
  2. ;; Copyright (C) 1995, 1998, 2001-2012 Free Software Foundation, Inc.
  3. ;; Author: Paul D. Smith <psmith@BayNetworks.com>
  4. ;; Keywords: data
  5. ;; This file is part of GNU Emacs.
  6. ;; GNU Emacs is free software: you can redistribute it and/or modify
  7. ;; it under the terms of the GNU General Public License as published by
  8. ;; the Free Software Foundation, either version 3 of the License, or
  9. ;; (at your option) any later version.
  10. ;; GNU Emacs is distributed in the hope that it will be useful,
  11. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ;; GNU General Public License for more details.
  14. ;; You should have received a copy of the GNU General Public License
  15. ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
  16. ;;; Commentary:
  17. ;; INTRODUCTION
  18. ;; ------------
  19. ;; This package provides a major mode for editing SNMP MIBs. It
  20. ;; provides all the modern Emacs 19 bells and whistles: default
  21. ;; fontification via font-lock, imenu search functions, etc.
  22. ;;
  23. ;; SNMP mode also uses tempo, a textual boilerplate insertion package
  24. ;; distributed with Emacs, to add in boilerplate SNMP MIB structures.
  25. ;; See tempo.el for more details about tempo.
  26. ;;
  27. ;; If you want to change or add new tempo templates, use the tempo tag
  28. ;; list `snmp-tempo-tags' (or `snmpv2-tempo-tags'): this list is
  29. ;; automatically installed when snmp-mode (or snmpv2-mode) is entered.
  30. ;;
  31. ;; The SNMPv2 mode in this version has been enhanced thanks to popular
  32. ;; demand.
  33. ;;
  34. ;; I'm very interested in new tempo macros for both v1 and v2, and any
  35. ;; other suggestions for enhancements (different syntax table items, new
  36. ;; keybindings, etc.)
  37. ;;
  38. ;;
  39. ;; USAGE
  40. ;; -----
  41. ;; Mostly, use it as you would any other mode. There's a very
  42. ;; simplistic auto-indent feature; hopefully it'll help more than get in
  43. ;; your way. For the most part it tries to indent to the same level as
  44. ;; the previous line. It will try to recognize some very simple tokens
  45. ;; on the previous line that tell it to use extra indent or outdent.
  46. ;;
  47. ;; Templates
  48. ;; ---------
  49. ;; To use the Tempo templates, type the Tempo tag (or a unique prefix)
  50. ;; and use C-c C-i (C-c TAB) to complete it; if you don't have
  51. ;; tempo-interactive set to nil it will ask you to fill in values.
  52. ;; Fields with predefined values (SYNTAX, STATUS, etc.) will do
  53. ;; completing-reads on a list of valid values; use the normal SPC or TAB
  54. ;; to complete.
  55. ;;
  56. ;; Currently the following templates are available:
  57. ;;
  58. ;; objectType -- Defines an OBJECT-TYPE macro.
  59. ;;
  60. ;; tableType -- Defines both a Table and Entry OBJECT-TYPE, and a
  61. ;; SEQUENCE for the ASN.1 Entry definition.
  62. ;;
  63. ;; Once the template is done, you can use C-cC-f and C-cC-b to move back
  64. ;; and forth between the Tempo sequence points to fill in the rest of
  65. ;; the information.
  66. ;;
  67. ;; Font Lock
  68. ;; ------------
  69. ;;
  70. ;; If you want font-lock in your MIB buffers, add this:
  71. ;;
  72. ;; (add-hook 'snmp-common-mode-hook 'turn-on-font-lock)
  73. ;;
  74. ;; Enabling global-font-lock-mode is also sufficient.
  75. ;;
  76. ;;; Code:
  77. (eval-when-compile
  78. (require 'cl)
  79. (require 'imenu) ; Need this stuff when compiling for imenu macros, etc.
  80. (require 'tempo))
  81. ;;;----------------------------------------------------------------------------
  82. ;;
  83. ;; Customize these:
  84. ;;
  85. ;;;----------------------------------------------------------------------------
  86. (defgroup snmp nil
  87. "Mode for editing SNMP MIB files."
  88. :group 'data
  89. :version "20.4")
  90. (defcustom snmp-special-indent t
  91. "If non-nil, use a simple heuristic to try to guess the right indentation.
  92. If nil, then no special indentation is attempted."
  93. :type 'boolean
  94. :group 'snmp)
  95. (defcustom snmp-indent-level 4
  96. "Indentation level for SNMP MIBs."
  97. :type 'integer
  98. :group 'snmp)
  99. (defcustom snmp-tab-always-indent nil
  100. "Non-nil means TAB should always reindent the current line.
  101. A value of nil means reindent if point is within the initial line indentation;
  102. otherwise insert a TAB."
  103. :type 'boolean
  104. :group 'snmp)
  105. (defcustom snmp-completion-ignore-case t
  106. "Non-nil means that case differences are ignored during completion.
  107. A value of nil means that case is significant.
  108. This is used during Tempo template completion."
  109. :type 'boolean
  110. :group 'snmp)
  111. (defcustom snmp-common-mode-hook nil
  112. "Hook(s) evaluated when a buffer enters either SNMP or SNMPv2 mode."
  113. :type 'hook
  114. :group 'snmp)
  115. (defcustom snmp-mode-hook nil
  116. "Hook(s) evaluated when a buffer enters SNMP mode."
  117. :type 'hook
  118. :group 'snmp)
  119. (defcustom snmpv2-mode-hook nil
  120. "Hook(s) evaluated when a buffer enters SNMPv2 mode."
  121. :type 'hook
  122. :group 'snmp)
  123. (defvar snmp-tempo-tags nil
  124. "*Tempo tags for SNMP mode.")
  125. (defvar snmpv2-tempo-tags nil
  126. "*Tempo tags for SNMPv2 mode.")
  127. ;; Enable fontification for SNMP MIBs
  128. ;;
  129. ;; These are pretty basic fontifications. Note we assume these macros
  130. ;; are first on a line (except whitespace), to speed up fontification.
  131. ;;
  132. (defvar snmp-font-lock-keywords-1
  133. (list
  134. ;; OBJECT-TYPE, TRAP-TYPE, and OBJECT-IDENTIFIER macros
  135. '("^[ \t]*\\([a-z][-a-zA-Z0-9]+\\)[ \t]+\\(\\(MODULE-\\(COMPLIANCE\\|IDENTITY\\)\\|OBJECT-\\(COMPLIANCE\\|GROUP\\|IDENTITY\\|TYPE\\)\\|TRAP-\\(GROUP\\|TYPE\\)\\)\\|\\(OBJECT\\)[ \t]+\\(IDENTIFIER\\)[ \t]*::=\\)"
  136. (1 font-lock-variable-name-face) (3 font-lock-keyword-face nil t)
  137. (7 font-lock-keyword-face nil t) (8 font-lock-keyword-face nil t))
  138. ;; DEFINITIONS clause
  139. '("^[ \t]*\\([A-Z][-a-zA-Z0-9]+\\)[ \t]+\\(DEFINITIONS\\)[ \t]*::="
  140. (1 font-lock-function-name-face) (2 font-lock-keyword-face))
  141. )
  142. "Basic SNMP MIB mode expression highlighting.")
  143. (defvar snmp-font-lock-keywords-2
  144. (append
  145. '(("ACCESS\\|BEGIN\\|DE\\(FVAL\\|SCRIPTION\\)\\|END\\|FROM\\|I\\(MPORTS\\|NDEX\\)\\|S\\(TATUS\\|YNTAX\\)"
  146. (0 font-lock-keyword-face)))
  147. snmp-font-lock-keywords-1)
  148. "Medium SNMP MIB mode expression highlighting.")
  149. (defvar snmp-font-lock-keywords-3
  150. (append
  151. '(("\\([^\n]+\\)[ \t]+::=[ \t]+\\(SEQUENCE\\)[ \t]+{"
  152. (1 font-lock-reference-face) (2 font-lock-keyword-face))
  153. ("::=[ \t]*{[ \t]*\\([a-z0-9].*[ \t]+\\)?\\([0-9]+\\)[ \t]*}"
  154. (1 font-lock-reference-face nil t) (2 font-lock-variable-name-face)))
  155. snmp-font-lock-keywords-2)
  156. "Gaudy SNMP MIB mode expression highlighting.")
  157. (defvar snmp-font-lock-keywords snmp-font-lock-keywords-1
  158. "Default SNMP MIB mode expression highlighting.")
  159. ;; These lists are used for the completion capabilities in the tempo
  160. ;; templates.
  161. ;;
  162. (defvar snmp-mode-syntax-list nil
  163. "Predefined types for SYNTAX clauses.")
  164. (defvar snmp-rfc1155-types
  165. '("INTEGER" "OCTET STRING" "OBJECT IDENTIFIER" "NULL" "IpAddress"
  166. "NetworkAddress" "Counter" "Gauge" "TimeTicks" "Opaque")
  167. "Types from RFC 1155 v1 SMI.")
  168. (defvar snmp-rfc1213-types
  169. '("DisplayString")
  170. "Types from RFC 1213 MIB-II.")
  171. (defvar snmp-rfc1902-types
  172. '("INTEGER" "OCTET STRING" "OBJECT IDENTIFIER" "Integer32"
  173. "IpAddress" "Counter32" "Gauge32" "Unsigned32" "TimeTicks"
  174. "Opaque" "Counter64")
  175. "Types from RFC 1902 v2 SMI.")
  176. (defvar snmp-rfc1903-types
  177. '("DisplayString" "PhysAddress" "MacAddress" "TruthValue"
  178. "TestAndIncr" "AutonomousType" "InstancePointer"
  179. "VariablePointer" "RowPointer" "RowStatus" "TimeStamp"
  180. "TimeInterval" "DateAndTime" "StorageType" "TDomain"
  181. "TAddress")
  182. "Types from RFC 1903 Textual Conventions.")
  183. (defvar snmp-mode-access-list nil
  184. "Predefined values for ACCESS clauses.")
  185. (defvar snmp-rfc1155-access
  186. '("read-only" "read-write" "write-only" "not-accessible")
  187. "ACCESS values from RFC 1155 v1 SMI.")
  188. (defvar snmp-rfc1902-access
  189. '("read-only" "read-write" "read-create" "not-accessible"
  190. "accessible-for-notify")
  191. "ACCESS values from RFC 1155 v1 SMI.")
  192. (defvar snmp-mode-status-list nil
  193. "Predefined values for STATUS clauses.")
  194. (defvar snmp-rfc1212-status
  195. '("mandatory" "obsolete" "deprecated")
  196. "STATUS values from RFC 1212 v1 SMI.")
  197. (defvar snmp-rfc1902-status
  198. '("current" "obsolete" "deprecated")
  199. "STATUS values from RFC 1902 v2 SMI.")
  200. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  201. ;;;----------------------------------------------------------------------------
  202. ;;
  203. ;; Nothing to customize below here.
  204. ;;
  205. ;;;----------------------------------------------------------------------------
  206. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  207. ;; Create abbrev table for SNMP MIB mode
  208. ;;
  209. (defvar snmp-mode-abbrev-table nil
  210. "Abbrev table in use in SNMP mode.")
  211. (define-abbrev-table 'snmp-mode-abbrev-table ())
  212. ;; Create abbrev table for SNMPv2 mode
  213. ;;
  214. (defvar snmpv2-mode-abbrev-table nil
  215. "Abbrev table in use in SNMPv2 mode.")
  216. (define-abbrev-table 'snmpv2-mode-abbrev-table ())
  217. ;; Set up our keymap
  218. ;;
  219. (defvar snmp-mode-map
  220. (let ((map (make-sparse-keymap)))
  221. (define-key map "\177" 'backward-delete-char-untabify)
  222. (define-key map "\C-c\C-i" 'tempo-complete-tag)
  223. (define-key map "\C-c\C-f" 'tempo-forward-mark)
  224. (define-key map "\C-c\C-b" 'tempo-backward-mark)
  225. map)
  226. "Keymap used in SNMP mode.")
  227. ;; Set up our syntax table
  228. ;;
  229. (defvar snmp-mode-syntax-table
  230. (let ((st (make-syntax-table)))
  231. (modify-syntax-entry ?\\ "\\" st)
  232. (modify-syntax-entry ?- "_ 1234" st)
  233. (modify-syntax-entry ?\n ">" st)
  234. (modify-syntax-entry ?\^m ">" st)
  235. (modify-syntax-entry ?_ "." st)
  236. (modify-syntax-entry ?: "." st)
  237. (modify-syntax-entry ?= "." st)
  238. st)
  239. "Syntax table used for buffers in SNMP mode.")
  240. ;; Set up the stuff that's common between snmp-mode and snmpv2-mode
  241. ;;
  242. (defun snmp-common-mode (name mode abbrev font-keywords imenu-index tempo-tags)
  243. (kill-all-local-variables)
  244. ;; Become the current major mode
  245. (setq mode-name name)
  246. (setq major-mode mode)
  247. ;; Activate keymap, syntax table, and abbrev table
  248. (use-local-map snmp-mode-map)
  249. (set-syntax-table snmp-mode-syntax-table)
  250. (setq local-abbrev-table abbrev)
  251. ;; Set up paragraphs (?)
  252. (make-local-variable 'paragraph-start)
  253. (setq paragraph-start (concat "$\\|" page-delimiter))
  254. (make-local-variable 'paragraph-separate)
  255. (setq paragraph-separate paragraph-start)
  256. (make-local-variable 'paragraph-ignore-fill-prefix)
  257. (setq paragraph-ignore-fill-prefix t)
  258. ;; Set up comments
  259. (make-local-variable 'comment-start)
  260. (setq comment-start "-- ")
  261. (make-local-variable 'comment-start-skip)
  262. (setq comment-start-skip "--+[ \t]*")
  263. (make-local-variable 'comment-column)
  264. (setq comment-column 40)
  265. (make-local-variable 'parse-sexp-ignore-comments)
  266. (setq parse-sexp-ignore-comments t)
  267. ;; Set up indentation
  268. (if snmp-special-indent
  269. (set (make-local-variable 'indent-line-function) 'snmp-indent-line))
  270. (set (make-local-variable 'tab-always-indent) snmp-tab-always-indent)
  271. ;; Font Lock
  272. (make-local-variable 'font-lock-defaults)
  273. (setq font-lock-defaults (cons font-keywords '(nil nil ((?- . "w 1234")))))
  274. ;; Imenu
  275. (make-local-variable 'imenu-create-index-function)
  276. (setq imenu-create-index-function imenu-index)
  277. ;; Tempo
  278. (tempo-use-tag-list tempo-tags)
  279. (make-local-variable 'tempo-match-finder)
  280. (setq tempo-match-finder "\\b\\(.+\\)\\=")
  281. (make-local-variable 'tempo-interactive)
  282. (setq tempo-interactive t)
  283. ;; Miscellaneous customization
  284. (make-local-variable 'require-final-newline)
  285. (setq require-final-newline mode-require-final-newline))
  286. ;; SNMPv1 MIB Editing Mode.
  287. ;;
  288. ;;;###autoload
  289. (defun snmp-mode ()
  290. "Major mode for editing SNMP MIBs.
  291. Expression and list commands understand all C brackets.
  292. Tab indents for C code.
  293. Comments start with -- and end with newline or another --.
  294. Delete converts tabs to spaces as it moves back.
  295. \\{snmp-mode-map}
  296. Turning on snmp-mode runs the hooks in `snmp-common-mode-hook', then
  297. `snmp-mode-hook'."
  298. (interactive)
  299. (snmp-common-mode "SNMP" 'snmp-mode
  300. snmp-mode-abbrev-table
  301. '(snmp-font-lock-keywords
  302. snmp-font-lock-keywords-1
  303. snmp-font-lock-keywords-2
  304. snmp-font-lock-keywords-3)
  305. 'snmp-mode-imenu-create-index
  306. 'snmp-tempo-tags)
  307. ;; Completion lists
  308. (make-local-variable 'snmp-mode-syntax-list)
  309. (setq snmp-mode-syntax-list (append snmp-rfc1155-types
  310. snmp-rfc1213-types
  311. snmp-mode-syntax-list))
  312. (make-local-variable 'snmp-mode-access-list)
  313. (setq snmp-mode-access-list snmp-rfc1155-access)
  314. (make-local-variable 'snmp-mode-status-list)
  315. (setq snmp-mode-status-list snmp-rfc1212-status)
  316. ;; Run hooks
  317. (run-mode-hooks 'snmp-common-mode-hook 'snmp-mode-hook))
  318. ;;;###autoload
  319. (defun snmpv2-mode ()
  320. "Major mode for editing SNMPv2 MIBs.
  321. Expression and list commands understand all C brackets.
  322. Tab indents for C code.
  323. Comments start with -- and end with newline or another --.
  324. Delete converts tabs to spaces as it moves back.
  325. \\{snmp-mode-map}
  326. Turning on snmp-mode runs the hooks in `snmp-common-mode-hook',
  327. then `snmpv2-mode-hook'."
  328. (interactive)
  329. (snmp-common-mode "SNMPv2" 'snmpv2-mode
  330. snmpv2-mode-abbrev-table
  331. '(snmp-font-lock-keywords
  332. snmp-font-lock-keywords-1
  333. snmp-font-lock-keywords-2
  334. snmp-font-lock-keywords-3)
  335. 'snmp-mode-imenu-create-index
  336. 'snmpv2-tempo-tags)
  337. ;; Completion lists
  338. (make-local-variable 'snmp-mode-syntax-list)
  339. (setq snmp-mode-syntax-list (append snmp-rfc1902-types
  340. snmp-rfc1903-types
  341. snmp-mode-syntax-list))
  342. (make-local-variable 'snmp-mode-access-list)
  343. (setq snmp-mode-access-list snmp-rfc1902-access)
  344. (make-local-variable 'snmp-mode-status-list)
  345. (setq snmp-mode-status-list snmp-rfc1902-status)
  346. ;; Run hooks
  347. (run-mode-hooks 'snmp-common-mode-hook 'snmpv2-mode-hook))
  348. ;;;----------------------------------------------------------------------------
  349. ;;
  350. ;; Indentation Setup
  351. ;;
  352. ;;;----------------------------------------------------------------------------
  353. (defvar snmp-macro-open
  354. "[a-zA-Z][-a-zA-Z0-9]*[ \t]*\\(OBJECT\\|TRAP\\)-\\(TYPE\\|GROUP\\)\
  355. \\|DESCRIPTION\\|IMPORTS\\|MODULE\\(-IDENTITY\\|-COMPLIANCE\\)\
  356. \\|.*::=[ \t]*\\(BEGIN\\|TEXTUAL-CONVENTION\\)[ \t]*$")
  357. (defvar snmp-macro-close
  358. "::=[ \t]*{\\|\\(END\\|.*[;\"]\\)[ \t]*$")
  359. (defun snmp-calculate-indent ()
  360. "Calculate the current line indentation in SNMP MIB code.
  361. We use a very simple scheme: if the previous non-empty line was a \"macro
  362. open\" string, add `snmp-indent-level' to it. If it was a \"macro close\"
  363. string, subtract `snmp-indent-level'. Otherwise, use the same indentation
  364. as the previous non-empty line. Note comments are considered empty
  365. lines for the purposes of this function."
  366. (let ((empty (concat "\\([ \t]*\\)\\(" comment-start-skip "\\|$\\)"))
  367. (case-fold-search nil)) ; keywords must be in uppercase
  368. (save-excursion
  369. (while (and (>= (forward-line -1) 0)
  370. (looking-at empty)))
  371. (skip-chars-forward " \t")
  372. (+ (current-column)
  373. ;; Are we looking at a macro open string? If so, add more.
  374. (cond ((looking-at snmp-macro-open)
  375. snmp-indent-level)
  376. ;; macro close string? If so, remove some.
  377. ((looking-at snmp-macro-close)
  378. (- snmp-indent-level))
  379. ;; Neither; just stay here.
  380. (t 0))))))
  381. (defun snmp-indent-line ()
  382. "Indent current line as SNMP MIB code."
  383. (let ((indent (snmp-calculate-indent))
  384. (pos (- (point-max) (point)))
  385. shift-amt beg)
  386. (beginning-of-line)
  387. (setq beg (point))
  388. (skip-chars-forward " \t")
  389. (setq shift-amt (- indent (current-column)))
  390. (if (zerop shift-amt)
  391. nil
  392. (delete-region beg (point))
  393. (indent-to indent))
  394. ;; If initial point was within line's indentation,
  395. ;; position after the indentation. Else stay at same point in text.
  396. (if (> (- (point-max) pos) (point))
  397. (goto-char (- (point-max) pos)))))
  398. ;;;----------------------------------------------------------------------------
  399. ;;
  400. ;; Imenu Setup
  401. ;;
  402. ;;;----------------------------------------------------------------------------
  403. (defvar snmp-clause-regexp
  404. "^[ \t]*\\([a-zA-Z][-a-zA-Z0-9]*\\)[ \t\n]*\
  405. \\(TRAP-TYPE\\|::=\\|OBJECT\\(-TYPE[ \t\n]+SYNTAX\\|[ \t\n]+IDENTIFIER[ \t\n]*::=\\)\\)")
  406. (defun snmp-mode-imenu-create-index ()
  407. (let ((index-alist '())
  408. (index-oid-alist '())
  409. (index-tc-alist '())
  410. (index-table-alist '())
  411. (index-trap-alist '())
  412. (case-fold-search nil) ; keywords must be uppercase
  413. prev-pos token end)
  414. (goto-char (point-min))
  415. (imenu-progress-message prev-pos 0)
  416. ;; Search for a useful MIB item (that's not in a comment)
  417. (save-match-data
  418. (while (re-search-forward snmp-clause-regexp nil t)
  419. (imenu-progress-message prev-pos)
  420. (setq
  421. end (match-end 0)
  422. token (cons (match-string 1)
  423. (set-marker (make-marker) (match-beginning 1))))
  424. (goto-char (match-beginning 2))
  425. (cond ((looking-at "OBJECT-TYPE[ \t\n]+SYNTAX")
  426. (push token index-alist))
  427. ((looking-at "OBJECT[ \t\n]+IDENTIFIER[ \t\n]*::=")
  428. (push token index-oid-alist))
  429. ((looking-at "::=[ \t\n]*SEQUENCE[ \t\n]*{")
  430. (push token index-table-alist))
  431. ((looking-at "TRAP-TYPE")
  432. (push token index-trap-alist))
  433. ((looking-at "::=")
  434. (push token index-tc-alist)))
  435. (goto-char end)))
  436. ;; Create the menu
  437. (imenu-progress-message prev-pos 100)
  438. (setq index-alist (nreverse index-alist))
  439. (and index-tc-alist
  440. (push (cons "Textual Conventions" (nreverse index-tc-alist))
  441. index-alist))
  442. (and index-trap-alist
  443. (push (cons "Traps" (nreverse index-trap-alist))
  444. index-alist))
  445. (and index-table-alist
  446. (push (cons "Tables" (nreverse index-table-alist))
  447. index-alist))
  448. (and index-oid-alist
  449. (push (cons "Object IDs" (nreverse index-oid-alist))
  450. index-alist))
  451. index-alist))
  452. ;;;----------------------------------------------------------------------------
  453. ;;
  454. ;; Tempo Setup
  455. ;;
  456. ;;;----------------------------------------------------------------------------
  457. (require 'tempo)
  458. ;; Perform a completing-read with info given
  459. ;;
  460. (defun snmp-completing-read (prompt table &optional pred require init hist)
  461. "Read from the minibuffer, with completion.
  462. Like `completing-read', but the variable `snmp-completion-ignore-case'
  463. controls whether case is significant."
  464. (let ((completion-ignore-case snmp-completion-ignore-case))
  465. (completing-read prompt table pred require init hist)))
  466. ;; OBJECT-TYPE macro template
  467. ;;
  468. (tempo-define-template "snmp-object-type"
  469. '(> (P "Object Label: ") " OBJECT-TYPE" n>
  470. "SYNTAX "
  471. (if tempo-interactive
  472. (snmp-completing-read "Syntax: " snmp-mode-syntax-list nil nil)
  473. p) n>
  474. "ACCESS "
  475. (if tempo-interactive
  476. (snmp-completing-read "Access: " snmp-mode-access-list nil t)
  477. p) n>
  478. "STATUS "
  479. (if tempo-interactive
  480. (snmp-completing-read "Status: " snmp-mode-status-list nil t)
  481. p) n>
  482. "DESCRIPTION" n> "\"" p "\"" n>
  483. (P "Default Value: " defval t)
  484. (if (string= "" (tempo-lookup-named 'defval))
  485. nil
  486. '(l "DEFVAL { " (s defval) " }" n>))
  487. "::= { " (p "OID: ") " }" n)
  488. "objectType"
  489. "Insert an OBJECT-TYPE macro."
  490. 'snmp-tempo-tags)
  491. ;; Table macro template
  492. ;;
  493. (tempo-define-template "snmp-table-type"
  494. ;; First the table OBJECT-TYPE
  495. '(> (P "Table Name: " table)
  496. (P "Entry Name: " entry t)
  497. (let* ((entry (tempo-lookup-named 'entry))
  498. (seq (copy-sequence entry)))
  499. (aset entry 0 (downcase (aref entry 0)))
  500. (aset seq 0 (upcase (aref seq 0)))
  501. (tempo-save-named 'obj-entry entry)
  502. (tempo-save-named 'seq-entry seq)
  503. nil)
  504. " OBJECT-TYPE" n>
  505. "SYNTAX SEQUENCE OF "
  506. (s seq-entry) n>
  507. "ACCESS not-accessible" n>
  508. "STATUS mandatory" n>
  509. "DESCRIPTION" n> "\"" p "\"" n>
  510. "::= { " (p "OID: ") " }" n n>
  511. ;; Next the row OBJECT-TYPE
  512. (s obj-entry) " OBJECT-TYPE" n>
  513. "SYNTAX " (s seq-entry) n>
  514. "ACCESS not-accessible" n>
  515. "STATUS mandatory" n>
  516. "DESCRIPTION" n> "\"" p "\"" n>
  517. "INDEX { " (p "Index List: ") " }" n>
  518. "::= {" (s table) " 1 }" n n>
  519. ;; Finally the SEQUENCE type
  520. (s seq-entry) " ::= SEQUENCE {" n> p n> "}" n)
  521. "tableType"
  522. "Insert an SNMP table."
  523. 'snmp-tempo-tags)
  524. ;; v2 SMI OBJECT-TYPE macro template
  525. ;;
  526. (tempo-define-template "snmpv2-object-type"
  527. '(> (P "Object Label: ") " OBJECT-TYPE" n>
  528. "SYNTAX "
  529. (if tempo-interactive
  530. (snmp-completing-read "Syntax: " snmp-mode-syntax-list nil nil)
  531. p) n>
  532. "MAX-ACCESS "
  533. (if tempo-interactive
  534. (snmp-completing-read "Max Access: " snmp-mode-access-list nil t)
  535. p) n>
  536. "STATUS "
  537. (if tempo-interactive
  538. (snmp-completing-read "Status: " snmp-mode-status-list nil t)
  539. p) n>
  540. "DESCRIPTION" n> "\"" p "\"" n>
  541. (P "Default Value: " defval t)
  542. (if (string= "" (tempo-lookup-named 'defval))
  543. nil
  544. '(l "DEFVAL { " (s defval) " }" n>))
  545. "::= { " (p "OID: ") " }" n)
  546. "objectType"
  547. "Insert an v2 SMI OBJECT-TYPE macro."
  548. 'snmpv2-tempo-tags)
  549. ;; v2 SMI Table macro template
  550. ;;
  551. (tempo-define-template "snmpv2-table-type"
  552. ;; First the table OBJECT-TYPE
  553. '(> (P "Table Name: " table)
  554. (P "Entry Name: " entry t)
  555. (let* ((entry (tempo-lookup-named 'entry))
  556. (seq (copy-sequence entry)))
  557. (aset entry 0 (downcase (aref entry 0)))
  558. (aset seq 0 (upcase (aref seq 0)))
  559. (tempo-save-named 'obj-entry entry)
  560. (tempo-save-named 'seq-entry seq)
  561. nil)
  562. " OBJECT-TYPE" n>
  563. "SYNTAX SEQUENCE OF "
  564. (s seq-entry) n>
  565. "MAX-ACCESS not-accessible" n>
  566. "STATUS current" n>
  567. "DESCRIPTION" n> "\"" p "\"" n>
  568. "::= { " (p "OID: ") " }" n n>
  569. ;; Next the row OBJECT-TYPE
  570. (s obj-entry) " OBJECT-TYPE" n>
  571. "SYNTAX " (s seq-entry) n>
  572. "MAX-ACCESS not-accessible" n>
  573. "STATUS current" n>
  574. "DESCRIPTION" n> "\"" p "\"" n>
  575. "INDEX { " (p "Index List: ") " }" n>
  576. "::= { " (s table) " 1 }" n n>
  577. ;; Finally the SEQUENCE type
  578. (s seq-entry) " ::= SEQUENCE {" n> p n> "}" n)
  579. "tableType"
  580. "Insert an v2 SMI SNMP table."
  581. 'snmpv2-tempo-tags)
  582. ;; v2 SMI TEXTUAL-CONVENTION macro template
  583. ;;
  584. (tempo-define-template "snmpv2-textual-convention"
  585. '(> (P "Textual Convention Type: ") " ::= TEXTUAL-CONVENTION" n>
  586. "STATUS "
  587. (if tempo-interactive
  588. (snmp-completing-read "Status: " snmp-mode-status-list nil t)
  589. p) n>
  590. "DESCRIPTION" n> "\"" p "\"" n>
  591. "SYNTAX "
  592. (if tempo-interactive
  593. (snmp-completing-read "Syntax: " snmp-mode-syntax-list nil nil)
  594. p) n> )
  595. "textualConvention"
  596. "Insert an v2 SMI TEXTUAL-CONVENTION macro."
  597. 'snmpv2-tempo-tags)
  598. (provide 'snmp-mode)
  599. ;;; snmp-mode.el ends here