unofficial mirror of help-gnu-emacs@gnu.org
 help / color / mirror / Atom feed
From: Alan Mackenzie <acm@muc.de>
Subject: Re: How to indent on LOCK(); macro???
Date: Thu, 1 Sep 2005 16:28:14 +0000	[thread overview]
Message-ID: <u6a7fd.va.ln@acm.acm> (raw)
In-Reply-To: roy-AE20D4.19500131082005@reader2.panix.com

Roy Smith <roy@panix.com> wrote on Wed, 31 Aug 2005 19:50:01 -0400:
> In article <drh4fd.76.ln@acm.acm>, Alan Mackenzie <acm@muc.de> wrote:
>> And if you're not a Lisp hacker (or can't be bothered), say so, and I'll
>> throw some code together for you.

> Wow.  An offer I can't refuse.  Thanks!

OK, here goes!  Put the code into your .emacs.  Both the functions here
get byte compiled (they'll be getting called a _lot_).  To hook up to
your CC Mode, do one of:

(a) If you're a hooker:
  (add-hook 'c-special-indent-hook 'rs-LOCK-reindent)

(b) If you're a touch more stylish:
  Put a line like this into your style definition:
(c-special-indent-hook . rs-LOCK-reindent)

Here's the code:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun rs-back-to-LOCK-p ()
  "Search backwards for the LOCK keyword.  If we find it, leave point there
and return non-`nil'.  If we don't find it, return nil, and point is left
undefined."
  (let (in-lit target)
    (while (and (search-backward-regexp "^[ \t]*\\(LOCK[ \t]*(\\)" nil t)
		(setq target (match-beginning 1))
		(setq in-lit (c-in-literal))))
    (when (and target (not in-lit))
      (goto-char target)
      t)))
(byte-compile 'rs-back-to-LOCK-p)

(defun rs-LOCK-reindent ()
  "Function to reindent lines inside and around blocks of lines delimited by
the macros LOCK and END_LOCK, as follows:

1   LOCK (mydatalock)
2       *myData++ = foo;
3       Data_count += 1;
4   END_LOCK
5   do_something_else ();

NOTE:  There are no semicolons terminating the LOCK/END_LOCK lines."
  ;; Another note: c-syntactic-context is bound to the s.c. for the current
  ;; line.
  (let (org-indent new-indent stmt-dpair)
    (save-excursion
      (save-match-data
	(setq org-indent (progn (back-to-indentation) (current-column))
	      new-indent org-indent)
	(cond
	 ;; L4?
	 ((looking-at "END_LOCK")
	  (if (rs-back-to-LOCK-p)
	    (setq new-indent (current-column))))
	 ((setq stmt-dpair (assq 'statement-cont c-syntactic-context))
	  (goto-char (if (consp (cdr stmt-dpair))
			 (cadr stmt-dpair) ; cc-mode >= 5.30
		       (cdr stmt-dpair))) ; cc-mode 5.28
	  (cond
	   ;; L5?
	   ((looking-at "END_LOCK\\>\\([^_]\\|$\\)")
	    (if (rs-back-to-LOCK-p)
		(setq new-indent (current-column))))
	   ;; L2?
	   ((looking-at "LOCK[ \t]")
	    (setq new-indent (+ (current-column) c-basic-offset)))))
	 ;; L3?
	 ((and (assq 'statement c-syntactic-context)
	       ;; (eq (c-beginning-of-statement-1) 'previous) ; Needs >= 5.30
	       (progn (c-beginning-of-statement-1)
		      (looking-at "LOCK[ \t]+(")))
	  (setq new-indent (+ (current-column) c-basic-offset))))))
    (c-shift-line-indentation (- new-indent org-indent))))
(byte-compile 'rs-LOCK-reindent)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Just one thing - the code as it stands might not handle labels properly.
I mean, you've not got any goto's in the C code, have you?  Certainly not
in critical sections.  ;-)

Let me know how you get on!

-- 
Alan Mackenzie (Munich, Germany)
Email: aacm@muuc.dee; to decode, wherever there is a repeated letter
(like "aa"), remove half of them (leaving, say, "a").

      reply	other threads:[~2005-09-01 16:28 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-08-30 20:51 How to indent on LOCK(); macro??? Roy Smith
2005-08-30 21:21 ` Denis Bueno
2005-08-30 21:27   ` Roy Smith
2005-08-31  8:10 ` Alan Mackenzie
2005-08-31 12:31   ` Roy Smith
2005-08-31 15:20     ` Alan Mackenzie
2005-08-31 23:50       ` Roy Smith
2005-09-01 16:28         ` Alan Mackenzie [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=u6a7fd.va.ln@acm.acm \
    --to=acm@muc.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).