
(defun c-beginning-of-decl ()
  "Go the beginning of a c function declaration.  This function only
works if you put the both type and name of a function on the line with
the open parenthesis that starts the arguemnts."
  (interactive)
  (backward-sexp 1)
  (beginning-of-line))  

(defun c-make-dual-fn-decl ()
  "Take current function declaration and make it into one with both 
ANSI and non-ANSI style definitions conditionalized on the __STDC__
preprocessor symbol. 

To use, position the point at the beginning of either an ANSI-style or
an old-style declaration."
  (interactive)
  (c-beginning-of-decl)
  (open-line 1)
  (insert "#ifdef __STDC__")
  (forward-line 1)
  (beginning-of-line)
  (let ((fdeclstart)
	(fdeclend)
	(fdeclstr)
	(argsstart)
	(argsend)
	(argstrlist)
	(saveargstrlist)
	(curargstart)
	(curargend)
	(junkstart)
	(junkend)
	)
    (setq fdeclstart (point))
    (search-forward "(")
    (setq argsstart (point))
    (backward-char)
    (setq fdeclend (point))
    (setq fdeclstr (buffer-substring fdeclstart fdeclend))
    (forward-sexp 1)
    (backward-char 1)
    (setq argsend (point))
    (setq argstrlist ())
    (goto-char argsstart)
    (catch 'done
      (while t
	(setq curargstart (point))
	(if (re-search-forward "," argsend t)
	    (progn
	      (backward-char 1)
	      (setq curargend (point))
	      (setq curargstr (buffer-substring curargstart curargend))
	      (setq argstrlist (append argstrlist (list curargstr)))
	      (forward-word 1)
	      (backward-word 1))
	  (progn
	    (setq curargstr (buffer-substring curargstart argsend))
	    (setq argstrlist (append argstrlist (list curargstr)))
	    (throw 'done nil)))))
    (goto-char argsend)
    (end-of-line)
    (insert "\n#else\n")
    (insert fdeclstr)
    (if (equal (car argstrlist) "void")
	(insert "()\n")
      (progn
	(insert "(")
	(setq saveargstrlist argstrlist)
	(while (not (null argstrlist))
	  (setq curargstr (car argstrlist))
	  (setq argstrlist (cdr argstrlist))
	  (setq junkstart (point))
	  (insert curargstr)
	  (setq junkend (point))
	  (re-search-backward "[a-zA-Z_][a-zA-Z0-9_]*")
	  (goto-char (match-end 0))
	  (delete-region (point) junkend)
	  (re-search-backward "[^a-zA-Z0-9_]")
	  (forward-char 1)
	  (delete-region junkstart (point))
	  (end-of-line)
	  (insert ", "))
	(delete-char -2)
	(insert ")\n")
	(setq argstrlist saveargstrlist)
	(while (not (null argstrlist))
	  (setq curargstr (car argstrlist))
	  (setq argstrlist (cdr argstrlist))
	  (c-indent-command)
	  (insert curargstr)
	  (insert ";\n"))))
    (insert "#endif /* __STDC__ */\n")
    ))

(defun c-ansidecl-to-proto ()
  "Take current ansi function declaration and make it into a function
prototype.

To use, position the point at the beginning of declaration."
  (interactive)
  (let ((fdeclstart)
	(fdeclend)
	(fdeclstr)
	(varend)
	(argsstart)
	(argsend)
	(argstrlist)
	(saveargstrlist)
	(curargstart)
	(curargend)
	(junkstart)
	(junkend)
	(allargsstart)
	)
    (search-forward "(")
    (setq allargsstart (point))
    (if (not (looking-at "void)"))
	(progn
	  (backward-char 1)
	  (setq argsstart (point))
	  (catch 'done
	    (while t
	      (progn
		(save-excursion
		  (goto-char argsstart)
		  (forward-sexp 1)
		  (backward-char 1)
		  (setq argsend (point)))
		(if (search-forward "," argsend t)
		    (progn
		      (re-search-backward "[a-zA-Z_][a-zA-Z0-9_]*")
		      (goto-char (match-end 0))
		      (setq varend (point))
		      (re-search-backward "[^a-zA-Z0-9_]")
		      (forward-char 1)
		      (re-search-backward "[^ ]")
		      (forward-char 1)
		      (delete-region (point) varend)
		      (forward-char 1))
		  (progn
		    (goto-char argsend)
		    (re-search-backward "[a-zA-Z_][a-zA-Z0-9_]*")
		    (goto-char (match-end 0))
		    (setq varend (point))
		    (re-search-backward "[^a-zA-Z0-9_]")
		    (forward-char 1)
		    (re-search-backward "[^ ]")
		    (forward-char 1)
		    (delete-region (point) varend)
		    (throw 'done nil))))))))
    (goto-char allargsstart)
    (backward-char 1)
    (forward-sexp 1)
    (insert ";")
    ))
  

(defun c-make-ansi-decl()
  "Make an old-style function declaration into an ANSI-C style declaration.
This function won't work on procedures that have some arguments implicitely
declared."
  (interactive)
  (save-restriction
    (let ((fdeclstart)
	  (argsstart)
	  (marker)
	  )
      (setq fdeclstart (point))
      (search-forward "{")
      (narrow-to-region fdeclstart (point))
      (goto-char fdeclstart)
      (search-forward "(")
      (if (looking-at ")")
	  (progn
	    (insert "void")
	    (forward-char 1))
	(progn
	  (setq argsstart (point))
	  (backward-char 1)
	  (forward-sexp 1)
	  (delete-region argsstart (point))
	  (goto-char argsstart)
	  (catch 'done
	    (while t
	      (if (save-excursion (search-forward ";" (point-max) t))
		  (progn
		    (setq marker (point))
		    (insert " ")
		    (backward-char 1)
		    (re-search-forward "[^ \t\n]")
		    (backward-char 1)
		    (delete-region marker (point))
		    (setq marker (point))
		    (search-forward ";")
		    (delete-char -1)
		    (if (save-excursion (search-forward ";" (point-max) t))
			(insert ", ")
		      (progn
			(insert ")")
			(throw 'done nil))))))))))))
