Scheme: Graph lines of code in Subversion

This checks out every tenth version from SVN and produces a data file which can easily be used as input to gnuplot. You can see the final graph.

(module foo
  (main main))
 
(define *new-test-regexp* (pregexp "^[ \t][ \t]*void\\s+test[A-Za-z_0-9]*\\s*\\(\\s*\\)"))
 
(define (is-test-header? filename)
  (cond
    ((not (string-ci=? "h" (suffix filename)))
     #f)
    ((<= (string-length (basename filename)) 5)
     #f)
    ((string-ci=? "Test_" (substring (basename filename) 0 5))
     #t)
    (else
      #f)))
 
(define (is-code-file? filename)
  (or (string-ci=? "cpp" (suffix filename))
      (string-ci=? "h" (suffix filename))
      (string-ci=? "hpp" (suffix filename))
      (string-ci=? "cxx" (suffix filename))
      (string-ci=? "hxx" (suffix filename))))
 
(define (main args)
  (let ((output-file (open-output-file "report.txt")))
    (let loop ((version 10))
      (if (< version 2142)
	(begin
	  (system (format "svn up -r ~a" version))
 
	  (let ((code-lines 0)
		(test-lines 0)
		(number-of-tests 0))
 
	    (let scan-dir ((dir-name ".")
			   (all-test-code #f))
	      (display dir-name)
	      (newline)
	      (let loop ((files (directory->list dir-name)))
		(cond
		  ((null? files)
		   #f)
 
		  ((string-ci=? ".svn" (basename (car files)))
		   (loop (cdr files)))
 
		  ((string-ci=? "boost" (basename (car files)))
		   (loop (cdr files)))
 
		  ((string-ci=? "WindowsSDK" (basename (car files)))
		   (loop (cdr files)))
 
		  ((string-ci=? "XML" (basename (car files)))
		   (loop (cdr files)))
 
		  ((string-ci=? "OPENSSL" (basename (car files)))
		   (loop (cdr files)))
 
		  ((string-ci=? "Release" (basename (car files)))
		   (loop (cdr files)))
 
		  ((and (string-ci=? "cxxtest" (basename (car files)))
		        (directory? (string-append dir-name "\\" (car files))))
		   (scan-dir (string-append dir-name "\\" (car files)) #t)
		   (loop (cdr files)))
 
		  ((directory? (string-append dir-name "\\" (car files)))
		   (scan-dir (string-append dir-name "\\" (car files)) all-test-code)
		   (loop (cdr files)))
 
		  ((or (is-test-header? (car files))
		       (and all-test-code
			    (is-code-file? (car files))))
		   (with-input-from-file (string-append dir-name "\\" (car files))
		     (lambda ()
		       (let l-loop ((l (read-line)))
			 (if (eof-object? l)
			   #f
			   (begin
			     (set! test-lines (+ 1 test-lines))
 
			     (let ((result (pregexp-match *new-test-regexp* l)))
			       (if result
				 (set! number-of-tests (+ 1 number-of-tests))))
 
			     (l-loop (read-line)))))))
 
		   (loop (cdr files)))
 
		  ((is-code-file? (car files))
		   (with-input-from-file (string-append dir-name "\\" (car files))
		     (lambda ()
		       (let l-loop ((l (read-line)))
			 (if (eof-object? l)
			   #f
			   (begin
			     (set! code-lines (+ 1 code-lines))
			     (l-loop (read-line)))))))
		   (loop (cdr files)))
 
		  (else
		    (loop (cdr files))))))
 
	    (display (format "~a ~a ~a ~a" version code-lines test-lines number-of-tests) output-file)
	    (newline output-file))
	  (loop (+ version 10)))))))
Posted by: Jason Felice on June 11, 2009 • Tags: , , , , • Posted in: Jigs

One Response to “Scheme: Graph lines of code in Subversion”

  1. //FIXME » Jigcode.com - June 16, 2009

    [...] Silly little scripts. Things that sort every third line ending with “L”, remove the artifacts of PDF layout, and encode the result as a static C data. Things that grep source files for things, avoiding large binary files and recursing into .svn directories. Things that remove VSS mangling from .dsp files, frob version control, glue together the build process, or produce pretty graphs useful in annual reviews. [...]

Comments are closed for this entry.