Glue between the null display driver and the rest of Magic so that
running with -d null does not require any process-level resources
(signals, timers, stdin, an X display, or a Tcl interpreter).
* utils/signals.c — gate setitimer, fcntl-based file watches, kill
and the legacy sigsetmask/sigaction setup behind #ifdef
__EMSCRIPTEN__. Every signals path becomes a no-op in WASM.
Also fixes DBWriteBackup() being called with one argument when
its real prototype takes three.
* windows/windDisp.c — WindUpdate() returns immediately when
GrDisplayStatus == DISPLAY_SUSPEND. This is the runtime
counterpart to the null driver's DISPLAY_SUSPEND state.
* extflat/EFargs.c — EFArgs() with a missing input name no longer
jumps to "usage:" in headless WASM (which would call MainExit and
kill the process); it sets *err_result and returns NULL so the
caller can decide what to do. Native MAGIC_WRAPPER and native
non-MAGIC_WRAPPER builds keep their original behavior.
* dbwind/DBWcommands.c — registers exttosim / ext2sim / exttospice /
ext2spice in non-MAGIC_WRAPPER builds. Without this, WASM users
could not invoke these commands at all (they were previously
inside an #ifdef MAGIC_WRAPPER block). The C implementations
(CmdExtToSim / CmdExtToSpice) are linked unconditionally outside
modular builds.
* textio/txCommands.c, textio/textio.h — TxDispatchString(), a new
library-style command entry point that parses a single string,
dispatches it through WindSendCommand and returns a status code.
This is what magic_wasm_run_command() calls from JavaScript.
Magic's graphics layer routes every drawing primitive through
function pointers (GrXxxPtr / grXxxPtr) that are bound to a driver
at startup. The original null driver assigned a single 0-arg
nullDoNothing() to every pointer, which works in native builds
because of K&R loose prototype rules but fails in WASM where
call_indirect requires an exact type match between caller and
callee.
This commit:
* Adds typed no-op stubs nullDoNothingI/II/IIII/IIIIIII for
void-returning callbacks of various arities.
* Adds nullReturnFalseI/II/III for bool-returning callbacks and
nullReturnZeroI for int-returning callbacks.
* Casts each pointer assignment in nullSetDisplay() to the K&R
pointer type the public header still uses, while the underlying
function carries the correct WASM signature.
* Fills in window-management and backing-store pointers that the
original null driver left at NULL — many of these are called
unconditionally by WindUpdate paths, and need at least a no-op
to avoid traps.
* Guards the stdin watch in nullSetDisplay() with #ifndef
__EMSCRIPTEN__: WASM has no real stdin file descriptor and
TxAdd1InputDevice() / SigWatchFile() are POSIX-specific.
Native builds are unaffected: the K&R-loose prototype machinery
still accepts the previous and the new code identically.
CIFGenSubcells() and extSubtree() set GrDisplayStatus =
DISPLAY_IN_PROGRESS while they run a 5-second progress timer, then
unconditionally restore DISPLAY_IDLE on exit. In native builds the
initial state is always IDLE, so this is harmless. In WASM/headless
builds the null display driver sets DISPLAY_SUSPEND at startup, and
forcing IDLE at the end of these long operations destroys the
SUSPEND guard that protects WindUpdate() from running display
callbacks against a non-existent screen.
Save the previous status before overwriting and restore it on exit.
This is also reentrant-safe: nested DISPLAY_IN_PROGRESS scopes (e.g.
extract followed by gds write) now keep the outer state intact.
* cif/CIFhier.c — CIFGenSubcells
* extract/ExtSubtree.c — extSubtree
WASM call_indirect enforces an exact type match between the caller
and the callee. Many Magic callbacks had K&R-style () forward
declarations and a single-argument definition, but were passed to
iterators that always push a trailing ClientData argument. Native
builds tolerated the mismatch via loose prototypes; WASM traps with
"indirect call signature mismatch".
Added the missing ClientData (or, where the concrete type is known,
FindRegion *) parameter to:
* calma/CalmaRead.c, calma/CalmaWrite.c, calma/CalmaWriteZ.c —
calmaWriteInitFunc
* cif/CIFwrite.c — cifWriteInitFunc
* commands/CmdSubrs.c — cmdWindSet
* database/DBtimestmp.c — dbStampFunc
* dbwind/DBWelement.c — dbwElementAlways1
* dbwind/DBWfdback.c — dbwfbWindFunc
* dbwind/DBWhlights.c — DBWHLRedrawWind
* ext2spice/ext2hier.c — spcnodeHierVisit
* extract/ExtBasic.c — extSDTileFunc, extTransPerimFunc,
extAnnularTileFunc, extResistorTileFunc
* extract/ExtMain.c — extDefInitFunc
* extract/ExtTimes.c — extTimesInitFunc
Also adjusted commands/CmdE.c and commands/CmdTZ.c: SelectExpand was
being called with four arguments (the legacy surroundFlag), but its
real signature has been three arguments for years (the surround mode
is encoded in the expandType bit). The fourth argument was redundant
(DB_EXPAND_SURROUND in arg 2 is the source of truth) and rejected by
WASM. Native behavior is unchanged.
The added parameters are unused in the function bodies; they exist
only to satisfy the indirect-call signature.
These bugs all exist in stock Magic but were tolerated by the K&R-loose
native build. The strict WASM call_indirect type checks turned them up.
* cif/CIFhier.c: ASSERT in cifFlatMaskHints accessed
oldproprec->prop_value.prop_type, but prop_type is a top-level member
of PropertyRecord. Changed to oldproprec->prop_type.
* extflat/EFargs.c: efLoadSearchPath was assigning a pointer to a
string literal ("." in RO data), which callers later try to free or
StrDup. Replaced with StrDup(path, ".") so the pointer always lives
on the heap.
* router/rtrVia.c: rtrFollowName called RtrMilestonePrint("#"), but
the function takes no arguments.
* sim/SimSelect.c: SimAddLabels called DBWLabelChanged with five
arguments, but its real signature is (CellDef *, Label *, int).
Replaced with the equivalent DBWAreaChanged call.
* windows/windView.c: extern declaration of DBMovePoint had return
type void, but the function actually returns bool.
DEV_RSUBCKT as well as (previously implemented) DEV_RES. The
handling of DEV_RSUBCKT includes checking if the subcircuit has
a substrate pin, and zeroing the capacitance to substrate for the
resistor node, under the assumption that the parasitics are part of
the resistor subcircuit model.
There is a bug where left-clicking a hidden layer in the toolbar successfully makes the layer visible in the layout but fails to update the toolbar icon to the "active" state.
The root cause is a positional argument mismatch in magic::toolupdate. When the Magic C-core issues a callback for a "see" command with two arguments, the third argument (layerlist) is passed as an empty string ("") rather than being omitted. This prevents the Tcl procedure from falling back to its hardcoded default of "none", causing the script to skip the logic that reassigns $yesno to "yes".
This patch changes the default value of $layerlist to "" and updates the conditional check to ensure the state and layer name are correctly reassigned regardless of how the C-core signals the update.
Added logic to ensure all cells are loaded into memory to prevent corruption when saving files. This is a fix for a minor edge case when generating "netlist_to_spice" for a file that already has a netlist, and which contains cells containing other cells. Followed by "writeall force". This causes unloaded files (that are still referenced) to be loaded during save with "ignoreTech" being true, and thus disregarding the scale, corrupting all coordinates if a scale is used.
This was caused by skipping regenerating cells that already had a .mag file
due to moving away from using the node "location" in favor of a
drivepoint specified by a port or other connection point. The
"location" record can end up at the default value of "infinity",
and should not be used to set the area for searches. This fix
is in response to issue #502 on the github issue tracker, submitted
by Julian Schwarz.
code now for 10 days). The last commit fixed an error when using
drcCanonicalMaxwidth() multiple times in DRC rule checks on a single
edge. At the time, I also added a method to save some
drcCanonicalMaxwidth() results to prevent needlessly re-doing the
same (potentially expensive) computation over and over. However,
where I reused the cached result, I did not check if the number of
entries is zero. Other code does not check the number of entries
and depends on the prior behavior that drcCanonicalMaxwidth()
returns NULL when there are no entries. So the code needed to check
if the number of entries is zero before re-using the cached result.
Without the fix, any time the caching is used, the last computed
maximum area rectangle will be made active even when the current
check area does not meet the area requirement, resulting in many
false positive errors.
routine, which in turn affects various DRC rules like maxrect,
widespacing, and runlength spacing. drcTile() was computing
the drcCanonicalMaxwidth() result for the tile and reusing it,
failing to account for the fact that within the loop over
DRCCookies, other rules might require calling drcCanonicalMaxwidth()
on a neighboring tile, or on the same tile with a different width
requirement. Implemented a cached version, in which three results
are kept: One for neighboring tiles (which can never be reused on
the same edge), one for the first required use of the routine for
the tile, and one for any other use required for the tile. If
there are one or two such rules for an edge, then the routine will
work at maximum efficiency. If there are three rules, then one
will always be a cache hit and reduce the total amount of
computation, although it will still be doing a massive amount of
redundant computation. If this seems to be something that
occurs regularly, then it can be revisited. The existing
implementation works fine for all the open PDKs. Some more
advanced PDKs with a number of staged wide-spacing rules could
have issues.
"magic::add_dependency" procedure. The "check" function should always
be called first, followed by the dependencies. Because otherwise, if
an incorrect value is entered for a device parameter, then it gets
used to calculate dependent values *before* it gets corrected by the
"check" procedure, resulting in an incorrect value being displayed
for the dependent value, even after the bad entry has been corrected.
the exiting documentation does not include the handful of options
available to the macro command, nor does it explain the relationship
between tools and macro sets.
"tool" command was changed to be overridden by a Tcl command. Due
to macro clients being registered with the tool name instead of
just "layout", the "macro" command with no arguments or with a
window client argument was just broken. In the process of fixing
this, I realized that there was a conflict between the use of
"netlist" as a window name and also as the name of a tool, so I
changed the tool name to "nettool", a change which should be
transparent to the end user. Otherwise, "macro netlist" returns
the key bindings for the window, and the only way to get the key
bindings for the tool is to make the tool active and then use
"macro" without arguments. One remaining issue is that there is
no syntax error that will cause the list of valid windows and
tools to be printed. Probably "macro help" should print usage
information instead of acting like "macro" with no arguments.
operator does a second search to reset tiles and clear the
"processed" mark. This second search was only searching on the
types being bloated *into* and not the original types being
bloated. This caused tiles to remain marked as "processed" which
could in turn cause the tiles to be ignored forever after, potentially
resulting in bad GDS output.
by old code that still references devices like FETs assuming
four ports. I resolved the crash condition but have not worked
on fixing the code to properly handle a variable number of
terminals per device.
had numerous problems, the main one being that each of the three
commands was inconsistent: "expand toggle" inverts the expansion
of the selection and syncs with the layout. But "expand" expands
the layout where instances overlap the box and does not sync to
the selection, and "unexpand" unexpands the layout where the box
completely surrounds instances. Added a set of options to
"expand" and "unexpand" so that these functions can be made
consistent with each other. All varieties of the function now
always sync the selection and the layout.
The main changes are:
(1) Changed the hash function used to generate the 6-character
suffix for generated device cell names. The original hash
function is not good for ensuring unique names, and can
cause cell name collisions (two different parameter sets
having the same cell name). The chance of name collisions
should now be diminishingly small.
(2) Modified the string passed to the hash:
(A) Ordered the parameter names alphabetically, since iterating
through dictionary keys is not guaranteed to be in any
specific order, leading to different strings for the same
parameter set
(B) Normalized numerical parameters, so that "2", "2.0", "2e0"
are all hashed the same, again to avoid having multiple
cell names for the same set of parameters.
(3) Fixed a problem in which when changing parameters for a cell
instance, the instance would become unselected and the instance
name would be lost and revert to magic's auto-generated name.
(4) Fixed the annoyance of having a pop-up dialog whenever magic
decides that a parameterized cell name is not being used anywhere,
and it can safely delete the cell.
(5) Fixed an issue where the check for whether a cell can be deleted
is not run consistently.
The result is, I hope, a much more pleasant experience with generated
cells.
back to the file, instead resulting in a property key only and no
value; this in turn produces an error when read back in. Another
cycle of reading and writing causes the property to disappear
altogether.
Also: Corrected another related error that claims to have truncated
the mask hints when in fact everything was working normally.
(1) There was still one place that dimensional units were not being
printed, which was "setlabel", with both "setlabel size" and
"setlabel offset". This has been fixed.
(2) Fixing (1) surfaced an error in the text helper dialog, which was
not setting units properly when checking the size and offset entries.
(3) Fixed a very long-standing problem in which port labels were showing
up with the "pale" style of a subcell's label being drawn on top
when the parent and child had the same label in exactly the same
position. This was due to a parent-first search resulting in the
child cell being visited last, so its "pale" style label being drawn
last. Added a flag for label searches for display to reverse the
search order, visiting children first and then the parent, so that
the top cell's labels are the last to be drawn.
much performance can be sped up if the DRC process can be
interrupted at much finer intervals. Unfortunately, the method
cannot work without an additional method to ensure that magic is
immediately aware when a search routine has been entered
recursively and to then break out of the search and clean up
after itself. For now, I am just commenting out the code so that
magic isn't unstable.
-DEMSCRIPTEN=1 appears to not be present any more by default in emcc compiler.
There is -D__EMSCRIPTEN__=1 but that would require modifying many locations
in the codebase which are already being reviewed separately under a single
source multi-platform build cleanup process.
Anyhow maybe ./configure would set -DEMSCRIPTEN=1 itself, much like -Dlinux=1
for other targets. This commits defers evaluation on that until later and just
restores how it worked before.
ExtNghbors.c:615:1: error: label at end of compound statement
since: 846c8e0f6 (2026-01-15 8.3.591)
This fixes AppImage 7/8/9 which use older compiler versions.
This task is failing due to invalid gmail email address or email outbound
MTA credentials via gmail, maybe the ${{secrets.MAILING_KEY}} is invalidated ?
While the docker image at vezzal/vezzal:v1 was last updated over 3y ago,
with vezzal/vezzal:v2 was last updated over 4y ago.
The project references a github upstream project that appears to be deleted
along with the entire user account associated with it.
https://hub.docker.com/r/vezzal/vezzalhttps://github.com/lankasaicharan/vezzal
Because this does not appear to exist this now becomes a security concern
as the docker contents can not be audited as to what it does and it runs in the
context of the main project GHA CI that produces redistributable artifacts.
If this is be reinstated maybe it should be done as .github/workflows/vezzal.yml
so an independant workflow outside of the main.yml CI workflow that is used to
quickly cross check compilation state of the project.
and managed to commit some code that I thought I had tested---
but apparently what I tested was not the latest version of the
code. So 8.3.627 is quite broken and won't even compile. This
update fixes that.
exceptions; avoided the use of "signed char" altogether by just
making the drcc_exception value a bit mask with the lower 7 bits
being the index and the upper bit being the flag for exception (0)
vs. exemption (1), with the value 0xff being reserved for "none"
(no exception or exemption). This implementation should avoid any
issues caused by ambiguity in the use of signed vs. unsigned char.
routine, in which it calls the same "cleanup" routine as for CIF
files, which in turn processes the top level cell. However, GDS
doesn't have the same concept of a top level cell, so it ends up
re-processing part of the last cell read. This would appear to be
harmless, except that there is some kind of scaling discrepancy
in which the cell bounding box can get incorrectly scaled by the
cleanup routine. The solution appears to be simply (?) to not do
the "top level" processing. Bypassing the CIFPaintCurrent() from
the cleanup routine when reading a GDS file appears to solve the
problem.
description, because otherwise it only appears in the tech file
reference, where it doesn't really belong since the labels are a
user-level feature, even if they do affect extraction. The new
feature of using gate attributes for parameters was added to the
command description. I noticed that the tech file reference made
mention of a gate label in the form of ":ext <name>=<value>", but
this seems not to be implemented anywhere. At any rate, the method
just committed supercedes that.
specify additional parameters for a device. Any gate attribute
(label ending with "^") that has an "=" in it is considered a
parameter, and is output with the device in the .ext file. This
gives a way to add specific parameters to a device, which otherwise
have no meaning to the layout editor. Note that prior to this
extension, the gate attribute was used only to set the device
index. If a gate attribute is made for a device index, it cannot
have "=" in the name, so it remains backwardly compatible. Only
non-parameter attributes are passed on to ext2spice.
the issue of a device name in a netlist having different case than
the procedures defined for the device in the PDK. The difference
in case is transparent to SPICE, so it should also be transparent
to the PDK.
allow ideal devices in an input netlist to be mapped to
automatically generated cells. This works if the PDK toolkit
defines a device called either "capacitor" or "resistor". The
device must be defined such that it can determine sane parameters
for the drawn device from only a value given in the netlist
(capacitance in farads, or resistance in ohms).
actually works, and also can be called multiple times. The chaining
of commands and bindings had earlier been done for one of the widget
types (selection) but not the others (entry or checkbox).
to avoid bogus values for array pitch in the direction in which
a cell is not arrayed: If the array declares an ANGLE of 90 or
270, then rows and columns are effectively swapped for the
purpose of figuring out which coordinate direction should be
ignored in the input. The original example did not use ANGLE
and so the exception was not handled.
ideal, unmodeled capacitors or resistors are missing a space
between the 2nd terminal and the device value in the output
netlist. This affects the ability to produce correct output
for, for example, a metal fingered capacitor using the
"device" property to generate an ideal capacitor in the
netlist.
to material in a child cell, and the label is a point or line label,
and the parent cell has no material other than the label in the
immediate area, then the "interaction area" will have zero area,
which will cause problems as area checks on a zero-sized area don't
do anything useful. The solution is to ensure that interaction areas
do not have zero area, but will expand around point labels. This
should not have any other implications, because the interaction area
is just a way to limit the amount of processing; larger interaction
areas do not affect the extraction result (except in this case, where
it fixes the error).
the use of "property list <key>" to return NULL if <key> is
undefined, instead of printing an error message that cannot be
suppressed. Scripts which wish to test whether or not a bounding
box exists will of course want the "quiet" version of the command.