all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* How to indent on LOCK(); macro???
@ 2005-08-30 20:51 Roy Smith
  2005-08-30 21:21 ` Denis Bueno
  2005-08-31  8:10 ` Alan Mackenzie
  0 siblings, 2 replies; 8+ messages in thread
From: Roy Smith @ 2005-08-30 20:51 UTC (permalink / raw)


I'm working on a project which uses a LOCK/END_LOCK macro pair for
mutex locking in C++ source files.  A typical section of code would
look like:

    LOCK (myDataLock)
        myData = foo;
    END_LOCK

How can I convince the indenting engine to treat the LOCK and END_LOCK
lines as beginning and ending blocks?

I'm running GNU Emacs 21.3.1.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: How to indent on LOCK(); macro???
  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
  1 sibling, 1 reply; 8+ messages in thread
From: Denis Bueno @ 2005-08-30 21:21 UTC (permalink / raw)
  Cc: help-gnu-emacs

On 30 Aug 2005, at 16.51, Roy Smith wrote:
> I'm working on a project which uses a LOCK/END_LOCK macro pair for
> mutex locking in C++ source files.  A typical section of code would
> look like:
>
>     LOCK (myDataLock)
>         myData = foo;
>     END_LOCK
>
> How can I convince the indenting engine to treat the LOCK and END_LOCK
> lines as beginning and ending blocks?

If you wrote the macro in a certain way, you can use braces in your  
source code (thus obviating your problem):

     #define WITH_MUTEX_LOCK 
(l)                                              \
         for (int WITH_MUTEX_LOCK_ret = (0 == pthread_mutex_lock 
(l));        \
               
WITH_MUTEX_LOCK_ret;                                           \
              WITH_MUTEX_LOCK_ret = 0, (void) pthread_mutex_unlock 
(l))       \

That's at least one solution (perhaps not the best). Then you would  
write:

     WITH_MUTEX_LOCK (myDataLock) {
        myData = foo;
     }

-Denis

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: How to indent on LOCK(); macro???
  2005-08-30 21:21 ` Denis Bueno
@ 2005-08-30 21:27   ` Roy Smith
  0 siblings, 0 replies; 8+ messages in thread
From: Roy Smith @ 2005-08-30 21:27 UTC (permalink / raw)
  Cc: help-gnu-emacs

Denis Bueno wrote:

> On 30 Aug 2005, at 16.51, Roy Smith wrote:
>
>> I'm working on a project which uses a LOCK/END_LOCK macro pair for
>> mutex locking in C++ source files.  A typical section of code would
>> look like:
>>
>>     LOCK (myDataLock)
>>         myData = foo;
>>     END_LOCK
>>
>> How can I convince the indenting engine to treat the LOCK and END_LOCK
>> lines as beginning and ending blocks?
>
>
> If you wrote the macro in a certain way, you can use braces in your  
> source code (thus obviating your problem):
>
>     #define WITH_MUTEX_LOCK 
> (l)                                              \
>         for (int WITH_MUTEX_LOCK_ret = (0 == pthread_mutex_lock 
> (l));        \
>               
> WITH_MUTEX_LOCK_ret;                                           \
>              WITH_MUTEX_LOCK_ret = 0, (void) pthread_mutex_unlock 
> (l))       \
>
> That's at least one solution (perhaps not the best). Then you would  
> write:
>
>     WITH_MUTEX_LOCK (myDataLock) {
>        myData = foo;
>     }
>
> -Denis

Thanks, but unfortunately, the macro pre-dates me and isn't going to 
change.  I must live with what I've been given.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: How to indent on LOCK(); macro???
  2005-08-30 20:51 How to indent on LOCK(); macro??? Roy Smith
  2005-08-30 21:21 ` Denis Bueno
@ 2005-08-31  8:10 ` Alan Mackenzie
  2005-08-31 12:31   ` Roy Smith
  1 sibling, 1 reply; 8+ messages in thread
From: Alan Mackenzie @ 2005-08-31  8:10 UTC (permalink / raw)


Roy Smith <roy@panix.com> wrote on 30 Aug 2005 16:51:20 -0400:
> I'm working on a project which uses a LOCK/END_LOCK macro pair for
> mutex locking in C++ source files.  A typical section of code would
> look like:

>     LOCK (myDataLock)
>         myData = foo;
>     END_LOCK

> How can I convince the indenting engine to treat the LOCK and END_LOCK
> lines as beginning and ending blocks?

Only with braces:

LOCK (MyDataLock) {
    myData = foo;
} END_LOCK;

(The semicolon ater END_LOCK will prevent the next statement being
indented one level too many.)  And if you use auto-newline, you might
want to extend the functionality of c-snug-do-while so as to indent the
LOCK construct like a do-while, as above.

I know that's not quite what you're asking for.  But what you're asking
for isn't entirely reasonable; a macro in C or C++ can expand to
absolutely _anything_.  The CC Mode indentation engine works purely
syntactically, i.e. according to what the source "looks like".  If the
indentation were to be extended to handle "common" macro expansions, it
would add a whole new level of complexity.  For a start, the indentation
engine would have somehow to be told that LOCK should behave like an open
brace and END_LOCK like a close brace.  Would this be done by you setting
a configuration variable, or would CC Mode be expected to scan #include
files, parsing all the macros?  (And if you're not sure just how
complicated the indentation engine already is, take a glance at the
function `c-guess-basic-syntax' in cc-engine.el.)

The other thing is, do you really want your C++ code to look more like
Pascal?  ;-)

> I'm running GNU Emacs 21.3.1.

-- 
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").

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: How to indent on LOCK(); macro???
  2005-08-31  8:10 ` Alan Mackenzie
@ 2005-08-31 12:31   ` Roy Smith
  2005-08-31 15:20     ` Alan Mackenzie
  0 siblings, 1 reply; 8+ messages in thread
From: Roy Smith @ 2005-08-31 12:31 UTC (permalink / raw)


Alan Mackenzie <acm@muc.de> wrote:
> > How can I convince the indenting engine to treat the LOCK and END_LOCK
> > lines as beginning and ending blocks?
> 
> Only with braces:
> 
> LOCK (MyDataLock) {
>     myData = foo;
> } END_LOCK;
> 
> (The semicolon ater END_LOCK will prevent the next statement being
> indented one level too many.)  And if you use auto-newline, you might
> want to extend the functionality of c-snug-do-while so as to indent the
> LOCK construct like a do-while, as above.

Hmmm, I need to think on this, it may be good enough.  The LOCK and 
END_LOCK macros already include the braces (and the trailing semicolon), 
but I can't think of any reason why an extra set of braces or an extra 
semicolon will break anything.  Still, it's not the style used here, and 
(for better or worse), it's difficult (and often a bad idea) to not go 
along with the established style on a big project.

> For a start, the indentation
> engine would have somehow to be told that LOCK should behave like an open
> brace and END_LOCK like a close brace.  Would this be done by you setting
> a configuration variable, or would CC Mode be expected to scan #include
> files, parsing all the macros?

I was thinking (hoping) that there must be some kind of syntax table that I 
could just add an entry to.  From what you're saying, it sounds like there 
isn't.  I certainly agree that parsing all the #include files would be 
impractical (even assuming emacs had enough information to make it 
possible, which it doesn't).

> The other thing is, do you really want your C++ code to look more like
> Pascal?  ;-)

Well, to be honest, I want my C++ code to look more like Python, but I'm 
the new kid on a project with 10 years of history, so I don't always get 
what I want :-(

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: How to indent on LOCK(); macro???
  2005-08-31 12:31   ` Roy Smith
@ 2005-08-31 15:20     ` Alan Mackenzie
  2005-08-31 23:50       ` Roy Smith
  0 siblings, 1 reply; 8+ messages in thread
From: Alan Mackenzie @ 2005-08-31 15:20 UTC (permalink / raw)


Roy Smith <roy@panix.com> wrote on Wed, 31 Aug 2005 08:31:33 -0400:
> Alan Mackenzie <acm@muc.de> wrote:
>> > How can I convince the indenting engine to treat the LOCK and END_LOCK
>> > lines as beginning and ending blocks?

>> Only with braces:

>> LOCK (MyDataLock) {
>>     myData = foo;
>> } END_LOCK;

>> (The semicolon ater END_LOCK will prevent the next statement being
>> indented one level too many.)  And if you use auto-newline, you might
>> want to extend the functionality of c-snug-do-while so as to indent
>> the LOCK construct like a do-while, as above.

> Hmmm, I need to think on this, it may be good enough.  The LOCK and
> END_LOCK macros already include the braces (and the trailing
> semicolon), but I can't think of any reason why an extra set of braces
> or an extra semicolon will break anything.

It can't break anything.  The contents of a brace pair are a compound
statement, i.e. syntactically seen, just another statement.

> Still, it's not the style used here, and (for better or worse), it's
> difficult (and often a bad idea) to not go along with the established
> style on a big project.

It's _always_ a bad idea.  ;-(  (From somebody who's been edged out of
projects more than once for questioning the way things are done.)

Er, can I retract the answer I gave on my last post, please?  You sound
like the sort of guy who can write Elisp.  There is a hook called
`c-special-indent-hook' called after each line has been indented.  You
could put a function onto it that would check if the previous line was a
"LOCK", or the current line is an "END_LOCK", and if so give the line one
more/one less level of indentation.  That hook is described in the CC
Manual on page "Other Special Indentation".

And if you're not a Lisp hacker (or can't be bothered), say so, and I'll
throw some code together for you.

[ .... ]

>> The other thing is, do you really want your C++ code to look more like
>> Pascal?  ;-)

> Well, to be honest, I want my C++ code to look more like Python, but
> I'm the new kid on a project with 10 years of history, so I don't
> always get what I want :-(

Oh, _that_ sort of project.  ;-(

-- 
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").

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: How to indent on LOCK(); macro???
  2005-08-31 15:20     ` Alan Mackenzie
@ 2005-08-31 23:50       ` Roy Smith
  2005-09-01 16:28         ` Alan Mackenzie
  0 siblings, 1 reply; 8+ messages in thread
From: Roy Smith @ 2005-08-31 23:50 UTC (permalink / raw)


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!

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: How to indent on LOCK(); macro???
  2005-08-31 23:50       ` Roy Smith
@ 2005-09-01 16:28         ` Alan Mackenzie
  0 siblings, 0 replies; 8+ messages in thread
From: Alan Mackenzie @ 2005-09-01 16:28 UTC (permalink / raw)


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").

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2005-09-01 16:28 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.