;;; ska-skel-c.el --- skeletons and other templates for C/C++
;; $Id: $
;; Copyright (C) 2002 by Stefan Kamphausen
;; Author: Stefan Kamphausen <mail@skamphausen.de>
;; Keywords: languages, tools
;; This file is not part of XEmacs.

;; This program is free software; you can redistribute it and/or modify it
;; under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.

;; This program is distributed in the hope that it will be useful, but
;; WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
;; General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with this program; see the file COPYING. If not, write to the Free
;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
;; 02111-1307, USA.


;;; Commentary:
;; This file provides some skeletons to make me type less in c/c++ mode


;;; Code:
(require 'skeleton)
(require 'ska-skel-utils)

(define-skeleton ska-skel-c-main
  "Insert a typical main function."
  nil
  "int main(int argc, char** argv) {\n"
  > _
  "\n}"
  )

(define-skeleton ska-skel-c-comment
  "Insert comment."
  nil
  "/* "
  > _
  " */"
  )

(define-skeleton ska-skel-c-printf
  "Insert the common printf statement at point."
  nil
  > "printf(\""
  _
  "\");"
  )

(define-skeleton ska-skel-c-printf-flush
  "Insert the common printf statement followed by an fflush at point."
  nil
  > "printf(\""
  _
  "\");fflush(stdout);"
  )

(define-skeleton ska-skel-c-printf-newline
  "Insert a printf statement with newline"
  nil
  "printf(\"\\n\");"
)

(define-skeleton ska-skel-cc-loop-for
  "Insert a for-loop with an int counter variable."
  "Counter variable(int): "
  >"for(int " str "=0;" str "<" _ ";" str "++) {" \n
  \n
  > "}" \n
  )

(define-skeleton ska-skel-c-loop-for
  "Insert a for-loop with an int counter variable."
  "Counter variable(int): "
  >"for(" str "=0;" str "<" _ ";" str "++) {" \n
  \n
  > "}" \n
  )

(define-skeleton ska-skel-c-loop-while
  "Insert a while-loop template."
  > "while(" _ ") {"\n
  \n
  >"}" \n
  )

(define-skeleton ska-skel-c-fflush
  "Insert a fflush of stdout."
  nil
  > "fflush(stdout);"
  )

(define-skeleton ska-skel-c-fprintf
  "Insert a fprintf statement at point asking for the stream."
  "STREAM: "
  > "fprintf(" str ",\""
  _
  "\\n\");"
  )


(define-skeleton ska-skel-c-include
  "Insert a precompiler include statement, asking for what to include.
You need to give the quotation marks or the angles yourself."
  "include what? "
  > "# include " str
  )


;; C++ Special
(defun ska-skel-cc-endl ()
  "Insert the correct endl-string."
  (interactive)
  (when (not (save-excursion
               (skip-chars-backward " \t\n<")
               (looking-at "\\s-*<")))
    (just-one-space)
    (insert "<<"))
    (just-one-space)
  (insert "endl;\n"))
           
(defun ska-skel-cc-class (name)
  "Insert a C++ class definition.
It creates a matching header file, inserts the class definition and
creates the  most important function templates in a named after the
class name. This might still be somewhat buggy."
  (interactive "sclass name: ")
  (let* ((header-file-name (concat name ".hh"))
         (header-include-string (upcase (concat name "_HH_INCLUDED")))
         (def-file-name    (concat name ".cc")))

    ;; write header file
    (set-buffer (get-buffer-create header-file-name))
    (set-visited-file-name header-file-name)
    (c++-mode)
    (turn-on-font-lock)
    (insert (concat
             "// -*- C++ -*-\n"
             "// File: " header-file-name "\n//\n"
             "// Time-stamp: <>\n"
             "// $Id: $\n//\n"
             "// Copyright (C) "(substring (current-time-string) -4)
             " by " auto-insert-copyright "\n//\n"
             "// Author: " (user-full-name) "\n//\n"
             "// Description: \n// "
             ;; get this point...
             "\n\n" 
             "# ifndef " header-include-string "\n"
             "# define " header-include-string "\n\n"
             "# include <stdio.h>\n\n"
             "# include <stdlib.h>\n\n"
             "# include <string>\n"
             "# include <vector>\n\n"
             "# include <mtrandom>\n\n"
             "class " name ";\n\n"
             "class " name " {\n"
             "public:\n"
             name "();" "\n"
             name "(const " name "& src);\n"
             "~" name "();" "\n"
             name "& operator=(const " name "& rv);\n"
             "\nprivate:\n"
             "void init();\n"
             "void reset();\n"
             "void init_and_copy(const " name "& src);\n\n"
             "protected: \n\n"
             "};"
             "\n\n# endif"))
    (beginning-of-buffer)
    (while (and (not (eobp)) (forward-line))
      (indent-according-to-mode))
    
    ;; create CC file
    (set-buffer (get-buffer-create def-file-name))
    (set-visited-file-name def-file-name)
    (switch-to-buffer (current-buffer))
    (c++-mode)
    (turn-on-font-lock)
    (insert (concat
             "// -*- C++ -*-\n"
             "// File: " def-file-name "\n//\n"
             "// Time-stamp: <>\n"
             "// $Id: $\n//\n"
             "// Copyright (C) "(substring (current-time-string) -4)
             " by " auto-insert-copyright "\n//\n"
             "// Author: " (user-full-name) "\n//\n"
             "// Description: \n//\n\n "
             "# include <stdio.h>\n\n"
             "# include <string>\n"
             "# include <vector>\n\n"
             "# include <mtrandom>\n"
             "\n# include \"" header-file-name "\"\n\n"
             name "::\n" name "() {\ninit();\n}\n\n"
             name "::\n" name "(const " name "& src) {\ninit_and_copy(src);\n}\n\n"
             name "::\n~" name "() {\nreset();\n}\n\n"
             "void\n" name "::\ninit() {\n\n}\n\n"
             "void\n" name "::\nreset() {\n\n}\n\n"
             "void\n" name "::\ninit_and_copy(const " name "& src) {\n\n}\n\n"
             name "&\n" name "::\noperator=(const " name "& src) {\n\n}\n\n"
             ))
    (beginning-of-buffer)
    (while (and (not (eobp)) (forward-line))
      (indent-according-to-mode))
    (beginning-of-buffer)
    (search-forward "Description:")
    )
)

(provide 'ska-skel-c)

;;; ska-skel-c.el ends here