1 ;;; gEDA - GPL Electronic Design Automation
2 ;;; gnetlist - gEDA Netlist
3 ;;; Copyright (C) 1998-2010 Ales Hvezda
4 ;;; Copyright (C) 1998-2010 gEDA Contributors (see ChangeLog for details)
6 ;;; This program is free software; you can redistribute it and/or modify
7 ;;; it under the terms of the GNU General Public License as published by
8 ;;; the Free Software Foundation; either version 2 of the License, or
9 ;;; (at your option) any later version.
11 ;;; This program is distributed in the hope that it will be useful,
12 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ;;; GNU General Public License for more details.
16 ;;; You should have received a copy of the GNU General Public License
17 ;;; along with this program; if not, write to the Free Software
18 ;;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 ;;----------------------------------------------------------------------
21 ;; The below functions added by SDB in Sept 2003 to support command-line flag
23 ;;----------------------------------------------------------------------
25 ;;---------------------------------------------------------------
27 ;; Wrapper which spews debug messages if -v flag is set, otherwise
29 ;; Calling form: (debug-spew "verbose debug text")
30 ;;--------------------------------------------------------------
32 (lambda (debug-string)
33 (if (calling-flag? "verbose_mode" (gnetlist:get-calling-flags))
34 (display debug-string)
38 ;;---------------------------------------------------------------
40 ;; Returns #t or #f depending upon the corresponding flag
41 ;; was set in the calling flags given to gnetlist.
43 ;;---------------------------------------------------------------
45 (lambda (searched-4-flag calling-flag-list)
47 (if (null? calling-flag-list)
48 '#f ;; return #f if null list -- sort_mode not found.
49 (let* ((calling-pair (car calling-flag-list)) ;; otherwise look for sort_mode in remainder of list.
50 (calling-flag (car calling-pair))
51 (flag-value (cadr calling-pair)) )
53 ;; (display (string-append "examining calling-flag = " calling-flag "\n" ))
54 ;; (display (string-append "flag-value = " (if flag-value "true" "false") "\n" ))
56 (if (string=? calling-flag searched-4-flag)
57 flag-value ;; return flag-value if sort_mode found
58 (calling-flag? searched-4-flag (cdr calling-flag-list)) ;; otherwise recurse until sort_mode is found
64 ;;------------- End of SDB's command line flag functions ----------------
68 ;; This fcn should behave exactly the same as C's strncmp fcn.
69 ;; It compares two strings from the start up to a user-defined end
70 ;; char count. It also checks that the string compare was successful through
71 ;; the end char count (i.e. that both strings are >= "end"). This
72 ;; guards against returning #t when comparing "unconnected_pin-23" to "unc"
74 ;; I needed to write this because substring chokes when the string arg is
75 ;; shorter than the end arg.
78 (lambda (string1 string2 end)
80 (string-ci=? (substring string1 0 (min end (string-length string1)))
81 (substring string2 0 (min end (string-length string2))))
82 (>= (min (string-length string1) (string-length string2)) end)
88 ;; This fcn returns the first len characters of the string str. If
89 ;; str has less than len characters, it returns the whole string
90 ;; (but doesn't choke)
91 (define safe-string-head
93 (substring str 0 (min len (string-length str)))
98 ;; Given a uref, returns the device attribute value (unknown if not defined)
102 (gnetlist:get-package-attribute package "device")))
104 ;; Shorthand for get component values
107 (gnetlist:get-package-attribute package "value")))
109 (define get-component-text
111 (let ((value (gnetlist:get-package-attribute package "value"))
112 (label (gnetlist:get-package-attribute package "label"))
113 (device (gnetlist:get-package-attribute package "device")))
114 (if (not (string=? "unknown" value))
116 (if (not (string=? "unknown" label))
121 ;; return all pins for a particular package
124 (gnetlist:get-pins package)))
126 ;; this is really crude, but I'm tired... :)
133 ;; ah.. wonder what use this is...
136 (for-each display-nl pin-list)))
139 ;; ha. I'm playing with scheme here.. don't mind me
140 (define display-all-pins
142 (for-each display-pin all-pins)))
145 ;; another misc function
146 (define print-packages
148 (for-each display-nl plist)))
152 ;; Usage: (find-device packages devicename)
153 ;; Returns the first package which matches the devicename
155 (lambda (components devicename)
156 (if (not (null? components))
157 (if (string=? devicename (get-device (car components)))
159 (find-device (cdr components) devicename)))))
164 ;; Usage: (find-devices packages devicename '())
165 ;; Returns a list of packages which match the device name
167 (lambda (components devicename list)
168 (if (not (null? components))
169 (if (string=? devicename (get-device (car components)))
170 (find-devices (cdr components)
172 (cons (car components) list))
173 (find-devices (cdr components)
180 ;; Usage (contains? list item)
181 ;; True if the list contains the item, according to string=?
186 ((string=? item (car ls)) #t)
187 (#t (contains? (cdr ls) item)))))
190 ;; Usage: (number-nets all-unique-nets 1)
191 ;; Returns a list of pairs of form (netname . number)
193 (lambda (nets number)
196 (if (string=? "GND" (car nets))
197 (cons (cons "GND" 0) (number-nets (cdr nets) number))
199 (cons (car nets) number)
200 (number-nets (cdr nets)(+ number 1)))))))
203 ;; Usage: (get-net-number netname numberlist)
204 ;; numberlist should be from (number-nets) above
205 ;; Returns the number corresponding to the net
206 (define get-net-number
207 (lambda (netname numberlist)
208 (if (not (null? numberlist))
209 (if (string=? netname (car (car numberlist)))
210 (cdr (car numberlist))
211 (get-net-number netname (cdr numberlist))))))
214 ;; Useful output functions contributed by Andrew Bardsley
216 (define (print-to-port port . l)
217 (for-each (lambda (elem) (display elem port)) l))
220 (apply print-to-port (cons (current-output-port) l)))
223 ;; Wrap a string into lines no longer than wrap-length
224 ;; wrap-char is put on the end-of-the-wrapped-line, before the return
225 ;; (from Stefan Petersen)
226 (define (gnetlist:wrap string-to-wrap wrap-length wrap-char)
227 (if (> wrap-length (string-length string-to-wrap))
228 string-to-wrap ; Last snippet of string
229 (let ((pos (string-rindex string-to-wrap #\space 0 wrap-length)))
231 (display "Couldn't wrap string at requested position\n")
235 (substring string-to-wrap 0 pos)
238 (gnetlist:wrap (substring string-to-wrap (+ pos 1)) wrap-length wrap-char)))))))
241 ; (define (run-test test-string wrap-len)
242 ; (display (string-append "Wrapping \"" test-string "\" into "))
245 ; (display (gnetlist:wrap test-string wrap-len " \\"))
249 ; (run-test "one two three four five six seven eight nine ten" 5)
250 ; (run-test "one two three four five six seven eight nine ten" 10)
251 ; (run-test "one two three four five six seven eight nine ten" 20)
253 ;; determine the uref to use for a particular OBJECT
254 (define (gnetlist:get-uref object)
255 ; Returns first value of first attrib found with given name, or #f.
256 (define (attrib-first-value object name)
257 (let ((attrib-lst (get-attrib-value-by-attrib-name object name)))
258 (if (null? attrib-lst) #f (car attrib-lst))))
259 ; Handler if we find uref=
260 (define (handle-uref value)
261 (simple-format (current-output-port)
262 "WARNING: Found uref=~A" value)
264 (simple-format (current-output-port)
265 "uref= is deprecated, please use refdes=~A" value)
269 ; Actually find attribute: check refdes, then uref, then return #f.
271 ((attrib-first-value object "refdes") => (lambda (x) x))
272 ((attrib-first-value object "uref") => handle-uref)
275 ;; define the default handler for get-uref
276 (define get-uref gnetlist:get-uref)