Initial Commit
[packages] / xemacs-packages / jde / lisp / jde-stat.el
1 ;;; jde-stat.el -- Integrated Development Environment for Java.
2 ;; $Revision: 1.7 $ $Date: 2003/03/28 05:33:30 $ 
3
4 ;; Author: Stephane Nicolas <s.nicolas@videotron.ca>
5 ;; Maintainer: Paul Kinnucan
6 ;; Keywords: java, tools
7
8 ;; Copyright (C) 2000, 2002 Stephane Nicolas, Paul Kinnucan
9
10 ;; GNU Emacs is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14
15 ;; GNU Emacs is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
22 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.
24
25 ;;; Commentary:
26
27 ;; This is one of a set of packages that make up the 
28 ;; Java Development Environment (JDE) for Emacs. See the
29 ;; JDE User's Guide for more information.
30
31 ;; The latest version of the JDE is available at
32 ;; <URL:http://sunsite.auc.dk/jde/>.
33 ;; <URL:http://www.geocities.com/SiliconValley/Lakes/1506/>
34
35 ;; Please send any comments, bugs, or upgrade requests to
36 ;; Paul Kinnucan at paulk@mathworks.com.
37
38 ;;; Code:
39
40 ;;;###autoload
41 (defun jde-stat-loc-report (&optional count &optional total-files)
42   "Generates a report showing the number of code, comment,
43 javadoc, and blank lines in the current Java source buffer. Optionally
44 a total count could be passed to be displayes, as well as the number of
45 processed files."
46   (interactive)
47   (flet ((perc2x2 (a b)
48                   (format "%.1f" (* 100(/ (float a) (float b))))))
49     (let* ((fname (buffer-file-name))
50            (result (if count count (jde-stat-count-loc)))
51            (total (nth 0 result))
52            (comment (nth 1 result)) 
53            (javadoc (nth 2 result))
54            (blank (nth 3 result))
55            (code (- total (+ comment javadoc blank)))
56            (code-perc (perc2x2 code total))
57            (doc-perc (perc2x2 comment total))
58            (jdoc-perc (perc2x2 javadoc total))
59            (blank-perc (perc2x2 blank total)))
60       (with-output-to-temp-buffer "LOC Report"
61         (princ "Lines of Code Report\n\n")
62         (if (and count total-files)
63             (princ (format "Total files:  %d\n" total-files))
64           (progn 
65             (princ (format "File name: %s\n" fname))
66             (princ (format "File date: %s\n" (format-time-string "%D" (nth 5 (file-attributes fname)))))))
67         (princ "------------------- \n")
68         (princ (format "Code lines:    %d (%s%%)\n" code code-perc))
69         (princ (format "Javadoc lines: %d (%s%%)\n" javadoc jdoc-perc))
70         (princ (format "Comment lines: %d (%s%%)\n" comment doc-perc))
71         (princ (format "Blank lines:   %d (%s%%)\n" blank blank-perc))
72         (princ (format "Total lines:   %d  \n" total))
73         (princ "")))))
74
75
76 (defun jde-stat-parse-token-out-of-quote (token line)
77   (let (result)
78      ;;;Does the line contain '//'?
79     (if (string-match token line)
80          ;;;if so, does it contain '"'
81         (if (not (string-match "\"" line ))
82              ;;;no! Ok, it's a comment
83             (setq result t)
84            ;;;yes!? so, we've got to parse to see if '//' exists without enclosing quote
85           (let (
86                 ;;;we split the line in '"' delimited parts
87                 (to-parse (split-string line "\""))
88                 (temp "")
89                 (count-even 0))
90             ;;;we consider the even numbered parts of split
91             ;;;to see if the contain a'//'
92             ;;;if so, this is a doc line
93             (while temp
94               (setq temp (nth count-even to-parse))
95               (if temp
96                   (if (string-match token temp)
97                       (progn 
98                         (setq result t)
99                         (setq temp nil))))
100               (setq count-even (+ 2  count-even))))))
101     result))
102
103 (defun jde-stat-count-loc ()
104   "Counts the code, comments, javadoc, and blank lines in the current buffer.
105 Returns the counts in a list: (TOTAL-LINES COMMENT-LINES JAVADOC-LINES BLANK-LINES)."
106   (let ((count 0)
107         (line "")
108         (javadoc-count 0)
109         (comment-count 0)
110         (blank-count 0)
111         in-javadoc
112         in-comment
113         (test-b t)
114         start
115         end)
116     (save-excursion
117       (goto-char (point-min))
118       (while test-b
119         (beginning-of-line 1)
120         (setq start (point))
121         (end-of-line 1)
122         (setq end (point))
123         (setq line (buffer-substring start end))
124         (setq count (+ 1 count))
125
126       ;;;To match a blank line, we search the pattern representing an empty line 
127       ;;;or a line that just contains spaces
128         (if (string-match "^ *$" line)
129             (setq blank-count (+ 1 blank-count) ))
130
131       ;;;To match a comment line, we search the pattern '//' 
132       ;;;but we must disgard the '//' patterns enclosed in a pair of quote '"'
133         (if (jde-stat-parse-token-out-of-quote "//" line)
134             (setq comment-count (+ 1 comment-count))) 
135
136       ;;;To match a comment block start, we search the pattern '/*' and exclude those of type '/**' 
137       ;;;but we must disgard the '/*' patterns enclosed in a pair of quote '"'
138         (if (and 
139              (jde-stat-parse-token-out-of-quote "/\\*" line)
140              (not (jde-stat-parse-token-out-of-quote "/\\*\\*" line)))
141             (setq in-comment t)) 
142
143       ;;;To match a javadoc block start, we search the pattern '/**'
144       ;;;but we must disgard the '/**' patterns enclosed in a pair of quote '"'
145         (if (jde-stat-parse-token-out-of-quote "/\\*\\*" line)
146             (setq in-javadoc t)) 
147
148       ;;;To match a block end, we search the pattern '*/'
149       ;;;but we must disgard the '*/' patterns enclosed in a pair of quote '"'
150         (if (jde-stat-parse-token-out-of-quote "\\*/" line)
151             (progn  
152               (if in-javadoc
153                   (setq javadoc-count (+ 1 javadoc-count)))
154               (if in-comment
155                   (setq comment-count (+ 1 comment-count)))
156               (setq in-javadoc nil)
157               (setq in-comment nil)))
158         (if in-javadoc
159             (setq javadoc-count (+ 1 javadoc-count)))
160         (if in-comment 
161             (setq comment-count (+ 1 comment-count)))
162         (if (not (= (forward-line 1) 0))
163             (setq test-b nil))))
164     (list count comment-count javadoc-count blank-count))) 
165  
166 ;;;###autoload
167 (defun jde-stat-loc-report-project (dir)
168   "Generates a report showing the number of code, comment,
169 javadoc, and blank lines in all the java files in the current
170 directory and subdirectories. This method will kill any
171 buffer containing a java file contained in dir."
172   (interactive "D directory name: ")
173   (let ((count (jde-stat-loc-count-directories dir)))
174     (jde-stat-loc-report (car count) (cadr count))))
175
176 (defun jde-stat-loc-count-directories (dir)
177   "Counts the number of code, comment,
178 javadoc, and blank lines in all the java files in the current
179 directory and subdirectories. This method will kill any buffer
180 containing a java file contained in dir. It returns a list containing
181 two elements, a list of the number of code lines, comment lines,
182 javadoc lines and blank lines and the number fo files."
183   (let* ((directories (jde-stat-get-directories dir))
184          (count (jde-stat-loc-count-directory dir))
185          (current-count (car count))
186          (number-of-files (cadr count)))
187     (while directories
188       (setq count (jde-stat-loc-count-directories (car directories)))
189       (setq current-count (jde-stat-add current-count (car count)))
190       (setq number-of-files (+ number-of-files (cadr count)))
191       (setq directories (cdr directories)))
192     (list current-count number-of-files)))
193       
194 (defun jde-stat-get-directories (dir)
195   "Returns a list of the subdirectories in dir."
196   (let (result)
197     (apply 'nconc
198            (mapcar (function
199                     (lambda (file)
200                       (if (and (not (string= (substring file -1) "."))
201                                (file-directory-p file))
202                           (setq result (append result (list file))))))
203                    (directory-files dir t nil t)))
204     result))
205
206 ;;;###autoload
207 (defun jde-stat-loc-report-directory (dir)
208   "Generates a report showing the number of code, comment,
209 javadoc, and blank lines in all the java files in the current
210 directory. This method will kill any buffer containing a java file
211 contained in dir."
212   (interactive "D directory name: ")
213   (let ((count (jde-stat-loc-count-directory dir)))
214     (jde-stat-loc-report (car count) (cadr count))))
215
216 (defun jde-stat-loc-count-directory (dir)
217   "Counts the number of code, comment,
218 javadoc, and blank lines in all the java files in the current
219 directory. This method will kill any buffer containing a java file
220 contained in dir. It returns a list containing two elements,
221 a list of the number of code lines, comment lines,
222 javadoc lines and blank lines and the number fo files."
223   (let* ((files (directory-files dir t (wildcard-to-regexp "*.java") t))
224          (number-of-files (length files))
225          (count (list 0 0 0 0)))
226     (while files
227       (switch-to-buffer (find-file-noselect (car files) nil t))
228       (setq count (jde-stat-add count (jde-stat-count-loc)))
229       (kill-buffer (current-buffer))
230       (setq files (cdr files)))
231     (list count number-of-files)))
232
233 (defun jde-stat-add (count count2)
234   "It takes as an argument two lists of 4 elements. The first element
235 is the total number of lines, the second the number of comment lines,
236 the third the number of javadoc lines, and fourth the number of
237 blank lines. It adds the respective elements in each list and returns another
238 list of four elements."
239   (list (+ (nth 0 count) (nth 0 count2))
240         (+ (nth 1 count) (nth 1 count2))
241         (+ (nth 2 count) (nth 2 count2))
242         (+ (nth 3 count) (nth 3 count2))))
243
244 ;; Register and initialize the customization variables defined
245 ;; by this package.
246 (jde-update-autoloaded-symbols)
247
248 (provide 'jde-stat)
249
250 ;; Change History
251 ;;
252 ;; $Log: jde-stat.el,v $
253 ;; Revision 1.7  2003/03/28 05:33:30  andyp
254 ;; XEmacs optimizations for JDEbug and efc.
255 ;;
256 ;; Revision 1.6  2002/11/21 04:18:41  paulk
257 ;; These packages, when autoloaded, now register and initialize the customization variables
258 ;; that they define to the values specified in the current project file.
259 ;;
260 ;; Revision 1.5  2002/10/11 05:53:21  paulk
261 ;; Added more packages to the list of packages that are demand loaded. This is intended to reduce the startup time for the JDEE.
262 ;;
263 ;; Revision 1.4  2002/10/01 05:43:10  paulk
264 ;; Made commands defined by this package autoloadable.
265 ;;
266 ;; Revision 1.3  2001/08/28 12:53:23  jslopez
267 ;; Fixing typo in the documentation for jde-stat-loc-report-project.
268 ;; Formatting the documentation of jde-stat-loc-count-directories and
269 ;; jde-stat-loc-count-directory.
270 ;;
271 ;; Revision 1.2  2001/08/28 00:50:33  jslopez
272 ;; Modified jde-stat-loc-report to take a count and a total number of files as
273 ;; arguments.
274 ;; Added jde-stat-loc-report-project and jde-stat-loc-report directory.
275 ;;
276 ;; Revision 1.1  2000/07/28 05:59:43  paulk
277 ;; Initial revision. Thanks to Stephane Nicolas <s.nicolas@videotron.ca>
278 ;; for contributing the initial version of this package.
279 ;;
280 ;;
281 ;; End of jde-stat.el