all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* Functionality to maintain function prototypes in C
@ 2016-10-28 18:55 Nikolai Weibull
  2016-10-28 21:38 ` Pascal J. Bourguignon
  2016-10-29  8:34 ` Thien-Thi Nguyen
  0 siblings, 2 replies; 5+ messages in thread
From: Nikolai Weibull @ 2016-10-28 18:55 UTC (permalink / raw)
  To: Emacs Users

Hi!

C has the issue of being compiled in a single pass.  After many years
of working around this issue by defining my static functions in
reverse order, which is good for the compiler, but bad for the user,
I’m now looking to try writing them in a more natural order.  The main
issue with this is maintaining the static-function prototypes.  I’ve
looked around, but I can’t find a minor mode that’ll add, update, and
remove static-function prototypes automatically, either by command or
at file save, so I was hoping that someone here could point me in the
right direction.

Thanks!



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

* Re: Functionality to maintain function prototypes in C
  2016-10-28 18:55 Functionality to maintain function prototypes in C Nikolai Weibull
@ 2016-10-28 21:38 ` Pascal J. Bourguignon
  2016-10-29  1:30   ` John Mastro
  2016-10-29  8:26   ` Nikolai Weibull
  2016-10-29  8:34 ` Thien-Thi Nguyen
  1 sibling, 2 replies; 5+ messages in thread
From: Pascal J. Bourguignon @ 2016-10-28 21:38 UTC (permalink / raw)
  To: help-gnu-emacs

Nikolai Weibull <now@disu.se> writes:

> Hi!
>
> C has the issue of being compiled in a single pass.  After many years
> of working around this issue by defining my static functions in
> reverse order, which is good for the compiler, but bad for the user,
> I’m now looking to try writing them in a more natural order.  The main
> issue with this is maintaining the static-function prototypes.  I’ve
> looked around, but I can’t find a minor mode that’ll add, update, and
> remove static-function prototypes automatically, either by command or
> at file save, so I was hoping that someone here could point me in the
> right direction.

Once upon a time, I used macros:

In a file named BcInterface.h:

#define PROCEDURE(nam,prm,res)       extern         res      nam  prm    ;


In a file named BcImplementation.h:

#define PROCEDURE(nam,prm,res)                      res      nam  prm


Then it was a simple matter of:

( cat ${source}_header_prefix
  grep PROCEDURE ${source}.c
  cat ${source}_header_suffix ) > ${source}.h

But that was before I used emacs :-)


;;; Code:

(defun c-collect-defun-signatures ()
  "Return a list of C function signatures found in the buffer."
  (let ((signatures '())
        (last-defun -1))
    (goto-char (point-min))
    (end-of-defun)
    (beginning-of-defun)
    (while (/= last-defun (point))
      (setf last-defun (point))
      (when (re-search-forward "\\(.*(.*)\\)[^(){}]*{" nil t)
        (push (match-string 1) signatures))
      (end-of-defun)
      (end-of-defun)
      (beginning-of-defun))
    signatures))

(defun c-update-forward-defun-signatures ()
  "Update the forward function signatures.
If a section doesn't already exist, creates it at point."
  (interactive)
  (let ((signatures (save-excursion (nreverse (c-collect-defun-signatures))))
        (section-begin "\n// BEGIN FORWARD FUNCTION SIGNATURES\n")
        (section-end   "\n// END FORWARD FUNCTION SIGNATURES\n"))
    (goto-char (or (save-excursion
                    (goto-char (point-min))
                    (when (re-search-forward
                           (format "%s.*%s" section-begin section-end)
                           nil t)
                      (delete-region (match-beginning 0) (match-end 0))
                      (match-beginning 0)))
                   (point)))
    (insert section-begin)
    (dolist (signature signatures)
      (insert signature ";\n"))
    (insert section-end)))

(provide 'c-defun)
;;; c-defun.el ends here


The first time, move the point where you want the forward signatures to
be inserted and M-x c-update-forward-defun-signatures RET

Then  M-x c-update-forward-defun-signatures RET again will update the
same section, wherever the point is.

Now, you will have to move all the type definition used in the function
signature before this section…

-- 
__Pascal Bourguignon__                 http://www.informatimago.com/
“The factory of the future will have only two employees, a man and a
dog. The man will be there to feed the dog. The dog will be there to
keep the man from touching the equipment.” -- Carl Bass CEO Autodesk




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

* Re: Functionality to maintain function prototypes in C
  2016-10-28 21:38 ` Pascal J. Bourguignon
@ 2016-10-29  1:30   ` John Mastro
  2016-10-29  8:26   ` Nikolai Weibull
  1 sibling, 0 replies; 5+ messages in thread
From: John Mastro @ 2016-10-29  1:30 UTC (permalink / raw)
  To: help-gnu-emacs@gnu.org; +Cc: Pascal J. Bourguignon

Pascal J. Bourguignon <pjb@informatimago.com> wrote:
> The first time, move the point where you want the forward signatures to
> be inserted and M-x c-update-forward-defun-signatures RET
>
> Then  M-x c-update-forward-defun-signatures RET again will update the
> same section, wherever the point is.
>
> Now, you will have to move all the type definition used in the function
> signature before this section…

Thanks for posting this - there have definitely been times I could have
used it.

I made one modification to the part where it searches for an existing
block of declarations, changing the regexp to:

    (format "%s\\(.\\|\n\\)*%s" section-begin section-end)

Because "." doesn't match newlines.

I also gave both functions an optional argument STATIC-ONLY to only
collect functions declared static, since that's generally what I've
wanted.

The result with those tweaks, in case it's useful to anyone:

(defun c-collect-defun-signatures (&optional static-only)
  "Return a list of C function signatures found in the buffer."
  (let ((regexp (if static-only
                    "\\(static .*(.*)\\)[^(){}]*{"
                  "\\(.*(.*)\\)[^(){}]*{"))
        (signatures '())
        (last-defun -1))
    (goto-char (point-min))
    (end-of-defun)
    (beginning-of-defun)
    (while (/= last-defun (point))
      (setf last-defun (point))
      (when (re-search-forward regexp nil t)
        (push (match-string 1) signatures))
      (end-of-defun)
      (end-of-defun)
      (beginning-of-defun))
    signatures))

(defun c-update-forward-defun-signatures (&optional static-only)
  "Update the forward function signatures.
If a section doesn't already exist, creates it at point."
  (interactive "*P")
  (let ((signatures (save-excursion
                      (nreverse (c-collect-defun-signatures static-only))))
        (section-begin "// BEGIN FORWARD FUNCTION SIGNATURES\n")
        (section-end   "// END FORWARD FUNCTION SIGNATURES\n"))
    (goto-char (or (save-excursion
                     (goto-char (point-min))
                     (when (re-search-forward
                            (format "%s\\(.\\|\n\\)*%s" section-begin
section-end)
                            nil t)
                       (delete-region (match-beginning 0) (match-end 0))
                       (match-beginning 0)))
                   (point)))
    (insert section-begin)
    (dolist (signature signatures)
      (insert signature ";\n"))
    (insert section-end)))



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

* Re: Functionality to maintain function prototypes in C
  2016-10-28 21:38 ` Pascal J. Bourguignon
  2016-10-29  1:30   ` John Mastro
@ 2016-10-29  8:26   ` Nikolai Weibull
  1 sibling, 0 replies; 5+ messages in thread
From: Nikolai Weibull @ 2016-10-29  8:26 UTC (permalink / raw)
  To: Pascal J. Bourguignon; +Cc: Emacs Users

On Fri, Oct 28, 2016 at 11:38 PM, Pascal J. Bourguignon
<pjb@informatimago.com> wrote:
> Nikolai Weibull <now@disu.se> writes:
>
>> Hi!
>>
>> I’ve
>> looked around, but I can’t find a minor mode that’ll add, update, and
>> remove static-function prototypes automatically, either by command or
>> at file save, so I was hoping that someone here could point me in the
>> right direction.

> ;;; Code:

I should have mentioned this before, but I would very much prefer if
there was something in cc-mode or cedet to use for this already.  Or
at least implemented using one of these modes’ parsing APIs.



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

* Re: Functionality to maintain function prototypes in C
  2016-10-28 18:55 Functionality to maintain function prototypes in C Nikolai Weibull
  2016-10-28 21:38 ` Pascal J. Bourguignon
@ 2016-10-29  8:34 ` Thien-Thi Nguyen
  1 sibling, 0 replies; 5+ messages in thread
From: Thien-Thi Nguyen @ 2016-10-29  8:34 UTC (permalink / raw)
  To: Emacs Users

[-- Attachment #1: Type: text/plain, Size: 829 bytes --]


() Nikolai Weibull <now@disu.se>
() Fri, 28 Oct 2016 20:55:15 +0200

   I’m now looking to try writing them in a more natural order.

upside down on the ground i meet
a wond'rous Creature, an acquaintance treat:
  tongue buried in earth,
  rings oldened in dearth,
heaving to heaven its frond-freaky feet.

M-x rectify, i cry and eval w/ haste
(thinking: misaligned points of view are a waste).
  my Friend does not look at me,
  but continues (quite) patiently
to sweat nocturnal perfume and paint minerals traced.

-- 
Thien-Thi Nguyen -----------------------------------------------
 (defun responsep (type via)
   (case type
     (technical (eq 'mailing-list via))
     ...))                              748E A0E8 1CB8 A748 9BFA
--------------------------------------- 6CE4 6703 2224 4C80 7502


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 197 bytes --]

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

end of thread, other threads:[~2016-10-29  8:34 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-10-28 18:55 Functionality to maintain function prototypes in C Nikolai Weibull
2016-10-28 21:38 ` Pascal J. Bourguignon
2016-10-29  1:30   ` John Mastro
2016-10-29  8:26   ` Nikolai Weibull
2016-10-29  8:34 ` Thien-Thi Nguyen

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.