Home | History | Annotate | Line # | Download | only in lisp
      1      1.1  mrg ;;; gmpasm-mode.el -- GNU MP asm and m4 editing mode.
      2      1.1  mrg 
      3      1.1  mrg 
      4  1.1.1.2  mrg ;; Copyright 1999-2002 Free Software Foundation, Inc.
      5  1.1.1.2  mrg 
      6  1.1.1.2  mrg ;;   This file is part of the GNU MP Library.
      7  1.1.1.3  mrg ;;
      8  1.1.1.2  mrg ;;   The GNU MP Library is free software; you can redistribute it and/or modify
      9  1.1.1.2  mrg ;;   it under the terms of either:
     10  1.1.1.3  mrg ;;
     11  1.1.1.2  mrg ;;     * the GNU Lesser General Public License as published by the Free
     12  1.1.1.2  mrg ;;       Software Foundation; either version 3 of the License, or (at your
     13  1.1.1.2  mrg ;;       option) any later version.
     14  1.1.1.3  mrg ;;
     15  1.1.1.2  mrg ;;   or
     16  1.1.1.3  mrg ;;
     17  1.1.1.2  mrg ;;     * the GNU General Public License as published by the Free Software
     18  1.1.1.2  mrg ;;       Foundation; either version 2 of the License, or (at your option) any
     19  1.1.1.2  mrg ;;       later version.
     20  1.1.1.3  mrg ;;
     21  1.1.1.2  mrg ;;   or both in parallel, as here.
     22  1.1.1.3  mrg ;;
     23  1.1.1.2  mrg ;;   The GNU MP Library is distributed in the hope that it will be useful, but
     24  1.1.1.2  mrg ;;   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     25  1.1.1.2  mrg ;;   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     26  1.1.1.2  mrg ;;   for more details.
     27  1.1.1.3  mrg ;;
     28  1.1.1.2  mrg ;;   You should have received copies of the GNU General Public License and the
     29  1.1.1.2  mrg ;;   GNU Lesser General Public License along with the GNU MP Library.  If not,
     30  1.1.1.2  mrg ;;   see https://www.gnu.org/licenses/.
     31      1.1  mrg 
     32      1.1  mrg 
     33      1.1  mrg ;;; Commentary:
     34      1.1  mrg ;;
     35      1.1  mrg ;; gmpasm-mode is a major mode for editing m4 processed assembler code and
     36      1.1  mrg ;; m4 macro files in GMP.  It's similar to m4-mode, but has a number of
     37      1.1  mrg ;; settings better suited to GMP.
     38      1.1  mrg ;;
     39      1.1  mrg ;;
     40      1.1  mrg ;; Install
     41      1.1  mrg ;; -------
     42      1.1  mrg ;;
     43      1.1  mrg ;; To make M-x gmpasm-mode available, put gmpasm-mode.el somewhere in your
     44      1.1  mrg ;; load-path and the following in your .emacs
     45      1.1  mrg ;;
     46      1.1  mrg ;;	(autoload 'gmpasm-mode "gmpasm-mode" nil t)
     47      1.1  mrg ;;
     48      1.1  mrg ;; To use gmpasm-mode automatically on all .asm and .m4 files, put the
     49      1.1  mrg ;; following in your .emacs
     50      1.1  mrg ;;
     51      1.1  mrg ;;	(add-to-list 'auto-mode-alist '("\\.asm\\'" . gmpasm-mode))
     52      1.1  mrg ;;	(add-to-list 'auto-mode-alist '("\\.m4\\'" . gmpasm-mode))
     53      1.1  mrg ;;
     54      1.1  mrg ;; To have gmpasm-mode only on gmp files, try instead something like the
     55      1.1  mrg ;; following, which uses it only in a directory starting with "gmp", or a
     56      1.1  mrg ;; sub-directory of such.
     57      1.1  mrg ;;
     58      1.1  mrg ;;	(add-to-list 'auto-mode-alist
     59      1.1  mrg ;;	             '("/gmp.*/.*\\.\\(asm\\|m4\\)\\'" . gmpasm-mode))
     60      1.1  mrg ;;
     61      1.1  mrg ;; Byte compiling will slightly speed up loading.  If you want a docstring
     62      1.1  mrg ;; in the autoload you can use M-x update-file-autoloads if you set it up
     63      1.1  mrg ;; right.
     64      1.1  mrg ;;
     65      1.1  mrg ;;
     66      1.1  mrg ;; Emacsen
     67      1.1  mrg ;; -------
     68      1.1  mrg ;;
     69      1.1  mrg ;; GNU Emacs 20.x, 21.x and XEmacs 20.x all work well.  GNU Emacs 19.x
     70      1.1  mrg ;; should work if replacements for the various 20.x-isms are available,
     71      1.1  mrg ;; though comment-region with "C" doesn't do the right thing.
     72      1.1  mrg 
     73      1.1  mrg 
     74      1.1  mrg ;;; Code:
     75      1.1  mrg 
     76      1.1  mrg (defgroup gmpasm nil
     77      1.1  mrg   "GNU MP m4 and asm editing."
     78      1.1  mrg   :prefix "gmpasm-"
     79      1.1  mrg   :group 'languages)
     80      1.1  mrg 
     81      1.1  mrg (defcustom gmpasm-mode-hook nil
     82      1.1  mrg   "*Hook called by `gmpasm-mode'."
     83      1.1  mrg   :type 'hook
     84      1.1  mrg   :group 'gmpasm)
     85      1.1  mrg 
     86      1.1  mrg (defcustom gmpasm-comment-start-regexp "\\([#;!@*|C]\\|//\\)"
     87      1.1  mrg   "*Regexp matching possible comment styles.
     88      1.1  mrg See `gmpasm-mode' docstring for how this is used.
     89      1.1  mrg 
     90      1.1  mrg Commenting styles within GMP include
     91      1.1  mrg   #   - alpha, i386, i960, vax, traditional unix
     92      1.1  mrg   ;   - a29k, clipper, hppa, m88k, ppc
     93      1.1  mrg   !   - sh, sparc, z8000
     94      1.1  mrg   |   - m68k
     95      1.1  mrg   @   - arm
     96      1.1  mrg   *   - cray
     97      1.1  mrg   C   - GMP m4, see mpn/asm-defs.m4
     98      1.1  mrg   //  - ia64"
     99      1.1  mrg   :type 'regexp
    100      1.1  mrg   :group 'gmpasm)
    101      1.1  mrg 
    102      1.1  mrg 
    103      1.1  mrg (defun gmpasm-add-to-list-second (list-var element)
    104      1.1  mrg   "(gmpasm-add-to-list-second LIST-VAR ELEMENT)
    105      1.1  mrg 
    106      1.1  mrg Add ELEMENT to LIST-VAR as the second element in the list, if it isn't
    107      1.1  mrg already in the list.  If LIST-VAR is nil, then ELEMENT is just added as the
    108      1.1  mrg sole element in the list.
    109      1.1  mrg 
    110      1.1  mrg This is like `add-to-list', but it puts the new value second in the list.
    111      1.1  mrg 
    112      1.1  mrg The first cons cell is copied rather than changed in-place, so references to
    113      1.1  mrg the list elsewhere won't be affected."
    114      1.1  mrg 
    115      1.1  mrg   (if (member element (symbol-value list-var))
    116      1.1  mrg       (symbol-value list-var)
    117      1.1  mrg     (set list-var
    118      1.1  mrg 	 (if (symbol-value list-var)
    119      1.1  mrg 	     (cons (car (symbol-value list-var))
    120      1.1  mrg 		   (cons element
    121      1.1  mrg 			 (cdr (symbol-value list-var))))
    122      1.1  mrg 	   (list element)))))
    123      1.1  mrg 
    124      1.1  mrg 
    125      1.1  mrg (defun gmpasm-remove-from-list (list-var element)
    126      1.1  mrg   "(gmpasm-remove-from-list LIST-VAR ELEMENT)
    127      1.1  mrg 
    128      1.1  mrg Remove ELEMENT from LIST-VAR, using `copy-sequence' and `delete'.
    129      1.1  mrg This is vaguely like `add-to-list', but the element is removed from the list.
    130      1.1  mrg The list is copied rather than changed in-place, so references to it elsewhere
    131      1.1  mrg aren't affected."
    132      1.1  mrg 
    133      1.1  mrg ;; Only the portion of the list up to the removed element needs to be
    134      1.1  mrg ;; copied, but there's no need to bother arranging that, since this function
    135      1.1  mrg ;; is only used for a couple of initializations.
    136      1.1  mrg 
    137      1.1  mrg   (set list-var (delete element (copy-sequence (symbol-value list-var)))))
    138      1.1  mrg 
    139      1.1  mrg 
    140      1.1  mrg (defvar gmpasm-mode-map
    141      1.1  mrg   (let ((map (make-sparse-keymap)))
    142      1.1  mrg 
    143      1.1  mrg     ;; assembler and dnl commenting
    144      1.1  mrg     (define-key map "\C-c\C-c" 'comment-region)
    145      1.1  mrg     (define-key map "\C-c\C-d" 'gmpasm-comment-region-dnl)
    146      1.1  mrg 
    147      1.1  mrg     ;; kill an M-x compile, since it's not hard to put m4 into an infinite
    148      1.1  mrg     ;; loop
    149      1.1  mrg     (define-key map "\C-c\C-k" 'kill-compilation)
    150      1.1  mrg 
    151      1.1  mrg     map)
    152      1.1  mrg   "Keymap for `gmpasm-mode'.")
    153      1.1  mrg 
    154      1.1  mrg 
    155      1.1  mrg (defvar gmpasm-mode-syntax-table
    156      1.1  mrg   (let ((table (make-syntax-table)))
    157      1.1  mrg     ;; underscore left as a symbol char, like C mode
    158      1.1  mrg 
    159      1.1  mrg     ;; m4 quotes
    160      1.1  mrg     (modify-syntax-entry ?`  "('"  table)
    161      1.1  mrg     (modify-syntax-entry ?'  ")`"  table)
    162      1.1  mrg 
    163      1.1  mrg     table)
    164      1.1  mrg   "Syntax table used in `gmpasm-mode'.
    165      1.1  mrg 
    166      1.1  mrg '#' and '\n' aren't set as comment syntax.  In m4 these are a comment
    167      1.1  mrg outside quotes, but not inside.  Omitting a syntax entry ensures that when
    168      1.1  mrg inside quotes emacs treats parentheses and apostrophes the same way that m4
    169      1.1  mrg does.  When outside quotes this is not quite right, but having it right when
    170      1.1  mrg nesting expressions is more important.
    171      1.1  mrg 
    172      1.1  mrg '*', '!' or '|' aren't setup as comment syntax either, on CPUs which use
    173      1.1  mrg these for comments.  The GMP macro setups don't set them in m4 changecom(),
    174      1.1  mrg since that prevents them being used in eval() expressions, and on that basis
    175      1.1  mrg they don't change the way quotes and parentheses are treated by m4 and
    176      1.1  mrg should be treated by emacs.")
    177      1.1  mrg 
    178      1.1  mrg 
    179      1.1  mrg (defvar gmpasm-font-lock-keywords
    180      1.1  mrg   (eval-when-compile
    181      1.1  mrg     (list
    182      1.1  mrg      (cons
    183      1.1  mrg       (concat
    184      1.1  mrg        "\\b"
    185      1.1  mrg        (regexp-opt
    186      1.1  mrg 	'("deflit" "defreg" "defframe" "defframe_pushl"
    187      1.1  mrg 	  "define_not_for_expansion"
    188      1.1  mrg 	  "m4_error" "m4_warning"
    189      1.1  mrg 	  "ASM_START" "ASM_END"
    190      1.1  mrg 	  "PROLOGUE" "PROLOGUE_GP" "MULFUNC_PROLOGUE" "EPILOGUE"
    191      1.1  mrg 	  "DATASTART" "DATAEND"
    192      1.1  mrg 	  "forloop"
    193      1.1  mrg 	  "TEXT" "DATA" "ALIGN" "W32" "FLOAT64"
    194      1.1  mrg 	  "builtin" "changecom" "changequote" "changeword" "debugfile"
    195      1.1  mrg 	  "debugmode" "decr" "define" "defn" "divert" "divnum" "dumpdef"
    196      1.1  mrg 	  "errprint" "esyscmd" "eval" "__file__" "format" "gnu" "ifdef"
    197      1.1  mrg 	  "ifelse" "include" "incr" "index" "indir" "len" "__line__"
    198      1.1  mrg 	  "m4exit" "m4wrap" "maketemp" "patsubst" "popdef" "pushdef"
    199      1.1  mrg 	  "regexp" "shift" "sinclude" "substr" "syscmd" "sysval"
    200      1.1  mrg 	  "traceoff" "traceon" "translit" "undefine" "undivert" "unix")
    201      1.1  mrg 	t)
    202      1.1  mrg        "\\b") 'font-lock-keyword-face)))
    203      1.1  mrg 
    204      1.1  mrg   "`font-lock-keywords' for `gmpasm-mode'.
    205      1.1  mrg 
    206      1.1  mrg The keywords are m4 builtins and some of the GMP macros used in asm files.
    207      1.1  mrg L doesn't look good fontified, so it's omitted.
    208      1.1  mrg 
    209      1.1  mrg The right assembler comment regexp is added dynamically buffer-local (with
    210      1.1  mrg dnl too).")
    211      1.1  mrg 
    212      1.1  mrg 
    213      1.1  mrg ;; Initialized if gmpasm-mode finds filladapt loaded.
    214      1.1  mrg (defvar gmpasm-filladapt-token-table nil
    215      1.1  mrg   "Filladapt token table used in `gmpasm-mode'.")
    216      1.1  mrg (defvar gmpasm-filladapt-token-match-table nil
    217      1.1  mrg   "Filladapt token match table used in `gmpasm-mode'.")
    218      1.1  mrg (defvar gmpasm-filladapt-token-conversion-table nil
    219      1.1  mrg   "Filladapt token conversion table used in `gmpasm-mode'.")
    220      1.1  mrg 
    221      1.1  mrg 
    222      1.1  mrg ;;;###autoload
    223      1.1  mrg (defun gmpasm-mode ()
    224      1.1  mrg   "A major mode for editing GNU MP asm and m4 files.
    225      1.1  mrg 
    226      1.1  mrg \\{gmpasm-mode-map}
    227      1.1  mrg `comment-start' and `comment-end' are set buffer-local to assembler
    228      1.1  mrg commenting appropriate for the CPU by looking for something matching
    229      1.1  mrg `gmpasm-comment-start-regexp' at the start of a line, or \"#\" is used if
    230      1.1  mrg there's no match (if \"#\" isn't what you want, type in a desired comment
    231      1.1  mrg and do \\[gmpasm-mode] to reinitialize).
    232      1.1  mrg 
    233      1.1  mrg `adaptive-fill-regexp' is set buffer-local to the standard regexp with
    234      1.1  mrg `comment-start' and dnl added.  If filladapt.el has been loaded it similarly
    235      1.1  mrg gets `comment-start' and dnl added as buffer-local fill prefixes.
    236      1.1  mrg 
    237      1.1  mrg Font locking has the m4 builtins, some of the GMP macros, m4 dnl commenting,
    238      1.1  mrg and assembler commenting (based on the `comment-start' determined).
    239      1.1  mrg 
    240      1.1  mrg Note that `gmpasm-comment-start-regexp' is only matched as a whole word, so
    241      1.1  mrg the `C' in it is only matched as a whole word, not on something that happens
    242      1.1  mrg to start with `C'.  Also it's only the particular `comment-start' determined
    243      1.1  mrg that's added for filling etc, not the whole `gmpasm-comment-start-regexp'.
    244      1.1  mrg 
    245      1.1  mrg `gmpasm-mode-hook' is run after initializations are complete."
    246      1.1  mrg 
    247      1.1  mrg   (interactive)
    248      1.1  mrg   (kill-all-local-variables)
    249      1.1  mrg   (setq major-mode 'gmpasm-mode
    250      1.1  mrg         mode-name  "gmpasm")
    251      1.1  mrg   (use-local-map gmpasm-mode-map)
    252      1.1  mrg   (set-syntax-table gmpasm-mode-syntax-table)
    253      1.1  mrg   (setq fill-column 76)
    254      1.1  mrg 
    255      1.1  mrg   ;; Short instructions might fit with 32, but anything with labels or
    256      1.1  mrg   ;; expressions soon needs the comments pushed out to column 40.
    257      1.1  mrg   (setq comment-column 40)
    258      1.1  mrg 
    259      1.1  mrg   ;; Don't want to find out the hard way which dumb assemblers don't like a
    260      1.1  mrg   ;; missing final newline.
    261      1.1  mrg   (set (make-local-variable 'require-final-newline) t)
    262      1.1  mrg 
    263      1.1  mrg   ;; The first match of gmpasm-comment-start-regexp at the start of a line
    264      1.1  mrg   ;; determines comment-start, or "#" if no match.
    265      1.1  mrg   (set (make-local-variable 'comment-start)
    266      1.1  mrg        (save-excursion
    267      1.1  mrg 	 (goto-char (point-min))
    268      1.1  mrg 	 (if (re-search-forward
    269      1.1  mrg 	      (concat "^\\(" gmpasm-comment-start-regexp "\\)\\(\\s-\\|$\\)")
    270      1.1  mrg 	      nil t)
    271      1.1  mrg 	     (match-string 1)
    272      1.1  mrg 	   "#")))
    273      1.1  mrg   (set (make-local-variable 'comment-end) "")
    274      1.1  mrg 
    275      1.1  mrg   ;; If comment-start ends in an alphanumeric then \b is used to match it
    276      1.1  mrg   ;; only as a separate word.  The test is for an alphanumeric rather than
    277      1.1  mrg   ;; \w since we might try # or ! as \w characters but without wanting \b on
    278      1.1  mrg   ;; them.
    279      1.1  mrg   (let ((comment-regexp
    280      1.1  mrg 	 (concat (regexp-quote comment-start)
    281      1.1  mrg 		 (if (string-match "[a-zA-Z0-9]\\'" comment-start) "\\b"))))
    282      1.1  mrg 
    283      1.1  mrg     ;; Whitespace is required before a comment-start so m4 $# doesn't match
    284      1.1  mrg     ;; when comment-start is "#".
    285      1.1  mrg     (set (make-local-variable 'comment-start-skip)
    286      1.1  mrg 	 (concat "\\(^\\|\\s-\\)\\(\\<dnl\\>\\|" comment-regexp "\\)[ \t]*"))
    287      1.1  mrg 
    288      1.1  mrg     ;; Comment fontification based on comment-start, and always with dnl.
    289      1.1  mrg     ;; Same treatment of a space before "#" as in comment-start-skip, but
    290      1.1  mrg     ;; don't fontify that space.
    291      1.1  mrg     (add-to-list (make-local-variable 'gmpasm-font-lock-keywords)
    292      1.1  mrg 		 (list (concat "\\(^\\|\\s-\\)\\(\\(\\<dnl\\>\\|"
    293      1.1  mrg 			       comment-regexp
    294      1.1  mrg 			       "\\).*$\\)")
    295      1.1  mrg 		       2 'font-lock-comment-face))
    296      1.1  mrg 
    297      1.1  mrg     (set (make-local-variable 'font-lock-defaults)
    298      1.1  mrg 	 '(gmpasm-font-lock-keywords
    299      1.1  mrg 	   t	         ; no syntactic fontification (of strings etc)
    300      1.1  mrg 	   nil           ; no case-fold
    301      1.1  mrg 	   ((?_ . "w"))  ; _ part of a word while fontifying
    302      1.1  mrg 	   ))
    303      1.1  mrg 
    304      1.1  mrg     ;; Paragraphs are separated by blank lines, or lines with only dnl or
    305      1.1  mrg     ;; comment-start.
    306      1.1  mrg     (set (make-local-variable 'paragraph-separate)
    307      1.1  mrg 	 (concat "[ \t\f]*\\(\\(" comment-regexp "\\|dnl\\)[ \t]*\\)*$"))
    308      1.1  mrg     (set (make-local-variable 'paragraph-start)
    309      1.1  mrg 	 (concat "\f\\|" paragraph-separate))
    310      1.1  mrg 
    311      1.1  mrg     ;; Some sort of "def...(" m4 define, possibly with ` for quoting.
    312      1.1  mrg     ;; Could do something with PROLOGUE here, but in GMP the filename is
    313      1.1  mrg     ;; enough, it's not normally necessary to say the function name.
    314      1.1  mrg     (set (make-local-variable 'add-log-current-defun-header-regexp)
    315      1.1  mrg 	 "^def[a-z0-9_]+(`?\\([a-zA-Z0-9_]+\\)")
    316      1.1  mrg 
    317      1.1  mrg     ;; Adaptive fill gets dnl and comment-start as comment style prefixes on
    318      1.1  mrg     ;; top of the standard regexp (which has # and ; already actually).
    319      1.1  mrg     (set (make-local-variable 'adaptive-fill-regexp)
    320      1.1  mrg 	 (concat "[ \t]*\\(\\("
    321      1.1  mrg 		 comment-regexp
    322      1.1  mrg 		 "\\|dnl\\|[-|#;>*]+\\|(?[0-9]+[.)]\\)[ \t]*\\)*"))
    323      1.1  mrg     (set (make-local-variable 'adaptive-fill-first-line-regexp)
    324      1.1  mrg 	 "\\`\\([ \t]*dnl\\)?[ \t]*\\'")
    325      1.1  mrg 
    326      1.1  mrg     (when (fboundp 'filladapt-mode)
    327      1.1  mrg       (unless gmpasm-filladapt-token-table
    328      1.1  mrg 	(setq gmpasm-filladapt-token-table
    329      1.1  mrg 	      filladapt-token-table)
    330      1.1  mrg 	(setq gmpasm-filladapt-token-match-table
    331      1.1  mrg 	      filladapt-token-match-table)
    332      1.1  mrg 	(setq gmpasm-filladapt-token-conversion-table
    333      1.1  mrg 	      filladapt-token-conversion-table)
    334      1.1  mrg 
    335      1.1  mrg 	;; Numbered bullet points like "2.1" get matched at the start of a
    336      1.1  mrg 	;; line when it's really something like "2.1 cycles/limb", so remove
    337      1.1  mrg 	;; this from the list.  The regexp for "1.", "2." etc is left
    338      1.1  mrg 	;; though.
    339      1.1  mrg 	(gmpasm-remove-from-list 'gmpasm-filladapt-token-table
    340      1.1  mrg 				 '("[0-9]+\\(\\.[0-9]+\\)+[ \t]"
    341      1.1  mrg 				   bullet))
    342      1.1  mrg 
    343      1.1  mrg 	;; "%" as a comment prefix interferes with register names on some
    344      1.1  mrg 	;; CPUs, like %eax on x86, so remove this.
    345      1.1  mrg 	(gmpasm-remove-from-list 'gmpasm-filladapt-token-table
    346      1.1  mrg 				 '("%+" postscript-comment))
    347      1.1  mrg 
    348      1.1  mrg 	(add-to-list 'gmpasm-filladapt-token-match-table
    349      1.1  mrg 		     '(gmpasm-comment gmpasm-comment))
    350      1.1  mrg 	(add-to-list 'gmpasm-filladapt-token-conversion-table
    351      1.1  mrg 		     '(gmpasm-comment . exact)))
    352      1.1  mrg 
    353      1.1  mrg       (set (make-local-variable 'filladapt-token-table)
    354      1.1  mrg 	   gmpasm-filladapt-token-table)
    355      1.1  mrg       (set (make-local-variable 'filladapt-token-match-table)
    356      1.1  mrg 	   gmpasm-filladapt-token-match-table)
    357      1.1  mrg       (set (make-local-variable 'filladapt-token-conversion-table)
    358      1.1  mrg 	   gmpasm-filladapt-token-conversion-table)
    359      1.1  mrg 
    360      1.1  mrg       ;; Add dnl and comment-start as fill prefixes.
    361      1.1  mrg       ;; Comments in filladapt.el say filladapt-token-table must begin
    362      1.1  mrg       ;; with ("^" beginning-of-line), so put our addition second.
    363      1.1  mrg       (gmpasm-add-to-list-second 'filladapt-token-table
    364      1.1  mrg 				 (list (concat "dnl[ \t]\\|" comment-regexp)
    365      1.1  mrg 				       'gmpasm-comment))))
    366      1.1  mrg 
    367      1.1  mrg   (run-hooks 'gmpasm-mode-hook))
    368      1.1  mrg 
    369      1.1  mrg 
    370      1.1  mrg (defun gmpasm-comment-region-dnl (beg end &optional arg)
    371      1.1  mrg   "(gmpasm-comment-region-dnl BEG END &optional ARG)
    372      1.1  mrg 
    373      1.1  mrg Comment or uncomment each line in the region using `dnl'.
    374      1.1  mrg With \\[universal-argument] prefix arg, uncomment each line in region.
    375      1.1  mrg This is `comment-region', but using \"dnl\"."
    376      1.1  mrg 
    377      1.1  mrg   (interactive "r\nP")
    378      1.1  mrg   (let ((comment-start "dnl")
    379      1.1  mrg 	(comment-end ""))
    380      1.1  mrg     (comment-region beg end arg)))
    381      1.1  mrg 
    382      1.1  mrg 
    383      1.1  mrg (provide 'gmpasm-mode)
    384      1.1  mrg 
    385      1.1  mrg ;;; gmpasm-mode.el ends here
    386