Commit Graph

2558 Commits

Author SHA1 Message Date
R. Timothy Edwards 0013dda92d Response to issue #513 in the github issue tracker: The command-
line parser does not recognize arguments that are both in the
same word and also space separated;  this is easy to do from, e.g.,
a python interpreter by setting an option as a single string as
in "-d null";  it is harder to do from the command line, but can
be done with quotes, as in 'magic "-d null"'.

The utils/args.c routine parses this with ArgStr(), which recognizes
two cases, one in which the option is split across two arguments,
and one in which the option is one word without space separation.

I modified ArgStr() to accept a third syntax in which the option
is in a single argument but is also space-separated.  This simply
detects a space in the third character position and moves forward
to the next non-space character and returns that position.
2026-05-13 08:30:32 -04:00
R. Timothy Edwards 85561d0503 Corrected an error with the new "tagged" operator when used in
"cifinput";  instead of cifSrTiles(), which ignores the "area"
argument and searches over the entire plane, it should have been
using cifSrTiles2(), which translates the area to CIF coordinates
and searches only over that area.  Otherwise, everything on the
same layer in a cell gets tagged, rather than just connected
material.
2026-05-12 12:06:16 -04:00
R. Timothy Edwards eb83075e16 Modified EXT_DOALL to include EXT_DOUNIQUE. Prior to a recent
change, unique node names could only be enforced by running the
command "extract unique", and there was no way to ensure that
the user would run the command as part of the extraction
recipe.  Now that it has been changed to an extraction option
instead of a separate command, and does not permanently alter
labels in the layout like the standalone command version did,
it is possible to include the setting in "extract do all",
making it run by default, and requiring the user to manually
turn it off for certain use cases (which are relatively rare).
2026-05-12 10:36:36 -04:00
R. Timothy Edwards 8fea20425e Merged PR #512 from Intubun, reworking the wasm workflow. Updated
the version to force a test of the workflow.
2026-05-12 08:57:42 -04:00
Intubun ad14c26597 ci(wasm): also publish on tag push 2026-05-12 11:19:11 +02:00
Intubun 19a2d5c57c ci(wasm): auto-publish @<owner>/magic-vlsi-wasm to GitHub Packages when VERSION changes 2026-05-12 11:13:25 +02:00
R. Timothy Edwards fb01f77755 Updated the version to go along with the merge of pull request
the repo parsing on opencircuitdesign.com, since yesterday I found
out that the tags were not updating, caused by a documentation
change in a copy of the repository that created a merge conflict
when seen by the script.  Will check tomorrow that everything ran
smoothly overnight.
2026-05-11 14:23:04 -04:00
Enno Schnackenberg 9d74f4f9a7 update main.yml 2026-05-11 14:20:47 -04:00
Enno Schnackenberg 9af6b329de update main.yml 2026-05-11 14:20:47 -04:00
Enno Schnackenberg 6d3494a8fe Update extract.tcl 2026-05-11 14:20:47 -04:00
Enno Schnackenberg 068b93608a Update extract.tcl 2026-05-11 14:20:47 -04:00
Enno Schnackenberg e62626fc06 Update extract.tcl 2026-05-11 14:20:47 -04:00
Enno Schnackenberg 145fba9ac0 Update extract.tcl 2026-05-11 14:20:47 -04:00
Enno Schnackenberg 19113bec89 Update extract.tcl 2026-05-11 14:20:47 -04:00
Enno Schnackenberg 480c40f516 Update extract.tcl 2026-05-11 14:20:47 -04:00
Enno Schnackenberg 1fffc2b8b4 Update main-wasm.yml 2026-05-11 14:20:47 -04:00
Enno Schnackenberg 392d9c4408 Rework WASM CI structure 2026-05-11 14:20:47 -04:00
Enno Schnackenberg c8b50a702d Change npm examples to scmos examples 2026-05-11 14:20:47 -04:00
Intubun 354416f717 ci: add ARM WASM build job with Emscripten diagnostics to CI-aarch64 2026-05-11 14:20:47 -04:00
Intubun f802d729af Annotate ClientData callbacks: /*ARGSUSED*/ + /* UNUSED */ markers
All functions that received a ClientData (or FindRegion *) parameter in
commit fc21472e solely to satisfy WASM call_indirect signature matching
are now annotated so static analysers and casual readers can see the
intent has been verified:

  /*ARGSUSED*/          before each such function definition
  /* UNUSED */          on each unused parameter in the definition
  /* UNUSED */          on matching forward declarations

Affected: calmaWriteInitFunc, cifWriteInitFunc, cmdWindSet,
dbStampFunc, dbwElementAlways1, dbwfbWindFunc, DBWHLRedrawWind,
spcnodeHierVisit, extSDTileFunc, extTransPerimFunc,
extAnnularTileFunc, extResistorTileFunc, extDefInitFunc,
extTimesInitFunc.
2026-05-11 14:20:47 -04:00
Intubun 1d402d2c5f npm: stamp version as base-YYYYMMDD.hash on every CI build
Mirrors the AppImage versioning form (8.3.637~20260414~d157eea) as
closely as semver allows: 8.3.637-20260414.d157eea.

- package.json: placeholder 0.0.0-dev; CI always overwrites before pack
- npm-publish.yml: version step now runs unconditionally (not just on
  tags), reading VERSION + git date + git hash — dry-run artifacts are
  stamped too, making them unambiguously traceable to their source commit
2026-05-11 14:20:47 -04:00
Intubun 2d6a3a8ed6 CI: publish to GitHub Packages, emsdk latest by default, add ARM WASM job
- npm-publish.yml: target GitHub Packages instead of npm registry; no
  NPM_TOKEN needed, uses GITHUB_TOKEN
- Both workflows: emsdk defaults to 'latest' on every automated run so
  CI tracks emsdk HEAD and catches breakage early; version is overridable
  via workflow_dispatch input
- npm-publish.yml: add parallel ARM (ubuntu-24.04-arm) WASM build job
  with Emscripten diagnostics step
- main.yml, npm-publish.yml: upgrade runners from ubuntu-22.04 to
  ubuntu-latest
2026-05-11 14:20:47 -04:00
Intubun 8560027569 Add npm package and CI workflows
The user-facing layer of the WASM port: a publishable npm package
plus the GitHub Actions that build and ship it.

* npm/package.json — publishes as `magic-vlsi-wasm`, ESM-only, HPND
  licensed, version tracks Magic's own VERSION file (8.3.637).
  Whitelists the published files and exposes index.js + index.d.ts.

* npm/index.js, npm/index.d.ts — thin JS/TS wrapper around the four
  WASM exports. createMagic(opts) returns { init, runCommand,
  sourceFile, update, FS } so consumers can write into the
  Emscripten virtual filesystem and dispatch Magic commands from
  Node.js, browsers or Web Workers.

* npm/build.sh — end-to-end build: locates emsdk (via PATH or
  EMSDK_DIR), runs distclean+configure+make in the right order
  (techs before mains so embed-files are present), copies
  magic.js / magic.wasm into npm/. Optional --release, --test,
  --pack flags. Preserves configure's exec bits across invocations.

* npm/pack.sh — produces a reproducible npm tarball by touching
  every file to the build time and exporting SOURCE_DATE_EPOCH so
  pacote does not rewrite mtimes to its 1985 fallback.

* npm/examples/ — runnable smoke tests for the four common
  workflows (extract, gds, drc, cif), driven by examples/all.js.
  Each example is self-contained and uses the bundled siliwiz
  technology. helpers.js encapsulates the boilerplate.

* npm/LICENSE, npm/README.md — license text and consumer-facing
  docs (install, quick-start, API, examples, build-from-source,
  license, third-party content notice).

* .github/workflows/main.yml — adds a `simple_build_wasm` job that
  installs a pinned emsdk (3.1.56), builds the WASM module, runs
  the example test suite and uploads the npm tarball as an
  artifact. Pinned for reproducibility against the post-build.sh
  patches; switchable to "latest" by commenting two lines.

* .github/workflows/main-aarch64.yml — drops the now-redundant
  WASM ARM job. WASM is architecture-independent.

* .github/workflows/npm-publish.yml — new workflow. Publishes to
  npm on `v*` tag pushes (manual `workflow_dispatch` supported as
  a dry-run). Uses the same pinned emsdk and pack.sh.

Also sets FORCE_JAVASCRIPT_ACTIONS_TO_NODE24 in both workflows to
silence the Node.js 20 deprecation warnings until
actions/upload-artifact@v6 ships a Node-24 release.
2026-05-11 14:20:47 -04:00
Intubun 02087ea3f8 cmwind: ARGSUSED/UNUSED annotation on CMWreposition (newScreenArea unused) 2026-05-11 14:20:47 -04:00
Intubun 8e8fada32f Add WASM entry point and Emscripten build wiring
The pieces that make Magic actually buildable as a WASM library.

* magic/magicWasm.c — new headless entry point exporting four
  functions used by the JS wrapper:
    - magic_wasm_init()           idempotent initialisation
    - magic_wasm_run_command(s)   dispatch one Magic command
    - magic_wasm_source_file(p)   execute a script from the VFS
    - magic_wasm_update()         drive a display-update cycle
  Sets CAD_ROOT=/ if unset, so embedded technology files under
  /magic/sys/ resolve correctly. Centers the command point inside
  GrScreenRect so commands route to the layout window client
  rather than the border/window-management client.

* utils/main.c, utils/main.h — split magicMain() into magicMainInit()
  + the dispatch loop. magicMainInit is idempotent (a static flag
  guards against re-initialisation) so JS callers can call any of
  the four wasm entry points first without sequencing.

* magic/Makefile — adds the WASM link target, gated by MAKE_WASM=1
  set from toolchains/emscripten/defs.mak. Conditionally compiles
  magicWasm.c into the main binary, links to magic.js and runs
  post-build.sh on the result.

* toolchains/emscripten/defs.mak — Emscripten linker flags (WASM=1,
  MODULARIZE, EXPORT_ES6, ALLOW_MEMORY_GROWTH, INITIAL_MEMORY=32M,
  STACK_SIZE=5M), the four EXPORTED_FUNCTIONS, and the embed-file
  bindings for the technology files under /magic/sys/.

* toolchains/emscripten/post-build.sh — patches Emscripten's ESM
  output so it works in pure Node.js ESM: aliases require()
  through createRequire, injects __filename / __dirname shims,
  and resyncs the ___emscripten_embedded_file_data constant from
  the wasm global section if Emscripten emitted a stale value.
  Idempotent and pinned to emsdk 3.1.56 (see WARNING in the
  header).

* toolchains/emscripten/README.md — full build documentation:
  quick-start via npm/build.sh, manual build, list of embedded
  files, exported C API, JavaScript usage example, and notes on
  CAD_ROOT, DISPLAY_SUSPEND, and the signal-API stubs.

* .gitignore — adds the WASM artefacts (magic.js, magic.wasm,
  magic.symbols), tightens the editor/OS cruft list, and keeps
  toolchains/emscripten/defs.mak tracked despite the `defs.mak`
  ignore rule.
2026-05-11 14:20:47 -04:00
Intubun f4c22438c6 Wire up headless / WASM mode at module boundaries
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.
2026-05-11 14:20:47 -04:00
Intubun fdfb54badb graphics/grNull.c: typed no-op stubs for WASM call_indirect
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.
2026-05-11 14:20:47 -04:00
Intubun 6fc7b30386 Save and restore GrDisplayStatus across long operations
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
2026-05-11 14:20:47 -04:00
Intubun 476bb5474c Add ClientData parameter to indirect-call callbacks for WASM
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.
2026-05-11 14:20:47 -04:00
Intubun 537d370536 Fix five latent bugs surfaced while porting to WASM
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.
2026-05-11 14:20:47 -04:00
R. Timothy Edwards bdc0325901 Extended the use of "ext2spice resistor tee on" to include
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.
2026-05-09 20:05:52 -04:00
Ahmed Nematallah fa80458d80 Ensure layer name compatibility in wrapper.tcl
Added check for 'none' layer name to ensure backwards compatibility.
2026-05-06 11:43:32 -04:00
Ahmed Nematallah c3ee33e9a1 tcl/tk: Fix layer toolbar icon synchronization on left-click
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.
2026-05-06 11:43:32 -04:00
Ahmed Nematallah 900f6d7b0f Ensure all cells are loaded into memory in netlist_to_spice to avoid file corruption during save
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
2026-05-06 11:37:52 -04:00
Ahmed Nematallah 97fd047aab Implement existing cell check for layout generation
Added logic to check if subcircuits are already loaded and generate layouts accordingly.
2026-05-06 11:37:52 -04:00
R. Timothy Edwards df4ec3ab32 Corrects an error that can cause "extresist" to segfault. This is
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.
2026-05-06 10:21:35 -04:00
R. Timothy Edwards d0e38df6bf Fixed an error introduced in the last commit (which has been in the
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.
2026-04-24 11:21:15 -04:00
R. Timothy Edwards d157eea7f3 Fixed an error that was discovered with the drcCanonicalMaxwidth()
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.
2026-04-14 17:37:10 -04:00
R. Timothy Edwards 67c6ed9395 Corrected the handling of toolkit callbacks created by the
"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.
2026-04-13 15:29:51 -04:00
R. Timothy Edwards f15f0dabbb Added HTML documentation for the "macro" command, after finding that
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.
2026-04-13 13:01:54 -04:00
R. Timothy Edwards ae6d26578e Fixed issues with the "macro" command that have existed since the
"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.
2026-04-13 12:26:42 -04:00
R. Timothy Edwards cb1653b157 Found that I needed to apply the same correction as the last
commit to the "tagged" GDS/CIF operator, or else this will have
exactly the same issue as "bloat-all".
2026-04-10 13:39:17 -04:00
R. Timothy Edwards a3f5e665d1 Found an extremely bad error, where the "bloat-all" GDS output
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.
2026-04-09 11:13:30 -04:00
R. Timothy Edwards 2eea849c06 Corrected a crash condition in R-C extraction (extresist) caused
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.
2026-04-07 21:15:56 -04:00
R. Timothy Edwards 6e295d030e Also updated the HTML command reference for the "expand" and
"unexpand" commands to include the options just implemented.
2026-04-04 21:03:06 -04:00
R. Timothy Edwards ceba050a21 Fixed the mess that is the "expand"/"unexpand" command set. This
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.
2026-04-04 20:47:04 -04:00
R. Timothy Edwards f7cceed5e3 Made a fairly major overhaul to the toolkit for generated devices.
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.
2026-04-02 17:13:17 -04:00
R. Timothy Edwards 5d35ae38b5 Corrected an issue causing MASKHINTS values to fail to be written
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.
2026-04-02 14:45:08 -04:00
R. Timothy Edwards 05561b90f3 Solved three issues:
(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.
2026-04-01 21:17:54 -04:00
R. Timothy Edwards 06eab7feb6 Removed three lines of code that were meant to be a test of how
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.
2026-03-26 19:44:00 -04:00