4 ;;; gEDA - GPL Electronic Design Automation
5 ;;; gnetlist - gEDA Netlist
6 ;;; Copyright (C) 1998-2010 Ales Hvezda
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., 675 Mass Ave, Cambridge, MA 02139, USA.
22 ;; gsch2pcb format (based on PCBboard format by JM Routoure & Stefan Petersen)
23 ;; Bill Wilson billw@wt.net
29 (define gsch2pcb:write-top-header
31 (display "# release: pcb 1.99x\n" port)
32 (display "# To read pcb files, the pcb version (or the" port)
33 (display " cvs source date) must be >= the file version\n" port)
34 (display "FileVersion[20070407]\n" port)
35 (display "PCB[\"\" 600000 500000]\n" port)
36 (display "Grid[10000.000000 0 0 0]\n" port)
37 (display "Cursor[0 0 0.000000]\n" port)
38 (display "PolyArea[200000000.000000]\n" port)
39 (display "Thermal[0.500000]\n" port)
40 (display "DRC[1000 1000 1000 1000 1500 1000]\n" port)
41 (display "Flags(\"nameonpcb,uniquename,clearnew,snappin\")\n" port)
42 (display "Groups(\"1,c:2,s:3:4:5:6:7:8\")\n" port)
43 (display "Styles[\"Signal,1000,3600,2000,1000:" port)
44 (display "Power,2500,6000,3500,1000:" port)
45 (display "Fat,4000,6000,3500,1000:" port)
46 (display "Skinny,600,2402,1181,600\"]\n" port)
51 (define gsch2pcb:write-bottom-footer
53 (display "Layer(1 \"component\")\n(\n)\n" port)
54 (display "Layer(2 \"solder\")\n(\n)\n" port)
55 (display "Layer(3 \"outline\")\n(\n)\n" port)
56 (display "Layer(4 \"GND\")\n(\n)\n" port)
57 (display "Layer(5 \"power\")\n(\n)\n" port)
58 (display "Layer(6 \"signal1\")\n(\n)\n" port)
59 (display "Layer(7 \"signal2\")\n(\n)\n" port)
60 (display "Layer(8 \"signal3\")\n(\n)\n" port)
61 (display "Layer(9 \"silk\")\n(\n)\n" port)
62 (display "Layer(10 \"silk\")\n(\n)" port)
68 ;; Split string at current split-char and returns
69 ;; a pair with substrings. If string is not splitable
71 (define (gsch2pcb:string-split the-string split-char)
72 ;;string-index is Guile specific
73 (let ((split-index (string-index the-string split-char))
74 (last-index (- (string-length the-string) 1)))
75 ;;Check if split-char happens to be in the beginning or end of the string
76 (cond ((not split-index)
79 (gsch2pcb:string-split
80 (substring the-string 1 (string-length the-string))
82 ((= split-index last-index)
85 (cons (substring the-string 0 split-index)
86 (substring the-string (+ split-index 1)
87 (string-length the-string))))
91 ;; Splits a string with space separated words and returns a list
92 ;; of the words (still as strings).
93 (define (gsch2pcb:split-to-list the-string)
94 (let ((the-list (gsch2pcb:string-split the-string #\space)))
96 (cons (car the-list) (gsch2pcb:split-to-list (cdr the-list)))
99 ;; Joins the elements of a list of strings into a single string,
100 ;; with each element prefixed by a given prefix string.
101 (define (gsch2pcb:list-join-with-prefixes the-list prefix)
104 (string-append prefix (car the-list)
105 (gsch2pcb:list-join-with-prefixes (cdr the-list) prefix))))
108 (define gsch2pcb:write-value-footprint
111 ;; refdes contains the first element of ls
112 (let* ((refdes (car ls))
113 (value (gnetlist:get-package-attribute refdes "value"))
114 (footprint (gsch2pcb:split-to-list
115 (gnetlist:get-package-attribute refdes "footprint") ) )
116 (lquote (if gsch2pcb:use-m4 "`" ""))
117 (rquote (if gsch2pcb:use-m4 "'" ""))
121 (display (string-append "PKG_" (car footprint)) pipe)
122 (display (string-append "(" lquote (car footprint)) pipe)
123 (display (gsch2pcb:list-join-with-prefixes (cdr footprint) "-") pipe)
124 (display (string-append rquote "," lquote refdes rquote "," lquote ) pipe)
127 (display (gsch2pcb:list-join-with-prefixes (cdr footprint) (string-append rquote "," lquote)) pipe)
128 (display (string-append rquote ")") pipe)
130 (gsch2pcb:write-value-footprint pipe (cdr ls))) )))
135 (define gsch2pcb:use-m4 #f)
138 ;; Let the user override the m4 command, the directory
139 ;; where pcb stores its m4 files and the pcb config directory.
140 (if (not (defined? 'gsch2pcb:pcb-m4-command)) (define gsch2pcb:pcb-m4-command "@m4@"))
141 (if (not (defined? 'gsch2pcb:pcb-m4-dir)) (define gsch2pcb:pcb-m4-dir "@pcbm4dir@"))
142 (if (not (defined? 'gsch2pcb:pcb-m4-confdir)) (define gsch2pcb:pcb-m4-confdir "@pcbconfdir@"))
144 ;; Let the user override the m4 search path
145 (if (not (defined? 'gsch2pcb:pcb-m4-path))
146 (define gsch2pcb:pcb-m4-path (list gsch2pcb:pcb-m4-dir gsch2pcb:pcb-m4-confdir "$HOME/.pcb" "."))
149 ;; Build up the m4 command line
151 (define gsch2pcb:m4-command-line-tmp (string-append
152 gsch2pcb:pcb-m4-command " -d ") )
153 (define gsch2pcb:pcb-m4-path-str #f)
154 (for-each (lambda (d)
155 (set! gsch2pcb:m4-command-line-tmp (string-append
156 gsch2pcb:m4-command-line-tmp
158 (if gsch2pcb:pcb-m4-path-str
159 (set! gsch2pcb:pcb-m4-path-str (string-append
160 gsch2pcb:pcb-m4-path-str
162 (set! gsch2pcb:pcb-m4-path-str d)
170 (set! gsch2pcb:m4-command-line-tmp
171 ( string-append gsch2pcb:m4-command-line-tmp
172 " " gsch2pcb:pcb-m4-dir "/common.m4 - >> "
176 (if (not (defined? 'gsch2pcb:pcb-m4-command-line))
177 (define gsch2pcb:pcb-m4-command-line
178 gsch2pcb:m4-command-line-tmp)
181 (use-modules (ice-9 popen))
183 (define (gsch2pcb output-filename)
184 (let ((port (open-output-file output-filename)))
185 (gsch2pcb:write-top-header port)
189 (set! gsch2pcb:pcb-m4-command-line (string-append
190 gsch2pcb:pcb-m4-command-line
192 (display (string-append
193 "=====================================================\n"
194 "gsch2pcb backend configuration:\n"
196 " ----------------------------------------\n"
197 " Variables which may be changed in gafrc:\n"
198 " ----------------------------------------\n"
199 " gsch2pcb:pcb-m4-command: " gsch2pcb:pcb-m4-command "\n"
200 " gsch2pcb:pcb-m4-dir: " gsch2pcb:pcb-m4-dir "\n"
201 " gsch2pcb:pcb-m4-confdir: " gsch2pcb:pcb-m4-confdir "\n"
202 " gsch2pcb:pcb-m4-path: " gsch2pcb:pcb-m4-path-str "\n"
203 " gsch2pcb:m4-command-line: " gsch2pcb:pcb-m4-command-line "\n"
205 " ---------------------------------------------------\n"
206 " Variables which may be changed in the project file:\n"
207 " ---------------------------------------------------\n"
208 " gsch2pcb:use-m4: " (if gsch2pcb:use-m4 "yes" "no") "\n"
210 "=====================================================\n"
214 ;; If we have defined gsch2pcb:use-m4 then run the footprints
215 ;; through the pcb m4 setup. Otherwise skip m4 entirely
217 ;; pipe with the macro define in pcb program
218 (let ((pipe (open-output-pipe gsch2pcb:pcb-m4-command-line))
221 (display "Using the m4 processor for pcb footprints\n")
222 ;; packages is a list with the different refdes value
223 (gsch2pcb:write-value-footprint pipe packages)
227 (let ((port (open output-filename (logior O_WRONLY O_APPEND))))
228 (display "Skipping the m4 processor for pcb footprints\n")
229 (gsch2pcb:write-value-footprint port packages)
234 (let ((port (open output-filename (logior O_WRONLY O_APPEND))))
235 (gsch2pcb:write-bottom-footer port)