PennMUSH Community

root/1.8.3/trunk/utils/typedefs.scm

Revision 846, 5.2 kB (checked in by penndev, 1 year ago)

PennMUSH 1.8.3p2 release candidate.

Line 
1 #!/usr/bin/env csi -script # -*-scheme-*-
2 ; Print out a list of all typedefs in the src in a format suitable for
3 ; using in the indent rule for src/Makefile. Requires chicken scheme.
4 ; http://call-with-current-continuation.org or your package manager.
5 ;
6 ; Written by Raevnos <shawnw@speakeasy.org> for PennMUSH.
7 ;
8 ; Version 0.9.1.
9 ;
10 ; Usage:
11 ; % csc -O2 -heap-initial-size 768k -o typedefs utils/typedefs.scm
12 ; % make etags
13 ; % ./typedefs < src/TAGS > indent.defs
14 ; % emacs src/Makefile.in indent.defs
15 ;    edit Makefile.in to modify the indent typedef section
16 ; % ./config.status
17 ; % make
18 ;
19 ; You can also use it as an interpreted script:
20 ; % csi -script utils/typedefs.scm < src/TAGS > indent.defs
21 ; or
22 ; % chmod +x typedefs.scm
23 ; % ./typedefs.scm < TAGS
24 ;
25 ; This is just slower to run, thus good for occasional use.
26 ; Some rough time trials suggest that the compiled version runs
27 ; twice as fast. Of course, it also takes a while to compile it...
28 ;
29 ;
30 ; TODO
31 ; Take command-line arguments: The TAGS file and whether or not to
32 ; generate output to be included into a Makefile (Lines continued by \)
33 ; or into an .indent.pro file. # of columns, tab stops, etc.
34
35 ; Optimization and module directives.
36 (cond-expand
37  ((and chicken compiling)
38   (declare
39    (fixnum)
40    (block)
41    (usual-integrations)
42    (disable-interrupts)
43    (lambda-lift)
44    (no-procedure-checks-for-usual-bindings)
45    (bound-to-procedure string-between/shared process-line read-typedefs
46                copy-typedef emit-typedef)
47    (uses utils srfi-1 srfi-13)))
48  ((and chicken csi)
49   (require-extension utils)
50   (require-extension srfi-1)
51   (require-extension srfi-13))
52  (else #f))
53
54
55 ; Return what's between the first occurance of fc and the last of lc in
56 ; a string. Raises an error if index(fc) > index(lc) or one of the two
57 ; doesn't exist.
58 (define (string-between/shared str fc lc)
59   (let ((first-index (string-index str fc))
60     (last-index (string-index-right str lc)))
61     (cond
62      ((not (and (integer? first-index) (integer? last-index)))
63        (signal 'out-of-range))
64      ((fx>= first-index last-index)
65       (signal 'out-of-range))
66      (else
67       (substring/shared str (fx+ first-index 1) last-index)))))
68
69 ; The special characters that mark the start and end of an identifier
70 (define-constant type-start #\x7F)
71 (define-constant type-end #\x01)
72
73 ; Either return a typedef name or a symbol : 'line-did-not-match or
74 ; 'read-more-lines
75 (define process-line #f)
76 (let*
77     ((in-struct-typedef? #f)
78      (in-enum-typedef? #f)
79      (copy-typedef (lambda (str)
80              (string-between/shared str type-start type-end)))
81      (pl (lambda (line)
82        (handle-exceptions
83         exn (if (eq? exn 'out-of-range)
84             (begin
85               (display
86                (format "Unable to extract typedef name from line: ~A\n"
87                    line) (current-error-port))
88               'line-did-not-match)
89             (abort exn))
90         (cond
91          (in-struct-typedef?
92           (if (char=? (string-ref line 0) #\})
93           (begin
94             (set! in-struct-typedef? #f)
95             (copy-typedef line))
96           'read-more-lines))
97          (in-enum-typedef?
98           (if (char=? (string-ref line 0) #\})
99           (begin
100             (set! in-enum-typedef? #f)
101             (copy-typedef line))
102           'read-more-lines))
103          ((string-prefix? "typedef struct " line)           
104           (if (string-index line #\;)
105           (copy-typedef line)
106           (begin
107             ; If the struct is defined here the typedef name
108             ; is on the next line starting with }. There are
109             ; optional structure member lines between.
110             (set! in-struct-typedef? #t)
111             'read-more-lines)))
112          ((string-prefix? "typedef enum " line)
113           (if (string-index line #\;)
114           (copy-typedef line)
115           (begin
116             ; Skip enum values
117             (set! in-enum-typedef? #t)
118             'read-more-lines)))
119          ((string-prefix? "typedef " line)
120           (copy-typedef line))
121          ((string-prefix? "} " line)
122           ; We get this with a typedef of an anonymous struct.
123           ; If it then starts an array, some versions of etags
124               ; won't record the typedef name and you'll get a warning.
125           (copy-typedef line))
126          (else 'line-did-not-match))))))
127   (set! process-line pl))
128
129 (define-macro (prepend! val lst)
130   `(set! ,lst (cons ,val ,lst)))
131
132 ; Read all typedefs from an inchannel or filename.
133 (define (read-typedefs from)
134   (let*
135       ((typedefs '())
136        (fl-proc (lambda (line)
137           (let ((res (process-line line)))
138             (if (string? res) (prepend! res typedefs))))))
139     (for-each-line fl-proc from)
140     (delete-duplicates (sort typedefs string-ci<) string-ci=)))
141
142 ; Control pretty-printing of the typedefs.
143 (define-constant max-column-width 75)
144 (define-constant tab-stop 8)
145
146 ; Print out one typedef to stdout, formated as indent args.
147 (define emit-typedef #f)
148 (let*
149     ((column tab-stop)
150      (et (lambda (typedef)
151        (let* ((start-of-line? (fx= column tab-stop))
152           (len (fx+ (string-length typedef)
153                (if start-of-line? 3 4))))
154          (if (fx>= (fx+ column len) max-column-width)
155          (begin
156            (display " \\\n\t")
157            (set! column tab-stop)
158            (set! start-of-line? #t)))
159          (if start-of-line?
160          (printf "-T ~A" typedef)
161          (printf " -T ~A" typedef))
162          (set! column (fx+ column len))))))
163   (set! emit-typedef et))
164
165 ; main
166 (let ((typedefs (read-typedefs (current-input-port))))
167   (write-char #\tab)
168   (for-each emit-typedef typedefs)
169   (newline))
Note: See TracBrowser for help on using the browser.