2 ; gEDA - GNU Electronic Design Automation
4 ; Copyright (C) 2000-2001 Stefan Petersen (spe@stacken.kth.se)
8 ; This program is free software; you can redistribute it and/or modify
9 ; it under the terms of the GNU General Public License as published by
10 ; the Free Software Foundation; either version 2 of the License, or
11 ; (at your option) any later version.
13 ; This program is distributed in the hope that it will be useful,
14 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ; GNU General Public License for more details.
18 ; You should have received a copy of the GNU General Public License
19 ; along with this program; if not, write to the Free Software
20 ; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
24 ; These are data that is the result of the parsing
26 ; *aperture-description* is a list with descriptions of all
27 ; apertures used. Each element of the list is a list with:
28 ; (<aperture no> <aperture type> <apterture size(s)>)
29 ; <aperture type> is one of circle, rectangle, oval or polygon.
30 ; <apterture size(s)> is one value if circle and two if rectangle.
31 (define *aperture-description* '())
33 ; *netlist* is the actual netlist. Each element of the list consist of
34 ; (<X> <Y> (<aperture no> . <exposure type>))
35 ; The elements in the list is 'backwards', the first element in the
36 ; list is the last in the file. This is simply fixed by a
38 (define *netlist* '())
42 (list (cons 'unit 'inches)
43 (cons 'polarity 'positive)
44 (cons 'omit-leading-zeros #t)
45 (cons 'coordinates 'absolute)
51 (define *current-x* #f)
52 (define *current-y* #f)
54 (define (set-aperture-size aperture size)
56 (cons size (cdr aperture))
57 (display "Wrong aperture number in set-aperture-size!\n")))
59 (define (set-aperture-state aperture state)
60 (if (or (eq? state 'exposure-off)
61 (eq? state 'exposure-on)
62 (eq? state 'exposure-flash))
63 (cons (car aperture) state)
64 (display "Wrong state in set-aperture-state!\n")))
66 (define *current-aperture* (cons #f #f))
68 ; Main function. Call this one.
69 (define (parse-gerber port)
70 (let ((latest (read-char port)))
71 (if (not (eof-object? latest))
77 (set! *current-aperture* (parse-D-code port *current-aperture*))
83 (set! *current-x* (list->string (parse-pos-code port)))
86 (set! *current-y* (list->string (parse-pos-code port)))
89 (parse-274X-code port)
92 (if (and *current-x* ; If all these set
94 (car *current-aperture*)
95 (cdr *current-aperture*))
97 ; (display *current-x*)
99 ; (display *current-y*)
101 ; (display *current-aperture*)
104 (cons (list *current-x* *current-y* *current-aperture*)
106 (parse-gerber port))))
107 (else ; Eat dead meat
108 ;Whitespaces keeps us away from using this
109 ; (display "Strange code : ")
112 (parse-gerber port))))))
115 (define (parse-G-code port)
116 (let* ((first (read-char port))
117 (second (read-char port))
118 (code (string first second)))
119 (cond ((string=? code "00") ; Move
121 ((string=? code "01") ; Linear Interpolation (1X scale)
123 ((string=? code "02") ; Clockwise Linear Interpolation
125 ((string=? code "03") ; Counter Clockwise Linear Interpolation
127 ((string=? code "04") ; Ignore Data Block
130 ((string=? code "10") ; Linear Interpolation (10X scale)
132 ((string=? code "11") ; Linear Interpolation (0.1X scale)
134 ((string=? code "12") ; Linear Interpolation (0.01X scale)
136 ((string=? code "36") ; Turn on Polygon Area Fill
138 ((string=? code "37") ; Turn off Polygon Area Fill
140 ((string=? code "54") ; Tool prepare
141 (if (char=? (read-char port) #\D)
142 (set! *current-aperture* (parse-D-code port *current-aperture*)))
144 ((string=? code "70") ; Specify inches
146 ((string=? code "71") ; Specify millimeters
148 ((string=? code "74") ; Disable 360 circular interpolation
150 ((string=? code "75") ; Enable 360 circular interpolation
152 ((string=? code "90") ; Specify absolut format
154 ((string=? code "91") ; Specify incremental format
157 (display "Strange G-code : ")
162 (define (parse-M-code port)
163 (let* ((first (read-char port))
164 (second (read-char port))
165 (code (string first second)))
166 (cond ((string=? code "00") ; Program Stop
167 ); The file ends anyhow
168 ((string=? code "01") ; Optional Stop
169 ); The file ends anyhow
170 ((string=? code "02") ; End Of Program
171 ); The file ends anyhow
173 (display "Strange M code")
177 (define (parse-D-code port current-aperture)
178 (let ((aperture (list->string (parse-pos-code port))))
179 (cond ((string=? aperture "1") ; Exposure on
180 (set-aperture-state current-aperture 'exposure-on))
181 ((string=? aperture "2") ; Exposure off
182 (set-aperture-state aperture 'exposure-off))
183 ((string=? aperture "3") ; Flash aperture
184 (set-aperture-state current-aperture 'exposure-flash))
185 ((string=? aperture "01") ; Exposure on
186 (set-aperture-state current-aperture 'exposure-on))
187 ((string=? aperture "02") ; Exposure off
188 (set-aperture-state current-aperture 'exposure-off))
189 ((string=? aperture "03") ; Flash aperture
190 (set-aperture-state current-aperture 'exposure-flash))
191 (else ; Select an aperture defined by an AD parameter
192 (set-aperture-size current-aperture (string->number aperture))))))
195 (define (parse-274X-code port)
196 (let* ((first (read-char port))
197 (second (read-char port))
198 (code (string first second)))
199 ; Directive parameters
200 (cond ((string=? code "AS") ; Axis Select
203 ((string=? code "FS") ; Format Statement
204 (if (char=? (read-char port) #\L) ; or T
205 (assoc-set! *image* 'omit-leading-zeros #t)
206 (assoc-set! *image* 'omit-leading-zeros #f))
207 (if (char=? (read-char port) #\A) ; or I
208 (assoc-set! *image* 'coordinates 'absolut)
209 (assoc-set! *image* 'coordinates 'incremental))
210 (read-char port) ; eat X
211 (assoc-set! *image* 'x-int (char->integer(read-char port)))
212 (assoc-set! *image* 'x-dec (char->integer(read-char port)))
213 (read-char port) ; eat Y
214 (assoc-set! *image* 'y-int (char->integer(read-char port)))
215 (assoc-set! *image* 'y-dec (char->integer(read-char port)))
217 ((string=? code "MI") ; Mirror Image
220 ((string=? code "MO") ; Mode of units
221 (let ((unit (string (read-char port) (read-char port))))
222 (cond ((string=? unit "IN")
223 (assoc-set! *image* 'unit 'inch))
224 ((string=? unit "MM")
225 (assoc-set! *image* 'unit 'mm))))
227 ((string=? code "OF") ; Offset
230 ((string=? code "SF") ; Scale Factor
234 ((string=? code "IJ") ; Image Justify
236 ((string=? code "IN") ; Image Name
238 ((string=? code "IO") ; Image Offset
240 ((string=? code "IP") ; Image Polarity
241 (let ((unit (string (read-char port) (read-char port) (read-char port))))
242 (cond ((string=? unit "POS")
243 (assoc-set! *image* 'polarity 'positive))
244 ((string=? unit "NEG")
245 (assoc-set! *image* 'polarity 'negative))))
247 ((string=? code "IR") ; Image Rotation
249 ((string=? code "PF") ; Plotter Film
251 ; Aperture Parameters
252 ((string=? code "AD") ; Aperture Description
253 (read-char port) ; Read the D. Should check that it really is a D.
254 (set! *aperture-description*
255 (cons (cons (car (parse-D-code port '(#f .#f)))
256 (parse-aperture-definition port))
257 *aperture-description*))
259 ((string=? code "AM") ; Aperture Macro
262 (eat-til-eop port)))))
265 (define (parse-aperture-definition port)
266 (let ((aperture-type (read-char port))
267 (read-comma (read-char port)))
270 (cons 'circle (parse-modifier port)))
271 ((#\R) ; Rectangle or Square
272 (cons 'rectangle (parse-modifier port)))
274 (cons 'oval (parse-modifier port)))
276 (cons 'polygon (parse-modifier port)))
281 (define (parse-modifier port)
282 (let ((dimension (list->string (parse-pos-code port)))
283 (next (peek-char port)))
284 (if (char=? next #\X)
287 (cons dimension (parse-modifier port)))
288 (cons dimension '()))))
291 (define (eat-til-eop port)
292 (let ((latest (read-char port)))
293 (if (not (char=? latest #\%))
294 (eat-til-eop port))))
297 (define (parse-pos-code port) ; Returns a list with all characters in position
298 (let ((sneak (peek-char port)))
299 (if (or (and (char>=? sneak #\0)
302 (cons (read-char port) (parse-pos-code port))
306 (define (eat-til-eob port)
307 (if (not (char=? #\* (read-char port)))