pennmush-1.8.3p3/game/data/
pennmush-1.8.3p3/game/log/
pennmush-1.8.3p3/game/save/
pennmush-1.8.3p3/game/txt/evt/
pennmush-1.8.3p3/game/txt/nws/
pennmush-1.8.3p3/po/
pennmush-1.8.3p3/win32/msvc.net/
pennmush-1.8.3p3/win32/msvc6/
#!/usr/bin/env csi -script # -*-scheme-*-
; Print out a list of all typedefs in the src in a format suitable for
; using in the indent rule for src/Makefile. Requires chicken scheme.
; http://call-with-current-continuation.org or your package manager.
;
; Written by Raevnos <shawnw@speakeasy.org> for PennMUSH.
;
; Version 0.9.1.
;
; Usage:
; % csc -O2 -heap-initial-size 768k -o typedefs utils/typedefs.scm
; % make etags
; % ./typedefs < src/TAGS > indent.defs
; % emacs src/Makefile.in indent.defs
;    edit Makefile.in to modify the indent typedef section
; % ./config.status
; % make
;
; You can also use it as an interpreted script:
; % csi -script utils/typedefs.scm < src/TAGS > indent.defs
; or
; % chmod +x typedefs.scm
; % ./typedefs.scm < TAGS
;
; This is just slower to run, thus good for occasional use.
; Some rough time trials suggest that the compiled version runs
; twice as fast. Of course, it also takes a while to compile it...
;
;
; TODO
; Take command-line arguments: The TAGS file and whether or not to
; generate output to be included into a Makefile (Lines continued by \)
; or into an .indent.pro file. # of columns, tab stops, etc.

; Optimization and module directives. 
(cond-expand
 ((and chicken compiling)
  (declare
   (fixnum)
   (block)
   (usual-integrations)
   (disable-interrupts)
   (lambda-lift)
   (no-procedure-checks-for-usual-bindings)
   (bound-to-procedure string-between/shared process-line read-typedefs
		       copy-typedef emit-typedef)
   (uses utils srfi-1 srfi-13)))
 ((and chicken csi)
  (require-extension utils)
  (require-extension srfi-1)
  (require-extension srfi-13))
 (else #f))


; Return what's between the first occurance of fc and the last of lc in
; a string. Raises an error if index(fc) > index(lc) or one of the two
; doesn't exist.
(define (string-between/shared str fc lc)
  (let ((first-index (string-index str fc))
	(last-index (string-index-right str lc)))
    (cond
     ((not (and (integer? first-index) (integer? last-index)))
       (signal 'out-of-range))
     ((fx>= first-index last-index)
      (signal 'out-of-range))
     (else
      (substring/shared str (fx+ first-index 1) last-index)))))

; The special characters that mark the start and end of an identifier
(define-constant type-start #\x7F)
(define-constant type-end #\x01)

; Either return a typedef name or a symbol : 'line-did-not-match or
; 'read-more-lines
(define process-line #f)
(let*
    ((in-struct-typedef? #f)
     (in-enum-typedef? #f)
     (copy-typedef (lambda (str)
		     (string-between/shared str type-start type-end)))
     (pl (lambda (line)
	   (handle-exceptions
	    exn (if (eq? exn 'out-of-range)
		    (begin
		      (display
		       (format "Unable to extract typedef name from line: ~A\n"
			       line) (current-error-port))
		      'line-did-not-match)
		    (abort exn))
	    (cond
	     (in-struct-typedef?
	      (if (char=? (string-ref line 0) #\})
		  (begin
		    (set! in-struct-typedef? #f)
		    (copy-typedef line))
		  'read-more-lines))
	     (in-enum-typedef?
	      (if (char=? (string-ref line 0) #\})
		  (begin
		    (set! in-enum-typedef? #f)
		    (copy-typedef line))
		  'read-more-lines))
	     ((string-prefix? "typedef struct " line)		     
	      (if (string-index line #\;)
		  (copy-typedef line)
		  (begin
		    ; If the struct is defined here the typedef name
		    ; is on the next line starting with }. There are 
		    ; optional structure member lines between.
		    (set! in-struct-typedef? #t)
		    'read-more-lines)))
	     ((string-prefix? "typedef enum " line)
	      (if (string-index line #\;)
		  (copy-typedef line)
		  (begin
		    ; Skip enum values
		    (set! in-enum-typedef? #t)
		    'read-more-lines)))
	     ((string-prefix? "typedef " line)
	      (copy-typedef line))
	     ((string-prefix? "} " line)
	      ; We get this with a typedef of an anonymous struct.
	      ; If it then starts an array, some versions of etags
              ; won't record the typedef name and you'll get a warning.
	      (copy-typedef line))
	     (else 'line-did-not-match))))))
  (set! process-line pl))

(define-macro (prepend! val lst)
  `(set! ,lst (cons ,val ,lst)))

; Read all typedefs from an inchannel or filename.
(define (read-typedefs from)
  (let*
      ((typedefs '())
       (fl-proc (lambda (line) 
		  (let ((res (process-line line)))
		    (if (string? res) (prepend! res typedefs))))))
    (for-each-line fl-proc from)
    (delete-duplicates (sort typedefs string-ci<) string-ci=)))

; Control pretty-printing of the typedefs.
(define-constant max-column-width 75)
(define-constant tab-stop 8)

; Print out one typedef to stdout, formated as indent args.
(define emit-typedef #f)
(let*
    ((column tab-stop)
     (et (lambda (typedef)
	   (let* ((start-of-line? (fx= column tab-stop))
		  (len (fx+ (string-length typedef)
			   (if start-of-line? 3 4))))
	     (if (fx>= (fx+ column len) max-column-width)
		 (begin 
		   (display " \\\n\t")
		   (set! column tab-stop)
		   (set! start-of-line? #t)))
	     (if start-of-line?
		 (printf "-T ~A" typedef)
		 (printf " -T ~A" typedef))
	     (set! column (fx+ column len))))))
  (set! emit-typedef et))

; main
(let ((typedefs (read-typedefs (current-input-port))))
  (write-char #\tab)
  (for-each emit-typedef typedefs)
  (newline))