1# Wishrc startup for ToolScript (magic) 2# 3# For installation: Put this file and also magicwrap.so into 4# the same directory. Also see comments in shell script "magic.sh". 5 6global Opts 7 8# If we called magic via the non-console script, then we want to reset 9# the environment variable HOME to its original value. 10 11variable MAGIC_TCL_DIR [file dirname [file normalize [info script]]] 12variable CAD_ROOT_DEFAULT [file normalize [file join $MAGIC_TCL_DIR ../..]] 13 14if {${tcl_version} >= 8.6} { 15 load -lazy [file join $MAGIC_TCL_DIR tclmagic[info sharedlibextension]] 16} else { 17 load [file join $MAGIC_TCL_DIR tclmagic[info sharedlibextension]] 18} 19 20# It is important to make sure no magic commands overlap with Tcl built-in 21# commands, because otherwise the namespace import will fail. 22 23proc pushnamespace { name } { 24 25 set y [namespace eval ${name} info commands ::${name}::*] 26 set z [info commands] 27 28# Watch especially for magic "wizard" commands, as we don't want to confuse 29# the literal "*" with a regular expression *. "regsub" below takes care of it. 30 31 foreach v $y { 32 regsub -all {\*} $v {\\*} i 33 set x [namespace tail $i] 34 if {[lsearch $z $x] < 0} { 35 namespace import $i 36 } 37 } 38} 39 40proc popnamespace { name } { 41 set z [info commands] 42 set l [expr [string length ${name}] + 5] 43 44 while {[set v [lsearch $z ${name}_tcl_*]] >= 0} { 45 set y [lindex $z $v] 46 set w [string range $y $l end] 47 interp alias {} ::$w {} 48 rename ::$y ::$w 49 puts "Info: replacing ::$w with ::$y" 50 } 51 namespace forget ::${name}::* 52} 53 54#---------------------------------------------------------------------- 55# Define the drcstate procedure expected by the background DRC code. 56 57proc magic::drcstate {option} { 58 # (Null proc---see wrapper.tcl for a useful version) 59} 60 61#----------------------------------------------------------------- 62# Define these console routines so that they don't produce errors 63# when Magic is run in batch mode 64 65if {[catch {tkcon title}]} { 66 proc magic::suspendout {} {} 67 proc magic::resumeout {} {} 68 proc magic::dialog {} {} 69 proc magic::consolegeometry {} {} 70 proc magic::consolefocus {} {} 71} 72 73#---------------------------------------------------------------------- 74# Cross-Application section 75#---------------------------------------------------------------------- 76 77# Check namespaces for existence of other applications 78set UsingIRSIM 0 79set UsingXCircuit 0 80set UsingNetgen 0 81set nlist [namespace children] 82foreach i $nlist { 83 switch $i { 84 ::irsim { set UsingIRSIM 1 } 85 ::xcircuit { set UsingXCircuit 1 } 86 ::netgen { set UsingNetgen 1 } 87 } 88} 89 90# Setup IRSIM assuming that the Tcl version is installed. 91# We do not need to rename procedure irsim to NULL because it is 92# redefined in a script, which simply overwrites the original. 93 94proc irsim { args } { 95 global CAD_ROOT 96 set irsimscript [glob -nocomplain ${CAD_ROOT}/irsim/tcl/irsim.tcl] 97 if { ${irsimscript} == {} } { 98 puts stderr "\"irsim\" requires Tcl-based IRSIM version 9.6 or newer." 99 puts stderr "Could not find script \"irsim.tcl\". If IRSIM is installed in a" 100 puts stderr "place other than CAD_ROOT (=${CAD_ROOT}), use the command" 101 puts stderr "\"source <path>/irsim.tcl\" before doing \"irsim\"." 102 } else { 103 source $irsimscript 104 eval {irsim} $args 105 } 106} 107 108# Setup Xcircuit assuming that the Tcl version is installed. 109 110proc xcircuit { args } { 111 global CAD_ROOT 112 global argc 113 global argv 114 set xcircscript [glob -nocomplain ${CAD_ROOT}/xcircuit*/xcircuit.tcl] 115 if { ${xcircscript} == {} } { 116 puts stderr "\"xcircuit\" requires Tcl-based XCircuit version 3.1 or newer." 117 puts stderr "Could not find script \"xcircuit.tcl\". If XCircuit is installed in a" 118 puts stderr "place other than CAD_ROOT (=${CAD_ROOT}), use the command" 119 puts stderr "\"source <path>/xcircuit.tcl\"." 120 } else { 121 # if there are multiple installed versions, choose the highest version. 122 if {[llength $xcircscript] > 1} { 123 set xcircscript [lindex [lsort -decreasing -dictionary $xcircscript] 0] 124 } 125 # execute script in the scope of magic, because its variable space is 126 # not modularized. 127 set argv $args 128 set argc [llength $args] 129 uplevel #0 source $xcircscript 130 } 131} 132 133# Setup Netgen assuming that the Tcl version is installed. 134 135proc netgen { args } { 136 global CAD_ROOT 137 global argc 138 global argv 139 set netgenscript [glob -nocomplain ${CAD_ROOT}/netgen/tcl/netgen.tcl] 140 if { ${netgenscript} == {} } { 141 puts stderr "\"netgen\" requires Tcl-based Netgen version 1.2 or newer." 142 puts stderr "Could not find script \"netgen.tcl\". If Netgen is installed in a" 143 puts stderr "place other than CAD_ROOT (=${CAD_ROOT}), use the command" 144 puts stderr "\"source <path>/netgen.tcl\"." 145 } else { 146 set argv $args 147 set argc [llength $args] 148 uplevel #0 source $netgenscript 149 } 150} 151 152# Add the "echo" command 153 154proc echo {args} { 155 puts stdout $args 156} 157 158# Parse argument list for "-c[onsole]" and "-now[rapper]". 159 160set celllist {} 161set do_wrapper true 162set do_recover false 163set argafter {magic::initialize} 164set x {} 165for {set i 0} {$i < $argc} {incr i 1} { 166 set x [lindex $argv $i] 167# 168# Command-line argument handling goes here 169# We have to handle all of magic's command line arguments so we can 170# figure out if a cell has been named for preloading. 171# 172 switch -regexp -- $x { 173 ^-now(rap)?(per)?$ { ;# This regexp accepts -now, -nowrap, and -nowrapper 174 set do_wrapper false 175 } 176 ^-dnull { 177 set do_wrapper false 178 lappend argafter $x 179 } 180 ^-r(e)?(cover)?$ { 181 set do_recover true 182 } 183 ^-rc(file)?$ { 184 lappend argafter $x 185 incr i 1 186 lappend argafter [lindex $argv $i] 187 } 188 ^-d - 189 ^-g - 190 ^-m - 191 ^-i - 192 ^-T { 193 lappend argafter $x 194 incr i 1 195 lappend argafter [lindex $argv $i] 196 } 197 ^-F { 198 lappend argafter $x 199 incr i 1 200 lappend argafter [lindex $argv $i] 201 incr i 1 202 lappend argafter [lindex $argv $i] 203 } 204 ^--version { 205 puts stdout "MAGIC_VERSION.MAGIC_REVISION" 206 exit 0 207 } 208 ^--prefix { 209 puts stdout $CAD_ROOT 210 exit 0 211 } 212 ^-D - 213 ^-n* { 214 lappend argafter $x 215 } 216 default { 217 lappend celllist $x 218 lappend argafter $x 219 } 220 } 221} 222 223if {$do_wrapper} { 224 source ${CAD_ROOT}/magic/tcl/wrapper.tcl 225 lappend argafter "-nowindow" ;# Set no-initial-window option in magic. 226} 227unset x i do_wrapper 228if {[catch {eval $argafter}]} { ;# magic::initialize ${argv} 229 exit 1 230} 231 232#---------------------------------------------------------------------- 233# Check for presence of padlist manager script and include it 234 235if {[file exists ${CAD_ROOT}/magic/tcl/padlist.tcl]} { 236 source ${CAD_ROOT}/magic/tcl/padlist.tcl 237 set Opts(padlist) 0 238} 239 240#---------------------------------------------------------------------- 241# Check for presence of the miscellaneous tools script and include it 242 243if {[file exists ${CAD_ROOT}/magic/tcl/tools.tcl]} { 244 source ${CAD_ROOT}/magic/tcl/tools.tcl 245 set Opts(tools) 0 246} 247 248#---------------------------------------------------------------------- 249# Check for presence of the mazerouter script and include it 250 251if {[file exists ${CAD_ROOT}/magic/tcl/mazeroute.tcl]} { 252 source ${CAD_ROOT}/magic/tcl/mazeroute.tcl 253 set Opts(mazeroute) 0 254} 255 256#---------------------------------------------------------------------- 257# Check for presence of the toolkit script and include it 258# NOTE: This supercedes the older toolkit which is now 259# named toolkit_rev0.tcl, and the intermediate bsitools.tcl, 260# which are folded into the newer toolkit.tcl. 261 262if {[file exists ${CAD_ROOT}/magic/tcl/toolkit.tcl]} { 263 source ${CAD_ROOT}/magic/tcl/toolkit.tcl 264 set Opts(toolkit) 0 265} 266 267#---------------------------------------------------------------------- 268# Check for presence of the readspice script and include it 269 270if {[file exists ${CAD_ROOT}/magic/tcl/readspice.tcl]} { 271 source ${CAD_ROOT}/magic/tcl/readspice.tcl 272 set Opts(readspice) 0 273} 274 275#---------------------------------------------------------------------- 276# Magic start function drops back to interpreter after initialization & setup 277 278set auto_noexec 1 ;# don't EVER call UNIX commands w/o "shell" in front 279 280# Have we called magic from tkcon or a clone thereof? If so, set MagicConsole 281 282if {[lsearch [interp aliases] tkcon] != -1} { 283 set MagicConsole tkcon 284 catch {wm withdraw .} 285 286 # Get rid of some overlapping tkcon commands which are not needed. 287 288 if {[lsearch [info commands] orig_edit] < 0} {rename edit orig_edit} 289 if {[lsearch [info commands] orig_dump] < 0} {rename dump orig_dump} 290 if {[lsearch [info commands] orig_what] < 0} {rename what orig_what} 291} else { 292 rename unknown tcl_unknown 293 proc unknown { args } { 294 # CAD tools special: 295 # Check for commands which were renamed to tcl_(command) 296 297 set cmd [lindex $args 0] 298 if {[lsearch [info commands] tcl_$cmd] >= 0} { 299 set arglist [concat tcl_$cmd [lrange $args 1 end]] 300 set ret [catch {eval $arglist} result] 301 if {$ret == 0} { 302 return $result 303 } else { 304 return -code $ret -errorcode $errorCode $result 305 } 306 } 307 return [eval [concat tcl_unknown $args]] 308 } 309} 310 311# Set up certain commands to act like they do in non-Tcl-based magic; 312# These are the commands whose names have been extended so they don't 313# conflict with existing Tcl/Tk commands. This renaming & importing 314# *requires* the special code in the magic Tcl command dispatcher to 315# find and deal with each of these renamed commands! 316 317if {[lsearch [info commands] orig_clock] < 0} {rename clock orig_clock} 318if {[lsearch [info commands] tcl_flush] < 0} {rename flush tcl_flush} 319if {[lsearch [info commands] tcl_load] < 0} {rename load tcl_load} 320if {[lsearch [info commands] tcl_array] < 0} {rename array tcl_array} 321if {[lsearch [info commands] tcl_label] < 0} {catch {rename label tcl_label}} 322if {[lsearch [info commands] tcl_grid] < 0} {catch {rename grid tcl_grid}} 323 324namespace eval magic namespace export * 325pushnamespace magic 326 327#---------------------------------------------------------------------- 328# Read system startup files (mostly macro definitions) 329# Read user startup file, if any 330# Load initial cell, if any 331 332magic::startup 333 334if {![catch {set toptitle [wm title .]}]} { 335 if {[string range $toptitle 0 3] == "wish"} { 336 wm withdraw . 337 } 338 if {[string range $toptitle 0 8] == "magicexec"} { 339 wm withdraw . 340 } 341 unset toptitle 342} 343 344# After loading, magic will wander off and do a complete DRC check 345# before executing the rest of the script unless we temporarily 346# disable the DRC checker. 347 348set drcstate [drc status] 349drc off 350 351# Initial window for wrapper, if defined. 352# empty string is equivalent to passing NULL cell name. 353# 354# If a startup file has created a window, then don't make another one. 355 356if {[info commands magic::openwrapper] != {}} { 357 if {[windownames layout] == {}} { 358 set winname [magic::openwrapper] 359 magic::techmanager initall 360 magic::scrollupdate $winname 361 362 foreach cellname $celllist { 363 set fext [file extension $cellname] 364 puts stdout "handling file entry $cellname extension $fext" 365 switch $fext { 366 .lef - 367 .LEF {lef read $cellname} 368 .def - 369 .DEF {def read $cellname} 370 .gds - 371 .GDS - 372 .gds2 - 373 .GDS2 - 374 .gdsii - 375 .GDSII {gds read $cellname} 376 .cif - 377 .CIF {cif read $cellname} 378 .tcl {source $cellname} 379 .mag - 380 "" {magic::load $cellname} 381 default {puts stderr "don't know how to load file $cellname"} 382 } 383 } 384 } 385} else { 386 # Initial geometry handler for the default window, non-wrapper version 387 catch {wm geometry .magic1 ${Opts(geometry)}} 388} 389 390# Print the technology name and description 391puts stdout "Using technology \"[tech name]\", version [lindex [tech version] 0]" 392 393# Set a box, and set the view; if no cell has been loaded, choose a default 394# view. 395if {![box exists]} { 396 box 0 0 1 1 ;# create a unit box 397} 398if {[llength $celllist] > 0} { 399 view 400} else { 401 view -9 -9 10 10 402} 403 404# The Tcl version handles the "-r" on the command line by calling 405# command crash recover. 406 407if {$do_recover} {crash recover} 408 409# Unset global TCL variables so they don't conflict with magic nodes. 410unset celllist nlist do_recover 411 412if {$drcstate == 1} { 413 drc on 414} 415unset drcstate 416